summaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp173
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.