diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 334 |
1 files changed, 183 insertions, 151 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 19c46ab..33e83d0 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -10,9 +10,6 @@ // //===----------------------------------------------------------------------===/ #include "clang/Sema/SemaInternal.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/PrettyDeclStackTrace.h" -#include "clang/Sema/Template.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" @@ -22,6 +19,9 @@ #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" using namespace clang; @@ -60,6 +60,64 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, // Include attribute instantiation code. #include "clang/Sema/AttrTemplateInstantiate.inc" +static void instantiateDependentAlignedAttr( + Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, + const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion) { + if (Aligned->isAlignmentExpr()) { + // The alignment expression is a constant expression. + EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated); + ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs); + if (!Result.isInvalid()) + S.AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(), + Aligned->getSpellingListIndex(), IsPackExpansion); + } else { + TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(), + TemplateArgs, Aligned->getLocation(), + DeclarationName()); + if (Result) + S.AddAlignedAttr(Aligned->getLocation(), New, Result, + Aligned->getSpellingListIndex(), IsPackExpansion); + } +} + +static void instantiateDependentAlignedAttr( + Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, + const AlignedAttr *Aligned, Decl *New) { + if (!Aligned->isPackExpansion()) { + instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false); + return; + } + + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + if (Aligned->isAlignmentExpr()) + S.collectUnexpandedParameterPacks(Aligned->getAlignmentExpr(), + Unexpanded); + else + S.collectUnexpandedParameterPacks(Aligned->getAlignmentType()->getTypeLoc(), + Unexpanded); + assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); + + // Determine whether we can expand this attribute pack yet. + bool Expand = true, RetainExpansion = false; + Optional<unsigned> NumExpansions; + // FIXME: Use the actual location of the ellipsis. + SourceLocation EllipsisLoc = Aligned->getLocation(); + if (S.CheckParameterPacksForExpansion(EllipsisLoc, Aligned->getRange(), + Unexpanded, TemplateArgs, Expand, + RetainExpansion, NumExpansions)) + return; + + if (!Expand) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, -1); + instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, true); + } else { + for (unsigned I = 0; I != *NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, I); + instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false); + } + } +} + void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, Decl *New, LateInstantiatedAttrVec *LateAttrs, @@ -69,31 +127,13 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, const Attr *TmplAttr = *i; // FIXME: This should be generalized to more than just the AlignedAttr. - if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) { - if (Aligned->isAlignmentDependent()) { - if (Aligned->isAlignmentExpr()) { - // The alignment expression is a constant expression. - EnterExpressionEvaluationContext Unevaluated(*this, - Sema::ConstantEvaluated); - - ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(), - TemplateArgs); - if (!Result.isInvalid()) - AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(), - Aligned->getIsMSDeclSpec()); - } else { - TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(), - TemplateArgs, - Aligned->getLocation(), - DeclarationName()); - if (Result) - AddAlignedAttr(Aligned->getLocation(), New, Result, - Aligned->getIsMSDeclSpec()); - } - continue; - } + const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr); + if (Aligned && Aligned->isAlignmentDependent()) { + instantiateDependentAlignedAttr(*this, TemplateArgs, Aligned, 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. @@ -189,9 +229,9 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, // tag decl, re-establish that relationship for the new typedef. if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) { TagDecl *oldTag = oldTagType->getDecl(); - if (oldTag->getTypedefNameForAnonDecl() == D) { + if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) { TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl(); - assert(!newTag->getIdentifier() && !newTag->getTypedefNameForAnonDecl()); + assert(!newTag->hasNameForLinkage()); newTag->setTypedefNameForAnonDecl(Typedef); } } @@ -245,8 +285,8 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { TypeAliasTemplateDecl *PrevAliasTemplate = 0; if (Pattern->getPreviousDecl()) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); - if (Found.first != Found.second) { - PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(*Found.first); + if (!Found.empty()) { + PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Found.front()); } } @@ -298,8 +338,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { D->getInnerLocStart(), D->getLocation(), D->getIdentifier(), DI->getType(), DI, - D->getStorageClass(), - D->getStorageClassAsWritten()); + D->getStorageClass()); Var->setThreadSpecified(D->isThreadSpecified()); Var->setInitStyle(D->getInitStyle()); Var->setCXXForRangeDecl(D->isCXXForRangeDecl()); @@ -322,6 +361,11 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { Var->setReferenced(D->isReferenced()); } + SemaRef.InstantiateAttrs(TemplateArgs, D, Var, LateAttrs, StartingScope); + + if (Var->hasAttrs()) + SemaRef.CheckAlignasUnderalignment(Var); + // FIXME: In theory, we could have a previous declaration for variables that // are not static data members. // FIXME: having to fake up a LookupResult is dumb. @@ -345,7 +389,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { if (Owner->isFunctionOrMethod()) SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var); } - SemaRef.InstantiateAttrs(TemplateArgs, D, Var, LateAttrs, StartingScope); // Link instantiations of static data members back to the template from // which they were instantiated. @@ -459,6 +502,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope); + if (Field->hasAttrs()) + SemaRef.CheckAlignasUnderalignment(Field); + if (Invalid) Field->setInvalidDecl(); @@ -745,8 +791,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (!isFriend && Pattern->getPreviousDecl()) { DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); - if (Found.first != Found.second) { - PrevClassTemplate = dyn_cast<ClassTemplateDecl>(*Found.first); + if (!Found.empty()) { + PrevClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front()); if (PrevClassTemplate) PrevDecl = PrevClassTemplate->getTemplatedDecl(); } @@ -911,11 +957,11 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( // of the class template and return that. DeclContext::lookup_result Found = Owner->lookup(ClassTemplate->getDeclName()); - if (Found.first == Found.second) + if (Found.empty()) return 0; ClassTemplateDecl *InstClassTemplate - = dyn_cast<ClassTemplateDecl>(*Found.first); + = dyn_cast<ClassTemplateDecl>(Found.front()); if (!InstClassTemplate) return 0; @@ -1043,8 +1089,8 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context, FunctionProtoType::ExtProtoInfo NewEPI = NewFunc->getExtProtoInfo(); NewEPI.ExtInfo = OrigFunc->getExtInfo(); return Context.getFunctionType(NewFunc->getResultType(), - NewFunc->arg_type_begin(), - NewFunc->getNumArgs(), + ArrayRef<QualType>(NewFunc->arg_type_begin(), + NewFunc->getNumArgs()), NewEPI); } @@ -1116,10 +1162,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, FunctionDecl *Function = FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, - D->getStorageClass(), D->getStorageClassAsWritten(), + D->getStorageClass(), D->isInlineSpecified(), D->hasWrittenPrototype(), D->isConstexpr()); + if (D->isInlined()) + Function->setImplicitlyInline(); + if (QualifierLoc) Function->setQualifierInfo(QualifierLoc); @@ -1287,7 +1336,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, // // 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().CPlusPlus0x || + if ((!SemaRef.getLangOpts().CPlusPlus11 || SemaRef.Diags.getDiagnosticLevel( diag::warn_cxx98_compat_friend_redefinition, Function->getLocation()) @@ -1298,11 +1347,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, if (Function->isDefined(Definition) && Definition->getTemplateSpecializationKind() == TSK_Undeclared) { SemaRef.Diag(Function->getLocation(), - SemaRef.getLangOpts().CPlusPlus0x ? + SemaRef.getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_friend_redefinition : diag::err_redefinition) << Function->getDeclName(); SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); - if (!SemaRef.getLangOpts().CPlusPlus0x) + if (!SemaRef.getLangOpts().CPlusPlus11) Function->setInvalidDecl(); } // Check for redefinitions due to other instantiations of this or @@ -1314,7 +1363,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, continue; switch (R->getFriendObjectKind()) { case Decl::FOK_None: - if (!SemaRef.getLangOpts().CPlusPlus0x && + if (!SemaRef.getLangOpts().CPlusPlus11 && !queuedInstantiation && R->isUsed(false)) { if (MemberSpecializationInfo *MSInfo = Function->getMemberSpecializationInfo()) { @@ -1333,12 +1382,12 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, = R->getTemplateInstantiationPattern()) if (RPattern->isDefined(RPattern)) { SemaRef.Diag(Function->getLocation(), - SemaRef.getLangOpts().CPlusPlus0x ? + SemaRef.getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_friend_redefinition : diag::err_redefinition) << Function->getDeclName(); SemaRef.Diag(R->getLocation(), diag::note_previous_definition); - if (!SemaRef.getLangOpts().CPlusPlus0x) + if (!SemaRef.getLangOpts().CPlusPlus11) Function->setInvalidDecl(); break; } @@ -1479,12 +1528,14 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } else { Method = CXXMethodDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - D->isStatic(), - D->getStorageClassAsWritten(), + D->getStorageClass(), D->isInlineSpecified(), D->isConstexpr(), D->getLocEnd()); } + if (D->isInlined()) + Method->setImplicitlyInline(); + if (QualifierLoc) Method->setQualifierInfo(QualifierLoc); @@ -1581,10 +1632,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, SemaRef.CheckOverrideControl(Method); // If a function is defined as defaulted or deleted, mark it as such now. - if (D->isDefaulted()) - Method->setDefaulted(); + if (D->isExplicitlyDefaulted()) + SemaRef.SetDeclDefaulted(Method, Method->getLocation()); if (D->isDeletedAsWritten()) - Method->setDeletedAsWritten(); + SemaRef.SetDeclDeleted(Method, Method->getLocation()); // If there's a function template, let our caller handle it. if (FunctionTemplate) { @@ -1610,13 +1661,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Owner->addDecl(Method); } - if (D->isExplicitlyDefaulted()) { - SemaRef.SetDeclDefaulted(Method, Method->getLocation()); - } else { - assert(!D->isDefaulted() && - "should not implicitly default uninstantiated function"); - } - return Method; } @@ -1633,9 +1677,8 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) { } ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { - return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0, - llvm::Optional<unsigned>(), - /*ExpectParameterPack=*/false); + return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0, None, + /*ExpectParameterPack=*/ false); } Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( @@ -1701,7 +1744,7 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( // The non-type template parameter pack's type is a pack expansion of types. // Determine whether we need to expand this parameter pack into separate // types. - PackExpansionTypeLoc Expansion = cast<PackExpansionTypeLoc>(TL); + PackExpansionTypeLoc Expansion = TL.castAs<PackExpansionTypeLoc>(); TypeLoc Pattern = Expansion.getPatternLoc(); SmallVector<UnexpandedParameterPack, 2> Unexpanded; SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); @@ -1710,9 +1753,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( // be expanded. bool Expand = true; bool RetainExpansion = false; - llvm::Optional<unsigned> OrigNumExpansions + Optional<unsigned> OrigNumExpansions = Expansion.getTypePtr()->getNumExpansions(); - llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; + Optional<unsigned> NumExpansions = OrigNumExpansions; if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(), Pattern.getSourceRange(), Unexpanded, @@ -1867,7 +1910,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( // be expanded. bool Expand = true; bool RetainExpansion = false; - llvm::Optional<unsigned> NumExpansions; + Optional<unsigned> NumExpansions; if (SemaRef.CheckParameterPacksForExpansion(D->getLocation(), TempParams->getSourceRange(), Unexpanded, @@ -2069,7 +2112,7 @@ Decl * TemplateDeclInstantiator SS.Adopt(QualifierLoc); // Since NameInfo refers to a typename, it cannot be a C++ special name. - // Hence, no tranformation is required for it. + // Hence, no transformation is required for it. DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation()); NamedDecl *UD = SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), @@ -2138,6 +2181,23 @@ Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( return NewFD; } +Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl( + OMPThreadPrivateDecl *D) { + SmallVector<DeclRefExpr *, 5> Vars; + for (ArrayRef<DeclRefExpr *>::iterator I = D->varlist_begin(), + E = D->varlist_end(); + I != E; ++I) { + Expr *Var = SemaRef.SubstExpr(*I, TemplateArgs).take(); + assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr"); + Vars.push_back(cast<DeclRefExpr>(Var)); + } + + OMPThreadPrivateDecl *TD = + SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars); + + return TD; +} + Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs) { TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); @@ -2330,18 +2390,17 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (NewTInfo != OldTInfo) { // Get parameters from the new type info. TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); - if (FunctionProtoTypeLoc *OldProtoLoc - = dyn_cast<FunctionProtoTypeLoc>(&OldTL)) { + if (FunctionProtoTypeLoc OldProtoLoc = + OldTL.getAs<FunctionProtoTypeLoc>()) { TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens(); - FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL); - assert(NewProtoLoc && "Missing prototype?"); + FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>(); unsigned NewIdx = 0; - for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc->getNumArgs(); + for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumArgs(); OldIdx != NumOldParams; ++OldIdx) { - ParmVarDecl *OldParam = OldProtoLoc->getArg(OldIdx); + ParmVarDecl *OldParam = OldProtoLoc.getArg(OldIdx); LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope; - llvm::Optional<unsigned> NumArgumentsInExpansion; + Optional<unsigned> NumArgumentsInExpansion; if (OldParam->isParameterPack()) NumArgumentsInExpansion = SemaRef.getNumArgumentsInExpansion(OldParam->getType(), @@ -2349,14 +2408,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.getArg(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.getArg(NewIdx++); Params.push_back(NewParam); Scope->InstantiatedLocalPackArg(OldParam, NewParam); } @@ -2368,10 +2427,10 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, // substitution occurred. However, we still need to instantiate // the function parameters themselves. TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); - if (FunctionProtoTypeLoc *OldProtoLoc - = dyn_cast<FunctionProtoTypeLoc>(&OldTL)) { - for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) { - ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i)); + if (FunctionProtoTypeLoc OldProtoLoc = + OldTL.getAs<FunctionProtoTypeLoc>()) { + for (unsigned i = 0, i_end = OldProtoLoc.getNumArgs(); i != i_end; ++i) { + ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc.getArg(i)); if (!Parm) return 0; Params.push_back(Parm); @@ -2403,7 +2462,7 @@ static void addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function, // Expand the parameter pack. Scope.MakeInstantiatedLocalArgPack(PatternParam); - llvm::Optional<unsigned> NumArgumentsInExpansion + Optional<unsigned> NumArgumentsInExpansion = S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs); assert(NumArgumentsInExpansion && "should only be called when all template arguments are known"); @@ -2434,7 +2493,7 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, ThisTypeQuals = Method->getTypeQualifiers(); } Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals, - SemaRef.getLangOpts().CPlusPlus0x); + SemaRef.getLangOpts().CPlusPlus11); // The function has an exception specification or a "noreturn" // attribute. Substitute into each of the exception types. @@ -2452,7 +2511,7 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, bool Expand = false; bool RetainExpansion = false; - llvm::Optional<unsigned> NumExpansions + Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(), SourceRange(), @@ -2541,8 +2600,8 @@ static void InstantiateExceptionSpec(Sema &SemaRef, FunctionDecl *New, EPI.NoexceptExpr = NoexceptExpr; New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), - NewProto->arg_type_begin(), - NewProto->getNumArgs(), + ArrayRef<QualType>(NewProto->arg_type_begin(), + NewProto->getNumArgs()), EPI)); } @@ -2560,8 +2619,8 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); EPI.ExceptionSpecType = EST_None; Decl->setType(Context.getFunctionType(Proto->getResultType(), - Proto->arg_type_begin(), - Proto->getNumArgs(), + ArrayRef<QualType>(Proto->arg_type_begin(), + Proto->getNumArgs()), EPI)); return; } @@ -2605,12 +2664,12 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution || ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) { if (FunctionTemplateDecl *FunTmpl - = dyn_cast<FunctionTemplateDecl>((Decl *)ActiveInst.Entity)) { + = dyn_cast<FunctionTemplateDecl>(ActiveInst.Entity)) { assert(FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?"); (void) FunTmpl; ActiveInst.Kind = ActiveInstType::TemplateInstantiation; - ActiveInst.Entity = reinterpret_cast<uintptr_t>(New); + ActiveInst.Entity = New; } } @@ -2622,7 +2681,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, // DR1330: In C++11, defer instantiation of a non-trivial // exception specification. - if (SemaRef.getLangOpts().CPlusPlus0x && + if (SemaRef.getLangOpts().CPlusPlus11 && EPI.ExceptionSpecType != EST_None && EPI.ExceptionSpecType != EST_DynamicNone && EPI.ExceptionSpecType != EST_BasicNoexcept) { @@ -2641,8 +2700,8 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EPI.ExceptionSpecDecl = New; EPI.ExceptionSpecTemplate = ExceptionSpecTemplate; New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), - NewProto->arg_type_begin(), - NewProto->getNumArgs(), + ArrayRef<QualType>(NewProto->arg_type_begin(), + NewProto->getNumArgs()), EPI)); } else { ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs); @@ -2770,6 +2829,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, !PatternDecl->isInlined()) return; + if (PatternDecl->isInlined()) + Function->setImplicitlyInline(); + InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); if (Inst) return; @@ -2789,7 +2851,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, EnterExpressionEvaluationContext EvalContext(*this, Sema::PotentiallyEvaluated); - ActOnStartOfFunctionDef(0, Function); // Introduce a new scope where local variable instantiations will be // recorded, unless we're actually a member function within a local @@ -2801,21 +2862,21 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, LocalInstantiationScope Scope(*this, MergeWithParentScope); - // Enter the scope of this instantiation. We don't use - // PushDeclContext because we don't have a scope. - Sema::ContextRAII savedContext(*this, Function); + if (PatternDecl->isDefaulted()) + SetDeclDefaulted(Function, PatternDecl->getLocation()); + else { + ActOnStartOfFunctionDef(0, Function); - MultiLevelTemplateArgumentList TemplateArgs = - getTemplateInstantiationArgs(Function, 0, false, PatternDecl); + // Enter the scope of this instantiation. We don't use + // PushDeclContext because we don't have a scope. + Sema::ContextRAII savedContext(*this, Function); - addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, - TemplateArgs); + MultiLevelTemplateArgumentList TemplateArgs = + getTemplateInstantiationArgs(Function, 0, false, PatternDecl); - if (PatternDecl->isDefaulted()) { - ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true); + addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope, + TemplateArgs); - SetDeclDefaulted(Function, PatternDecl->getLocation()); - } else { // If this is a constructor, instantiate the member initializers. if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(PatternDecl)) { @@ -2831,11 +2892,11 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true); - } - PerformDependentDiagnostics(PatternDecl, TemplateArgs); + PerformDependentDiagnostics(PatternDecl, TemplateArgs); - savedContext.pop(); + savedContext.pop(); + } DeclGroupRef DG(Function); Consumer.HandleTopLevelDecl(DG); @@ -2928,7 +2989,18 @@ void Sema::InstantiateStaticDataMemberDefinition( if (TSK == TSK_ExplicitInstantiationDeclaration) return; - Consumer.HandleCXXStaticMemberVarInstantiation(Var); + // Make sure to pass the instantiated variable to the consumer at the end. + struct PassToConsumerRAII { + ASTConsumer &Consumer; + VarDecl *Var; + + PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var) + : Consumer(Consumer), Var(Var) { } + + ~PassToConsumerRAII() { + Consumer.HandleCXXStaticMemberVarInstantiation(Var); + } + } PassToConsumerRAII(Consumer, Var); // If we already have a definition, we're done. if (VarDecl *Def = Var->getDefinition()) { @@ -2965,12 +3037,11 @@ void Sema::InstantiateStaticDataMemberDefinition( previousContext.pop(); if (Var) { + PassToConsumerRAII.Var = Var; MemberSpecializationInfo *MSInfo = OldVar->getMemberSpecializationInfo(); assert(MSInfo && "Missing member specialization information?"); Var->setTemplateSpecializationKind(MSInfo->getTemplateSpecializationKind(), MSInfo->getPointOfInstantiation()); - DeclGroupRef DG(Var); - Consumer.HandleTopLevelDecl(DG); } Local.Exit(); @@ -3024,7 +3095,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, collectUnexpandedParameterPacks(BaseTL, Unexpanded); bool ShouldExpand = false; bool RetainExpansion = false; - llvm::Optional<unsigned> NumExpansions; + Optional<unsigned> NumExpansions; if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(), BaseTL.getSourceRange(), Unexpanded, @@ -3142,49 +3213,10 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New, ActOnMemInitializers(New, /*FIXME: ColonLoc */ SourceLocation(), - NewInits.data(), NewInits.size(), + NewInits, AnyErrors); } -ExprResult Sema::SubstInitializer(Expr *Init, - const MultiLevelTemplateArgumentList &TemplateArgs, - bool CXXDirectInit) { - // Initializers are instantiated like expressions, except that various outer - // layers are stripped. - if (!Init) - return Owned(Init); - - if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) - Init = ExprTemp->getSubExpr(); - - while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) - Init = Binder->getSubExpr(); - - if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) - Init = ICE->getSubExprAsWritten(); - - // If this is a direct-initializer, we take apart CXXConstructExprs. - // Everything else is passed through. - CXXConstructExpr *Construct; - if (!CXXDirectInit || !(Construct = dyn_cast<CXXConstructExpr>(Init)) || - isa<CXXTemporaryObjectExpr>(Construct)) - return SubstExpr(Init, TemplateArgs); - - SmallVector<Expr*, 8> NewArgs; - if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, - TemplateArgs, NewArgs)) - return ExprError(); - - // Treat an empty initializer like none. - if (NewArgs.empty()) - return Owned((Expr*)0); - - // Build a ParenListExpr to represent anything else. - // FIXME: Fake locations! - SourceLocation Loc = PP.getLocForEndOfToken(Init->getLocStart()); - return ActOnParenListExpr(Loc, Loc, NewArgs); -} - // TODO: this could be templated if the various decl types used the // same method name. static bool isInstantiationOf(ClassTemplateDecl *Pattern, @@ -3539,7 +3571,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, NamedDecl *Result = 0; if (D->getDeclName()) { DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); - Result = findInstantiationOf(Context, D, Found.first, Found.second); + Result = findInstantiationOf(Context, D, Found.begin(), Found.end()); } else { // Since we don't have a name for the entity we're looking for, // our only option is to walk through all of the declarations to |