blob: 7a65c2a6fe2c2f5502e8ed4bf0ffc2788280244a [file] [log] [blame]
//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// This file implements semantic analysis for C++ templates.
#include "TreeTransform.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include <iterator>
using namespace clang;
using namespace sema;
// Exported for use by Parser.
clang::getTemplateParamsRange(TemplateParameterList const * const *Ps,
unsigned N) {
if (!N) return SourceRange();
return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc());
unsigned Sema::getTemplateDepth(Scope *S) const {
unsigned Depth = 0;
// Each template parameter scope represents one level of template parameter
// depth.
for (Scope *TempParamScope = S->getTemplateParamParent(); TempParamScope;
TempParamScope = TempParamScope->getParent()->getTemplateParamParent()) {
// Note that there are template parameters with the given depth.
auto ParamsAtDepth = [&](unsigned D) { Depth = std::max(Depth, D + 1); };
// Look for parameters of an enclosing generic lambda. We don't create a
// template parameter scope for these.
for (FunctionScopeInfo *FSI : getFunctionScopes()) {
if (auto *LSI = dyn_cast<LambdaScopeInfo>(FSI)) {
if (!LSI->TemplateParams.empty()) {
if (LSI->GLTemplateParameterList) {
// Look for parameters of an enclosing terse function template. We don't
// create a template parameter scope for these either.
for (const InventedTemplateParameterInfo &Info :
getInventedParameterInfos()) {
if (!Info.TemplateParams.empty()) {
return Depth;
/// \brief Determine whether the declaration found is acceptable as the name
/// of a template and, if so, return that template declaration. Otherwise,
/// returns null.
/// Note that this may return an UnresolvedUsingValueDecl if AllowDependent
/// is true. In all other cases it will return a TemplateDecl (or null).
NamedDecl *Sema::getAsTemplateNameDecl(NamedDecl *D,
bool AllowFunctionTemplates,
bool AllowDependent) {
D = D->getUnderlyingDecl();
if (isa<TemplateDecl>(D)) {
if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D))
return nullptr;
return D;
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
// C++ [temp.local]p1:
// Like normal (non-template) classes, class templates have an
// injected-class-name (Clause 9). The injected-class-name
// can be used with or without a template-argument-list. When
// it is used without a template-argument-list, it is
// equivalent to the injected-class-name followed by the
// template-parameters of the class template enclosed in
// <>. When it is used with a template-argument-list, it
// refers to the specified class template specialization,
// which could be the current specialization or another
// specialization.
if (Record->isInjectedClassName()) {
Record = cast<CXXRecordDecl>(Record->getDeclContext());
if (Record->getDescribedClassTemplate())
return Record->getDescribedClassTemplate();
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Record))
return Spec->getSpecializedTemplate();
return nullptr;
// 'using Dependent::foo;' can resolve to a template name.
// 'using typename Dependent::foo;' cannot (not even if 'foo' is an
// injected-class-name).
if (AllowDependent && isa<UnresolvedUsingValueDecl>(D))
return D;
return nullptr;
void Sema::FilterAcceptableTemplateNames(LookupResult &R,
bool AllowFunctionTemplates,
bool AllowDependent) {
LookupResult::Filter filter = R.makeFilter();
while (filter.hasNext()) {
NamedDecl *Orig =;
if (!getAsTemplateNameDecl(Orig, AllowFunctionTemplates, AllowDependent))
bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R,
bool AllowFunctionTemplates,
bool AllowDependent,
bool AllowNonTemplateFunctions) {
for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) {
if (getAsTemplateNameDecl(*I, AllowFunctionTemplates, AllowDependent))
return true;
if (AllowNonTemplateFunctions &&
return true;
return false;
TemplateNameKind Sema::isTemplateName(Scope *S,
CXXScopeSpec &SS,
bool hasTemplateKeyword,
const UnqualifiedId &Name,
ParsedType ObjectTypePtr,
bool EnteringContext,
TemplateTy &TemplateResult,
bool &MemberOfUnknownSpecialization,
bool Disambiguation) {
assert(getLangOpts().CPlusPlus && "No template names in C!");
DeclarationName TName;
MemberOfUnknownSpecialization = false;
switch (Name.getKind()) {
case UnqualifiedIdKind::IK_Identifier:
TName = DeclarationName(Name.Identifier);
case UnqualifiedIdKind::IK_OperatorFunctionId:
TName = Context.DeclarationNames.getCXXOperatorName(
case UnqualifiedIdKind::IK_LiteralOperatorId:
TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier);
return TNK_Non_template;
QualType ObjectType = ObjectTypePtr.get();
AssumedTemplateKind AssumedTemplate;
LookupResult R(*this, TName, Name.getBeginLoc(), LookupOrdinaryName);
if (LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
MemberOfUnknownSpecialization, SourceLocation(),
return TNK_Non_template;
if (AssumedTemplate != AssumedTemplateKind::None) {
TemplateResult = TemplateTy::make(Context.getAssumedTemplateName(TName));
// Let the parser know whether we found nothing or found functions; if we
// found nothing, we want to more carefully check whether this is actually
// a function template name versus some other kind of undeclared identifier.
return AssumedTemplate == AssumedTemplateKind::FoundNothing
? TNK_Undeclared_template
: TNK_Function_template;
if (R.empty())
return TNK_Non_template;
NamedDecl *D = nullptr;
if (R.isAmbiguous()) {
// If we got an ambiguity involving a non-function template, treat this
// as a template name, and pick an arbitrary template for error recovery.
bool AnyFunctionTemplates = false;
for (NamedDecl *FoundD : R) {
if (NamedDecl *FoundTemplate = getAsTemplateNameDecl(FoundD)) {
if (isa<FunctionTemplateDecl>(FoundTemplate))
AnyFunctionTemplates = true;
else {
D = FoundTemplate;
// If we didn't find any templates at all, this isn't a template name.
// Leave the ambiguity for a later lookup to diagnose.
if (!D && !AnyFunctionTemplates) {
return TNK_Non_template;
// If the only templates were function templates, filter out the rest.
// We'll diagnose the ambiguity later.
if (!D)
// At this point, we have either picked a single template name declaration D
// or we have a non-empty set of results R containing either one template name
// declaration or a set of function templates.
TemplateName Template;
TemplateNameKind TemplateKind;
unsigned ResultCount = R.end() - R.begin();
if (!D && ResultCount > 1) {
// We assume that we'll preserve the qualifier from a function
// template name in other ways.
Template = Context.getOverloadedTemplateName(R.begin(), R.end());
TemplateKind = TNK_Function_template;
// We'll do this lookup again later.
} else {
if (!D) {
D = getAsTemplateNameDecl(*R.begin());
assert(D && "unambiguous result is not a template name");
if (isa<UnresolvedUsingValueDecl>(D)) {
// We don't yet know whether this is a template-name or not.
MemberOfUnknownSpecialization = true;
return TNK_Non_template;
TemplateDecl *TD = cast<TemplateDecl>(D);
if (SS.isSet() && !SS.isInvalid()) {
NestedNameSpecifier *Qualifier = SS.getScopeRep();
Template = Context.getQualifiedTemplateName(Qualifier,
hasTemplateKeyword, TD);
} else {
Template = TemplateName(TD);
if (isa<FunctionTemplateDecl>(TD)) {
TemplateKind = TNK_Function_template;
// We'll do this lookup again later.
} else {
assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD) ||
isa<TypeAliasTemplateDecl>(TD) || isa<VarTemplateDecl>(TD) ||
isa<BuiltinTemplateDecl>(TD) || isa<ConceptDecl>(TD));
TemplateKind =
isa<VarTemplateDecl>(TD) ? TNK_Var_template :
isa<ConceptDecl>(TD) ? TNK_Concept_template :
TemplateResult = TemplateTy::make(Template);
return TemplateKind;
bool Sema::isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
SourceLocation NameLoc,
ParsedTemplateTy *Template) {
CXXScopeSpec SS;
bool MemberOfUnknownSpecialization = false;
// We could use redeclaration lookup here, but we don't need to: the
// syntactic form of a deduction guide is enough to identify it even
// if we can't look up the template name at all.
LookupResult R(*this, DeclarationName(&Name), NameLoc, LookupOrdinaryName);
if (LookupTemplateName(R, S, SS, /*ObjectType*/ QualType(),
/*EnteringContext*/ false,
return false;
if (R.empty()) return false;
if (R.isAmbiguous()) {
// FIXME: Diagnose an ambiguity if we find at least one template.
return false;
// We only treat template-names that name type templates as valid deduction
// guide names.
TemplateDecl *TD = R.getAsSingle<TemplateDecl>();
if (!TD || !getAsTypeTemplateDecl(TD))
return false;
if (Template)
*Template = TemplateTy::make(TemplateName(TD));
return true;
bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
SourceLocation IILoc,
Scope *S,
const CXXScopeSpec *SS,
TemplateTy &SuggestedTemplate,
TemplateNameKind &SuggestedKind) {
// We can't recover unless there's a dependent scope specifier preceding the
// template name.
// FIXME: Typo correction?
if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
return false;
// The code is missing a 'template' keyword prior to the dependent template
// name.
NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep();
Diag(IILoc, diag::err_template_kw_missing)
<< Qualifier << II.getName()
<< FixItHint::CreateInsertion(IILoc, "template ");
= TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II));
SuggestedKind = TNK_Dependent_template_name;
return true;
bool Sema::LookupTemplateName(LookupResult &Found,
Scope *S, CXXScopeSpec &SS,
QualType ObjectType,
bool EnteringContext,
bool &MemberOfUnknownSpecialization,
RequiredTemplateKind RequiredTemplate,
AssumedTemplateKind *ATK,
bool AllowTypoCorrection) {
if (ATK)
*ATK = AssumedTemplateKind::None;
if (SS.isInvalid())
return true;
// Determine where to perform name lookup
MemberOfUnknownSpecialization = false;
DeclContext *LookupCtx = nullptr;
bool IsDependent = false;
if (!ObjectType.isNull()) {
// This nested-name-specifier occurs in a member access expression, e.g.,
// x->B::f, and we are looking into the type of the object.
assert(SS.isEmpty() && "ObjectType and scope specifier cannot coexist");
LookupCtx = computeDeclContext(ObjectType);
IsDependent = !LookupCtx && ObjectType->isDependentType();
assert((IsDependent || !ObjectType->isIncompleteType() ||
ObjectType->castAs<TagType>()->isBeingDefined()) &&
"Caller should have completed object type");
// Template names cannot appear inside an Objective-C class or object type
// or a vector type.
// FIXME: This is wrong. For example:
// template<typename T> using Vec = T __attribute__((ext_vector_type(4)));
// Vec<int> vi;
// vi.Vec<int>::~Vec<int>();
// ... should be accepted but we will not treat 'Vec' as a template name
// here. The right thing to do would be to check if the name is a valid
// vector component name, and look up a template name if not. And similarly
// for lookups into Objective-C class and object types, where the same
// problem can arise.
if (ObjectType->isObjCObjectOrInterfaceType() ||
ObjectType->isVectorType()) {
return false;
} else if (SS.isNotEmpty()) {
// This nested-name-specifier occurs after another nested-name-specifier,
// so long into the context associated with the prior nested-name-specifier.
LookupCtx = computeDeclContext(SS, EnteringContext);
IsDependent = !LookupCtx && isDependentScopeSpecifier(SS);
// The declaration context must be complete.
if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx))
return true;
bool ObjectTypeSearchedInScope = false;
bool AllowFunctionTemplatesInLookup = true;
if (LookupCtx) {
// Perform "qualified" name lookup into the declaration context we
// computed, which is either the type of the base of a member access
// expression or the declaration context associated with a prior
// nested-name-specifier.
LookupQualifiedName(Found, LookupCtx);
// FIXME: The C++ standard does not clearly specify what happens in the
// case where the object type is dependent, and implementations vary. In
// Clang, we treat a name after a . or -> as a template-name if lookup
// finds a non-dependent member or member of the current instantiation that
// is a type template, or finds no such members and lookup in the context
// of the postfix-expression finds a type template. In the latter case, the
// name is nonetheless dependent, and we may resolve it to a member of an
// unknown specialization when we come to instantiate the template.
IsDependent |= Found.wasNotFoundInCurrentInstantiation();
if (SS.isEmpty() && (ObjectType.isNull() || Found.empty())) {
// C++ [basic.lookup.classref]p1:
// In a class member access expression (5.2.5), if the . or -> token is
// immediately followed by an identifier followed by a <, the
// identifier must be looked up to determine whether the < is the
// beginning of a template argument list (14.2) or a less-than operator.
// The identifier is first looked up in the class of the object
// expression. If the identifier is not found, it is then looked up in
// the context of the entire postfix-expression and shall name a class
// template.
if (S)
LookupName(Found, S);
if (!ObjectType.isNull()) {
// FIXME: We should filter out all non-type templates here, particularly
// variable templates and concepts. But the exclusion of alias templates
// and template template parameters is a wording defect.
AllowFunctionTemplatesInLookup = false;
ObjectTypeSearchedInScope = true;
IsDependent |= Found.wasNotFoundInCurrentInstantiation();
if (Found.isAmbiguous())
return false;
if (ATK && SS.isEmpty() && ObjectType.isNull() &&
!RequiredTemplate.hasTemplateKeyword()) {
// C++2a [temp.names]p2:
// A name is also considered to refer to a template if it is an
// unqualified-id followed by a < and name lookup finds either one or more
// functions or finds nothing.
// To keep our behavior consistent, we apply the "finds nothing" part in
// all language modes, and diagnose the empty lookup in ActOnCallExpr if we
// successfully form a call to an undeclared template-id.
bool AllFunctions =
getLangOpts().CPlusPlus20 &&
std::all_of(Found.begin(), Found.end(), [](NamedDecl *ND) {
return isa<FunctionDecl>(ND->getUnderlyingDecl());
if (AllFunctions || (Found.empty() && !IsDependent)) {
// If lookup found any functions, or if this is a name that can only be
// used for a function, then strongly assume this is a function
// template-id.
*ATK = (Found.empty() && Found.getLookupName().isIdentifier())
? AssumedTemplateKind::FoundNothing
: AssumedTemplateKind::FoundFunctions;
return false;
if (Found.empty() && !IsDependent && AllowTypoCorrection) {
// If we did not find any names, and this is not a disambiguation, attempt
// to correct any typos.
DeclarationName Name = Found.getLookupName();
// Simple filter callback that, for keywords, only accepts the C++ *_cast
DefaultFilterCCC FilterCCC{};
FilterCCC.WantTypeSpecifiers = false;
FilterCCC.WantExpressionKeywords = false;
FilterCCC.WantRemainingKeywords = false;
FilterCCC.WantCXXNamedCasts = true;
if (TypoCorrection Corrected =
CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S,
&SS, FilterCCC, CTK_ErrorRecovery, LookupCtx)) {
if (auto *ND = Corrected.getFoundDecl())
if (Found.isAmbiguous()) {
} else if (!Found.empty()) {
if (LookupCtx) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
Name.getAsString() == CorrectedStr;
diagnoseTypo(Corrected, PDiag(diag::err_no_member_template_suggest)
<< Name << LookupCtx << DroppedSpecifier
<< SS.getRange());
} else {
diagnoseTypo(Corrected, PDiag(diag::err_no_template_suggest) << Name);
NamedDecl *ExampleLookupResult =
Found.empty() ? nullptr : Found.getRepresentativeDecl();
FilterAcceptableTemplateNames(Found, AllowFunctionTemplatesInLookup);
if (Found.empty()) {
if (IsDependent) {
MemberOfUnknownSpecialization = true;
return false;
// If a 'template' keyword was used, a lookup that finds only non-template
// names is an error.
if (ExampleLookupResult && RequiredTemplate) {
Diag(Found.getNameLoc(), diag::err_template_kw_refers_to_non_template)
<< Found.getLookupName() << SS.getRange()
<< RequiredTemplate.hasTemplateKeyword()
<< RequiredTemplate.getTemplateKeywordLoc();
<< Found.getLookupName();
return true;
return false;
if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope &&
!getLangOpts().CPlusPlus11) {
// C++03 [basic.lookup.classref]p1:
// [...] If the lookup in the class of the object expression finds a
// template, the name is also looked up in the context of the entire
// postfix-expression and [...]
// Note: C++11 does not perform this second lookup.
LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(),
LookupName(FoundOuter, S);
// FIXME: We silently accept an ambiguous lookup here, in violation of
// [basic.lookup]/1.
FilterAcceptableTemplateNames(FoundOuter, /*AllowFunctionTemplates=*/false);
NamedDecl *OuterTemplate;
if (FoundOuter.empty()) {
// - if the name is not found, the name found in the class of the
// object expression is used, otherwise
} else if (FoundOuter.isAmbiguous() || !FoundOuter.isSingleResult() ||
!(OuterTemplate =
getAsTemplateNameDecl(FoundOuter.getFoundDecl()))) {
// - if the name is found in the context of the entire
// postfix-expression and does not name a class template, the name
// found in the class of the object expression is used, otherwise
} else if (!Found.isSuppressingDiagnostics()) {
// - if the name found is a class template, it must refer to the same
// entity as the one found in the class of the object expression,
// otherwise the program is ill-formed.
if (!Found.isSingleResult() ||
getAsTemplateNameDecl(Found.getFoundDecl())->getCanonicalDecl() !=
OuterTemplate->getCanonicalDecl()) {
<< Found.getLookupName()
<< ObjectType;
<< ObjectType;
// Recover by taking the template that we found in the object
// expression's type.
return false;
void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
SourceLocation Less,
SourceLocation Greater) {
if (TemplateName.isInvalid())
DeclarationNameInfo NameInfo;
CXXScopeSpec SS;
LookupNameKind LookupKind;
DeclContext *LookupCtx = nullptr;
NamedDecl *Found = nullptr;
bool MissingTemplateKeyword = false;
// Figure out what name we looked up.
if (auto *DRE = dyn_cast<DeclRefExpr>(TemplateName.get())) {
NameInfo = DRE->getNameInfo();
LookupKind = LookupOrdinaryName;
Found = DRE->getFoundDecl();
} else if (auto *ME = dyn_cast<MemberExpr>(TemplateName.get())) {
NameInfo = ME->getMemberNameInfo();
LookupKind = LookupMemberName;
LookupCtx = ME->getBase()->getType()->getAsCXXRecordDecl();
Found = ME->getMemberDecl();
} else if (auto *DSDRE =
dyn_cast<DependentScopeDeclRefExpr>(TemplateName.get())) {
NameInfo = DSDRE->getNameInfo();
MissingTemplateKeyword = true;
} else if (auto *DSME =
dyn_cast<CXXDependentScopeMemberExpr>(TemplateName.get())) {
NameInfo = DSME->getMemberNameInfo();
MissingTemplateKeyword = true;
} else {
llvm_unreachable("unexpected kind of potential template name");
// If this is a dependent-scope lookup, diagnose that the 'template' keyword
// was missing.
if (MissingTemplateKeyword) {
Diag(NameInfo.getBeginLoc(), diag::err_template_kw_missing)
<< "" << NameInfo.getName().getAsString() << SourceRange(Less, Greater);
// Try to correct the name by looking for templates and C++ named casts.
struct TemplateCandidateFilter : CorrectionCandidateCallback {
Sema &S;
TemplateCandidateFilter(Sema &S) : S(S) {
WantTypeSpecifiers = false;
WantExpressionKeywords = false;
WantRemainingKeywords = false;
WantCXXNamedCasts = true;
bool ValidateCandidate(const TypoCorrection &Candidate) override {
if (auto *ND = Candidate.getCorrectionDecl())
return S.getAsTemplateNameDecl(ND);
return Candidate.isKeyword();
std::unique_ptr<CorrectionCandidateCallback> clone() override {
return std::make_unique<TemplateCandidateFilter>(*this);
DeclarationName Name = NameInfo.getName();
TemplateCandidateFilter CCC(*this);
if (TypoCorrection Corrected = CorrectTypo(NameInfo, LookupKind, S, &SS, CCC,
CTK_ErrorRecovery, LookupCtx)) {
auto *ND = Corrected.getFoundDecl();
if (ND)
ND = getAsTemplateNameDecl(ND);
if (ND || Corrected.isKeyword()) {
if (LookupCtx) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
Name.getAsString() == CorrectedStr;
<< Name << LookupCtx << DroppedSpecifier
<< SS.getRange(), false);
} else {
<< Name, false);
if (Found)
Diag(NameInfo.getLoc(), diag::err_non_template_in_template_id)
<< Name << SourceRange(Less, Greater);
if (Found)
Diag(Found->getLocation(), diag::note_non_template_in_template_id_found);
/// ActOnDependentIdExpression - Handle a dependent id-expression that
/// was just parsed. This is only possible with an explicit scope
/// specifier naming a dependent type.
Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
bool isAddressOfOperand,
const TemplateArgumentListInfo *TemplateArgs) {
DeclContext *DC = getFunctionLevelDeclContext();
// C++11 [expr.prim.general]p12:
// An id-expression that denotes a non-static data member or non-static
// member function of a class can only be used:
// (...)
// - if that id-expression denotes a non-static data member and it
// appears in an unevaluated operand.
// If this might be the case, form a DependentScopeDeclRefExpr instead of a
// CXXDependentScopeMemberExpr. The former can instantiate to either
// DeclRefExpr or MemberExpr depending on lookup results, while the latter is
// always a MemberExpr.
bool MightBeCxx11UnevalField =
getLangOpts().CPlusPlus11 && isUnevaluatedContext();
// Check if the nested name specifier is an enum type.
bool IsEnum = false;
if (NestedNameSpecifier *NNS = SS.getScopeRep())
IsEnum = dyn_cast_or_null<EnumType>(NNS->getAsType());
if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum &&
isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->isInstance()) {
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType();
// Since the 'this' expression is synthesized, we don't need to
// perform the double-lookup check.
NamedDecl *FirstQualifierInScope = nullptr;
return CXXDependentScopeMemberExpr::Create(
Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true,
/*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc,
FirstQualifierInScope, NameInfo, TemplateArgs);
return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
// DependentScopeDeclRefExpr::Create requires a valid QualifierLoc
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
if (!QualifierLoc)
return ExprError();
return DependentScopeDeclRefExpr::Create(
Context, QualifierLoc, TemplateKWLoc, NameInfo, TemplateArgs);
/// Determine whether we would be unable to instantiate this template (because
/// it either has no definition, or is in the process of being instantiated).
bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
NamedDecl *Instantiation,
bool InstantiatedFromMember,
const NamedDecl *Pattern,
const NamedDecl *PatternDef,
TemplateSpecializationKind TSK,
bool Complain /*= true*/) {
assert(isa<TagDecl>(Instantiation) || isa<FunctionDecl>(Instantiation) ||
bool IsEntityBeingDefined = false;
if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(PatternDef))
IsEntityBeingDefined = TD->isBeingDefined();
if (PatternDef && !IsEntityBeingDefined) {
NamedDecl *SuggestedDef = nullptr;
if (!hasVisibleDefinition(const_cast<NamedDecl*>(PatternDef), &SuggestedDef,
/*OnlyNeedComplete*/false)) {
// If we're allowed to diagnose this and recover, do so.
bool Recover = Complain && !isSFINAEContext();
if (Complain)
diagnoseMissingImport(PointOfInstantiation, SuggestedDef,
Sema::MissingImportKind::Definition, Recover);
return !Recover;
return false;
if (!Complain || (PatternDef && PatternDef->isInvalidDecl()))
return true;
llvm::Optional<unsigned> Note;
QualType InstantiationTy;
if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
InstantiationTy = Context.getTypeDeclType(TD);
if (PatternDef) {
<< /*implicit|explicit*/(TSK != TSK_ImplicitInstantiation)
<< InstantiationTy;
// Not much point in noting the template declaration here, since
// we're lexically inside it.
} else if (InstantiatedFromMember) {
if (isa<FunctionDecl>(Instantiation)) {
<< /*member function*/ 1 << Instantiation->getDeclName()
<< Instantiation->getDeclContext();
Note = diag::note_explicit_instantiation_here;
} else {
assert(isa<TagDecl>(Instantiation) && "Must be a TagDecl!");
<< InstantiationTy;
Note = diag::note_member_declared_at;
} else {
if (isa<FunctionDecl>(Instantiation)) {
<< Pattern;
Note = diag::note_explicit_instantiation_here;
} else if (isa<TagDecl>(Instantiation)) {
Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
<< (TSK != TSK_ImplicitInstantiation)
<< InstantiationTy;
Note = diag::note_template_decl_here;
} else {
assert(isa<VarDecl>(Instantiation) && "Must be a VarDecl!");
if (isa<VarTemplateSpecializationDecl>(Instantiation)) {
<< Instantiation;
} else
<< /*static data member*/ 2 << Instantiation->getDeclName()
<< Instantiation->getDeclContext();
Note = diag::note_explicit_instantiation_here;
if (Note) // Diagnostics were emitted.
Diag(Pattern->getLocation(), Note.getValue());
// In general, Instantiation isn't marked invalid to get more than one
// error for multiple undefined instantiations. But the code that does
// explicit declaration -> explicit definition conversion can't handle
// invalid declarations, so mark as invalid in that case.
if (TSK == TSK_ExplicitInstantiationDeclaration)
return true;
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
/// that the template parameter 'PrevDecl' is being shadowed by a new
/// declaration at location Loc. Returns true to indicate that this is
/// an error, and false otherwise.
void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
// C++ [temp.local]p4:
// A template-parameter shall not be redeclared within its
// scope (including nested scopes).
// Make this a warning when MSVC compatibility is requested.
unsigned DiagId = getLangOpts().MSVCCompat ? diag::ext_template_param_shadow
: diag::err_template_param_shadow;
Diag(Loc, DiagId) << cast<NamedDecl>(PrevDecl)->getDeclName();
Diag(PrevDecl->getLocation(), diag::note_template_param_here);
/// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
/// the parameter D to reference the templated declaration and return a pointer
/// to the template declaration. Otherwise, do nothing to D and return null.
TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) {
D = Temp->getTemplatedDecl();
return Temp;
return nullptr;
ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion(
SourceLocation EllipsisLoc) const {
assert(Kind == Template &&
"Only template template arguments can be pack expansions here");
assert(getAsTemplate().get().containsUnexpandedParameterPack() &&
"Template template argument pack expansion without packs");
ParsedTemplateArgument Result(*this);
Result.EllipsisLoc = EllipsisLoc;
return Result;
static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
const ParsedTemplateArgument &Arg) {
switch (Arg.getKind()) {
case ParsedTemplateArgument::Type: {
TypeSourceInfo *DI;
QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI);
if (!DI)
DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation());
return TemplateArgumentLoc(TemplateArgument(T), DI);
case ParsedTemplateArgument::NonType: {
Expr *E = static_cast<Expr *>(Arg.getAsExpr());
return TemplateArgumentLoc(TemplateArgument(E), E);
case ParsedTemplateArgument::Template: {
TemplateName Template = Arg.getAsTemplate().get();
TemplateArgument TArg;
if (Arg.getEllipsisLoc().isValid())
TArg = TemplateArgument(Template, Optional<unsigned int>());
TArg = Template;
return TemplateArgumentLoc(
SemaRef.Context, TArg,
Arg.getLocation(), Arg.getEllipsisLoc());
llvm_unreachable("Unhandled parsed template argument");
/// Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis.
void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
TemplateArgumentListInfo &TemplateArgs) {
for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I)
static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S,
SourceLocation Loc,
IdentifierInfo *Name) {
NamedDecl *PrevDecl = SemaRef.LookupSingleName(
S, Name, Loc, Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration);
if (PrevDecl && PrevDecl->isTemplateParameter())
SemaRef.DiagnoseTemplateParameterShadow(Loc, PrevDecl);
/// Convert a parsed type into a parsed template argument. This is mostly
/// trivial, except that we may have parsed a C++17 deduced class template
/// specialization type, in which case we should form a template template
/// argument instead of a type template argument.
ParsedTemplateArgument Sema::ActOnTemplateTypeArgument(TypeResult ParsedType) {
TypeSourceInfo *TInfo;
QualType T = GetTypeFromParser(ParsedType.get(), &TInfo);
if (T.isNull())
return ParsedTemplateArgument();
assert(TInfo && "template argument with no location");
// If we might have formed a deduced template specialization type, convert
// it to a template template argument.
if (getLangOpts().CPlusPlus17) {
TypeLoc TL = TInfo->getTypeLoc();
SourceLocation EllipsisLoc;
if (auto PET = TL.getAs<PackExpansionTypeLoc>()) {
EllipsisLoc = PET.getEllipsisLoc();
TL = PET.getPatternLoc();
CXXScopeSpec SS;
if (auto ET = TL.getAs<ElaboratedTypeLoc>()) {
TL = ET.getNamedTypeLoc();
if (auto DTST = TL.getAs<DeducedTemplateSpecializationTypeLoc>()) {
TemplateName Name = DTST.getTypePtr()->getTemplateName();
if (SS.isSet())
Name = Context.getQualifiedTemplateName(SS.getScopeRep(),
/*HasTemplateKeyword*/ false,
ParsedTemplateArgument Result(SS, TemplateTy::make(Name),
if (EllipsisLoc.isValid())
Result = Result.getTemplatePackExpansion(EllipsisLoc);
return Result;
// This is a normal type template argument. Note, if the type template
// argument is an injected-class-name for a template, it has a dual nature
// and can be used as either a type or a template. We handle that in
// convertTypeTemplateArgumentToTemplate.
return ParsedTemplateArgument(ParsedTemplateArgument::Type,
/// ActOnTypeParameter - Called when a C++ template type parameter
/// (e.g., "typename T") has been parsed. Typename specifies whether
/// the keyword "typename" was used to declare the type parameter
/// (otherwise, "class" was used), and KeyLoc is the location of the
/// "class" or "typename" keyword. ParamName is the name of the
/// parameter (NULL indicates an unnamed template parameter) and
/// ParamNameLoc is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
NamedDecl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
SourceLocation ParamNameLoc,
unsigned Depth, unsigned Position,
SourceLocation EqualLoc,
ParsedType DefaultArg,
bool HasTypeConstraint) {
assert(S->isTemplateParamScope() &&
"Template type parameter not in template parameter scope!");
bool IsParameterPack = EllipsisLoc.isValid();
TemplateTypeParmDecl *Param
= TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
KeyLoc, ParamNameLoc, Depth, Position,
ParamName, Typename, IsParameterPack,
if (Param->isParameterPack())
if (auto *LSI = getEnclosingLambda())
if (ParamName) {
maybeDiagnoseTemplateParameterShadow(*this, S, ParamNameLoc, ParamName);
// Add the template parameter into the current scope.
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
if (DefaultArg && IsParameterPack) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
DefaultArg = nullptr;
// Handle the default argument, if provided.
if (DefaultArg) {
TypeSourceInfo *DefaultTInfo;
GetTypeFromParser(DefaultArg, &DefaultTInfo);
assert(DefaultTInfo && "expected source information for type");
// Check for unexpanded parameter packs.
if (DiagnoseUnexpandedParameterPack(ParamNameLoc, DefaultTInfo,
return Param;
// Check the template argument itself.
if (CheckTemplateArgument(Param, DefaultTInfo)) {
return Param;
return Param;
/// Convert the parser's template argument list representation into our form.
static TemplateArgumentListInfo
makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation &TemplateId) {
TemplateArgumentListInfo TemplateArgs(TemplateId.LAngleLoc,
ASTTemplateArgsPtr TemplateArgsPtr(TemplateId.getTemplateArgs(),
S.translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
return TemplateArgs;
bool Sema::ActOnTypeConstraint(const CXXScopeSpec &SS,
TemplateIdAnnotation *TypeConstr,
TemplateTypeParmDecl *ConstrainedParameter,
SourceLocation EllipsisLoc) {
ConceptDecl *CD =
// C++2a [temp.param]p4:
// [...] The concept designated by a type-constraint shall be a type
// concept ([temp.concept]).
if (!CD->isTypeConcept()) {
return true;
bool WereArgsSpecified = TypeConstr->LAngleLoc.isValid();
if (!WereArgsSpecified &&
CD->getTemplateParameters()->getMinRequiredArguments() > 1) {
diag::err_type_constraint_missing_arguments) << CD;
return true;
TemplateArgumentListInfo TemplateArgs;
if (TypeConstr->LAngleLoc.isValid()) {
TemplateArgs =
makeTemplateArgumentListInfo(*this, *TypeConstr);
return AttachTypeConstraint(
SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc(),
TypeConstr->TemplateNameLoc), CD,
TypeConstr->LAngleLoc.isValid() ? &TemplateArgs : nullptr,
ConstrainedParameter, EllipsisLoc);
template<typename ArgumentLocAppender>
static ExprResult formImmediatelyDeclaredConstraint(
Sema &S, NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo,
ConceptDecl *NamedConcept, SourceLocation LAngleLoc,
SourceLocation RAngleLoc, QualType ConstrainedType,
SourceLocation ParamNameLoc, ArgumentLocAppender Appender,
SourceLocation EllipsisLoc) {
TemplateArgumentListInfo ConstraintArgs;
/*NTTPType=*/QualType(), ParamNameLoc));
// C++2a [temp.param]p4:
// [...] This constraint-expression E is called the immediately-declared
// constraint of T. [...]
CXXScopeSpec SS;
ExprResult ImmediatelyDeclaredConstraint = S.CheckConceptTemplateId(
SS, /*TemplateKWLoc=*/SourceLocation(), NameInfo,
/*FoundDecl=*/NamedConcept, NamedConcept, &ConstraintArgs);
if (ImmediatelyDeclaredConstraint.isInvalid() || !EllipsisLoc.isValid())
return ImmediatelyDeclaredConstraint;
// C++2a [temp.param]p4:
// [...] If T is not a pack, then E is E', otherwise E is (E' && ...).
// We have the following case:
// template<typename T> concept C1 = true;
// template<C1... T> struct s1;
// The constraint: (C1<T> && ...)
// Note that the type of C1<T> is known to be 'bool', so we don't need to do
// any unqualified lookups for 'operator&&' here.
return S.BuildCXXFoldExpr(/*UnqualifiedLookup=*/nullptr,
ImmediatelyDeclaredConstraint.get(), BO_LAnd,
EllipsisLoc, /*RHS=*/nullptr,
/// Attach a type-constraint to a template parameter.
/// \returns true if an error occured. This can happen if the
/// immediately-declared constraint could not be formed (e.g. incorrect number
/// of arguments for the named concept).
bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS,
DeclarationNameInfo NameInfo,
ConceptDecl *NamedConcept,
const TemplateArgumentListInfo *TemplateArgs,
TemplateTypeParmDecl *ConstrainedParameter,
SourceLocation EllipsisLoc) {
// C++2a [temp.param]p4:
// [...] If Q is of the form C<A1, ..., An>, then let E' be
// C<T, A1, ..., An>. Otherwise, let E' be C<T>. [...]
const ASTTemplateArgumentListInfo *ArgsAsWritten =
TemplateArgs ? ASTTemplateArgumentListInfo::Create(Context,
*TemplateArgs) : nullptr;
QualType ParamAsArgument(ConstrainedParameter->getTypeForDecl(), 0);
ExprResult ImmediatelyDeclaredConstraint =
*this, NS, NameInfo, NamedConcept,
TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(),
TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(),
ParamAsArgument, ConstrainedParameter->getLocation(),
[&] (TemplateArgumentListInfo &ConstraintArgs) {
if (TemplateArgs)
for (const auto &ArgLoc : TemplateArgs->arguments())
}, EllipsisLoc);
if (ImmediatelyDeclaredConstraint.isInvalid())
return true;
ConstrainedParameter->setTypeConstraint(NS, NameInfo,
NamedConcept, ArgsAsWritten,
return false;
bool Sema::AttachTypeConstraint(AutoTypeLoc TL, NonTypeTemplateParmDecl *NTTP,
SourceLocation EllipsisLoc) {
if (NTTP->getType() != TL.getType() ||
TL.getAutoKeyword() != AutoTypeKeyword::Auto) {
<< NTTP->getTypeSourceInfo()->getTypeLoc().getSourceRange();
return true;
// FIXME: Concepts: This should be the type of the placeholder, but this is
// unclear in the wording right now.
DeclRefExpr *Ref = BuildDeclRefExpr(NTTP, NTTP->getType(), VK_RValue,
if (!Ref)
return true;
ExprResult ImmediatelyDeclaredConstraint =
*this, TL.getNestedNameSpecifierLoc(), TL.getConceptNameInfo(),
TL.getNamedConcept(), TL.getLAngleLoc(), TL.getRAngleLoc(),
BuildDecltypeType(Ref, NTTP->getLocation()), NTTP->getLocation(),
[&] (TemplateArgumentListInfo &ConstraintArgs) {
for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I)
}, EllipsisLoc);
if (ImmediatelyDeclaredConstraint.isInvalid() ||
return true;
return false;
/// Check that the type of a non-type template parameter is
/// well-formed.
/// \returns the (possibly-promoted) parameter type if valid;
/// otherwise, produces a diagnostic and returns a NULL type.
QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI,
SourceLocation Loc) {
if (TSI->getType()->isUndeducedType()) {
// C++17 [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains
// - an identifier associated by name lookup with a non-type
// template-parameter declared with a type that contains a
// placeholder type (,
TSI = SubstAutoTypeSourceInfo(TSI, Context.DependentTy);
return CheckNonTypeTemplateParameterType(TSI->getType(), Loc);
/// Require the given type to be a structural type, and diagnose if it is not.
/// \return \c true if an error was produced.
bool Sema::RequireStructuralType(QualType T, SourceLocation Loc) {
if (T->isDependentType())
return false;
if (RequireCompleteType(Loc, T, diag::err_template_nontype_parm_incomplete))
return true;
if (T->isStructuralType())
return false;
// Structural types are required to be object types or lvalue references.
if (T->isRValueReferenceType()) {
Diag(Loc, diag::err_template_nontype_parm_rvalue_ref) << T;
return true;
// Don't mention structural types in our diagnostic prior to C++20. Also,
// there's not much more we can say about non-scalar non-class types --
// because we can't see functions or arrays here, those can only be language
// extensions.
if (!getLangOpts().CPlusPlus20 ||
(!T->isScalarType() && !T->isRecordType())) {
Diag(Loc, diag::err_template_nontype_parm_bad_type) << T;
return true;
// Structural types are required to be literal types.
if (RequireLiteralType(Loc, T, diag::err_template_nontype_parm_not_literal))
return true;
Diag(Loc, diag::err_template_nontype_parm_not_structural) << T;
// Drill down into the reason why the class is non-structural.
while (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
// All members are required to be public and non-mutable, and can't be of
// rvalue reference type. Check these conditions first to prefer a "local"
// reason over a more distant one.
for (const FieldDecl *FD : RD->fields()) {
if (FD->getAccess() != AS_public) {
Diag(FD->getLocation(), diag::note_not_structural_non_public) << T << 0;
return true;
if (FD->isMutable()) {
Diag(FD->getLocation(), diag::note_not_structural_mutable_field) << T;
return true;
if (FD->getType()->isRValueReferenceType()) {
Diag(FD->getLocation(), diag::note_not_structural_rvalue_ref_field)
<< T;
return true;
// All bases are required to be public.
for (const auto &BaseSpec : RD->bases()) {
if (BaseSpec.getAccessSpecifier() != AS_public) {
Diag(BaseSpec.getBaseTypeLoc(), diag::note_not_structural_non_public)
<< T << 1;
return true;
// All subobjects are required to be of structural types.
SourceLocation SubLoc;
QualType SubType;
int Kind = -1;
for (const FieldDecl *FD : RD->fields()) {
QualType T = Context.getBaseElementType(FD->getType());
if (!T->isStructuralType()) {
SubLoc = FD->getLocation();
SubType = T;
Kind = 0;
if (Kind == -1) {
for (const auto &BaseSpec : RD->bases()) {
QualType T = BaseSpec.getType();
if (!T->isStructuralType()) {
SubLoc = BaseSpec.getBaseTypeLoc();
SubType = T;
Kind = 1;
assert(Kind != -1 && "couldn't find reason why type is not structural");
Diag(SubLoc, diag::note_not_structural_subobject)
<< T << Kind << SubType;
T = SubType;
RD = T->getAsCXXRecordDecl();
return true;
QualType Sema::CheckNonTypeTemplateParameterType(QualType T,
SourceLocation Loc) {
// We don't allow variably-modified types as the type of non-type template
// parameters.
if (T->isVariablyModifiedType()) {
Diag(Loc, diag::err_variably_modified_nontype_template_param)
<< T;
return QualType();
// C++ [temp.param]p4:
// A non-type template-parameter shall have one of the following
// (optionally cv-qualified) types:
// -- integral or enumeration type,
if (T->isIntegralOrEnumerationType() ||
// -- pointer to object or pointer to function,
T->isPointerType() ||
// -- lvalue reference to object or lvalue reference to function,
T->isLValueReferenceType() ||
// -- pointer to member,
T->isMemberPointerType() ||
// -- std::nullptr_t, or
T->isNullPtrType() ||
// -- a type that contains a placeholder type.
T->isUndeducedType()) {
// C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter
// are ignored when determining its type.
return T.getUnqualifiedType();
// C++ [temp.param]p8:
// A non-type template-parameter of type "array of T" or
// "function returning T" is adjusted to be of type "pointer to
// T" or "pointer to function returning T", respectively.
if (T->isArrayType() || T->isFunctionType())
return Context.getDecayedType(T);
// If T is a dependent type, we can't do the check now, so we
// assume that it is well-formed. Note that stripping off the
// qualifiers here is not really correct if T turns out to be
// an array type, but we'll recompute the type everywhere it's
// used during instantiation, so that should be OK. (Using the
// qualified type is equally wrong.)
if (T->isDependentType())
return T.getUnqualifiedType();
// C++20 [temp.param]p6:
// -- a structural type
if (RequireStructuralType(T, Loc))
return QualType();
if (!getLangOpts().CPlusPlus20) {
// FIXME: Consider allowing structural types as an extension in C++17. (In
// earlier language modes, the template argument evaluation rules are too
// inflexible.)
Diag(Loc, diag::err_template_nontype_parm_bad_structural_type) << T;
return QualType();
Diag(Loc, diag::warn_cxx17_compat_template_nontype_parm_type) << T;
return T.getUnqualifiedType();
NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
unsigned Depth,
unsigned Position,
SourceLocation EqualLoc,
Expr *Default) {
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
// Check that we have valid decl-specifiers specified.
auto CheckValidDeclSpecifiers = [this, &D] {
// C++ [temp.param]
// p1
// template-parameter:
// ...
// parameter-declaration
// p2
// ... A storage class shall not be specified in a template-parameter
// declaration.
// [dcl.typedef]p1:
// The typedef specifier [...] shall not be used in the decl-specifier-seq
// of a parameter-declaration
const DeclSpec &DS = D.getDeclSpec();
auto EmitDiag = [this](SourceLocation Loc) {
Diag(Loc, diag::err_invalid_decl_specifier_in_nontype_parm)
<< FixItHint::CreateRemoval(Loc);
if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified)
if (DS.getThreadStorageClassSpec() != TSCS_unspecified)
// [dcl.inline]p1:
// The inline specifier can be applied only to the declaration or
// definition of a variable or function.
if (DS.isInlineSpecified())
// [dcl.constexpr]p1:
// The constexpr specifier shall be applied only to the definition of a
// variable or variable template or the declaration of a function or
// function template.
if (DS.hasConstexprSpecifier())
// [dcl.fct.spec]p1:
// Function-specifiers can be used only in function declarations.
if (DS.isVirtualSpecified())
if (DS.hasExplicitSpecifier())
if (DS.isNoreturnSpecified())
if (TInfo->getType()->isUndeducedType()) {
<< QualType(TInfo->getType()->getContainedAutoType(), 0);
assert(S->isTemplateParamScope() &&
"Non-type template parameter not in template parameter scope!");
bool Invalid = false;
QualType T = CheckNonTypeTemplateParameterType(TInfo, D.getIdentifierLoc());
if (T.isNull()) {
T = Context.IntTy; // Recover with an 'int' type.
Invalid = true;
CheckFunctionOrTemplateParamDeclarator(S, D);
IdentifierInfo *ParamName = D.getIdentifier();
bool IsParameterPack = D.hasEllipsis();
NonTypeTemplateParmDecl *Param = NonTypeTemplateParmDecl::Create(
Context, Context.getTranslationUnitDecl(), D.getBeginLoc(),
D.getIdentifierLoc(), Depth, Position, ParamName, T, IsParameterPack,
if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc())
if (TL.isConstrained())
if (AttachTypeConstraint(TL, Param, D.getEllipsisLoc()))
Invalid = true;
if (Invalid)
if (Param->isParameterPack())
if (auto *LSI = getEnclosingLambda())
if (ParamName) {
maybeDiagnoseTemplateParameterShadow(*this, S, D.getIdentifierLoc(),
// Add the template parameter into the current scope.
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
if (Default && IsParameterPack) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
Default = nullptr;
// Check the well-formedness of the default template argument, if provided.
if (Default) {
// Check for unexpanded parameter packs.
if (DiagnoseUnexpandedParameterPack(Default, UPPC_DefaultArgument))
return Param;
TemplateArgument Converted;
ExprResult DefaultRes =
CheckTemplateArgument(Param, Param->getType(), Default, Converted);
if (DefaultRes.isInvalid()) {
return Param;
Default = DefaultRes.get();
return Param;
/// ActOnTemplateTemplateParameter - Called when a C++ template template
/// parameter (e.g. T in template <template \<typename> class T> class array)
/// has been parsed. S is the current scope.
NamedDecl *Sema::ActOnTemplateTemplateParameter(Scope* S,
SourceLocation TmpLoc,
TemplateParameterList *Params,
SourceLocation EllipsisLoc,
IdentifierInfo *Name,
SourceLocation NameLoc,
unsigned Depth,
unsigned Position,
SourceLocation EqualLoc,
ParsedTemplateArgument Default) {
assert(S->isTemplateParamScope() &&
"Template template parameter not in template parameter scope!");
// Construct the parameter object.
bool IsParameterPack = EllipsisLoc.isValid();
TemplateTemplateParmDecl *Param =
TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
NameLoc.isInvalid()? TmpLoc : NameLoc,
Depth, Position, IsParameterPack,
Name, Params);
if (Param->isParameterPack())
if (auto *LSI = getEnclosingLambda())
// If the template template parameter has a name, then link the identifier
// into the scope and lookup mechanisms.
if (Name) {
maybeDiagnoseTemplateParameterShadow(*this, S, NameLoc, Name);
if (Params->size() == 0) {
Diag(Param->getLocation(), diag::err_template_template_parm_no_parms)
<< SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc());
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
if (IsParameterPack && !Default.isInvalid()) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
Default = ParsedTemplateArgument();
if (!Default.isInvalid()) {
// Check only that we have a template template argument. We don't want to
// try to check well-formedness now, because our template template parameter
// might have dependent types in its template parameters, which we wouldn't
// be able to match now.
// If none of the template template parameter's template arguments mention
// other template parameters, we could actually perform more checking here.
// However, it isn't worth doing.
TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
if (DefaultArg.getArgument().getAsTemplate().isNull()) {
Diag(DefaultArg.getLocation(), diag::err_template_arg_not_valid_template)
<< DefaultArg.getSourceRange();
return Param;
// Check for unexpanded parameter packs.
if (DiagnoseUnexpandedParameterPack(DefaultArg.getLocation(),
return Param;
Param->setDefaultArgument(Context, DefaultArg);
return Param;
/// ActOnTemplateParameterList - Builds a TemplateParameterList, optionally
/// constrained by RequiresClause, that contains the template parameters in
/// Params.
TemplateParameterList *
Sema::ActOnTemplateParameterList(unsigned Depth,
SourceLocation ExportLoc,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc,
Expr *RequiresClause) {
if (ExportLoc.isValid())
Diag(ExportLoc, diag::warn_template_export_unsupported);
return TemplateParameterList::Create(
Context, TemplateLoc, LAngleLoc,
llvm::makeArrayRef(, Params.size()),
RAngleLoc, RequiresClause);
static void SetNestedNameSpecifier(Sema &S, TagDecl *T,
const CXXScopeSpec &SS) {
if (SS.isSet())
DeclResult Sema::CheckClassTemplate(
Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
TemplateParameterList **OuterTemplateParamLists, SkipBodyInfo *SkipBody) {
assert(TemplateParams && TemplateParams->size() > 0 &&
"No template parameters");
assert(TUK != TUK_Reference && "Can only declare or define class templates");
bool Invalid = false;
// Check that we can declare a template here.
if (CheckTemplateDeclScope(S, TemplateParams))
return true;
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
assert(Kind != TTK_Enum && "can't build template of enumerated type");
// There is no such thing as an unnamed class template.
if (!Name) {
Diag(KWLoc, diag::err_template_unnamed_class);
return true;
// Find any previous declaration with this name. For a friend with no
// scope explicitly specified, we only look for tag declarations (per
// C++11 [basic.lookup.elab]p2).
DeclContext *SemanticContext;
LookupResult Previous(*this, Name, NameLoc,
(SS.isEmpty() && TUK == TUK_Friend)
? LookupTagName : LookupOrdinaryName,
if (SS.isNotEmpty() && !SS.isInvalid()) {
SemanticContext = computeDeclContext(SS, true);
if (!SemanticContext) {
// FIXME: Horrible, horrible hack! We can't currently represent this
// in the AST, and historically we have just ignored such friend
// class templates, so don't complain here.
Diag(NameLoc, TUK == TUK_Friend
? diag::warn_template_qualified_friend_ignored
: diag::err_template_qualified_declarator_no_match)
<< SS.getScopeRep() << SS.getRange();
return TUK != TUK_Friend;
if (RequireCompleteDeclContext(SS, SemanticContext))
return true;
// If we're adding a template to a dependent context, we may need to
// rebuilding some of the types used within the template parameter list,
// now that we know what the current instantiation is.
if (SemanticContext->isDependentContext()) {
ContextRAII SavedContext(*this, SemanticContext);
if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
Invalid = true;
} else if (TUK != TUK_Friend && TUK != TUK_Reference)
diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc, false);
LookupQualifiedName(Previous, SemanticContext);
} else {
SemanticContext = CurContext;
// C++14 [class.mem]p14:
// If T is the name of a class, then each of the following shall have a
// name different from T:
// -- every member template of class T
if (TUK != TUK_Friend &&
DeclarationNameInfo(Name, NameLoc)))
return true;
LookupName(Previous, S);
if (Previous.isAmbiguous())
return true;
NamedDecl *PrevDecl = nullptr;
if (Previous.begin() != Previous.end())
PrevDecl = (*Previous.begin())->getUnderlyingDecl();
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
// Just pretend that we didn't see the previous declaration.
PrevDecl = nullptr;
// If there is a previous declaration with the same name, check
// whether this is a valid redeclaration.
ClassTemplateDecl *PrevClassTemplate =
// We may have found the injected-class-name of a class template,
// class template partial specialization, or class template specialization.
// In these cases, grab the template that is being defined or specialized.
if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) &&
cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) {
PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext());
= cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate();
if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) {
= cast<ClassTemplateSpecializationDecl>(PrevDecl)
if (TUK == TUK_Friend) {
// C++ [namespace.memdef]p3:
// [...] When looking for a prior declaration of a class or a function
// declared as a friend, and when the name of the friend class or
// function is neither a qualified name nor a template-id, scopes outside
// the innermost enclosing namespace scope are not considered.
if (!SS.isSet()) {
DeclContext *OutermostContext = CurContext;
while (!OutermostContext->isFileContext())
OutermostContext = OutermostContext->getLookupParent();
if (PrevDecl &&
(OutermostContext->Equals(PrevDecl->getDeclContext()) ||
OutermostContext->Encloses(PrevDecl->getDeclContext()))) {
SemanticContext = PrevDecl->getDeclContext();
} else {
// Declarations in outer scopes don't matter. However, the outermost
// context we computed is the semantic context for our new
// declaration.
PrevDecl = PrevClassTemplate = nullptr;
SemanticContext = OutermostContext;
// Check that the chosen semantic context doesn't already contain a
// declaration of this name as a non-tag type.
DeclContext *LookupContext = SemanticContext;
while (LookupContext->isTransparentContext())
LookupContext = LookupContext->getLookupParent();
LookupQualifiedName(Previous, LookupContext);
if (Previous.isAmbiguous())
return true;
if (Previous.begin() != Previous.end())
PrevDecl = (*Previous.begin())->getUnderlyingDecl();
} else if (PrevDecl &&
!isDeclInScope(Previous.getRepresentativeDecl(), SemanticContext,
S, SS.isValid()))
PrevDecl = PrevClassTemplate = nullptr;
if (auto *Shadow = dyn_cast_or_null<UsingShadowDecl>(
PrevDecl ? Previous.getRepresentativeDecl() : nullptr)) {
if (SS.isEmpty() &&
!(PrevClassTemplate &&
SemanticContext->getRedeclContext()))) {
Diag(KWLoc, diag::err_using_decl_conflict_reverse);
Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0;
// Recover by ignoring the old declaration.
PrevDecl = PrevClassTemplate = nullptr;
if (PrevClassTemplate) {
// Ensure that the template parameter lists are compatible. Skip this check
// for a friend in a dependent context: the template parameter list itself
// could be dependent.
if (!(TUK == TUK_Friend && CurContext->isDependentContext()) &&
return true;
// C++ [temp.class]p4:
// In a redeclaration, partial specialization, explicit
// specialization or explicit instantiation of a class template,
// the class-key shall agree in kind with the original class
// template declaration (
RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl();
if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind,
TUK == TUK_Definition, KWLoc, Name)) {
Diag(KWLoc, diag::err_use_with_wrong_tag)
<< Name
<< FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName());
Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
Kind = PrevRecordDecl->getTagKind();
// Check for redefinition of this class template.
if (TUK == TUK_Definition) {
if (TagDecl *Def = PrevRecordDecl->getDefinition()) {
// If we have a prior definition that is not visible, treat this as
// simply making that previous definition visible.
NamedDecl *Hidden = nullptr;
if (SkipBody && !hasVisibleDefinition(Def, &Hidden)) {
SkipBody->ShouldSkip = true;
SkipBody->Previous = Def;
auto *Tmpl = cast<CXXRecordDecl>(Hidden)->getDescribedClassTemplate();
assert(Tmpl && "original definition of a class template is not a "
"class template?");
} else {
Diag(NameLoc, diag::err_redefinition) << Name;
Diag(Def->getLocation(), diag::note_previous_definition);
// FIXME: Would it make sense to try to "forget" the previous
// definition, as part of error recovery?
return true;
} else if (PrevDecl) {
// C++ [temp]p5:
// A class template shall not have the same name as any other
// template, class, function, object, enumeration, enumerator,
// namespace, or type in the same scope (3.3), except as specified
// in (14.5.4).
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
return true;
// Check the template parameter list of this declaration, possibly
// merging in the template parameter list from the previous class
// template declaration. Skip this check for a friend in a dependent
// context, because the template parameter list might be dependent.
if (!(TUK == TUK_Friend && CurContext->isDependentContext()) &&
? PrevClassTemplate->getMostRecentDecl()->getTemplateParameters()
: nullptr,
(SS.isSet() && SemanticContext && SemanticContext->isRecord() &&
? TPC_ClassTemplateMember
: TUK == TUK_Friend ? TPC_FriendClassTemplate : TPC_ClassTemplate,
Invalid = true;
if (SS.isSet()) {
// If the name of the template was qualified, we must be defining the
// template out-of-line.
if (!SS.isInvalid() && !Invalid && !PrevClassTemplate) {
Diag(NameLoc, TUK == TUK_Friend ? diag::err_friend_decl_does_not_match
: diag::err_member_decl_does_not_match)
<< Name << SemanticContext << /*IsDefinition*/true << SS.getRange();
Invalid = true;
// If this is a templated friend in a dependent context we should not put it
// on the redecl chain. In some cases, the templated friend can be the most
// recent declaration tricking the template instantiator to make substitutions
// there.
// FIXME: Figure out how to combine with shouldLinkDependentDeclWithPrevious
bool ShouldAddRedecl
= !(TUK == TUK_Friend && CurContext->isDependentContext());
CXXRecordDecl *NewClass =
CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
PrevClassTemplate && ShouldAddRedecl ?
PrevClassTemplate->getTemplatedDecl() : nullptr,
SetNestedNameSpecifier(*this, NewClass, SS);
if (NumOuterTemplateParamLists > 0)
Context, llvm::makeArrayRef(OuterTemplateParamLists,
// Add alignment attributes if necessary; these attributes are checked when
// the ASTContext lays out the structure.
if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) {
ClassTemplateDecl *NewTemplate
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
DeclarationName(Name), TemplateParams,
if (ShouldAddRedecl)
if (ModulePrivateLoc.isValid())
// Build the type for the class template declaration now.
QualType T = NewTemplate->getInjectedClassNameSpecialization();
T = Context.getInjectedClassNameType(NewClass, T);
assert(T->isDependentType() && "Class template type is not dependent?");
// If we are providing an explicit specialization of a member that is a
// class template, make a note of that.
if (PrevClassTemplate &&
// Set the access specifier.
if (!Invalid && TUK != TUK_Friend && NewTemplate->getDeclContext()->isRecord())
SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
// Set the lexical context of these templates
if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip))
ProcessDeclAttributeList(S, NewClass, Attr);
if (PrevClassTemplate)
mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
if (TUK != TUK_Friend) {
// Per C++ [basic.scope.temp]p2, skip the template parameter scopes.
Scope *Outer = S;
while ((Outer->getFlags() & Scope::TemplateParamScope) != 0)
Outer = Outer->getParent();
PushOnScopeChains(NewTemplate, Outer);
} else {
if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) {
// Friend templates are visible in fairly strange ways.
if (!CurContext->isDependentContext()) {
DeclContext *DC = SemanticContext->getRedeclContext();
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
PushOnScopeChains(NewTemplate, EnclosingScope,
/* AddToContext = */ false);
FriendDecl *Friend = FriendDecl::Create(
Context, CurContext, NewClass->getLocation(), NewTemplate, FriendLoc);
if (PrevClassTemplate)
CheckRedeclarationModuleOwnership(NewTemplate, PrevClassTemplate);
if (Invalid) {
if (SkipBody && SkipBody->ShouldSkip)
return SkipBody->Previous;
return NewTemplate;
namespace {
/// Tree transform to "extract" a transformed type from a class template's
/// constructor to a deduction guide.
class ExtractTypeForDeductionGuide
: public TreeTransform<ExtractTypeForDeductionGuide> {
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
Sema &SemaRef,
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs)
: Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs) {}
TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
ASTContext &Context = SemaRef.getASTContext();
TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
TypedefNameDecl *Decl = OrigDecl;
// Transform the underlying type of the typedef and clone the Decl only if
// the typedef has a dependent context.
if (OrigDecl->getDeclContext()->isDependentContext()) {
TypeLocBuilder InnerTLB;
QualType Transformed =
TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);
if (isa<TypeAliasDecl>(OrigDecl))
Decl = TypeAliasDecl::Create(
Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
else {
assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
Decl = TypedefDecl::Create(
Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
QualType TDTy = Context.getTypedefType(Decl);
TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
return TDTy;
/// Transform to convert portions of a constructor declaration into the
/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
struct ConvertConstructorToDeductionGuideTransform {
ConvertConstructorToDeductionGuideTransform(Sema &S,
ClassTemplateDecl *Template)
: SemaRef(S), Template(Template) {}
Sema &SemaRef;
ClassTemplateDecl *Template;
DeclContext *DC = Template->getDeclContext();
CXXRecordDecl *Primary = Template->getTemplatedDecl();
DeclarationName DeductionGuideName =
QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary);
// Index adjustment to apply to convert depth-1 template parameters into
// depth-0 template parameters.
unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
/// Transform a constructor declaration into a deduction guide.
NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
CXXConstructorDecl *CD) {
SmallVector<TemplateArgument, 16> SubstArgs;
LocalInstantiationScope Scope(SemaRef);
// C++ [over.match.class.deduct]p1:
// -- For each constructor of the class template designated by the
// template-name, a function template with the following properties:
// -- The template parameters are the template parameters of the class
// template followed by the template parameters (including default
// template arguments) of the constructor, if any.
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
if (FTD) {
TemplateParameterList *InnerParams = FTD->getTemplateParameters();
SmallVector<NamedDecl *, 16> AllParams;
AllParams.reserve(TemplateParams->size() + InnerParams->size());
TemplateParams->begin(), TemplateParams->end());
// Later template parameters could refer to earlier ones, so build up
// a list of substituted template arguments as we go.
for (NamedDecl *Param : *InnerParams) {
MultiLevelTemplateArgumentList Args;
NamedDecl *NewParam = transformTemplateParameter(Param, Args);
if (!NewParam)
return nullptr;
TemplateParams = TemplateParameterList::Create(
SemaRef.Context, InnerParams->getTemplateLoc(),
InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
/*FIXME: RequiresClause*/ nullptr);
// If we built a new template-parameter-list, track that we need to
// substitute references to the old parameters into references to the
// new ones.
MultiLevelTemplateArgumentList Args;
if (FTD) {
FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()->getTypeLoc()
assert(FPTL && "no prototype for constructor declaration");
// Transform the type of the function, adjusting the return type and
// replacing references to the old parameters with references to the
// new ones.
TypeLocBuilder TLB;
SmallVector<ParmVarDecl*, 8> Params;
SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
if (NewType.isNull())
return nullptr;
TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
return buildDeductionGuide(TemplateParams, CD->getExplicitSpecifier(),
NewTInfo, CD->getBeginLoc(), CD->getLocation(),
CD->getEndLoc(), MaterializedTypedefs);
/// Build a deduction guide with the specified parameter types.
NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
SourceLocation Loc = Template->getLocation();
// Build the requested type.
FunctionProtoType::ExtProtoInfo EPI;
EPI.HasTrailingReturn = true;
QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
DeductionGuideName, EPI);
TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
FunctionProtoTypeLoc FPTL =
// Build the parameters, needed during deduction / substitution.
SmallVector<ParmVarDecl*, 4> Params;
for (auto T : ParamTypes) {
ParmVarDecl *NewParam = ParmVarDecl::Create(
SemaRef.Context, DC, Loc, Loc, nullptr, T,
SemaRef.Context.getTrivialTypeSourceInfo(T, Loc), SC_None, nullptr);
NewParam->setScopeInfo(0, Params.size());
FPTL.setParam(Params.size(), NewParam);
return buildDeductionGuide(Template->getTemplateParameters(),
ExplicitSpecifier(), TSI, Loc, Loc, Loc);
/// Transform a constructor template parameter into a deduction guide template
/// parameter, rebuilding any internal references to earlier parameters and
/// renumbering as we go.
NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
MultiLevelTemplateArgumentList &Args) {
if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam)) {
// TemplateTypeParmDecl's index cannot be changed after creation, so
// substitute it directly.
auto *NewTTP = TemplateTypeParmDecl::Create(
SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(),
/*Depth*/ 0, Depth1IndexAdjustment + TTP->getIndex(),
TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
TTP->isParameterPack(), TTP->hasTypeConstraint(),
TTP->isExpandedParameterPack() ?
llvm::Optional<unsigned>(TTP->getNumExpansionParameters()) : None);
if (const auto *TC = TTP->getTypeConstraint()) {
TemplateArgumentListInfo TransformedArgs;
const auto *ArgsAsWritten = TC->getTemplateArgsAsWritten();
if (!ArgsAsWritten ||
ArgsAsWritten->NumTemplateArgs, TransformedArgs,
TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
TC->getNamedConcept(), ArgsAsWritten ? &TransformedArgs : nullptr,
? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
: SourceLocation());
if (TTP->hasDefaultArgument()) {
TypeSourceInfo *InstantiatedDefaultArg =
SemaRef.SubstType(TTP->getDefaultArgumentInfo(), Args,
TTP->getDefaultArgumentLoc(), TTP->getDeclName());
if (InstantiatedDefaultArg)
return NewTTP;
if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
return transformTemplateParameterImpl(TTP, Args);
return transformTemplateParameterImpl(
cast<NonTypeTemplateParmDecl>(TemplateParam), Args);
template<typename TemplateParmDecl>
TemplateParmDecl *
transformTemplateParameterImpl(TemplateParmDecl *OldParam,
MultiLevelTemplateArgumentList &Args) {
// Ask the template instantiator to do the heavy lifting for us, then adjust
// the index of the parameter once it's done.
auto *NewParam =
cast<TemplateParmDecl>(SemaRef.SubstDecl(OldParam, DC, Args));
assert(NewParam->getDepth() == 0 && "unexpected template param depth");
NewParam->setPosition(NewParam->getPosition() + Depth1IndexAdjustment);
return NewParam;
QualType transformFunctionProtoType(
TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
SmallVectorImpl<ParmVarDecl *> &Params,
MultiLevelTemplateArgumentList &Args,
SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
SmallVector<QualType, 4> ParamTypes;
const FunctionProtoType *T = TL.getTypePtr();
// -- The types of the function parameters are those of the constructor.
for (auto *OldParam : TL.getParams()) {
ParmVarDecl *NewParam =
transformFunctionTypeParam(OldParam, Args, MaterializedTypedefs);
if (!NewParam)
return QualType();
// -- The return type is the class template specialization designated by
// the template-name and template arguments corresponding to the
// template parameters obtained from the class template.
// We use the injected-class-name type of the primary template instead.
// This has the convenient property that it is different from any type that
// the user can write in a deduction-guide (because they cannot enter the
// context of the template), so implicit deduction guides can never collide
// with explicit ones.
QualType ReturnType = DeducedType;
// Resolving a wording defect, we also inherit the variadicness of the
// constructor.
FunctionProtoType::ExtProtoInfo EPI;
EPI.Variadic = T->isVariadic();
EPI.HasTrailingReturn = true;
QualType Result = SemaRef.BuildFunctionType(
ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
if (Result.isNull())
return QualType();
FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
NewTL.setParam(I, Params[I]);
return Result;
ParmVarDecl *transformFunctionTypeParam(
ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
TypeSourceInfo *NewDI;
if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
// Expand out the one and only element in each inner pack.
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
NewDI =
SemaRef.SubstType(PackTL.getPatternLoc(), Args,
OldParam->getLocation(), OldParam->getDeclName());
if (!NewDI) return nullptr;
NewDI =
SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
} else
NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
if (!NewDI)
return nullptr;
// Extract the type. This (for instance) replaces references to typedef
// members of the current instantiations with the definitions of those
// typedefs, avoiding triggering instantiation of the deduced type during
// deduction.
NewDI = ExtractTypeForDeductionGuide(SemaRef, MaterializedTypedefs)
// Resolving a wording defect, we also inherit default arguments from the
// constructor.
ExprResult NewDefArg;
if (OldParam->hasDefaultArg()) {
// We don't care what the value is (we won't use it); just create a
// placeholder to indicate there is a default argument.
QualType ParamTy = NewDI->getType();
NewDefArg = new (SemaRef.Context)
ParamTy->isLValueReferenceType() ? VK_LValue :
ParamTy->isRValueReferenceType() ? VK_XValue :
ParmVarDecl *NewParam = ParmVarDecl::Create(SemaRef.Context, DC,
SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
return NewParam;
FunctionTemplateDecl *buildDeductionGuide(
TemplateParameterList *TemplateParams, ExplicitSpecifier ES,
TypeSourceInfo *TInfo, SourceLocation LocStart, SourceLocation Loc,
SourceLocation LocEnd,
llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) {
DeclarationNameInfo Name(DeductionGuideName, Loc);
ArrayRef<ParmVarDecl *> Params =
// Build the implicit deduction guide template.
auto *Guide =
CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
TInfo->getType(), TInfo, LocEnd);
for (auto *Param : Params)
for (auto *TD : MaterializedTypedefs)
auto *GuideTemplate = FunctionTemplateDecl::Create(
SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
if (isa<CXXRecordDecl>(DC)) {
return GuideTemplate;
void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
SourceLocation Loc) {
if (CXXRecordDecl *DefRecord =
cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
Template = DescribedTemplate ? DescribedTemplate : Template;
DeclContext *DC = Template->getDeclContext();
if (DC->isDependentContext())
ConvertConstructorToDeductionGuideTransform Transform(
*this, cast<ClassTemplateDecl>(Template));
if (!isCompleteType(Loc, Transform.DeducedType))
// Check whether we've already declared deduction guides for this template.
// FIXME: Consider storing a flag on the template to indicate this.
auto Existing = DC->lookup(Transform.DeductionGuideName);
for (auto *D : Existing)
if (D->isImplicit())
// In case we were expanding a pack when we attempted to declare deduction
// guides, turn off pack expansion for everything we're about to do.
ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
// Create a template instantiation record to track the "instantiation" of
// constructors into deduction guides.
// FIXME: Add a kind for this to give more meaningful diagnostics. But can
// this substitution process actually fail?
InstantiatingTemplate BuildingDeductionGuides(*this, Loc, Template);
if (BuildingDeductionGuides.isInvalid())
// Convert declared constructors into deduction guide templates.
// FIXME: Skip constructors for which deduction must necessarily fail (those
// for which some class template parameter without a default argument never
// appears in a deduced context).
bool AddedAny = false;
for (NamedDecl *D : LookupConstructors(Transform.Primary)) {
D = D->getUnderlyingDecl();
if (D->isInvalidDecl() || D->isImplicit())
D = cast<NamedDecl>(D->getCanonicalDecl());
auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
auto *CD =
dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
// Class-scope explicit specializations (MS extension) do not result in
// deduction guides.
if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
// Cannot make a deduction guide when unparsed arguments are present.
if (std::any_of(CD->param_begin(), CD->param_end(), [](ParmVarDecl *P) {
return !P || P->hasUnparsedDefaultArg();
Transform.transformConstructor(FTD, CD);
AddedAny = true;
// C++17 [over.match.class.deduct]
// -- If C is not defined or does not declare any constructors, an
// additional function template derived as above from a hypothetical
// constructor C().
if (!AddedAny)
// -- An additional function template derived as above from a hypothetical
// constructor C(C), called the copy deduction candidate.
/// Diagnose the presence of a default template argument on a
/// template parameter, which is ill-formed in certain contexts.
/// \returns true if the default template argument should be dropped.
static bool DiagnoseDefaultTemplateArgument(Sema &S,
Sema::TemplateParamListContext TPC,