[OpenMP] Parse+Sema for '#pragma omp declare target' syntax version 4.5
Support OpenMP version 4.5 syntax for #pragma omp declare target.
Syntax:
#pragma omp declare target (extended-list) new-line
or
#pragma omp declare target clause[ [,] clause ... ] new-line
Where clause is one of the following:
to(extended-list)
link(list)
Differential Revision: http://reviews.llvm.org/D20011
llvm-svn: 268925
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index cbcf70b..ea26f6a 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1101,6 +1101,23 @@
return false;
}
};
+
+class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
+private:
+ Sema &SemaRef;
+
+public:
+ explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
+ bool ValidateCandidate(const TypoCorrection &Candidate) override {
+ NamedDecl *ND = Candidate.getCorrectionDecl();
+ if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
+ return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
+ SemaRef.getCurScope());
+ }
+ return false;
+ }
+};
+
} // namespace
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
@@ -10752,6 +10769,52 @@
IsInOpenMPDeclareTargetContext = false;
}
+void
+Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
+ const DeclarationNameInfo &Id,
+ OMPDeclareTargetDeclAttr::MapTypeTy MT,
+ NamedDeclSetType &SameDirectiveDecls) {
+ LookupResult Lookup(*this, Id, LookupOrdinaryName);
+ LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
+
+ if (Lookup.isAmbiguous())
+ return;
+ Lookup.suppressDiagnostics();
+
+ if (!Lookup.isSingleResult()) {
+ if (TypoCorrection Corrected =
+ CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
+ llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
+ CTK_ErrorRecovery)) {
+ diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
+ << Id.getName());
+ checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
+ return;
+ }
+
+ Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
+ return;
+ }
+
+ NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
+ if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
+ if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
+ Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
+
+ if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
+ ND->addAttr(A);
+ if (ASTMutationListener *ML = Context.getASTMutationListener())
+ ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
+ checkDeclIsAllowedInOpenMPTarget(nullptr, ND);
+ } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
+ Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
+ << Id.getName();
+ }
+ } else
+ Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
+}
+
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
Sema &SemaRef, Decl *D) {
if (!D)
@@ -10765,9 +10828,11 @@
// If this is an implicit variable that is legal and we do not need to do
// anything.
if (cast<VarDecl>(D)->isImplicit()) {
- D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context));
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
+ D->addAttr(A);
if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
- ML->DeclarationMarkedOpenMPDeclareTarget(D);
+ ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
return;
}
@@ -10780,9 +10845,11 @@
// target region (it can be e.g. a lambda) that is legal and we do not need
// to do anything else.
if (LD == D) {
- D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context));
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
+ D->addAttr(A);
if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
- ML->DeclarationMarkedOpenMPDeclareTarget(D);
+ ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
return;
}
}
@@ -10810,9 +10877,11 @@
SemaRef.Diag(SL, diag::note_used_here) << SR;
}
// Mark decl as declared target to prevent further diagnostic.
- D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context));
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
+ D->addAttr(A);
if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
- ML->DeclarationMarkedOpenMPDeclareTarget(D);
+ ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
}
}
@@ -10846,9 +10915,11 @@
!checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
// Mark decl as declared target to prevent further diagnostic.
if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
- VD->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context));
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ Context, OMPDeclareTargetDeclAttr::MT_To);
+ VD->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
- ML->DeclarationMarkedOpenMPDeclareTarget(VD);
+ ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
}
return;
}
@@ -10857,9 +10928,11 @@
// Checking declaration inside declare target region.
if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
(isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
- D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context));
+ Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+ Context, OMPDeclareTargetDeclAttr::MT_To);
+ D->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener())
- ML->DeclarationMarkedOpenMPDeclareTarget(D);
+ ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
}
return;
}