diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 689 |
1 files changed, 367 insertions, 322 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5c28e3b..accec95 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -12,13 +12,13 @@ #include "clang/Sema/SemaInternal.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" -#include "clang/Lex/Preprocessor.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" @@ -79,7 +79,7 @@ static void instantiateDependentAlignedAttr( EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs); if (!Result.isInvalid()) - S.AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(), + S.AddAlignedAttr(Aligned->getLocation(), New, Result.getAs<Expr>(), Aligned->getSpellingListIndex(), IsPackExpansion); } else { TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(), @@ -129,14 +129,46 @@ static void instantiateDependentAlignedAttr( } } +static void instantiateDependentEnableIfAttr( + Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, + const EnableIfAttr *A, const Decl *Tmpl, Decl *New) { + Expr *Cond = nullptr; + { + EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated); + ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs); + if (Result.isInvalid()) + return; + Cond = Result.getAs<Expr>(); + } + if (A->getCond()->isTypeDependent() && !Cond->isTypeDependent()) { + ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); + if (Converted.isInvalid()) + return; + Cond = Converted.get(); + } + + SmallVector<PartialDiagnosticAt, 8> Diags; + if (A->getCond()->isValueDependent() && !Cond->isValueDependent() && + !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(Tmpl), + Diags)) { + S.Diag(A->getLocation(), diag::err_enable_if_never_constant_expr); + for (int I = 0, N = Diags.size(); I != N; ++I) + S.Diag(Diags[I].first, Diags[I].second); + return; + } + + EnableIfAttr *EIA = new (S.getASTContext()) + EnableIfAttr(A->getLocation(), S.getASTContext(), Cond, + A->getMessage(), + A->getSpellingListIndex()); + New->addAttr(EIA); +} + void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, Decl *New, LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *OuterMostScope) { - for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end(); - i != e; ++i) { - const Attr *TmplAttr = *i; - + for (const auto *TmplAttr : Tmpl->attrs()) { // FIXME: This should be generalized to more than just the AlignedAttr. const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr); if (Aligned && Aligned->isAlignmentDependent()) { @@ -144,11 +176,18 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, continue; } + const EnableIfAttr *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr); + if (EnableIf && EnableIf->getCond()->isValueDependent()) { + instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl, + New); + continue; + } + assert(!TmplAttr->isPackExpansion()); if (TmplAttr->isLateParsed() && LateAttrs) { // Late parsed attributes must be instantiated and attached after the // enclosing class has been instantiated. See Sema::InstantiateClass. - LocalInstantiationScope *Saved = 0; + LocalInstantiationScope *Saved = nullptr; if (CurrentInstantiationScope) Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope); LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New)); @@ -258,7 +297,7 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev, TemplateArgs); if (!InstPrev) - return 0; + return nullptr; TypedefNameDecl *InstPrevTypedef = cast<TypedefNameDecl>(InstPrev); @@ -296,11 +335,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return 0; + return nullptr; TypeAliasDecl *Pattern = D->getTemplatedDecl(); - TypeAliasTemplateDecl *PrevAliasTemplate = 0; + TypeAliasTemplateDecl *PrevAliasTemplate = nullptr; if (Pattern->getPreviousDecl()) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); if (!Found.empty()) { @@ -311,7 +350,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { TypeAliasDecl *AliasInst = cast_or_null<TypeAliasDecl>( InstantiateTypedefNameDecl(Pattern, /*IsTypeAlias=*/true)); if (!AliasInst) - return 0; + return nullptr; TypeAliasTemplateDecl *Inst = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(), @@ -341,7 +380,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, if (const RecordType *RecordTy = D->getType()->getAs<RecordType>()) if (RecordTy->getDecl()->isAnonymousStructOrUnion()) if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl()))) - return 0; + return nullptr; // Do substitution on the type of the declaration TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(), @@ -349,12 +388,12 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, D->getTypeSpecStartLoc(), D->getDeclName()); if (!DI) - return 0; + return nullptr; if (DI->getType()->isFunctionType()) { SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function) << D->isStaticDataMember() << DI->getType(); - return 0; + return nullptr; } DeclContext *DC = Owner; @@ -373,10 +412,19 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, // Substitute the nested name specifier, if any. if (SubstQualifier(D, Var)) - return 0; + return nullptr; SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, StartingScope, InstantiatingVarTemplate); + + if (D->isNRVOVariable()) { + QualType ReturnType = cast<FunctionDecl>(DC)->getReturnType(); + if (SemaRef.isCopyElisionCandidate(ReturnType, Var, false)) + Var->setNRVOVariable(true); + } + + Var->setImplicit(D->isImplicit()); + return Var; } @@ -415,7 +463,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { Expr *BitWidth = D->getBitWidth(); if (Invalid) - BitWidth = 0; + BitWidth = nullptr; else if (BitWidth) { // The bit-width expression is a constant expression. EnterExpressionEvaluationContext Unevaluated(SemaRef, @@ -425,9 +473,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { = SemaRef.SubstExpr(BitWidth, TemplateArgs); if (InstantiatedBitWidth.isInvalid()) { Invalid = true; - BitWidth = 0; + BitWidth = nullptr; } else - BitWidth = InstantiatedBitWidth.takeAs<Expr>(); + BitWidth = InstantiatedBitWidth.getAs<Expr>(); } FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), @@ -439,10 +487,10 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { D->getInClassInitStyle(), D->getInnerLocStart(), D->getAccess(), - 0); + nullptr); if (!Field) { cast<Decl>(Owner)->setInvalidDecl(); - return 0; + return nullptr; } SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope); @@ -476,7 +524,7 @@ Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) { if (DI->getType()->isVariablyModifiedType()) { SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified) - << D->getName(); + << D; Invalid = true; } else if (DI->getType()->isInstantiationDependentType()) { DI = SemaRef.SubstType(DI, TemplateArgs, @@ -499,11 +547,9 @@ Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) { SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); } - MSPropertyDecl *Property = new (SemaRef.Context) - MSPropertyDecl(Owner, D->getLocation(), - D->getDeclName(), DI->getType(), DI, - D->getLocStart(), - D->getGetterId(), D->getSetterId()); + MSPropertyDecl *Property = MSPropertyDecl::Create( + SemaRef.Context, Owner, D->getLocation(), D->getDeclName(), DI->getType(), + DI, D->getLocStart(), D->getGetterId(), D->getSetterId()); SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs, StartingScope); @@ -522,13 +568,11 @@ Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) { new (SemaRef.Context)NamedDecl*[D->getChainingSize()]; int i = 0; - for (IndirectFieldDecl::chain_iterator PI = - D->chain_begin(), PE = D->chain_end(); - PI != PE; ++PI) { - NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI, + for (auto *PI : D->chain()) { + NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), PI, TemplateArgs); if (!Next) - return 0; + return nullptr; NamedChain[i++] = Next; } @@ -562,12 +606,12 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { D->getLocation(), DeclarationName()); } if (!InstTy) - return 0; + return nullptr; FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getLocStart(), D->getFriendLoc(), InstTy); if (!FD) - return 0; + return nullptr; FD->setAccess(AS_public); FD->setUnsupportedFriend(D->isUnsupportedFriend()); @@ -583,7 +627,7 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { // objects, with the most important detail being that the target // decl should almost certainly not be placed in Owner. Decl *NewND = Visit(ND); - if (!NewND) return 0; + if (!NewND) return nullptr; FriendDecl *FD = FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(), @@ -604,7 +648,7 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { ExprResult InstantiatedAssertExpr = SemaRef.SubstExpr(AssertExpr, TemplateArgs); if (InstantiatedAssertExpr.isInvalid()) - return 0; + return nullptr; return SemaRef.BuildStaticAssertDeclaration(D->getLocation(), InstantiatedAssertExpr.get(), @@ -614,12 +658,12 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { } Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { - EnumDecl *PrevDecl = 0; + EnumDecl *PrevDecl = nullptr; if (D->getPreviousDecl()) { NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), D->getPreviousDecl(), TemplateArgs); - if (!Prev) return 0; + if (!Prev) return nullptr; PrevDecl = cast<EnumDecl>(Prev); } @@ -650,7 +694,9 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation); Enum->setAccess(D->getAccess()); - if (SubstQualifier(D, Enum)) return 0; + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D)); + if (SubstQualifier(D, Enum)) return nullptr; Owner->addDecl(Enum); EnumDecl *Def = D->getDefinition(); @@ -692,12 +738,10 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( SmallVector<Decl*, 4> Enumerators; - EnumConstantDecl *LastEnumConst = 0; - for (EnumDecl::enumerator_iterator EC = Pattern->enumerator_begin(), - ECEnd = Pattern->enumerator_end(); - EC != ECEnd; ++EC) { + EnumConstantDecl *LastEnumConst = nullptr; + for (auto *EC : Pattern->enumerators()) { // The specified value for the enumerator. - ExprResult Value = SemaRef.Owned((Expr *)0); + ExprResult Value((Expr *)nullptr); if (Expr *UninstValue = EC->getInitExpr()) { // The enumerator's value expression is a constant expression. EnterExpressionEvaluationContext Unevaluated(SemaRef, @@ -709,7 +753,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( // Drop the initial value and continue. bool isInvalid = false; if (Value.isInvalid()) { - Value = SemaRef.Owned((Expr *)0); + Value = nullptr; isInvalid = true; } @@ -725,7 +769,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( } if (EnumConst) { - SemaRef.InstantiateAttrs(TemplateArgs, *EC, EnumConst); + SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst); EnumConst->setAccess(Enum->getAccess()); Enum->addDecl(EnumConst); @@ -736,7 +780,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( !Enum->isScoped()) { // If the enumeration is within a function or method, record the enum // constant as a local. - SemaRef.CurrentInstantiationScope->InstantiatedLocal(*EC, EnumConst); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(EC, EnumConst); } } } @@ -745,7 +789,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), Enum->getRBraceLoc(), Enum, Enumerators, - 0, 0); + nullptr, nullptr); } Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { @@ -761,7 +805,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return NULL; + return nullptr; CXXRecordDecl *Pattern = D->getTemplatedDecl(); @@ -773,11 +817,11 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; } - CXXRecordDecl *PrevDecl = 0; - ClassTemplateDecl *PrevClassTemplate = 0; + CXXRecordDecl *PrevDecl = nullptr; + ClassTemplateDecl *PrevClassTemplate = nullptr; if (!isFriend && Pattern->getPreviousDecl()) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); @@ -798,7 +842,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXScopeSpec SS; SS.Adopt(QualifierLoc); DC = SemaRef.computeDeclContext(SS); - if (!DC) return 0; + if (!DC) return nullptr; } else { DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(), Pattern->getDeclContext(), @@ -821,7 +865,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope) << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC << QualifierLoc.getSourceRange(); - return 0; + return nullptr; } bool AdoptedPreviousTemplateParams = false; @@ -843,11 +887,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (DCParent->isNamespace() && cast<NamespaceDecl>(DCParent)->getIdentifier() && cast<NamespaceDecl>(DCParent)->getIdentifier()->isStr("tr1")) { - DeclContext *DCParent2 = DCParent->getParent(); - if (DCParent2->isNamespace() && - cast<NamespaceDecl>(DCParent2)->getIdentifier() && - cast<NamespaceDecl>(DCParent2)->getIdentifier()->isStr("std") && - DCParent2->getParent()->isTranslationUnit()) + if (cast<Decl>(DCParent)->isInStdNamespace()) Complain = false; } } @@ -860,7 +900,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { Complain, Sema::TPL_TemplateMatch)) { if (Complain) - return 0; + return nullptr; AdoptedPreviousTemplateParams = true; InstParams = PrevParams; @@ -871,7 +911,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (!AdoptedPreviousTemplateParams && SemaRef.CheckTemplateParameterList(InstParams, PrevParams, Sema::TPC_ClassTemplate)) - return 0; + return nullptr; } } @@ -948,12 +988,12 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( DeclContext::lookup_result Found = Owner->lookup(ClassTemplate->getDeclName()); if (Found.empty()) - return 0; + return nullptr; ClassTemplateDecl *InstClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front()); if (!InstClassTemplate) - return 0; + return nullptr; if (ClassTemplatePartialSpecializationDecl *Result = InstClassTemplate->findPartialSpecInstantiatedFromMember(D)) @@ -972,10 +1012,10 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) { TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return NULL; + return nullptr; VarDecl *Pattern = D->getTemplatedDecl(); - VarTemplateDecl *PrevVarTemplate = 0; + VarTemplateDecl *PrevVarTemplate = nullptr; if (Pattern->getPreviousDecl()) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); @@ -991,8 +1031,9 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) { VarTemplateDecl *Inst = VarTemplateDecl::Create( SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams, - VarInst, PrevVarTemplate); + VarInst); VarInst->setDescribedVarTemplate(Inst); + Inst->setPreviousDecl(PrevVarTemplate); Inst->setAccess(D->getAccess()); if (!PrevVarTemplate) @@ -1052,9 +1093,9 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { TemplateParameterList *TempParams = D->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return NULL; + return nullptr; - FunctionDecl *Instantiated = 0; + FunctionDecl *Instantiated = nullptr; if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod, InstParams)); @@ -1064,7 +1105,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { InstParams)); if (!Instantiated) - return 0; + return nullptr; // Link the instantiated function template declaration to the function // template from which it was instantiated. @@ -1094,14 +1135,14 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { } Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { - CXXRecordDecl *PrevDecl = 0; + CXXRecordDecl *PrevDecl = nullptr; if (D->isInjectedClassName()) PrevDecl = cast<CXXRecordDecl>(Owner); else if (D->getPreviousDecl()) { NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), D->getPreviousDecl(), TemplateArgs); - if (!Prev) return 0; + if (!Prev) return nullptr; PrevDecl = cast<CXXRecordDecl>(Prev); } @@ -1112,7 +1153,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { // Substitute the nested name specifier, if any. if (SubstQualifier(D, Record)) - return 0; + return nullptr; Record->setImplicit(D->isImplicit()); // FIXME: Check against AS_none is an ugly hack to work around the issue that @@ -1135,19 +1176,20 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { if (D->isLocalClass()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Record, + SemaRef.Context.getManglingNumber(D)); + Owner->addDecl(Record); // DR1484 clarifies that the members of a local class are instantiated as part // of the instantiation of their enclosing entity. if (D->isCompleteDefinition() && D->isLocalClass()) { - if (SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs, - TSK_ImplicitInstantiation, - /*Complain=*/true)) { - llvm_unreachable("InstantiateClass shouldn't fail here!"); - } else { - SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs, - TSK_ImplicitInstantiation); - } + SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs, + TSK_ImplicitInstantiation, + /*Complain=*/true); + SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs, + TSK_ImplicitInstantiation); } return Record; } @@ -1170,15 +1212,14 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, FunctionProtoType::ExtProtoInfo NewEPI = NewFunc->getExtProtoInfo(); NewEPI.ExtInfo = OrigFunc->getExtInfo(); - return Context.getFunctionType(NewFunc->getResultType(), - NewFunc->getArgTypes(), NewEPI); + return Context.getFunctionType(NewFunc->getReturnType(), + NewFunc->getParamTypes(), NewEPI); } /// Normal class members are of more specific types and therefore /// don't make it here. This function serves two purposes: /// 1) instantiating function templates /// 2) substituting friend declarations -/// FIXME: preserve function definitions in case #2 Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams) { // Check whether there is already a function template specialization for @@ -1187,10 +1228,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, if (FunctionTemplate && !TemplateParams) { ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); - void *InsertPos = 0; + void *InsertPos = nullptr; FunctionDecl *SpecFunc - = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(), - InsertPos); + = FunctionTemplate->findSpecialization(Innermost, InsertPos); // If we already have a function template specialization, return it. if (SpecFunc) @@ -1203,7 +1243,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, else isFriend = (D->getFriendObjectKind() != Decl::FOK_None); - bool MergeWithParentScope = (TemplateParams != 0) || + bool MergeWithParentScope = (TemplateParams != nullptr) || Owner->isFunctionOrMethod() || !(isa<Decl>(Owner) && cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); @@ -1212,7 +1252,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, SmallVector<ParmVarDecl *, 4> Params; TypeSourceInfo *TInfo = SubstFunctionType(D, Params); if (!TInfo) - return 0; + return nullptr; QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); @@ -1220,7 +1260,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; } // If we're instantiating a local function declaration, put the result @@ -1234,7 +1274,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, CXXScopeSpec SS; SS.Adopt(QualifierLoc); DC = SemaRef.computeDeclContext(SS); - if (!DC) return 0; + if (!DC) return nullptr; } else { DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), TemplateArgs); @@ -1308,7 +1348,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost.begin(), Innermost.size()), - /*InsertPos=*/0); + /*InsertPos=*/nullptr); } else if (isFriend) { // Note, we need this connection even if the friend doesn't have a body. // Its body may exist but not have been attached yet due to deferred @@ -1342,14 +1382,14 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Info->getRAngleLoc()); if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), ExplicitArgs, TemplateArgs)) - return 0; + return nullptr; // Map the candidate templates to their instantiations. for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) { Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(), Info->getTemplate(I), TemplateArgs); - if (!Temp) return 0; + if (!Temp) return nullptr; Previous.addDecl(cast<FunctionTemplateDecl>(Temp)); } @@ -1375,7 +1415,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Previous.clear(); } - SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous, + SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous, isExplicitSpecialization); NamedDecl *PrincipalDecl = (TemplateParams @@ -1388,73 +1428,56 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, PrincipalDecl->setObjectOfFriendDecl(); DC->makeDeclVisibleInContext(PrincipalDecl); - bool queuedInstantiation = false; + bool QueuedInstantiation = false; - // C++98 [temp.friend]p5: When a function is defined in a friend function - // declaration in a class template, the function is defined at each - // instantiation of the class template. The function is defined even if it - // is never used. - // C++11 [temp.friend]p4: When a function is defined in a friend function - // declaration in a class template, the function is instantiated when the - // function is odr-used. - // - // If -Wc++98-compat is enabled, we go through the motions of checking for a - // redefinition, but don't instantiate the function. - if ((!SemaRef.getLangOpts().CPlusPlus11 || - SemaRef.Diags.getDiagnosticLevel( - diag::warn_cxx98_compat_friend_redefinition, - Function->getLocation()) - != DiagnosticsEngine::Ignored) && - D->isThisDeclarationADefinition()) { + // C++11 [temp.friend]p4 (DR329): + // When a function is defined in a friend function declaration in a class + // template, the function is instantiated when the function is odr-used. + // The same restrictions on multiple declarations and definitions that + // apply to non-template function declarations and definitions also apply + // to these implicit definitions. + if (D->isThisDeclarationADefinition()) { // Check for a function body. - const FunctionDecl *Definition = 0; + const FunctionDecl *Definition = nullptr; if (Function->isDefined(Definition) && Definition->getTemplateSpecializationKind() == TSK_Undeclared) { - SemaRef.Diag(Function->getLocation(), - SemaRef.getLangOpts().CPlusPlus11 ? - diag::warn_cxx98_compat_friend_redefinition : - diag::err_redefinition) << Function->getDeclName(); + SemaRef.Diag(Function->getLocation(), diag::err_redefinition) + << Function->getDeclName(); SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); - if (!SemaRef.getLangOpts().CPlusPlus11) - Function->setInvalidDecl(); } // Check for redefinitions due to other instantiations of this or // a similar friend function. - else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(), - REnd = Function->redecls_end(); - R != REnd; ++R) { - if (*R == Function) + else for (auto R : Function->redecls()) { + if (R == Function) continue; - switch (R->getFriendObjectKind()) { - case Decl::FOK_None: - if (!SemaRef.getLangOpts().CPlusPlus11 && - !queuedInstantiation && R->isUsed(false)) { - if (MemberSpecializationInfo *MSInfo - = Function->getMemberSpecializationInfo()) { - if (MSInfo->getPointOfInstantiation().isInvalid()) { - SourceLocation Loc = R->getLocation(); // FIXME - MSInfo->setPointOfInstantiation(Loc); - SemaRef.PendingLocalImplicitInstantiations.push_back( - std::make_pair(Function, Loc)); - queuedInstantiation = true; - } + + // If some prior declaration of this function has been used, we need + // to instantiate its definition. + if (!QueuedInstantiation && R->isUsed(false)) { + if (MemberSpecializationInfo *MSInfo = + Function->getMemberSpecializationInfo()) { + if (MSInfo->getPointOfInstantiation().isInvalid()) { + SourceLocation Loc = R->getLocation(); // FIXME + MSInfo->setPointOfInstantiation(Loc); + SemaRef.PendingLocalImplicitInstantiations.push_back( + std::make_pair(Function, Loc)); + QueuedInstantiation = true; } } - break; - default: - if (const FunctionDecl *RPattern - = R->getTemplateInstantiationPattern()) + } + + // If some prior declaration of this function was a friend with an + // uninstantiated definition, reject it. + if (R->getFriendObjectKind()) { + if (const FunctionDecl *RPattern = + R->getTemplateInstantiationPattern()) { if (RPattern->isDefined(RPattern)) { - SemaRef.Diag(Function->getLocation(), - SemaRef.getLangOpts().CPlusPlus11 ? - diag::warn_cxx98_compat_friend_redefinition : - diag::err_redefinition) + SemaRef.Diag(Function->getLocation(), diag::err_redefinition) << Function->getDeclName(); SemaRef.Diag(R->getLocation(), diag::note_previous_definition); - if (!SemaRef.getLangOpts().CPlusPlus11) - Function->setInvalidDecl(); break; } + } } } } @@ -1482,11 +1505,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // specialization for this particular set of template arguments. ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost(); - void *InsertPos = 0; + void *InsertPos = nullptr; FunctionDecl *SpecFunc - = FunctionTemplate->findSpecialization(Innermost.begin(), - Innermost.size(), - InsertPos); + = FunctionTemplate->findSpecialization(Innermost, InsertPos); // If we already have a function template specialization, return it. if (SpecFunc) @@ -1499,7 +1520,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, else isFriend = (D->getFriendObjectKind() != Decl::FOK_None); - bool MergeWithParentScope = (TemplateParams != 0) || + bool MergeWithParentScope = (TemplateParams != nullptr) || !(isa<Decl>(Owner) && cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); @@ -1513,7 +1534,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, TemplateParameterList *TempParams = D->getTemplateParameterList(I); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return NULL; + return nullptr; TempParamLists[I] = InstParams; } } @@ -1521,7 +1542,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, SmallVector<ParmVarDecl *, 4> Params; TypeSourceInfo *TInfo = SubstFunctionType(D, Params); if (!TInfo) - return 0; + return nullptr; QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); @@ -1529,7 +1550,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; } DeclContext *DC = Owner; @@ -1540,18 +1561,18 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, DC = SemaRef.computeDeclContext(SS); if (DC && SemaRef.RequireCompleteDeclContext(SS, DC)) - return 0; + return nullptr; } else { DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), TemplateArgs); } - if (!DC) return 0; + if (!DC) return nullptr; } // Build the instantiated method declaration. CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); - CXXMethodDecl *Method = 0; + CXXMethodDecl *Method = nullptr; SourceLocation StartLoc = D->getInnerLocStart(); DeclarationNameInfo NameInfo @@ -1577,7 +1598,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Sema::InstantiatingTemplate Inst(SemaRef, Constructor->getLocation(), Inh); if (Inst.isInvalid()) - return 0; + return nullptr; Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext()); LocalInstantiationScope LocalScope(SemaRef); @@ -1588,7 +1609,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Inh = cast_or_null<CXXConstructorDecl>( SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs)); if (!Inh) - return 0; + return nullptr; } cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh); } @@ -1649,7 +1670,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost.begin(), Innermost.size()), - /*InsertPos=*/0); + /*InsertPos=*/nullptr); } else if (!isFriend) { // Record that this is an instantiation of a member function. Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); @@ -1692,7 +1713,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } if (!IsClassScopeSpecialization) - SemaRef.CheckFunctionDeclaration(0, Method, Previous, false); + SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, false); if (D->isPure()) SemaRef.CheckPureMethod(Method, SourceRange()); @@ -1810,13 +1831,13 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( D->getLocation(), D->getDeclName()); if (!NewDI) - return 0; + return nullptr; ExpandedParameterPackTypesAsWritten.push_back(NewDI); QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(), D->getLocation()); if (NewT.isNull()) - return 0; + return nullptr; ExpandedParameterPackTypes.push_back(NewT); } @@ -1845,7 +1866,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( TemplateArgs, Expand, RetainExpansion, NumExpansions)) - return 0; + return nullptr; if (Expand) { for (unsigned I = 0; I != *NumExpansions; ++I) { @@ -1854,14 +1875,14 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( D->getLocation(), D->getDeclName()); if (!NewDI) - return 0; + return nullptr; ExpandedParameterPackTypesAsWritten.push_back(NewDI); QualType NewT = SemaRef.CheckNonTypeTemplateParameterType( NewDI->getType(), D->getLocation()); if (NewT.isNull()) - return 0; + return nullptr; ExpandedParameterPackTypes.push_back(NewT); } @@ -1879,12 +1900,12 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( D->getLocation(), D->getDeclName()); if (!NewPattern) - return 0; + return nullptr; DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(), NumExpansions); if (!DI) - return 0; + return nullptr; T = DI->getType(); } @@ -1893,7 +1914,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, D->getLocation(), D->getDeclName()); if (!DI) - return 0; + return nullptr; // Check that this type is acceptable for a non-type template parameter. T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(), @@ -1979,7 +2000,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( TemplateParameterList *Expansion = SubstTemplateParams(D->getExpansionTemplateParameters(I)); if (!Expansion) - return 0; + return nullptr; ExpandedParams.push_back(Expansion); } @@ -2004,7 +2025,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( TemplateArgs, Expand, RetainExpansion, NumExpansions)) - return 0; + return nullptr; if (Expand) { for (unsigned I = 0; I != *NumExpansions; ++I) { @@ -2012,7 +2033,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( LocalInstantiationScope Scope(SemaRef); TemplateParameterList *Expansion = SubstTemplateParams(TempParams); if (!Expansion) - return 0; + return nullptr; ExpandedParams.push_back(Expansion); } @@ -2029,7 +2050,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( LocalInstantiationScope Scope(SemaRef); InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return 0; + return nullptr; } } else { // Perform the actual substitution of template parameters within a new, @@ -2037,7 +2058,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( LocalInstantiationScope Scope(SemaRef); InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return 0; + return nullptr; } // Build the template template parameter. @@ -2114,7 +2135,7 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; // The name info is non-dependent, so no transformation // is required. @@ -2149,7 +2170,7 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { } if (!NewUD->isInvalidDecl() && - SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS, + SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS, NameInfo, D->getLocation())) NewUD->setInvalidDecl(); @@ -2162,24 +2183,21 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { return NewUD; if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) { - if (SemaRef.CheckInheritingConstructorUsingDecl(NewUD)) - NewUD->setInvalidDecl(); + SemaRef.CheckInheritingConstructorUsingDecl(NewUD); return NewUD; } bool isFunctionScope = Owner->isFunctionOrMethod(); // Process the shadow decls. - for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end(); - I != E; ++I) { - UsingShadowDecl *Shadow = *I; + for (auto *Shadow : D->shadows()) { NamedDecl *InstTarget = cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl( Shadow->getLocation(), Shadow->getTargetDecl(), TemplateArgs)); if (!InstTarget) - return 0; + return nullptr; - UsingShadowDecl *PrevDecl = 0; + UsingShadowDecl *PrevDecl = nullptr; if (CheckRedeclaration) { if (SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev, PrevDecl)) continue; @@ -2189,7 +2207,8 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { } UsingShadowDecl *InstShadow = - SemaRef.BuildUsingShadowDecl(/*Scope*/0, NewUD, InstTarget, PrevDecl); + SemaRef.BuildUsingShadowDecl(/*Scope*/nullptr, NewUD, InstTarget, + PrevDecl); SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow); if (isFunctionScope) @@ -2201,7 +2220,7 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { // Ignore these; we handle them in bulk when processing the UsingDecl. - return 0; + return nullptr; } Decl * TemplateDeclInstantiator @@ -2210,7 +2229,7 @@ Decl * TemplateDeclInstantiator = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; CXXScopeSpec SS; SS.Adopt(QualifierLoc); @@ -2219,8 +2238,8 @@ Decl * TemplateDeclInstantiator // Hence, no transformation is required for it. DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation()); NamedDecl *UD = - SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), - D->getUsingLoc(), SS, NameInfo, 0, + SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(), + D->getUsingLoc(), SS, NameInfo, nullptr, /*instantiation*/ true, /*typename*/ true, D->getTypenameLoc()); if (UD) @@ -2234,7 +2253,7 @@ Decl * TemplateDeclInstantiator NestedNameSpecifierLoc QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); if (!QualifierLoc) - return 0; + return nullptr; CXXScopeSpec SS; SS.Adopt(QualifierLoc); @@ -2243,8 +2262,8 @@ Decl * TemplateDeclInstantiator = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); NamedDecl *UD = - SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), - D->getUsingLoc(), SS, NameInfo, 0, + SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(), + D->getUsingLoc(), SS, NameInfo, nullptr, /*instantiation*/ true, /*typename*/ false, SourceLocation()); if (UD) @@ -2258,13 +2277,13 @@ Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *Decl) { CXXMethodDecl *OldFD = Decl->getSpecialization(); CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, - 0, true)); + nullptr, true)); LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); TemplateArgumentListInfo TemplateArgs; - TemplateArgumentListInfo* TemplateArgsPtr = 0; + TemplateArgumentListInfo *TemplateArgsPtr = nullptr; if (Decl->hasExplicitTemplateArgs()) { TemplateArgs = Decl->templateArgs(); TemplateArgsPtr = &TemplateArgs; @@ -2288,10 +2307,8 @@ Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( OMPThreadPrivateDecl *D) { SmallVector<Expr *, 5> Vars; - for (ArrayRef<Expr *>::iterator I = D->varlist_begin(), - E = D->varlist_end(); - I != E; ++I) { - Expr *Var = SemaRef.SubstExpr(*I, TemplateArgs).take(); + for (auto *I : D->varlists()) { + Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get(); assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr"); Vars.push_back(Var); } @@ -2299,15 +2316,18 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( OMPThreadPrivateDecl *TD = SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars); + TD->setAccess(AS_public); + Owner->addDecl(TD); + return TD; } Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { - return VisitFunctionDecl(D, 0); + return VisitFunctionDecl(D, nullptr); } Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { - return VisitCXXMethodDecl(D, 0); + return VisitCXXMethodDecl(D, nullptr); } Decl *TemplateDeclInstantiator::VisitRecordDecl(RecordDecl *D) { @@ -2330,11 +2350,11 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( DeclContext::lookup_result Found = Owner->lookup(ClassTemplate->getDeclName()); if (Found.empty()) - return 0; + return nullptr; ClassTemplateDecl *InstClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front()); if (!InstClassTemplate) - return 0; + return nullptr; // Substitute into the template arguments of the class template explicit // specialization. @@ -2347,7 +2367,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( ArgLocs.push_back(Loc.getArgLoc(I)); if (SemaRef.Subst(ArgLocs.data(), ArgLocs.size(), InstTemplateArgs, TemplateArgs)) - return 0; + return nullptr; // Check that the template argument list is well-formed for this // class template. @@ -2357,14 +2377,13 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( InstTemplateArgs, false, Converted)) - return 0; + return nullptr; // Figure out where to insert this class template explicit specialization // in the member template's set of class template explicit specializations. - void *InsertPos = 0; + void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl = - InstClassTemplate->findSpecialization(Converted.data(), Converted.size(), - InsertPos); + InstClassTemplate->findSpecialization(Converted, InsertPos); // Check whether we've already seen a conflicting instantiation of this // declaration (for instance, if there was a prior implicit instantiation). @@ -2376,7 +2395,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( PrevDecl->getSpecializationKind(), PrevDecl->getPointOfInstantiation(), Ignored)) - return 0; + return nullptr; // If PrevDecl was a definition and D is also a definition, diagnose. // This happens in cases like: @@ -2395,7 +2414,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( SemaRef.Diag(D->getLocation(), diag::err_redefinition) << PrevDecl; SemaRef.Diag(PrevDecl->getDefinition()->getLocation(), diag::note_previous_definition); - return 0; + return nullptr; } // Create the class template partial specialization declaration. @@ -2417,7 +2436,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( // Substitute the nested name specifier, if any. if (SubstQualifier(D, InstD)) - return 0; + return nullptr; // Build the canonical type that describes the converted template // arguments of the class template explicit specialization. @@ -2452,7 +2471,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( SemaRef.InstantiateClass(D->getLocation(), InstD, D, TemplateArgs, TSK_ImplicitInstantiation, /*Complain=*/true)) - return 0; + return nullptr; return InstD; } @@ -2472,22 +2491,21 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( if (SemaRef.Subst(TemplateArgsInfo.getArgumentArray(), TemplateArgsInfo.size(), VarTemplateArgsInfo, TemplateArgs)) - return 0; + return nullptr; // Check that the template argument list is well-formed for this template. SmallVector<TemplateArgument, 4> Converted; - bool ExpansionIntoFixedList = false; if (SemaRef.CheckTemplateArgumentList( VarTemplate, VarTemplate->getLocStart(), const_cast<TemplateArgumentListInfo &>(VarTemplateArgsInfo), false, - Converted, &ExpansionIntoFixedList)) - return 0; + Converted)) + return nullptr; // Find the variable template specialization declaration that // corresponds to these arguments. - void *InsertPos = 0; + void *InsertPos = nullptr; if (VarTemplateSpecializationDecl *VarSpec = VarTemplate->findSpecialization( - Converted.data(), Converted.size(), InsertPos)) + Converted, InsertPos)) // If we already have a variable template specialization, return it. return VarSpec; @@ -2498,26 +2516,26 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( VarTemplateDecl *VarTemplate, VarDecl *D, void *InsertPos, const TemplateArgumentListInfo &TemplateArgsInfo, - llvm::ArrayRef<TemplateArgument> Converted) { + ArrayRef<TemplateArgument> Converted) { // If this is the variable for an anonymous struct or union, // instantiate the anonymous struct/union type first. if (const RecordType *RecordTy = D->getType()->getAs<RecordType>()) if (RecordTy->getDecl()->isAnonymousStructOrUnion()) if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl()))) - return 0; + return nullptr; // Do substitution on the type of the declaration TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(), D->getDeclName()); if (!DI) - return 0; + return nullptr; if (DI->getType()->isFunctionType()) { SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function) << D->isStaticDataMember() << DI->getType(); - return 0; + return nullptr; } // Build the instantiated declaration @@ -2531,7 +2549,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( // Substitute the nested name specifier, if any. if (SubstQualifier(D, Var)) - return 0; + return nullptr; SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, StartingScope); @@ -2551,7 +2569,7 @@ Decl *TemplateDeclInstantiator::VisitFriendTemplateDecl(FriendTemplateDecl *D) { SemaRef.Diag(D->getLocation(), DiagID) << D->getDeclKindName(); - return 0; + return nullptr; } Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) { @@ -2562,7 +2580,7 @@ Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs) { TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); if (D->isInvalidDecl()) - return 0; + return nullptr; return Instantiator.Visit(D); } @@ -2591,7 +2609,7 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { // Clean up if we had an error. if (Invalid) - return NULL; + return nullptr; TemplateParameterList *InstL = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(), @@ -2625,7 +2643,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return 0; + return nullptr; // Substitute into the template arguments of the class template partial // specialization. @@ -2636,7 +2654,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(), TemplArgInfo->NumTemplateArgs, InstTemplateArgs, TemplateArgs)) - return 0; + return nullptr; // Check that the template argument list is well-formed for this // class template. @@ -2646,14 +2664,13 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( InstTemplateArgs, false, Converted)) - return 0; + return nullptr; // Figure out where to insert this class template partial specialization // in the member template's set of class template partial specializations. - void *InsertPos = 0; + void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl - = ClassTemplate->findPartialSpecialization(Converted.data(), - Converted.size(), InsertPos); + = ClassTemplate->findPartialSpecialization(Converted, InsertPos); // Build the canonical type that describes the converted template // arguments of the class template partial specialization. @@ -2696,7 +2713,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( << WrittenTy->getType(); SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here) << SemaRef.Context.getTypeDeclType(PrevDecl); - return 0; + return nullptr; } @@ -2713,17 +2730,18 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( Converted.size(), InstTemplateArgs, CanonType, - 0); + nullptr); // Substitute the nested name specifier, if any. if (SubstQualifier(PartialSpec, InstPartialSpec)) - return 0; + return nullptr; InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setTypeAsWritten(WrittenTy); // Add this partial specialization to the set of class template partial // specializations. - ClassTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0); + ClassTemplate->AddPartialSpecialization(InstPartialSpec, + /*InsertPos=*/nullptr); return InstPartialSpec; } @@ -2752,7 +2770,7 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) - return 0; + return nullptr; // Substitute into the template arguments of the variable template partial // specialization. @@ -2763,21 +2781,20 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(), TemplArgInfo->NumTemplateArgs, InstTemplateArgs, TemplateArgs)) - return 0; + return nullptr; // Check that the template argument list is well-formed for this // class template. SmallVector<TemplateArgument, 4> Converted; if (SemaRef.CheckTemplateArgumentList(VarTemplate, PartialSpec->getLocation(), InstTemplateArgs, false, Converted)) - return 0; + return nullptr; // Figure out where to insert this variable template partial specialization // in the member template's set of variable template partial specializations. - void *InsertPos = 0; + void *InsertPos = nullptr; VarTemplateSpecializationDecl *PrevDecl = - VarTemplate->findPartialSpecialization(Converted.data(), Converted.size(), - InsertPos); + VarTemplate->findPartialSpecialization(Converted, InsertPos); // Build the canonical type that describes the converted template // arguments of the variable template partial specialization. @@ -2816,7 +2833,7 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( << WrittenTy->getType(); SemaRef.Diag(PrevDecl->getLocation(), diag::note_var_prev_partial_spec_here); - return 0; + return nullptr; } // Do substitution on the type of the declaration @@ -2824,13 +2841,13 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( PartialSpec->getTypeSourceInfo(), TemplateArgs, PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName()); if (!DI) - return 0; + return nullptr; if (DI->getType()->isFunctionType()) { SemaRef.Diag(PartialSpec->getLocation(), diag::err_variable_instantiates_to_function) << PartialSpec->isStaticDataMember() << DI->getType(); - return 0; + return nullptr; } // Create the variable template partial specialization declaration. @@ -2843,14 +2860,14 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( // Substitute the nested name specifier, if any. if (SubstQualifier(PartialSpec, InstPartialSpec)) - return 0; + return nullptr; InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setTypeAsWritten(WrittenTy); // Add this partial specialization to the set of variable template partial // specializations. The instantiation of the initializer is not necessary. - VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0); + VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/nullptr); SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs, LateAttrs, Owner, StartingScope); @@ -2864,8 +2881,8 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); assert(OldTInfo && "substituting function without type source info"); assert(Params.empty() && "parameter vector is non-empty at start"); - - CXXRecordDecl *ThisContext = 0; + + CXXRecordDecl *ThisContext = nullptr; unsigned ThisTypeQuals = 0; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { ThisContext = cast<CXXRecordDecl>(Owner); @@ -2878,7 +2895,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, D->getDeclName(), ThisContext, ThisTypeQuals); if (!NewTInfo) - return 0; + return nullptr; TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); if (FunctionProtoTypeLoc OldProtoLoc = OldTL.getAs<FunctionProtoTypeLoc>()) { @@ -2887,9 +2904,9 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens(); FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>(); unsigned NewIdx = 0; - for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumArgs(); + for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumParams(); OldIdx != NumOldParams; ++OldIdx) { - ParmVarDecl *OldParam = OldProtoLoc.getArg(OldIdx); + ParmVarDecl *OldParam = OldProtoLoc.getParam(OldIdx); LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope; Optional<unsigned> NumArgumentsInExpansion; @@ -2900,14 +2917,14 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (!NumArgumentsInExpansion) { // Simple case: normal parameter, or a parameter pack that's // instantiated to a (still-dependent) parameter pack. - ParmVarDecl *NewParam = NewProtoLoc.getArg(NewIdx++); + ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++); Params.push_back(NewParam); Scope->InstantiatedLocal(OldParam, NewParam); } else { // Parameter pack expansion: make the instantiation an argument pack. Scope->MakeInstantiatedLocalArgPack(OldParam); for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) { - ParmVarDecl *NewParam = NewProtoLoc.getArg(NewIdx++); + ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++); Params.push_back(NewParam); Scope->InstantiatedLocalPackArg(OldParam, NewParam); } @@ -2919,18 +2936,19 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, // the function parameters themselves. const FunctionProtoType *OldProto = cast<FunctionProtoType>(OldProtoLoc.getType()); - for (unsigned i = 0, i_end = OldProtoLoc.getNumArgs(); i != i_end; ++i) { - ParmVarDecl *OldParam = OldProtoLoc.getArg(i); + for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end; + ++i) { + ParmVarDecl *OldParam = OldProtoLoc.getParam(i); if (!OldParam) { Params.push_back(SemaRef.BuildParmVarDeclForTypedef( - D, D->getLocation(), OldProto->getArgType(i))); + D, D->getLocation(), OldProto->getParamType(i))); continue; } ParmVarDecl *Parm = cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldParam)); if (!Parm) - return 0; + return nullptr; Params.push_back(Parm); } } @@ -2949,7 +2967,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), D->getNumParams(), TemplateArgs, ParamTypes, &Params)) - return 0; + return nullptr; } return NewTInfo; @@ -2969,6 +2987,14 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, // Simple case: not a parameter pack. assert(FParamIdx < Function->getNumParams()); ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); + // If the parameter's type is not dependent, update it to match the type + // in the pattern. They can differ in top-level cv-qualifiers, and we want + // the pattern's type here. If the type is dependent, they can't differ, + // per core issue 1668. + // FIXME: Updating the type to work around this is at best fragile. + if (!PatternDecl->getType()->isDependentType()) + FunctionParam->setType(PatternParam->getType()); + FunctionParam->setDeclName(PatternParam->getDeclName()); Scope.InstantiatedLocal(PatternParam, FunctionParam); ++FParamIdx; @@ -2983,6 +3009,9 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, "should only be called when all template arguments are known"); for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) { ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); + if (!PatternDecl->getType()->isDependentType()) + FunctionParam->setType(PatternParam->getType()); + FunctionParam->setDeclName(PatternParam->getDeclName()); Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); ++FParamIdx; @@ -3001,7 +3030,7 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq // and the end of the function-definition, member-declarator, or // declarator. - CXXRecordDecl *ThisContext = 0; + CXXRecordDecl *ThisContext = nullptr; unsigned ThisTypeQuals = 0; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(New)) { ThisContext = Method->getParent(); @@ -3083,7 +3112,7 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, Exceptions.push_back(T); } - Expr *NoexceptExpr = 0; + Expr *NoexceptExpr = nullptr; if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::ConstantEvaluated); @@ -3092,29 +3121,23 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); if (E.isUsable()) { - NoexceptExpr = E.take(); + NoexceptExpr = E.get(); if (!NoexceptExpr->isTypeDependent() && !NoexceptExpr->isValueDependent()) NoexceptExpr = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr, - 0, diag::err_noexcept_needs_constant_expression, - /*AllowFold*/ false).take(); + nullptr, diag::err_noexcept_needs_constant_expression, + /*AllowFold*/ false).get(); } } - // Rebuild the function type - const FunctionProtoType *NewProto - = New->getType()->getAs<FunctionProtoType>(); - assert(NewProto && "Template instantiation without function prototype?"); - - FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); + FunctionProtoType::ExtProtoInfo EPI; EPI.ExceptionSpecType = Proto->getExceptionSpecType(); EPI.NumExceptions = Exceptions.size(); EPI.Exceptions = Exceptions.data(); EPI.NoexceptExpr = NoexceptExpr; - New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), - NewProto->getArgTypes(), EPI)); + SemaRef.UpdateExceptionSpec(New, EPI); } void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, @@ -3128,10 +3151,9 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, if (Inst.isInvalid()) { // We hit the instantiation depth limit. Clear the exception specification // so that our callers don't have to cope with EST_Uninstantiated. - FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); + FunctionProtoType::ExtProtoInfo EPI; EPI.ExceptionSpecType = EST_None; - Decl->setType(Context.getFunctionType(Proto->getResultType(), - Proto->getArgTypes(), EPI)); + UpdateExceptionSpec(Decl, EPI); return; } @@ -3141,7 +3163,7 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, LocalInstantiationScope Scope(*this); MultiLevelTemplateArgumentList TemplateArgs = - getTemplateInstantiationArgs(Decl, 0, /*RelativeToPrimary*/true); + getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true); FunctionDecl *Template = Proto->getExceptionSpecTemplate(); addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs); @@ -3161,6 +3183,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (Tmpl->isDeleted()) New->setDeletedAsWritten(); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(New, + SemaRef.Context.getManglingNumber(Tmpl)); + // If we are performing substituting explicitly-specified template arguments // or deduced template arguments into a function template and we reach this // point, we are now past the point where SFINAE applies and have committed @@ -3211,7 +3237,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpecDecl = New; EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; New->setType(SemaRef.Context.getFunctionType( - NewProto->getResultType(), NewProto->getArgTypes(), EPI)); + NewProto->getReturnType(), NewProto->getParamTypes(), EPI)); } else { ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs); } @@ -3339,14 +3365,22 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, // initializer or return value, and class template specializations, other // explicit instantiation declarations have the effect of suppressing the // implicit instantiation of the entity to which they refer. - if (Function->getTemplateSpecializationKind() - == TSK_ExplicitInstantiationDeclaration && + if (Function->getTemplateSpecializationKind() == + TSK_ExplicitInstantiationDeclaration && !PatternDecl->isInlined() && - !PatternDecl->getResultType()->getContainedAutoType()) + !PatternDecl->getReturnType()->getContainedAutoType()) return; - if (PatternDecl->isInlined()) - Function->setImplicitlyInline(); + if (PatternDecl->isInlined()) { + // Function, and all later redeclarations of it (from imported modules, + // for instance), are now implicitly inline. + for (auto *D = Function->getMostRecentDecl(); /**/; + D = D->getPreviousDecl()) { + D->setImplicitlyInline(); + if (D == Function) + break; + } + } InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); if (Inst.isInvalid()) @@ -3383,14 +3417,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (PatternDecl->isDefaulted()) SetDeclDefaulted(Function, PatternDecl->getLocation()); else { - ActOnStartOfFunctionDef(0, Function); + ActOnStartOfFunctionDef(nullptr, Function); // Enter the scope of this instantiation. We don't use // PushDeclContext because we don't have a scope. Sema::ContextRAII savedContext(*this, Function); MultiLevelTemplateArgumentList TemplateArgs = - getTemplateInstantiationArgs(Function, 0, false, PatternDecl); + getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl); addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, TemplateArgs); @@ -3413,6 +3447,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, PerformDependentDiagnostics(PatternDecl, TemplateArgs); + if (auto *Listener = getASTMutationListener()) + Listener->FunctionDefinitionInstantiated(Function); + savedContext.pop(); } @@ -3453,11 +3490,11 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *StartingScope) { if (FromVar->isInvalidDecl()) - return 0; + return nullptr; InstantiatingTemplate Inst(*this, PointOfInstantiation, FromVar); if (Inst.isInvalid()) - return 0; + return nullptr; MultiLevelTemplateArgumentList TemplateArgLists; TemplateArgLists.addOuterTemplateArguments(&TemplateArgList); @@ -3467,7 +3504,18 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( // or may not be the declaration in the class; if it's in the class, we want // to instantiate a member in the class (a declaration), and if it's outside, // we want to instantiate a definition. - FromVar = FromVar->getFirstDecl(); + // + // If we're instantiating an explicitly-specialized member template or member + // partial specialization, don't do this. The member specialization completely + // replaces the original declaration in this case. + bool IsMemberSpec = false; + if (VarTemplatePartialSpecializationDecl *PartialSpec = + dyn_cast<VarTemplatePartialSpecializationDecl>(FromVar)) + IsMemberSpec = PartialSpec->isMemberSpecialization(); + else if (VarTemplateDecl *FromTemplate = FromVar->getDescribedVarTemplate()) + IsMemberSpec = FromTemplate->isMemberSpecialization(); + if (!IsMemberSpec) + FromVar = FromVar->getFirstDecl(); MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList); TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(), @@ -3491,7 +3539,7 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( SubstType(PatternDecl->getTypeSourceInfo(), TemplateArgs, PatternDecl->getTypeSpecStartLoc(), PatternDecl->getDeclName()); if (!DI) - return 0; + return nullptr; // Update the type of this variable template specialization. VarSpec->setType(DI->getType()); @@ -3552,16 +3600,15 @@ void Sema::BuildVariableInstantiation( InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope); - if (NewVar->hasAttrs()) - CheckAlignasUnderalignment(NewVar); - LookupResult Previous( *this, NewVar->getDeclName(), NewVar->getLocation(), NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage : Sema::LookupOrdinaryName, Sema::ForRedeclaration); - if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl()) { + if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() && + (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext() || + OldVar->getPreviousDecl()->getDeclContext()==OldVar->getDeclContext())) { // We have a previous declaration. Use that one, so we merge with the // right type. if (NamedDecl *NewPrev = FindInstantiatedDecl( @@ -3589,9 +3636,16 @@ void Sema::BuildVariableInstantiation( NewVar->setInstantiationOfStaticDataMember(OldVar, TSK_ImplicitInstantiation); + // Forward the mangling number from the template to the instantiated decl. + Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar)); + Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar)); + // Delay instantiation of the initializer for variable templates until a - // definition of the variable is needed. - if (!isa<VarTemplateSpecializationDecl>(NewVar) && !InstantiatingVarTemplate) + // definition of the variable is needed. We need it right away if the type + // contains 'auto'. + if ((!isa<VarTemplateSpecializationDecl>(NewVar) && + !InstantiatingVarTemplate) || + NewVar->getType()->isUndeducedType()) InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs); // Diagnose unused local variables with dependent types, where the diagnostic @@ -3623,9 +3677,15 @@ void Sema::InstantiateVariableInitializer( OldVar->getInitStyle() == VarDecl::CallInit); if (!Init.isInvalid()) { bool TypeMayContainAuto = true; - if (Init.get()) { + Expr *InitExpr = Init.get(); + + if (Var->hasAttr<DLLImportAttr>() && + (!InitExpr || + !InitExpr->isConstantInitializer(getASTContext(), false))) { + // Do not dynamically initialize dllimport variables. + } else if (InitExpr) { bool DirectInit = OldVar->isDirectInit(); - AddInitializerToDecl(Var, Init.take(), DirectInit, TypeMayContainAuto); + AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto); } else ActOnUninitializedDecl(Var, TypeMayContainAuto); } else { @@ -3673,7 +3733,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarTemplateSpecializationDecl *VarSpec = dyn_cast<VarTemplateSpecializationDecl>(Var); - VarDecl *PatternDecl = 0, *Def = 0; + VarDecl *PatternDecl = nullptr, *Def = nullptr; MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(Var); @@ -3883,7 +3943,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(), TemplateArgs); Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl( - VarSpec->getSpecializedTemplate(), Def, 0, + VarSpec->getSpecializedTemplate(), Def, nullptr, VarSpec->getTemplateArgsInfo(), VarSpec->getTemplateArgs().asArray())); if (Var) { llvm::PointerUnion<VarTemplateDecl *, @@ -3951,11 +4011,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, bool AnyErrors = Tmpl->isInvalidDecl(); // Instantiate all the initializers. - for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(), - InitsEnd = Tmpl->init_end(); - Inits != InitsEnd; ++Inits) { - CXXCtorInitializer *Init = *Inits; - + for (const auto *Init : Tmpl->inits()) { // Only instantiate written initializers, let Sema re-construct implicit // ones. if (!Init->isWritten()) @@ -4008,7 +4064,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, // Build the initializer. MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), - BaseTInfo, TempInit.take(), + BaseTInfo, TempInit.get(), New->getParent(), SourceLocation()); if (NewInit.isInvalid()) { @@ -4043,10 +4099,10 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, } if (Init->isBaseInitializer()) - NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(), + NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(), New->getParent(), EllipsisLoc); else - NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(), + NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(), cast<CXXRecordDecl>(CurContext->getParent())); } else if (Init->isMemberInitializer()) { FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl( @@ -4059,7 +4115,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, continue; } - NewInit = BuildMemberInitializer(Member, TempInit.take(), + NewInit = BuildMemberInitializer(Member, TempInit.get(), Init->getSourceLocation()); } else if (Init->isIndirectMemberInitializer()) { IndirectFieldDecl *IndirectMember = @@ -4073,7 +4129,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, continue; } - NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(), + NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(), Init->getSourceLocation()); } @@ -4287,7 +4343,7 @@ static NamedDecl *findInstantiationOf(ASTContext &Ctx, if (isInstantiationOf(Ctx, D, *first)) return cast<NamedDecl>(*first); - return 0; + return nullptr; } /// \brief Finds the instantiation of the given declaration context @@ -4339,7 +4395,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // find an instantiated decl for (T y) when the ParentDC for y is // the translation unit. // e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {} - // float baz(float(*)()) { return 0.0; }
+ // float baz(float(*)()) { return 0.0; } // Foo(baz); // The better fix here is perhaps to ensure that a ParmVarDecl, by the time // it gets here, always has a FunctionOrMethod as its ParentDC?? @@ -4377,7 +4433,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, return D; if (D->isInvalidDecl()) - return 0; + return nullptr; // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. @@ -4461,7 +4517,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); if (!ParentDC) - return 0; + return nullptr; if (ParentDC != D->getDeclContext()) { // We performed some kind of instantiation in the parent context, @@ -4480,13 +4536,13 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, IsBeingInstantiated = true; if (!Tag->isBeingDefined() && RequireCompleteType(Loc, T, diag::err_incomplete_type)) - return 0; + return nullptr; ParentDC = Tag->getDecl(); } } - NamedDecl *Result = 0; + NamedDecl *Result = nullptr; if (D->getDeclName()) { DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); @@ -4550,14 +4606,6 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, /// \brief Performs template instantiation for all implicit template /// instantiations we have seen until this point. void Sema::PerformPendingInstantiations(bool LocalOnly) { - // Load pending instantiations from the external source. - if (!LocalOnly && ExternalSource) { - SmallVector<PendingImplicitInstantiation, 4> Pending; - ExternalSource->ReadPendingInstantiations(Pending); - PendingInstantiations.insert(PendingInstantiations.begin(), - Pending.begin(), Pending.end()); - } - while (!PendingLocalImplicitInstantiations.empty() || (!LocalOnly && !PendingInstantiations.empty())) { PendingImplicitInstantiation Inst; @@ -4624,10 +4672,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { void Sema::PerformDependentDiagnostics(const DeclContext *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) { - for (DeclContext::ddiag_iterator I = Pattern->ddiag_begin(), - E = Pattern->ddiag_end(); I != E; ++I) { - DependentDiagnostic *DD = *I; - + for (auto DD : Pattern->ddiags()) { switch (DD->getKind()) { case DependentDiagnostic::Access: HandleDependentAccessCheck(*DD, TemplateArgs); |