summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp79
1 files changed, 47 insertions, 32 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2c29b8cbcc..09aa25ca0a 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2733,10 +2733,19 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
OMPDeclareReductionDecl *D) {
// Instantiate type and check if it is allowed.
- QualType SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType(
- D->getLocation(),
- ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
- D->getLocation(), DeclarationName())));
+ const bool RequiresInstantiation =
+ D->getType()->isDependentType() ||
+ D->getType()->isInstantiationDependentType() ||
+ D->getType()->containsUnexpandedParameterPack();
+ QualType SubstReductionType;
+ if (RequiresInstantiation) {
+ SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType(
+ D->getLocation(),
+ ParsedType::make(SemaRef.SubstType(
+ D->getType(), TemplateArgs, D->getLocation(), DeclarationName())));
+ } else {
+ SubstReductionType = D->getType();
+ }
if (SubstReductionType.isNull())
return nullptr;
bool IsCorrect = !SubstReductionType.isNull();
@@ -2753,25 +2762,35 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
/*S=*/nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(),
PrevDeclInScope);
auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
- if (isDeclWithinFunction(NewDRD))
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
+ if (!RequiresInstantiation) {
+ if (Expr *Combiner = D->getCombiner()) {
+ NewDRD->setCombinerData(D->getCombinerIn(), D->getCombinerOut());
+ NewDRD->setCombiner(Combiner);
+ if (Expr *Init = D->getInitializer()) {
+ NewDRD->setInitializerData(D->getInitOrig(), D->getInitPriv());
+ NewDRD->setInitializer(Init, D->getInitializerKind());
+ }
+ }
+ (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
+ /*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
+ return NewDRD;
+ }
Expr *SubstCombiner = nullptr;
Expr *SubstInitializer = nullptr;
// Combiners instantiation sequence.
if (D->getCombiner()) {
SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
/*S=*/nullptr, NewDRD);
- const char *Names[] = {"omp_in", "omp_out"};
- for (auto &Name : Names) {
- DeclarationName DN(&SemaRef.Context.Idents.get(Name));
- auto OldLookup = D->lookup(DN);
- auto Lookup = NewDRD->lookup(DN);
- if (!OldLookup.empty() && !Lookup.empty()) {
- assert(Lookup.size() == 1 && OldLookup.size() == 1);
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldLookup.front(),
- Lookup.front());
- }
- }
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
+ Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, /*TypeQuals*/ 0,
+ ThisContext);
SubstCombiner = SemaRef.SubstExpr(D->getCombiner(), TemplateArgs).get();
SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
// Initializers instantiation sequence.
@@ -2779,19 +2798,12 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
VarDecl *OmpPrivParm =
SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
/*S=*/nullptr, NewDRD);
- const char *Names[] = {"omp_orig", "omp_priv"};
- for (auto &Name : Names) {
- DeclarationName DN(&SemaRef.Context.Idents.get(Name));
- auto OldLookup = D->lookup(DN);
- auto Lookup = NewDRD->lookup(DN);
- if (!OldLookup.empty() && !Lookup.empty()) {
- assert(Lookup.size() == 1 && OldLookup.size() == 1);
- auto *OldVD = cast<VarDecl>(OldLookup.front());
- auto *NewVD = cast<VarDecl>(Lookup.front());
- SemaRef.InstantiateVariableInitializer(NewVD, OldVD, TemplateArgs);
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldVD, NewVD);
- }
- }
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getInitPriv())->getDecl(),
+ cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl());
if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) {
SubstInitializer =
SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get();
@@ -2808,8 +2820,9 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
SubstInitializer) ||
(D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
!SubstInitializer && !SubstInitializer));
- } else
+ } else {
IsCorrect = false;
+ }
(void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(/*S=*/nullptr, DRD,
IsCorrect);
@@ -4897,7 +4910,9 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
return D;
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
- (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext()) ||
+ ((ParentDC->isFunctionOrMethod() ||
+ isa<OMPDeclareReductionDecl>(ParentDC)) &&
+ ParentDC->isDependentContext()) ||
(isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
// D is a local of some kind. Look into the map of local
// declarations to their instantiations.