diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 173 |
1 files changed, 86 insertions, 87 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index be4c51930789..27ac2cd08f2a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -436,11 +436,12 @@ static void instantiateOMPDeclareVariantAttr( return; Expr *E = VariantFuncRef.get(); + // Check function/variant ref for `omp declare variant` but not for `omp // begin declare variant` (which use implicit attributes). Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData = - S.checkOpenMPDeclareVariantFunction(S.ConvertDeclToDeclGroup(New), - VariantFuncRef.get(), TI, + S.checkOpenMPDeclareVariantFunction(S.ConvertDeclToDeclGroup(New), E, TI, + Attr.appendArgs_size(), Attr.getRange()); if (!DeclVarData) @@ -481,7 +482,28 @@ static void instantiateOMPDeclareVariantAttr( } } - S.ActOnOpenMPDeclareVariantDirective(FD, E, TI, Attr.getRange()); + SmallVector<Expr *, 8> NothingExprs; + SmallVector<Expr *, 8> NeedDevicePtrExprs; + SmallVector<OMPDeclareVariantAttr::InteropType, 8> AppendArgs; + + for (Expr *E : Attr.adjustArgsNothing()) { + ExprResult ER = Subst(E); + if (ER.isInvalid()) + continue; + NothingExprs.push_back(ER.get()); + } + for (Expr *E : Attr.adjustArgsNeedDevicePtr()) { + ExprResult ER = Subst(E); + if (ER.isInvalid()) + continue; + NeedDevicePtrExprs.push_back(ER.get()); + } + for (auto A : Attr.appendArgs()) + AppendArgs.push_back(A); + + S.ActOnOpenMPDeclareVariantDirective( + FD, E, TI, NothingExprs, NeedDevicePtrExprs, AppendArgs, SourceLocation(), + SourceLocation(), Attr.getRange()); } static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr( @@ -556,30 +578,10 @@ static void instantiateDependentAMDGPUWavesPerEUAttr( static void instantiateDependentSYCLKernelAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const SYCLKernelAttr &Attr, Decl *New) { - // Functions cannot be partially specialized, so if we are being instantiated, - // we are obviously a complete specialization. Since this attribute is only - // valid on function template declarations, we know that this is a full - // instantiation of a kernel. - S.AddSYCLKernelLambda(cast<FunctionDecl>(New)); - - // Evaluate whether this would change any of the already evaluated - // __builtin_sycl_unique_stable_name values. - for (auto &Itr : S.Context.SYCLUniqueStableNameEvaluatedValues) { - const std::string &CurName = Itr.first->ComputeName(S.Context); - if (Itr.second != CurName) { - S.Diag(New->getLocation(), - diag::err_kernel_invalidates_sycl_unique_stable_name); - S.Diag(Itr.first->getLocation(), - diag::note_sycl_unique_stable_name_evaluated_here); - // Update this so future diagnostics work correctly. - Itr.second = CurName; - } - } - New->addAttr(Attr.clone(S.getASTContext())); } -/// Determine whether the attribute A might be relevent to the declaration D. +/// Determine whether the attribute A might be relevant to the declaration D. /// If not, we can skip instantiating it. The attribute may or may not have /// been instantiated yet. static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A) { @@ -1087,7 +1089,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner, StartingScope, InstantiatingVarTemplate); - if (D->isNRVOVariable()) { + if (D->isNRVOVariable() && !Var->isInvalidDecl()) { QualType RT; if (auto *F = dyn_cast<FunctionDecl>(DC)) RT = F->getReturnType(); @@ -1816,9 +1818,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { CXXRecordDecl *PrevDecl = nullptr; - if (D->isInjectedClassName()) - PrevDecl = cast<CXXRecordDecl>(Owner); - else if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) { + if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) { NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), PatternPrev, TemplateArgs); @@ -1827,6 +1827,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { } CXXRecordDecl *Record = nullptr; + bool IsInjectedClassName = D->isInjectedClassName(); if (D->isLambda()) Record = CXXRecordDecl::CreateLambda( SemaRef.Context, Owner, D->getLambdaTypeInfo(), D->getLocation(), @@ -1835,7 +1836,11 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { else Record = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(), D->getLocation(), - D->getIdentifier(), PrevDecl); + D->getIdentifier(), PrevDecl, + /*DelayTypeCreation=*/IsInjectedClassName); + // Link the type of the injected-class-name to that of the outer class. + if (IsInjectedClassName) + (void)SemaRef.Context.getTypeDeclType(Record, cast<CXXRecordDecl>(Owner)); // Substitute the nested name specifier, if any. if (SubstQualifier(D, Record)) @@ -1850,7 +1855,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { // specifier. Remove once this area of the code gets sorted out. if (D->getAccess() != AS_none) Record->setAccess(D->getAccess()); - if (!D->isInjectedClassName()) + if (!IsInjectedClassName) Record->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation); // If the original function was part of a friend declaration, @@ -1903,6 +1908,9 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { SemaRef.DiagnoseUnusedNestedTypedefs(Record); + if (IsInjectedClassName) + assert(Record->isInjectedClassName() && "Broken injected-class-name"); + return Record; } @@ -2051,8 +2059,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( } else { Function = FunctionDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo, - D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), - D->hasWrittenPrototype(), D->getConstexprKind(), + D->getCanonicalDecl()->getStorageClass(), D->UsesFPIntrin(), + D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(), TrailingRequiresClause); Function->setRangeEnd(D->getSourceRange().getEnd()); } @@ -2149,8 +2157,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( // Instantiate the explicit template arguments. TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), Info->getRAngleLoc()); - if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), - ExplicitArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, + ExplicitArgs)) return nullptr; // Map the candidate templates to their instantiations. @@ -2177,8 +2185,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( // Instantiate the explicit template arguments. TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), Info->getRAngleLoc()); - if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), - ExplicitArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, + ExplicitArgs)) return nullptr; if (SemaRef.CheckFunctionTemplateSpecialization(Function, @@ -2407,15 +2415,16 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { Method = CXXConstructorDecl::Create( SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - InstantiatedExplicitSpecifier, Constructor->isInlineSpecified(), false, + InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(), + Constructor->isInlineSpecified(), false, Constructor->getConstexprKind(), InheritedConstructor(), TrailingRequiresClause); Method->setRangeEnd(Constructor->getEndLoc()); } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { Method = CXXDestructorDecl::Create( SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - Destructor->isInlineSpecified(), false, Destructor->getConstexprKind(), - TrailingRequiresClause); + Destructor->UsesFPIntrin(), Destructor->isInlineSpecified(), false, + Destructor->getConstexprKind(), TrailingRequiresClause); Method->setRangeEnd(Destructor->getEndLoc()); Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName( SemaRef.Context.getCanonicalType( @@ -2423,15 +2432,15 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) { Method = CXXConversionDecl::Create( SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, - Conversion->isInlineSpecified(), InstantiatedExplicitSpecifier, - Conversion->getConstexprKind(), Conversion->getEndLoc(), - TrailingRequiresClause); + Conversion->UsesFPIntrin(), Conversion->isInlineSpecified(), + InstantiatedExplicitSpecifier, Conversion->getConstexprKind(), + Conversion->getEndLoc(), TrailingRequiresClause); } else { StorageClass SC = D->isStatic() ? SC_Static : SC_None; - Method = CXXMethodDecl::Create(SemaRef.Context, Record, StartLoc, NameInfo, - T, TInfo, SC, D->isInlineSpecified(), - D->getConstexprKind(), D->getEndLoc(), - TrailingRequiresClause); + Method = CXXMethodDecl::Create( + SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC, + D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(), + D->getEndLoc(), TrailingRequiresClause); } if (D->isInlined()) @@ -2512,8 +2521,8 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( // Instantiate the explicit template arguments. TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), Info->getRAngleLoc()); - if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), - ExplicitArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, + ExplicitArgs)) return nullptr; // Map the candidate templates to their instantiations. @@ -2539,8 +2548,8 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), Info->getRAngleLoc()); - if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), - ExplicitArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs, + ExplicitArgs)) return nullptr; if (SemaRef.CheckFunctionTemplateSpecialization(Method, @@ -2708,25 +2717,7 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( // TODO: Concepts: do not instantiate the constraint (delayed constraint // substitution) - const ASTTemplateArgumentListInfo *TemplArgInfo - = TC->getTemplateArgsAsWritten(); - TemplateArgumentListInfo InstArgs; - - if (TemplArgInfo) { - InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc); - InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc); - if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(), - TemplArgInfo->NumTemplateArgs, - InstArgs, TemplateArgs)) - return nullptr; - } - if (SemaRef.AttachTypeConstraint( - TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(), - TC->getNamedConcept(), &InstArgs, Inst, - D->isParameterPack() - ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint()) - ->getEllipsisLoc() - : SourceLocation())) + if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs)) return nullptr; } } @@ -3380,12 +3371,23 @@ Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) { SmallVector<OMPClause *, 4> Clauses; // Copy map clauses from the original mapper. for (OMPClause *C : D->clauselists()) { - auto *AC = cast<OMPAllocatorClause>(C); - ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs); - if (!NewE.isUsable()) - continue; - OMPClause *IC = SemaRef.ActOnOpenMPAllocatorClause( - NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc()); + OMPClause *IC = nullptr; + if (auto *AC = dyn_cast<OMPAllocatorClause>(C)) { + ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs); + if (!NewE.isUsable()) + continue; + IC = SemaRef.ActOnOpenMPAllocatorClause( + NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc()); + } else if (auto *AC = dyn_cast<OMPAlignClause>(C)) { + ExprResult NewE = SemaRef.SubstExpr(AC->getAlignment(), TemplateArgs); + if (!NewE.isUsable()) + continue; + IC = SemaRef.ActOnOpenMPAlignClause(NewE.get(), AC->getBeginLoc(), + AC->getLParenLoc(), AC->getEndLoc()); + // If align clause value ends up being invalid, this can end up null. + if (!IC) + continue; + } Clauses.push_back(IC); } @@ -3624,8 +3626,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( SmallVector<TemplateArgumentLoc, 4> ArgLocs; for (unsigned I = 0; I != Loc.getNumArgs(); ++I) ArgLocs.push_back(Loc.getArgLoc(I)); - if (SemaRef.Subst(ArgLocs.data(), ArgLocs.size(), - InstTemplateArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(ArgLocs, TemplateArgs, InstTemplateArgs)) return nullptr; // Check that the template argument list is well-formed for this @@ -3750,8 +3751,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo.getLAngleLoc()); VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo.getRAngleLoc()); - if (SemaRef.Subst(TemplateArgsInfo.getArgumentArray(), - TemplateArgsInfo.size(), VarTemplateArgsInfo, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(TemplateArgsInfo.arguments(), TemplateArgs, + VarTemplateArgsInfo)) return nullptr; // Check that the template argument list is well-formed for this template. @@ -4018,9 +4019,8 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( = PartialSpec->getTemplateArgsAsWritten(); TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc, TemplArgInfo->RAngleLoc); - if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(), - TemplArgInfo->NumTemplateArgs, - InstTemplateArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs, + InstTemplateArgs)) return nullptr; // Check that the template argument list is well-formed for this @@ -4146,9 +4146,8 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( = PartialSpec->getTemplateArgsAsWritten(); TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc, TemplArgInfo->RAngleLoc); - if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(), - TemplArgInfo->NumTemplateArgs, - InstTemplateArgs, TemplateArgs)) + if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs, + InstTemplateArgs)) return nullptr; // Check that the template argument list is well-formed for this @@ -5985,11 +5984,11 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext) { DeclContext *ParentDC = D->getDeclContext(); - // Determine whether our parent context depends on any of the tempalte + // Determine whether our parent context depends on any of the template // arguments we're currently substituting. bool ParentDependsOnArgs = isDependentContextAtLevel( ParentDC, TemplateArgs.getNumRetainedOuterLevels()); - // FIXME: Parmeters of pointer to functions (y below) that are themselves + // FIXME: Parameters 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 // is Dependent or/and a FunctionOrMethod. |
