diff options
| author | 2019-01-27 16:42:12 +0000 | |
|---|---|---|
| committer | 2019-01-27 16:42:12 +0000 | |
| commit | b773203fb58f3ef282fb69c832d8710cab5bc82d (patch) | |
| tree | e75913f147570fbd75169647b144df85b88a038c /gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
| parent | tweak errno in previous (diff) | |
| download | wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.tar.xz wireguard-openbsd-b773203fb58f3ef282fb69c832d8710cab5bc82d.zip | |
Import LLVM 7.0.1 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 202 |
1 files changed, 102 insertions, 100 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 9163fbc6f7e..512b00b1008 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -18,11 +18,12 @@ #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/PrettyDeclStackTrace.h" #include "clang/AST/TypeLoc.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" -#include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" +#include "clang/Sema/TemplateInstCallback.h" using namespace clang; @@ -175,7 +176,8 @@ static void instantiateDependentAllocAlignAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AllocAlignAttr *Align, Decl *New) { Expr *Param = IntegerLiteral::Create( - S.getASTContext(), llvm::APInt(64, Align->getParamIndex()), + S.getASTContext(), + llvm::APInt(64, Align->getParamIndex().getSourceIndex()), S.getASTContext().UnsignedLongLongTy, Align->getLocation()); S.AddAllocAlignAttr(Align->getLocation(), New, Param, Align->getSpellingListIndex()); @@ -343,14 +345,6 @@ static void instantiateOMPDeclareSimdDeclAttr( Attr.getRange()); } -static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) { - if (!D->hasAttrs() || NewAttr->duplicatesAllowed()) - return false; - return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) { - return Attr->getKind() == NewAttr->getKind(); - }) != D->getAttrs().end(); -} - void Sema::InstantiateAttrsForDecl( const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl, Decl *New, LateInstantiatedAttrVec *LateAttrs, @@ -365,7 +359,7 @@ void Sema::InstantiateAttrsForDecl( Attr *NewAttr = sema::instantiateTemplateAttributeForDecl( TmplAttr, Context, *this, TemplateArgs); - if (NewAttr && !DeclContainsAttr(New, NewAttr)) + if (NewAttr) New->addAttr(NewAttr); } } @@ -470,8 +464,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context, *this, TemplateArgs); - - if (NewAttr && !DeclContainsAttr(New, NewAttr)) + if (NewAttr) New->addAttr(NewAttr); } } @@ -736,7 +729,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, DI, D->getStorageClass()); // In ARC, infer 'retaining' for variables of retainable type. - if (SemaRef.getLangOpts().ObjCAutoRefCount && + if (SemaRef.getLangOpts().ObjCAutoRefCount && SemaRef.inferObjCARCLifetime(Var)) Var->setInvalidDecl(); @@ -749,7 +742,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, if (D->isNRVOVariable()) { QualType ReturnType = cast<FunctionDecl>(DC)->getReturnType(); - if (SemaRef.isCopyElisionCandidate(ReturnType, Var, false)) + if (SemaRef.isCopyElisionCandidate(ReturnType, Var, Sema::CES_Strict)) Var->setNRVOVariable(true); } @@ -1049,8 +1042,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { SemaRef.SubstType(TI->getType(), TemplateArgs, UnderlyingLoc, DeclarationName()); SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(), - DefnUnderlying, - /*EnumUnderlyingIsImplicit=*/false, Enum); + DefnUnderlying, /*IsFixed=*/true, Enum); } } @@ -1126,8 +1118,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition( } SemaRef.ActOnEnumBody(Enum->getLocation(), Enum->getBraceRange(), Enum, - Enumerators, - nullptr, nullptr); + Enumerators, nullptr, ParsedAttributesView()); } Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { @@ -1564,7 +1555,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { return Record; } -/// \brief Adjust the given function type for an instantiation of the +/// Adjust the given function type for an instantiation of the /// given declaration, to cope with modifications to the function's type that /// aren't reflected in the type-source information. /// @@ -1661,6 +1652,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, NameInfo, T, TInfo, D->getSourceRange().getEnd()); if (DGuide->isCopyDeductionCandidate()) cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate(); + Function->setAccess(D->getAccess()); } else { Function = FunctionDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, @@ -1815,45 +1807,24 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, // 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 = nullptr; - if (Function->isDefined(Definition) && - Definition->getTemplateSpecializationKind() == TSK_Undeclared) { - SemaRef.Diag(Function->getLocation(), diag::err_redefinition) - << Function->getDeclName(); - SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); - } - // Check for redefinitions due to other instantiations of this or - // a similar friend function. - else for (auto R : Function->redecls()) { - if (R == Function) - continue; - - // 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; - } - } - } - - // 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(), diag::err_redefinition) - << Function->getDeclName(); - SemaRef.Diag(R->getLocation(), diag::note_previous_definition); - break; + SemaRef.CheckForFunctionRedefinition(Function); + if (!Function->isInvalidDecl()) { + for (auto R : Function->redecls()) { + if (R == Function) + continue; + + // 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; + } } } } @@ -2085,7 +2056,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // previous declaration we just found. if (isFriend && Method->getPreviousDecl()) Method->setAccess(Method->getPreviousDecl()->getAccess()); - else + else Method->setAccess(D->getAccess()); if (FunctionTemplate) FunctionTemplate->setAccess(Method->getAccess()); @@ -2676,7 +2647,8 @@ Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl( NamedDecl *UD = SemaRef.BuildUsingDeclaration( /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(), - /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, nullptr, + /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, + ParsedAttributesView(), /*IsInstantiation*/ true); if (UD) SemaRef.Context.setInstantiatedFromUsingDecl(UD, D); @@ -2697,9 +2669,9 @@ Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl( Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) { SmallVector<NamedDecl*, 8> Expansions; for (auto *UD : D->expansions()) { - if (auto *NewUD = + if (NamedDecl *NewUD = SemaRef.FindInstantiatedDecl(D->getLocation(), UD, TemplateArgs)) - Expansions.push_back(cast<NamedDecl>(NewUD)); + Expansions.push_back(NewUD); else return nullptr; } @@ -2740,6 +2712,8 @@ Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( assert(Specialization && "Class scope Specialization is null"); SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD); + // FIXME: If this is a definition, check for redefinition errors! + return NewFD; } @@ -2859,7 +2833,10 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { Decl * TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { - return VisitFunctionDecl(D, nullptr); + Decl *Inst = VisitFunctionDecl(D, nullptr); + if (Inst && !D->getDescribedFunctionTemplate()) + Owner->addDecl(Inst); + return Inst; } Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { @@ -3112,7 +3089,7 @@ Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, return Instantiator.Visit(D); } -/// \brief Instantiates a nested template parameter list in the current +/// Instantiates a nested template parameter list in the current /// instantiation context. /// /// \param L The parameter list to instantiate @@ -3148,7 +3125,14 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { return InstL; } -/// \brief Instantiate the declaration of a class template partial +TemplateParameterList * +Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, + const MultiLevelTemplateArgumentList &TemplateArgs) { + TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); + return Instantiator.SubstTemplateParams(Params); +} + +/// Instantiate the declaration of a class template partial /// specialization. /// /// \param ClassTemplate the (instantiated) class template that is partially @@ -3282,7 +3266,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( return InstPartialSpec; } -/// \brief Instantiate the declaration of a variable template partial +/// Instantiate the declaration of a variable template partial /// specialization. /// /// \param VarTemplate the (instantiated) variable template that is partially @@ -3433,7 +3417,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, ThisContext = cast<CXXRecordDecl>(Owner); ThisTypeQuals = Method->getTypeQualifiers(); } - + TypeSourceInfo *NewTInfo = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), @@ -3624,7 +3608,7 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation, TemplateArgs); } -/// \brief Initializes the common fields of an instantiation function +/// Initializes the common fields of an instantiation function /// declaration (New) from the corresponding fields of its template (Tmpl). /// /// \returns true if there was an error @@ -3657,8 +3641,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, assert(FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?"); (void) FunTmpl; + atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); ActiveInst.Kind = ActiveInstType::TemplateInstantiation; ActiveInst.Entity = New; + atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); } } @@ -3710,7 +3696,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, return false; } -/// \brief Initializes common fields of an instantiated method +/// Initializes common fields of an instantiated method /// declaration (New) from the corresponding fields of its template /// (Tmpl). /// @@ -3774,7 +3760,7 @@ static void InstantiateDefaultCtorDefaultArgs(Sema &S, } } -/// \brief Instantiate the definition of the given function from its +/// Instantiate the definition of the given function from its /// template. /// /// \param PointOfInstantiation the point at which the instantiation was @@ -3854,8 +3840,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (PatternDecl->isLateTemplateParsed() && !LateTemplateParser) { Function->setInstantiationIsPending(true); - PendingInstantiations.push_back( - std::make_pair(Function, PointOfInstantiation)); + LateParsedInstantiations.push_back( + std::make_pair(Function, PointOfInstantiation)); return; } @@ -3912,7 +3898,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Function, SourceLocation(), "instantiating function definition"); // The instantiation is visible here, even if it was first declared in an @@ -3957,8 +3943,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, TemplateArgs)) return; + StmtResult Body; if (PatternDecl->hasSkippedBody()) { ActOnSkippedFunctionBody(Function); + Body = nullptr; } else { if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) { // If this is a constructor, instantiate the member initializers. @@ -3974,16 +3962,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } // Instantiate the function body. - StmtResult Body = SubstStmt(Pattern, TemplateArgs); + Body = SubstStmt(Pattern, TemplateArgs); if (Body.isInvalid()) Function->setInvalidDecl(); - - // FIXME: finishing the function body while in an expression evaluation - // context seems wrong. Investigate more. - ActOnFinishFunctionBody(Function, Body.get(), - /*IsInstantiation=*/true); } + // FIXME: finishing the function body while in an expression evaluation + // context seems wrong. Investigate more. + ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true); PerformDependentDiagnostics(PatternDecl, TemplateArgs); @@ -4050,7 +4036,7 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( VarTemplate, FromVar, InsertPos, TemplateArgsInfo, Converted)); } -/// \brief Instantiates a variable template specialization by completing it +/// Instantiates a variable template specialization by completing it /// with appropriate type information and initializer. VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, @@ -4100,6 +4086,7 @@ void Sema::BuildVariableInstantiation( NewVar->setTSCSpec(OldVar->getTSCSpec()); NewVar->setInitStyle(OldVar->getInitStyle()); NewVar->setCXXForRangeDecl(OldVar->isCXXForRangeDecl()); + NewVar->setObjCForDecl(OldVar->isObjCForDecl()); NewVar->setConstexpr(OldVar->isConstexpr()); NewVar->setInitCapture(OldVar->isInitCapture()); NewVar->setPreviousDeclInSameBlockScope( @@ -4173,7 +4160,7 @@ void Sema::BuildVariableInstantiation( DiagnoseUnusedDecl(NewVar); } -/// \brief Instantiate the initializer of a variable. +/// Instantiate the initializer of a variable. void Sema::InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs) { @@ -4219,7 +4206,9 @@ void Sema::InstantiateVariableInitializer( Var->setInvalidDecl(); } } else { - if (Var->isStaticDataMember()) { + // `inline` variables are a definition and declaration all in one; we won't + // pick up an initializer from anywhere else. + if (Var->isStaticDataMember() && !Var->isInline()) { if (!Var->isOutOfLine()) return; @@ -4230,14 +4219,17 @@ void Sema::InstantiateVariableInitializer( } // We'll add an initializer to a for-range declaration later. - if (Var->isCXXForRangeDecl()) + if (Var->isCXXForRangeDecl() || Var->isObjCForDecl()) return; ActOnUninitializedDecl(Var); } + + if (getLangOpts().CUDA) + checkAllowedCUDAInitializer(Var); } -/// \brief Instantiate the definition of the given variable from its +/// Instantiate the definition of the given variable from its /// template. /// /// \param PointOfInstantiation the point at which the instantiation was @@ -4321,7 +4313,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable initializer"); // The instantiation is visible here, even if it was first declared in an @@ -4434,7 +4426,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) return; - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable definition"); // If we're performing recursive template instantiation, create our own @@ -4856,7 +4848,7 @@ static NamedDecl *findInstantiationOf(ASTContext &Ctx, return nullptr; } -/// \brief Finds the instantiation of the given declaration context +/// Finds the instantiation of the given declaration context /// within the current instantiation. /// /// \returns NULL if there was an error @@ -4868,7 +4860,7 @@ DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC, } else return DC; } -/// \brief Find the instantiation of the given declaration within the +/// Find the instantiation of the given declaration within the /// current instantiation. /// /// This routine is intended to be used when \p D is a declaration @@ -4898,14 +4890,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext) { DeclContext *ParentDC = D->getDeclContext(); - // FIXME: Parmeters of pointer to functions (y below) that are themselves + // FIXME: Parmeters of pointer to functions (y below) that are themselves // parameters (p below) can have their ParentDC set to the translation-unit - // - thus we can not consistently check if the ParentDC of such a parameter + // - thus we can not consistently check if the ParentDC of such a parameter // is Dependent or/and a FunctionOrMethod. - // For e.g. this code, during Template argument deduction tries to + // For e.g. this code, during Template argument deduction tries to // 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())) {} + // the translation unit. + // e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {} // float baz(float(*)()) { return 0.0; } // Foo(baz); // The better fix here is perhaps to ensure that a ParmVarDecl, by the time @@ -5181,7 +5173,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, return D; } -/// \brief Performs template instantiation for all implicit template +/// Performs template instantiation for all implicit template /// instantiations we have seen until this point. void Sema::PerformPendingInstantiations(bool LocalOnly) { while (!PendingLocalImplicitInstantiations.empty() || @@ -5200,10 +5192,20 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) { bool DefinitionRequired = Function->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; - InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true, - DefinitionRequired, true); - if (Function->isDefined()) - Function->setInstantiationIsPending(false); + if (Function->isMultiVersion()) { + getASTContext().forEachMultiversionedFunctionVersion( + Function, [this, Inst, DefinitionRequired](FunctionDecl *CurFD) { + InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, CurFD, true, + DefinitionRequired, true); + if (CurFD->isDefined()) + CurFD->setInstantiationIsPending(false); + }); + } else { + InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, Function, true, + DefinitionRequired, true); + if (Function->isDefined()) + Function->setInstantiationIsPending(false); + } continue; } @@ -5238,7 +5240,7 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) { break; } - PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(), + PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(), "instantiating variable definition"); bool DefinitionRequired = Var->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; |
