diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 636 |
1 files changed, 344 insertions, 292 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 29385e5..02a05d5 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -29,14 +29,14 @@ bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl) { if (!OldDecl->getQualifierLoc()) return false; - + NestedNameSpecifierLoc NewQualifierLoc - = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), + = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), TemplateArgs); - + if (!NewQualifierLoc) return true; - + NewDecl->setQualifierInfo(NewQualifierLoc); return false; } @@ -45,14 +45,14 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, TagDecl *NewDecl) { if (!OldDecl->getQualifierLoc()) return false; - + NestedNameSpecifierLoc NewQualifierLoc - = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), + = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), TemplateArgs); - + if (!NewQualifierLoc) return true; - + NewDecl->setQualifierInfo(NewQualifierLoc); return false; } @@ -79,7 +79,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, else { TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(), TemplateArgs, - Aligned->getLocation(), + Aligned->getLocation(), DeclarationName()); if (Result) AddAlignedAttr(Aligned->getLocation(), New, Result); @@ -96,8 +96,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, Decl * TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) { - assert(false && "Translation units cannot be instantiated"); - return D; + llvm_unreachable("Translation units cannot be instantiated"); } Decl * @@ -110,8 +109,7 @@ TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) { Decl * TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) { - assert(false && "Namespaces cannot be instantiated"); - return D; + llvm_unreachable("Namespaces cannot be instantiated"); } Decl * @@ -165,13 +163,13 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, newTag->setTypedefNameForAnonDecl(Typedef); } } - + if (TypedefNameDecl *Prev = D->getPreviousDeclaration()) { NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev, TemplateArgs); if (!InstPrev) return 0; - + Typedef->setPreviousDeclaration(cast<TypedefNameDecl>(InstPrev)); } @@ -230,7 +228,7 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { if (!PrevAliasTemplate) Inst->setInstantiatedFromMemberTemplate(D); - + Owner->addDecl(Inst); return Inst; @@ -239,8 +237,6 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { /// \brief Instantiate an initializer, breaking it into separate /// initialization arguments. /// -/// \param S The semantic analysis object. -/// /// \param Init The initializer to instantiate. /// /// \param TemplateArgs Template arguments to be substituted into the @@ -249,11 +245,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { /// \param NewArgs Will be filled in with the instantiation arguments. /// /// \returns true if an error occurred, false otherwise -static bool InstantiateInitializer(Sema &S, Expr *Init, +bool Sema::InstantiateInitializer(Expr *Init, const MultiLevelTemplateArgumentList &TemplateArgs, - SourceLocation &LParenLoc, - ASTOwningVector<Expr*> &NewArgs, - SourceLocation &RParenLoc) { + SourceLocation &LParenLoc, + ASTOwningVector<Expr*> &NewArgs, + SourceLocation &RParenLoc) { NewArgs.clear(); LParenLoc = SourceLocation(); RParenLoc = SourceLocation(); @@ -273,24 +269,24 @@ static bool InstantiateInitializer(Sema &S, Expr *Init, if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { LParenLoc = ParenList->getLParenLoc(); RParenLoc = ParenList->getRParenLoc(); - return S.SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), - true, TemplateArgs, NewArgs); + return SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), + true, TemplateArgs, NewArgs); } if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) { if (!isa<CXXTemporaryObjectExpr>(Construct)) { - if (S.SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, - TemplateArgs, NewArgs)) + if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, + TemplateArgs, NewArgs)) return true; // FIXME: Fake locations! - LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart()); + LParenLoc = PP.getLocForEndOfToken(Init->getLocStart()); RParenLoc = LParenLoc; return false; } } - - ExprResult Result = S.SubstExpr(Init, TemplateArgs); + + ExprResult Result = SubstExpr(Init, TemplateArgs); if (Result.isInvalid()) return true; @@ -319,7 +315,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { << D->isStaticDataMember() << DI->getType(); return 0; } - + // Build the instantiated declaration VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner, D->getInnerLocStart(), @@ -342,21 +338,20 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { Var->setLexicalDeclContext(D->getLexicalDeclContext()); Var->setAccess(D->getAccess()); - + if (!D->isStaticDataMember()) { Var->setUsed(D->isUsed(false)); Var->setReferenced(D->isReferenced()); } - + // FIXME: In theory, we could have a previous declaration for variables that // are not static data members. - bool Redeclaration = false; // FIXME: having to fake up a LookupResult is dumb. LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); if (D->isStaticDataMember()) SemaRef.LookupQualifiedName(Previous, Owner, false); - SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration); + SemaRef.CheckVariableDeclaration(Var, Previous); if (D->isOutOfLine()) { if (!D->isStaticDataMember()) @@ -368,13 +363,13 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var); } SemaRef.InstantiateAttrs(TemplateArgs, D, Var); - + // Link instantiations of static data members back to the template from // which they were instantiated. if (Var->isStaticDataMember()) - SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D, + SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D, TSK_ImplicitInstantiation); - + if (Var->getAnyInitializer()) { // We already have an initializer in the class. } else if (D->getInit()) { @@ -386,8 +381,8 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { // Instantiate the initializer. SourceLocation LParenLoc, RParenLoc; ASTOwningVector<Expr*> InitArgs(SemaRef); - if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc, - InitArgs, RParenLoc)) { + if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc, + InitArgs, RParenLoc)) { bool TypeMayContainAuto = true; // Attach the initializer to the declaration, if we have one. if (InitArgs.size() == 0) @@ -409,7 +404,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { // because of a bogus initializer. Var->setInvalidDecl(); } - + SemaRef.PopExpressionEvaluationContext(); } else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) && !Var->isCXXForRangeDecl()) @@ -489,14 +484,14 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { } SemaRef.InstantiateAttrs(TemplateArgs, D, Field); - + if (Invalid) Field->setInvalidDecl(); if (!Field->getDeclName()) { // Keep track of where this decl came from. SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D); - } + } if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) { if (Parent->isAnonymousStructOrUnion() && Parent->getRedeclContext()->isFunctionOrMethod()) @@ -518,11 +513,11 @@ Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) { for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(), PE = D->chain_end(); PI != PE; ++PI) { - NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI, + NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI, TemplateArgs); if (!Next) return 0; - + NamedChain[i++] = Next; } @@ -560,13 +555,13 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getFriendLoc(), InstTy); if (!FD) return 0; - + FD->setAccess(AS_public); FD->setUnsupportedFriend(D->isUnsupportedFriend()); Owner->addDecl(FD); return FD; - } - + } + NamedDecl *ND = D->getFriendDecl(); assert(ND && "friend decl must be a decl or a type!"); @@ -578,7 +573,7 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { if (!NewND) return 0; FriendDecl *FD = - FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(), + FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(), cast<NamedDecl>(NewND), D->getFriendLoc()); FD->setAccess(AS_public); FD->setUnsupportedFriend(D->isUnsupportedFriend()); @@ -620,7 +615,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { TemplateArgs, UnderlyingLoc, DeclarationName())); - + if (!Enum->getIntegerTypeSourceInfo()) Enum->setIntegerType(SemaRef.Context.IntTy); } @@ -641,8 +636,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { if (D->getDeclContext()->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); - - llvm::SmallVector<Decl*, 4> Enumerators; + + SmallVector<Decl*, 4> Enumerators; EnumConstantDecl *LastEnumConst = 0; for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(), @@ -683,7 +678,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { Enum->addDecl(EnumConst); Enumerators.push_back(EnumConst); LastEnumConst = EnumConst; - + if (D->getDeclContext()->isFunctionOrMethod()) { // If the enumeration is within a function or method, record the enum // constant as a local. @@ -703,8 +698,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { } Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { - assert(false && "EnumConstantDecls can only occur within EnumDecls."); - return 0; + llvm_unreachable("EnumConstantDecls can only occur within EnumDecls."); } Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { @@ -789,7 +783,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // template parameters of the original declaration. In this one // case, we don't complain about the ill-formed friend // declaration. - if (isFriend && Pattern->getIdentifier() && + if (isFriend && Pattern->getIdentifier() && Pattern->getIdentifier()->isStr("_Map_base") && DC->isNamespace() && cast<NamespaceDecl>(DC)->getIdentifier() && @@ -812,7 +806,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // Make sure the parameter lists match. if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams, - Complain, + Complain, Sema::TPL_TemplateMatch)) { if (Complain) return 0; @@ -859,7 +853,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (!PrevClassTemplate) Inst->setInstantiatedFromMemberTemplate(D); } - + // Trigger creation of the type for the instantiation. SemaRef.Context.getInjectedClassNameType(RecordInst, Inst->getInjectedClassNameSpecialization()); @@ -869,14 +863,14 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { DC->makeDeclVisibleInContext(Inst, /*Recoverable*/ false); return Inst; } - + Owner->addDecl(Inst); if (!PrevClassTemplate) { // Queue up any out-of-line partial specializations of this member // class template; the client will force their instantiation once // the enclosing class has been instantiated. - llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; + SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; D->getPartialSpecializations(PartialSpecs); for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) if (PartialSpecs[I]->isOutOfLine()) @@ -890,19 +884,19 @@ Decl * TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D) { ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate(); - + // Lookup the already-instantiated declaration in the instantiation // of the class template and return that. DeclContext::lookup_result Found = Owner->lookup(ClassTemplate->getDeclName()); if (Found.first == Found.second) return 0; - + ClassTemplateDecl *InstClassTemplate = dyn_cast<ClassTemplateDecl>(*Found.first); if (!InstClassTemplate) return 0; - + if (ClassTemplatePartialSpecializationDecl *Result = InstClassTemplate->findPartialSpecInstantiatedFromMember(D)) return Result; @@ -914,7 +908,7 @@ Decl * TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { // Create a local instantiation scope for this function template, which // will contain the instantiations of the template parameters and then get - // merged with the local instantiation scope for the function template + // merged with the local instantiation scope for the function template // itself. LocalInstantiationScope Scope(SemaRef); @@ -922,16 +916,16 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) return NULL; - + FunctionDecl *Instantiated = 0; if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) - Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod, + Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod, InstParams)); else Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl( - D->getTemplatedDecl(), + D->getTemplatedDecl(), InstParams)); - + if (!Instantiated) return 0; @@ -939,10 +933,10 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { // Link the instantiated function template declaration to the function // template from which it was instantiated. - FunctionTemplateDecl *InstTemplate + FunctionTemplateDecl *InstTemplate = Instantiated->getDescribedFunctionTemplate(); InstTemplate->setAccess(D->getAccess()); - assert(InstTemplate && + assert(InstTemplate && "VisitFunctionDecl/CXXMethodDecl didn't create a template!"); bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None); @@ -952,7 +946,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { if (!InstTemplate->getInstantiatedFromMemberTemplate() && !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition())) InstTemplate->setInstantiatedFromMemberTemplate(D); - + // Make declarations visible in the appropriate context. if (!isFriend) Owner->addDecl(InstTemplate); @@ -1018,7 +1012,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); void *InsertPos = 0; if (FunctionTemplate && !TemplateParams) { - std::pair<const TemplateArgument *, unsigned> Innermost + std::pair<const TemplateArgument *, unsigned> Innermost = TemplateArgs.getInnermost(); FunctionDecl *SpecFunc @@ -1038,11 +1032,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, bool MergeWithParentScope = (TemplateParams != 0) || Owner->isFunctionOrMethod() || - !(isa<Decl>(Owner) && + !(isa<Decl>(Owner) && cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); - llvm::SmallVector<ParmVarDecl *, 4> Params; + SmallVector<ParmVarDecl *, 4> Params; TypeSourceInfo *TInfo = D->getTypeSourceInfo(); TInfo = SubstFunctionType(D, Params); if (!TInfo) @@ -1068,7 +1062,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, DC = SemaRef.computeDeclContext(SS); if (!DC) return 0; } else { - DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), + DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), TemplateArgs); } @@ -1076,7 +1070,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), D->getLocation(), D->getDeclName(), T, TInfo, D->getStorageClass(), D->getStorageClassAsWritten(), - D->isInlineSpecified(), D->hasWrittenPrototype()); + D->isInlineSpecified(), D->hasWrittenPrototype(), + /*isConstexpr*/ false); if (QualifierLoc) Function->setQualifierInfo(QualifierLoc); @@ -1110,7 +1105,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Params.push_back(Param); } } - Function->setParams(Params.data(), Params.size()); + Function->setParams(Params); SourceLocation InstantiateAtPOI; if (TemplateParams) { @@ -1124,7 +1119,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, // // X<int> x; // - // We are instantiating the friend function template "f" within X<int>, + // We are instantiating the friend function template "f" within X<int>, // which means substituting int for T, but leaving "f" as a friend function // template. // Build the function template itself. @@ -1144,25 +1139,28 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, } } else if (FunctionTemplate) { // Record this function template specialization. - std::pair<const TemplateArgument *, unsigned> Innermost + std::pair<const TemplateArgument *, unsigned> Innermost = TemplateArgs.getInnermost(); Function->setFunctionTemplateSpecialization(FunctionTemplate, TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost.first, Innermost.second), InsertPos); - } else if (isFriend && D->isThisDeclarationADefinition()) { - // TODO: should we remember this connection regardless of whether - // the friend declaration provided a body? + } 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 + // parsing. + // FIXME: It might be cleaner to set this when attaching the body to the + // friend function declaration, however that would require finding all the + // instantiations and modifying them. Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); } - + if (InitFunctionInstantiation(Function, D)) Function->setInvalidDecl(); - bool Redeclaration = false; bool isExplicitSpecialization = false; - + LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); @@ -1194,15 +1192,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, &ExplicitArgs, Previous)) Function->setInvalidDecl(); - + isExplicitSpecialization = true; } else if (TemplateParams || !FunctionTemplate) { - // Look only into the namespace where the friend would be declared to - // find a previous declaration. This is the innermost enclosing namespace, + // Look only into the namespace where the friend would be declared to + // find a previous declaration. This is the innermost enclosing namespace, // as described in ActOnFriendFunctionDecl. SemaRef.LookupQualifiedName(Previous, DC); - + // In C++, the previous declaration we find might be a tag type // (class or enum). In this case, the new declaration will hide the // tag type. Note that this does does not apply if we're declaring a @@ -1210,9 +1208,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, if (Previous.isSingleTagDecl()) Previous.clear(); } - + SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous, - isExplicitSpecialization, Redeclaration); + isExplicitSpecialization); NamedDecl *PrincipalDecl = (TemplateParams ? cast<NamedDecl>(FunctionTemplate) @@ -1238,11 +1236,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, const FunctionDecl *Definition = 0; if (Function->isDefined(Definition) && Definition->getTemplateSpecializationKind() == TSK_Undeclared) { - SemaRef.Diag(Function->getLocation(), diag::err_redefinition) + SemaRef.Diag(Function->getLocation(), diag::err_redefinition) << Function->getDeclName(); SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); - Function->setInvalidDecl(); - } + 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(), @@ -1269,7 +1267,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, if (const FunctionDecl *RPattern = R->getTemplateInstantiationPattern()) if (RPattern->isDefined(RPattern)) { - SemaRef.Diag(Function->getLocation(), diag::err_redefinition) + SemaRef.Diag(Function->getLocation(), diag::err_redefinition) << Function->getDeclName(); SemaRef.Diag(R->getLocation(), diag::note_previous_definition); Function->setInvalidDecl(); @@ -1290,14 +1288,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Decl * TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, - TemplateParameterList *TemplateParams) { + TemplateParameterList *TemplateParams, + bool IsClassScopeSpecialization) { FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); void *InsertPos = 0; if (FunctionTemplate && !TemplateParams) { // We are creating a function template specialization from a function // template. Check whether there is already a function template // specialization for this particular set of template arguments. - std::pair<const TemplateArgument *, unsigned> Innermost + std::pair<const TemplateArgument *, unsigned> Innermost = TemplateArgs.getInnermost(); FunctionDecl *SpecFunc @@ -1316,12 +1315,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, isFriend = (D->getFriendObjectKind() != Decl::FOK_None); bool MergeWithParentScope = (TemplateParams != 0) || - !(isa<Decl>(Owner) && + !(isa<Decl>(Owner) && cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); // Instantiate enclosing template arguments for friends. - llvm::SmallVector<TemplateParameterList *, 4> TempParamLists; + SmallVector<TemplateParameterList *, 4> TempParamLists; unsigned NumTempParamLists = 0; if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) { TempParamLists.set_size(NumTempParamLists); @@ -1334,7 +1333,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } } - llvm::SmallVector<ParmVarDecl *, 4> Params; + SmallVector<ParmVarDecl *, 4> Params; TypeSourceInfo *TInfo = D->getTypeSourceInfo(); TInfo = SubstFunctionType(D, Params); if (!TInfo) @@ -1352,18 +1351,18 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // synthesized in the method declaration. if (!isa<FunctionProtoType>(T.IgnoreParens())) { assert(!Params.size() && "Instantiating type could not yield parameters"); - llvm::SmallVector<QualType, 4> ParamTypes; - if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), - D->getNumParams(), TemplateArgs, ParamTypes, + SmallVector<QualType, 4> ParamTypes; + if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), + D->getNumParams(), TemplateArgs, ParamTypes, &Params)) - return 0; + return 0; } NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); if (QualifierLoc) { QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs); - if (!QualifierLoc) + if (!QualifierLoc) return 0; } @@ -1396,7 +1395,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, StartLoc, NameInfo, T, TInfo, Constructor->isExplicit(), Constructor->isInlineSpecified(), - false); + false, /*isConstexpr*/ false); } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { Method = CXXDestructorDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, @@ -1407,6 +1406,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, StartLoc, NameInfo, T, TInfo, Conversion->isInlineSpecified(), Conversion->isExplicit(), + /*isConstexpr*/ false, Conversion->getLocEnd()); } else { Method = CXXMethodDecl::Create(SemaRef.Context, Record, @@ -1414,7 +1414,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, D->isStatic(), D->getStorageClassAsWritten(), D->isInlineSpecified(), - D->getLocEnd()); + /*isConstexpr*/ false, D->getLocEnd()); } if (QualifierLoc) @@ -1446,7 +1446,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Method->setDescribedFunctionTemplate(FunctionTemplate); } else if (FunctionTemplate) { // Record this function template specialization. - std::pair<const TemplateArgument *, unsigned> Innermost + std::pair<const TemplateArgument *, unsigned> Innermost = TemplateArgs.getInnermost(); Method->setFunctionTemplateSpecialization(FunctionTemplate, TemplateArgumentList::CreateCopy(SemaRef.Context, @@ -1457,7 +1457,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // Record that this is an instantiation of a member function. Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); } - + // If we are instantiating a member function defined // out-of-line, the instantiation will have the same lexical // context (which will be a namespace scope) as the template. @@ -1475,7 +1475,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // Attach the parameters for (unsigned P = 0; P < Params.size(); ++P) Params[P]->setOwningFunction(Method); - Method->setParams(Params.data(), Params.size()); + Method->setParams(Params); if (InitMethodInstantiation(Method, D)) Method->setInvalidDecl(); @@ -1494,8 +1494,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Previous.clear(); } - bool Redeclaration = false; - SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration); + if (!IsClassScopeSpecialization) + SemaRef.CheckFunctionDeclaration(0, Method, Previous, false); if (D->isPure()) SemaRef.CheckPureMethod(Method, SourceRange()); @@ -1514,7 +1514,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, : Method); if (isFriend) Record->makeDeclVisibleInContext(DeclToAdd); - else + else if (!IsClassScopeSpecialization) Owner->addDecl(DeclToAdd); } @@ -1558,14 +1558,14 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( D->wasDeclaredWithTypename(), D->isParameterPack()); Inst->setAccess(AS_public); - + if (D->hasDefaultArgument()) - Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false); + Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false); - // Introduce this template parameter's instantiation into the instantiation + // Introduce this template parameter's instantiation into the instantiation // scope. SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst); - + return Inst; } @@ -1573,26 +1573,26 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( NonTypeTemplateParmDecl *D) { // Substitute into the type of the non-type template parameter. TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc(); - llvm::SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; - llvm::SmallVector<QualType, 4> ExpandedParameterPackTypes; + SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; + SmallVector<QualType, 4> ExpandedParameterPackTypes; bool IsExpandedParameterPack = false; - TypeSourceInfo *DI; + TypeSourceInfo *DI; QualType T; bool Invalid = false; if (D->isExpandedParameterPack()) { - // The non-type template parameter pack is an already-expanded pack + // The non-type template parameter pack is an already-expanded pack // expansion of types. Substitute into each of the expanded types. ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes()); ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes()); for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { TypeSourceInfo *NewDI =SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs, - D->getLocation(), + D->getLocation(), D->getDeclName()); if (!NewDI) return 0; - + ExpandedParameterPackTypesAsWritten.push_back(NewDI); QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(), D->getLocation()); @@ -1600,7 +1600,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( return 0; ExpandedParameterPackTypes.push_back(NewT); } - + IsExpandedParameterPack = true; DI = D->getTypeSourceInfo(); T = DI->getType(); @@ -1610,9 +1610,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( // types. PackExpansionTypeLoc Expansion = cast<PackExpansionTypeLoc>(TL); TypeLoc Pattern = Expansion.getPatternLoc(); - llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; + SmallVector<UnexpandedParameterPack, 2> Unexpanded; SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); - + // Determine whether the set of unexpanded parameter packs can and should // be expanded. bool Expand = true; @@ -1622,22 +1622,21 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(), Pattern.getSourceRange(), - Unexpanded.data(), - Unexpanded.size(), + Unexpanded, TemplateArgs, - Expand, RetainExpansion, + Expand, RetainExpansion, NumExpansions)) return 0; - + if (Expand) { for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); TypeSourceInfo *NewDI = SemaRef.SubstType(Pattern, TemplateArgs, - D->getLocation(), + D->getLocation(), D->getDeclName()); if (!NewDI) return 0; - + ExpandedParameterPackTypesAsWritten.push_back(NewDI); QualType NewT = SemaRef.CheckNonTypeTemplateParameterType( NewDI->getType(), @@ -1646,7 +1645,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( return 0; ExpandedParameterPackTypes.push_back(NewT); } - + // Note that we have an expanded parameter pack. The "type" of this // expanded parameter pack is the original expansion type, but callers // will end up using the expanded parameter pack types for type-checking. @@ -1658,62 +1657,62 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( // pattern and create a new pack expansion type. Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); TypeSourceInfo *NewPattern = SemaRef.SubstType(Pattern, TemplateArgs, - D->getLocation(), + D->getLocation(), D->getDeclName()); if (!NewPattern) return 0; - + DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(), NumExpansions); if (!DI) return 0; - + T = DI->getType(); } } else { // Simple case: substitution into a parameter that is not a parameter pack. - DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, + DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs, D->getLocation(), D->getDeclName()); if (!DI) return 0; - + // Check that this type is acceptable for a non-type template parameter. - T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(), + T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(), D->getLocation()); if (T.isNull()) { T = SemaRef.Context.IntTy; Invalid = true; } } - + NonTypeTemplateParmDecl *Param; if (IsExpandedParameterPack) - Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, + Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), - D->getDepth() - TemplateArgs.getNumLevels(), - D->getPosition(), + D->getDepth() - TemplateArgs.getNumLevels(), + D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes.data(), ExpandedParameterPackTypes.size(), ExpandedParameterPackTypesAsWritten.data()); else - Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, + Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), - D->getDepth() - TemplateArgs.getNumLevels(), - D->getPosition(), - D->getIdentifier(), T, + D->getDepth() - TemplateArgs.getNumLevels(), + D->getPosition(), + D->getIdentifier(), T, D->isParameterPack(), DI); - + Param->setAccess(AS_public); if (Invalid) Param->setInvalidDecl(); - + Param->setDefaultArgument(D->getDefaultArgument(), false); - - // Introduce this template parameter's instantiation into the instantiation + + // Introduce this template parameter's instantiation into the instantiation // scope. SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); return Param; @@ -1732,34 +1731,34 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( InstParams = SubstTemplateParams(TempParams); if (!InstParams) return NULL; - } - + } + // Build the template template parameter. TemplateTemplateParmDecl *Param = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(), - D->getDepth() - TemplateArgs.getNumLevels(), - D->getPosition(), D->isParameterPack(), + D->getDepth() - TemplateArgs.getNumLevels(), + D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams); Param->setDefaultArgument(D->getDefaultArgument(), false); Param->setAccess(AS_public); - - // Introduce this template parameter's instantiation into the instantiation + + // Introduce this template parameter's instantiation into the instantiation // scope. SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); - + return Param; } Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { // Using directives are never dependent (and never contain any types or // expressions), so they require no explicit instantiation work. - + UsingDirectiveDecl *Inst = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(), - D->getNamespaceKeyLocation(), + D->getNamespaceKeyLocation(), D->getQualifierLoc(), - D->getIdentLocation(), - D->getNominatedNamespace(), + D->getIdentLocation(), + D->getNominatedNamespace(), D->getCommonAncestor()); Owner->addDecl(Inst); return Inst; @@ -1863,7 +1862,7 @@ Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { Decl * TemplateDeclInstantiator ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { NestedNameSpecifierLoc QualifierLoc - = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), + = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); if (!QualifierLoc) return 0; @@ -1891,7 +1890,7 @@ Decl * TemplateDeclInstantiator = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); if (!QualifierLoc) return 0; - + CXXScopeSpec SS; SS.Adopt(QualifierLoc); @@ -1909,6 +1908,29 @@ Decl * TemplateDeclInstantiator return UD; } + +Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *Decl) { + CXXMethodDecl *OldFD = Decl->getSpecialization(); + CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, 0, true)); + + LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, + Sema::ForRedeclaration); + + SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext); + if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous)) { + NewFD->setInvalidDecl(); + return NewFD; + } + + // Associate the specialization with the pattern. + FunctionDecl *Specialization = cast<FunctionDecl>(Previous.getFoundDecl()); + assert(Specialization && "Class scope Specialization is null"); + SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD); + + return NewFD; +} + Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs) { TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); @@ -1930,7 +1952,7 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { bool Invalid = false; unsigned N = L->size(); - typedef llvm::SmallVector<NamedDecl *, 8> ParamVector; + typedef SmallVector<NamedDecl *, 8> ParamVector; ParamVector Params; Params.reserve(N); for (TemplateParameterList::iterator PI = L->begin(), PE = L->end(); @@ -1951,13 +1973,13 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { return InstL; } -/// \brief Instantiate the declaration of a class template partial +/// \brief Instantiate the declaration of a class template partial /// specialization. /// /// \param ClassTemplate the (instantiated) class template that is partially // specialized by the instantiation of \p PartialSpec. /// -/// \param PartialSpec the (uninstantiated) class template partial +/// \param PartialSpec the (uninstantiated) class template partial /// specialization that we are instantiating. /// /// \returns The instantiated partial specialization, if successful; otherwise, @@ -1970,28 +1992,28 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // specialization, which will contain the instantiations of the template // parameters. LocalInstantiationScope Scope(SemaRef); - + // Substitute into the template parameters of the class template partial // specialization. TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); TemplateParameterList *InstParams = SubstTemplateParams(TempParams); if (!InstParams) return 0; - + // Substitute into the template arguments of the class template partial // specialization. TemplateArgumentListInfo InstTemplateArgs; // no angle locations - if (SemaRef.Subst(PartialSpec->getTemplateArgsAsWritten(), - PartialSpec->getNumTemplateArgsAsWritten(), + if (SemaRef.Subst(PartialSpec->getTemplateArgsAsWritten(), + PartialSpec->getNumTemplateArgsAsWritten(), InstTemplateArgs, TemplateArgs)) return 0; - + // Check that the template argument list is well-formed for this // class template. - llvm::SmallVector<TemplateArgument, 4> Converted; - if (SemaRef.CheckTemplateArgumentList(ClassTemplate, + SmallVector<TemplateArgument, 4> Converted; + if (SemaRef.CheckTemplateArgumentList(ClassTemplate, PartialSpec->getLocation(), - InstTemplateArgs, + InstTemplateArgs, false, Converted)) return 0; @@ -2002,10 +2024,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( ClassTemplateSpecializationDecl *PrevDecl = ClassTemplate->findPartialSpecialization(Converted.data(), Converted.size(), InsertPos); - + // Build the canonical type that describes the converted template // arguments of the class template partial specialization. - QualType CanonType + QualType CanonType = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate), Converted.data(), Converted.size()); @@ -2023,7 +2045,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( PartialSpec->getLocation(), InstTemplateArgs, CanonType); - + if (PrevDecl) { // We've already seen a partial specialization with the same template // parameters and template arguments. This can happen, for example, when @@ -2046,17 +2068,17 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( << SemaRef.Context.getTypeDeclType(PrevDecl); return 0; } - - + + // Create the class template partial specialization declaration. ClassTemplatePartialSpecializationDecl *InstPartialSpec - = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, + = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, PartialSpec->getTagKind(), - Owner, + Owner, PartialSpec->getLocStart(), PartialSpec->getLocation(), InstParams, - ClassTemplate, + ClassTemplate, Converted.data(), Converted.size(), InstTemplateArgs, @@ -2069,7 +2091,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setTypeAsWritten(WrittenTy); - + // Add this partial specialization to the set of class template partial // specializations. ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos); @@ -2078,7 +2100,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( TypeSourceInfo* TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, - llvm::SmallVectorImpl<ParmVarDecl *> &Params) { + SmallVectorImpl<ParmVarDecl *> &Params) { TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); assert(OldTInfo && "substituting function without type source info"); assert(Params.empty() && "parameter vector is non-empty at start"); @@ -2104,7 +2126,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (!OldParam->isParameterPack() || (NewIdx < NumNewParams && NewProtoLoc->getArg(NewIdx)->isParameterPack())) { - // Simple case: normal parameter, or a parameter pack that's + // Simple case: normal parameter, or a parameter pack that's // instantiated to a (still-dependent) parameter pack. ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++); Params.push_back(NewParam); @@ -2112,7 +2134,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, NewParam); continue; } - + // Parameter pack: make the instantiation an argument pack. SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack( OldParam); @@ -2184,43 +2206,42 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) { // The function has an exception specification or a "noreturn" // attribute. Substitute into each of the exception types. - llvm::SmallVector<QualType, 4> Exceptions; + SmallVector<QualType, 4> Exceptions; for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) { // FIXME: Poor location information! if (const PackExpansionType *PackExpansion = Proto->getExceptionType(I)->getAs<PackExpansionType>()) { // We have a pack expansion. Instantiate it. - llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; + SmallVector<UnexpandedParameterPack, 2> Unexpanded; SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), Unexpanded); - assert(!Unexpanded.empty() && + assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); bool Expand = false; bool RetainExpansion = false; llvm::Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); - if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), + if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), SourceRange(), - Unexpanded.data(), - Unexpanded.size(), + Unexpanded, TemplateArgs, - Expand, + Expand, RetainExpansion, NumExpansions)) break; if (!Expand) { // We can't expand this pack expansion into separate arguments yet; - // just substitute into the pattern and create a new pack expansion + // just substitute into the pattern and create a new pack expansion // type. Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); - QualType T = SemaRef.SubstType(PackExpansion->getPattern(), + QualType T = SemaRef.SubstType(PackExpansion->getPattern(), TemplateArgs, New->getLocation(), New->getDeclName()); if (T.isNull()) break; - + T = SemaRef.Context.getPackExpansionType(T, NumExpansions); Exceptions.push_back(T); continue; @@ -2230,8 +2251,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, bool Invalid = false; for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); - - QualType T = SemaRef.SubstType(PackExpansion->getPattern(), + + QualType T = SemaRef.SubstType(PackExpansion->getPattern(), TemplateArgs, New->getLocation(), New->getDeclName()); if (T.isNull()) { @@ -2247,11 +2268,11 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, continue; } - + QualType T = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs, New->getLocation(), New->getDeclName()); - if (T.isNull() || + if (T.isNull() || SemaRef.CheckSpecifiedExceptionType(T, New->getLocation())) continue; @@ -2262,10 +2283,24 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); if (E.isUsable()) + E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); + + if (E.isUsable()) { + SourceLocation ErrLoc; + llvm::APSInt NoexceptVal; NoexceptExpr = E.take(); + if (!NoexceptExpr->isTypeDependent() && + !NoexceptExpr->isValueDependent() && + !NoexceptExpr->isIntegerConstantExpr(NoexceptVal, SemaRef.Context, + &ErrLoc, /*evaluated=*/false)){ + SemaRef.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression) + << NoexceptExpr->getSourceRange(); + NoexceptExpr = 0; + } + } } - // Rebuild the function type + // Rebuild the function type FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); EPI.ExceptionSpecType = Proto->getExceptionSpecType(); @@ -2283,6 +2318,13 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI)); } + // C++0x [dcl.constexpr]p6: If the instantiated template specialization of + // a constexpr function template satisfies the requirements for a constexpr + // function, then it is a constexpr function. + if (Tmpl->isConstexpr() && + SemaRef.CheckConstexprFunctionDecl(New, Sema::CCK_Instantiation)) + New->setConstexpr(true); + const FunctionDecl* Definition = Tmpl; // Get the definition. Leaves the variable unchanged if undefined. @@ -2337,8 +2379,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (Function->isInvalidDecl() || Function->isDefined()) return; - // Never instantiate an explicit specialization. - if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + // Never instantiate an explicit specialization except if it is a class scope + // explicit specialization. + if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization && + !Function->getClassScopeSpecializationPattern()) return; // Find the function body that we'll be substituting. @@ -2362,7 +2406,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } // Call the LateTemplateParser callback if there a need to late parse - // a templated function definition. + // a templated function definition. if (!Pattern && PatternDecl->isLateTemplateParsed() && LateTemplateParser) { LateTemplateParser(OpaqueParser, PatternDecl); @@ -2372,16 +2416,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (!Pattern && !PatternDecl->isDefaulted()) { if (DefinitionRequired) { if (Function->getPrimaryTemplate()) - Diag(PointOfInstantiation, + Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_func_template) << Function->getPrimaryTemplate(); else - Diag(PointOfInstantiation, + Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_member) << 1 << Function->getDeclName() << Function->getDeclContext(); - + if (PatternDecl) - Diag(PatternDecl->getLocation(), + Diag(PatternDecl->getLocation(), diag::note_explicit_instantiation_here); Function->setInvalidDecl(); } else if (Function->getTemplateSpecializationKind() @@ -2404,19 +2448,19 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); if (Inst) - return; - + return; + // If we're performing recursive template instantiation, create our own // queue of pending implicit instantiations that we will instantiate later, // while we're still within our own instantiation context. - llvm::SmallVector<VTableUse, 16> SavedVTableUses; + SmallVector<VTableUse, 16> SavedVTableUses; std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; if (Recursive) { VTableUses.swap(SavedVTableUses); PendingInstantiations.swap(SavedPendingInstantiations); } - EnterExpressionEvaluationContext EvalContext(*this, + EnterExpressionEvaluationContext EvalContext(*this, Sema::PotentiallyEvaluated); ActOnStartOfFunctionDef(0, Function); @@ -2445,11 +2489,11 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, ++FParamIdx; continue; } - + // Expand the parameter pack. Scope.MakeInstantiatedLocalArgPack(PatternParam); - for (unsigned NumFParams = Function->getNumParams(); - FParamIdx < NumFParams; + for (unsigned NumFParams = Function->getNumParams(); + FParamIdx < NumFParams; ++FParamIdx) { ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); FunctionParam->setDeclName(PatternParam->getDeclName()); @@ -2481,7 +2525,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (Body.isInvalid()) Function->setInvalidDecl(); - + ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true); } @@ -2545,7 +2589,7 @@ void Sema::InstantiateStaticDataMemberDefinition( // Find the out-of-line definition of this static data member. VarDecl *Def = Var->getInstantiatedFromStaticDataMember(); assert(Def && "This data member was not instantiated from a template?"); - assert(Def->isStaticDataMember() && "Not a static data member?"); + assert(Def->isStaticDataMember() && "Not a static data member?"); Def = Def->getOutOfLineDefinition(); if (!Def) { @@ -2555,7 +2599,7 @@ void Sema::InstantiateStaticDataMemberDefinition( // another translation unit. if (DefinitionRequired) { Def = Var->getInstantiatedFromStaticDataMember(); - Diag(PointOfInstantiation, + Diag(PointOfInstantiation, diag::err_explicit_instantiation_undefined_member) << 2 << Var->getDeclName() << Var->getDeclContext(); Diag(Def->getLocation(), diag::note_explicit_instantiation_here); @@ -2571,12 +2615,12 @@ void Sema::InstantiateStaticDataMemberDefinition( // Never instantiate an explicit specialization. if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) return; - + // C++0x [temp.explicit]p9: // Except for inline functions, other explicit instantiation declarations // have the effect of suppressing the implicit instantiation of the entity // to which they refer. - if (Var->getTemplateSpecializationKind() + if (Var->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDeclaration) return; @@ -2591,7 +2635,7 @@ void Sema::InstantiateStaticDataMemberDefinition( // If we're performing recursive template instantiation, create our own // queue of pending implicit instantiations that we will instantiate later, // while we're still within our own instantiation context. - llvm::SmallVector<VTableUse, 16> SavedVTableUses; + SmallVector<VTableUse, 16> SavedVTableUses; std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; if (Recursive) { VTableUses.swap(SavedVTableUses); @@ -2639,14 +2683,26 @@ void Sema::InstantiateStaticDataMemberDefinition( } } +static MultiInitializer CreateMultiInitializer(SmallVectorImpl<Expr*> &Args, + const CXXCtorInitializer *Init) { + // FIXME: This is a hack that will do slightly the wrong thing for an + // initializer of the form foo({...}). + // The right thing to do would be to modify InstantiateInitializer to create + // the MultiInitializer. + if (Args.size() == 1 && isa<InitListExpr>(Args[0])) + return MultiInitializer(Args[0]); + return MultiInitializer(Init->getLParenLoc(), Args.data(), + Args.size(), Init->getRParenLoc()); +} + void Sema::InstantiateMemInitializers(CXXConstructorDecl *New, const CXXConstructorDecl *Tmpl, const MultiLevelTemplateArgumentList &TemplateArgs) { - llvm::SmallVector<MemInitTy*, 4> NewInits; + SmallVector<CXXCtorInitializer*, 4> NewInits; bool AnyErrors = false; - + // Instantiate all the initializers. for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(), InitsEnd = Tmpl->init_end(); @@ -2662,20 +2718,19 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, ASTOwningVector<Expr*> NewArgs(*this); SourceLocation EllipsisLoc; - + if (Init->isPackExpansion()) { // This is a pack expansion. We should expand it now. TypeLoc BaseTL = Init->getBaseClassInfo()->getTypeLoc(); - llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; + SmallVector<UnexpandedParameterPack, 2> Unexpanded; collectUnexpandedParameterPacks(BaseTL, Unexpanded); bool ShouldExpand = false; bool RetainExpansion = false; llvm::Optional<unsigned> NumExpansions; - if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), + if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), BaseTL.getSourceRange(), - Unexpanded.data(), - Unexpanded.size(), - TemplateArgs, ShouldExpand, + Unexpanded, + TemplateArgs, ShouldExpand, RetainExpansion, NumExpansions)) { AnyErrors = true; @@ -2683,22 +2738,22 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, continue; } assert(ShouldExpand && "Partial instantiation of base initializer?"); - - // Loop over all of the arguments in the argument pack(s), + + // Loop over all of the arguments in the argument pack(s), for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); // Instantiate the initializer. - if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, + if (InstantiateInitializer(Init->getInit(), TemplateArgs, LParenLoc, NewArgs, RParenLoc)) { AnyErrors = true; break; } // Instantiate the base type. - TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), - TemplateArgs, - Init->getSourceLocation(), + TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), + TemplateArgs, + Init->getSourceLocation(), New->getDeclName()); if (!BaseTInfo) { AnyErrors = true; @@ -2706,52 +2761,45 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, } // Build the initializer. - MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), - BaseTInfo, - (Expr **)NewArgs.data(), - NewArgs.size(), - Init->getLParenLoc(), - Init->getRParenLoc(), + MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); + MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(), + BaseTInfo, MultiInit, New->getParent(), SourceLocation()); if (NewInit.isInvalid()) { AnyErrors = true; break; } - + NewInits.push_back(NewInit.get()); NewArgs.clear(); } - + continue; } // Instantiate the initializer. - if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs, + if (InstantiateInitializer(Init->getInit(), TemplateArgs, LParenLoc, NewArgs, RParenLoc)) { AnyErrors = true; continue; } - + MemInitResult NewInit; if (Init->isBaseInitializer()) { - TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), - TemplateArgs, - Init->getSourceLocation(), + TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), + TemplateArgs, + Init->getSourceLocation(), New->getDeclName()); if (!BaseTInfo) { AnyErrors = true; New->setInvalidDecl(); continue; } - - NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, - (Expr **)NewArgs.data(), - NewArgs.size(), - Init->getLParenLoc(), - Init->getRParenLoc(), - New->getParent(), - EllipsisLoc); + + MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); + NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, MultiInit, + New->getParent(), EllipsisLoc); } else if (Init->isMemberInitializer()) { FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl( Init->getMemberLocation(), @@ -2763,11 +2811,9 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, continue; } - NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(), - NewArgs.size(), - Init->getSourceLocation(), - Init->getLParenLoc(), - Init->getRParenLoc()); + MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); + NewInit = BuildMemberInitializer(Member, MultiInit, + Init->getSourceLocation()); } else if (Init->isIndirectMemberInitializer()) { IndirectFieldDecl *IndirectMember = cast_or_null<IndirectFieldDecl>(FindInstantiatedDecl( @@ -2777,14 +2823,12 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, if (!IndirectMember) { AnyErrors = true; New->setInvalidDecl(); - continue; + continue; } - - NewInit = BuildMemberInitializer(IndirectMember, (Expr **)NewArgs.data(), - NewArgs.size(), - Init->getSourceLocation(), - Init->getLParenLoc(), - Init->getRParenLoc()); + + MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init)); + NewInit = BuildMemberInitializer(IndirectMember, MultiInit, + Init->getSourceLocation()); } if (NewInit.isInvalid()) { @@ -2794,7 +2838,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, // FIXME: It would be nice if ASTOwningVector had a release function. NewArgs.take(); - NewInits.push_back((MemInitTy *)NewInit.get()); + NewInits.push_back(NewInit.get()); } } @@ -2824,20 +2868,20 @@ static bool isInstantiationOf(ClassTemplateDecl *Pattern, static bool isInstantiationOf(FunctionTemplateDecl *Pattern, FunctionTemplateDecl *Instance) { Pattern = Pattern->getCanonicalDecl(); - + do { Instance = Instance->getCanonicalDecl(); if (Pattern == Instance) return true; Instance = Instance->getInstantiatedFromMemberTemplate(); } while (Instance); - + return false; } -static bool +static bool isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern, ClassTemplatePartialSpecializationDecl *Instance) { - Pattern + Pattern = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl()); do { Instance = cast<ClassTemplatePartialSpecializationDecl>( @@ -2846,7 +2890,7 @@ isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern, return true; Instance = Instance->getInstantiatedFromMember(); } while (Instance); - + return false; } @@ -3052,11 +3096,11 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found = CurrentInstantiationScope->findInstantiationOf(D); - + if (Found) { if (Decl *FD = Found->dyn_cast<Decl *>()) return cast<NamedDecl>(FD); - + unsigned PackIdx = ArgumentPackSubstitutionIndex; return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]); } @@ -3064,10 +3108,10 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // 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. assert(isa<LabelDecl>(D)); - + Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); assert(Inst && "Failed to instantiate label??"); - + CurrentInstantiationScope->InstantiatedLocal(D, Inst); return cast<LabelDecl>(Inst); } @@ -3075,7 +3119,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { if (!Record->isDependentContext()) return D; - + // If the RecordDecl is actually the injected-class-name or a // "templated" declaration for a class template, class template // partial specialization, or a member class of a class template, @@ -3083,7 +3127,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // or partial specialization to find the new DeclContext. QualType T; ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate(); - + if (ClassTemplate) { T = ClassTemplate->getInjectedClassNameSpecialization(); } else if (ClassTemplatePartialSpecializationDecl *PartialSpec @@ -3096,26 +3140,26 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, assert(isa<InjectedClassNameType>(T) && "type of partial specialization is not an InjectedClassNameType"); T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType(); - } - + } + if (!T.isNull()) { // Substitute into the injected-class-name to get the type // corresponding to the instantiation we want, which may also be // the current instantiation (if we're in a template // definition). This substitution should never fail, since we // know we can instantiate the injected-class-name or we - // wouldn't have gotten to the injected-class-name! + // wouldn't have gotten to the injected-class-name! // FIXME: Can we use the CurrentInstantiationScope to avoid this // extra instantiation in the common case? T = SubstType(T, TemplateArgs, Loc, DeclarationName()); assert(!T.isNull() && "Instantiation of injected-class-name cannot fail."); - + if (!T->isDependentType()) { assert(T->isRecordType() && "Instantiation must produce a record type"); return T->getAs<RecordType>()->getDecl(); } - + // We are performing "partial" template instantiation to create // the member declarations for the members of a class template // specialization. Therefore, D is actually referring to something @@ -3128,7 +3172,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, DC = DC->getParent()) { if (ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) - if (isInstantiationOf(ClassTemplate, + if (isInstantiationOf(ClassTemplate, Spec->getSpecializedTemplate())) return Spec; @@ -3139,10 +3183,10 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // We're performing "instantiation" of a member of the current // instantiation while we are type-checking the // definition. Compute the declaration context and return that. - assert(!SawNonDependentContext && + assert(!SawNonDependentContext && "No dependent context while instantiating record"); DeclContext *DC = computeDeclContext(T); - assert(DC && + assert(DC && "Unable to find declaration for the current instantiation"); return cast<CXXRecordDecl>(DC); } @@ -3153,7 +3197,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, if (!ParentDC->isDependentContext()) return D; - + ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); if (!ParentDC) return 0; @@ -3207,7 +3251,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // declaration failed to instantiate. There's no point in complaining // further, since this is normal in invalid code. } else if (IsBeingInstantiated) { - // The class in which this member exists is currently being + // The class in which this member exists is currently being // instantiated, and we haven't gotten around to instantiating this // member yet. This can happen when the code uses forward declarations // of member classes, and introduces ordering dependencies via @@ -3221,7 +3265,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, llvm_unreachable("Unable to find instantiation of declaration!"); } } - + D = Result; } @@ -3231,6 +3275,14 @@ 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<std::pair<ValueDecl *, SourceLocation>, 4> Pending; + ExternalSource->ReadPendingInstantiations(Pending); + PendingInstantiations.insert(PendingInstantiations.begin(), + Pending.begin(), Pending.end()); + } + while (!PendingLocalImplicitInstantiations.empty() || (!LocalOnly && !PendingInstantiations.empty())) { PendingImplicitInstantiation Inst; @@ -3267,7 +3319,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { // and removed the need for implicit instantiation. switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) { case TSK_Undeclared: - assert(false && "Cannot instantitiate an undeclared specialization."); + llvm_unreachable("Cannot instantitiate an undeclared specialization."); case TSK_ExplicitInstantiationDeclaration: case TSK_ExplicitSpecialization: continue; // No longer need to instantiate this type. |