RitanyaB updated this revision to Diff 521014.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146418/new/
https://reviews.llvm.org/D146418
Files:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/declare_target_messages.cpp
clang/test/OpenMP/declare_target_variables_ast_print.cpp
clang/test/OpenMP/nvptx_target_exceptions_messages.cpp
Index: clang/test/OpenMP/nvptx_target_exceptions_messages.cpp
===================================================================
--- clang/test/OpenMP/nvptx_target_exceptions_messages.cpp
+++ clang/test/OpenMP/nvptx_target_exceptions_messages.cpp
@@ -95,7 +95,7 @@
int (*D)() = C; // expected-note {{used here}}
// host-note@-1 {{used here}}
#pragma omp end declare target
-int foobar3() { throw 1; }
+int foobar3() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
// Check no infinite recursion in deferred diagnostic emitter.
long E = (long)&E;
Index: clang/test/OpenMP/declare_target_variables_ast_print.cpp
===================================================================
--- /dev/null
+++ clang/test/OpenMP/declare_target_variables_ast_print.cpp
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -w -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK
+// expected-no-diagnostics
+
+static int variable = 100;
+static float variable1 = 200;
+static float variable2 = variable1;
+
+static int var = 1;
+
+static int var1 = 10;
+static int *var2 = &var1;
+static int **ptr1 = &var2;
+
+int arr[2] = {1,2};
+int (*arrptr)[2] = &arr;
+
+class declare{
+ public: int x;
+ void print();
+};
+declare obj1;
+declare *obj2 = &obj1;
+
+struct target{
+ int x;
+ void print();
+};
+static target S;
+
+#pragma omp declare target
+int target_var = variable;
+float target_var1 = variable2;
+int *ptr = &var;
+int ***ptr2 = &ptr1;
+int (**ptr3)[2] = &arrptr;
+declare **obj3 = &obj2;
+target *S1 = &S;
+#pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: static int variable = 100;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static float variable1 = 200;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static float variable2 = variable1;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK: #pragma omp declare target
+// CHECK-NEXT: static int var = 1;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static int var1 = 10;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static int *var2 = &var1;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static int **ptr1 = &var2;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int arr[2] = {1, 2};
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int (*arrptr)[2] = &arr;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: class declare {
+// CHECK-NEXT: public:
+// CHECK-NEXT: int x;
+// CHECK-NEXT: void print();
+// CHECK-NEXT: };
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: declare obj1;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: declare *obj2 = &obj1;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: struct target {
+// CHECK-NEXT: int x;
+// CHECK-NEXT: void print();
+// CHECK-NEXT: };
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: static target S;
+// CHECK-NEXT: #pragma omp end declare target
+
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int target_var = variable;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: float target_var1 = variable2;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int *ptr = &var;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int ***ptr2 = &ptr1;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: int (**ptr3)[2] = &arrptr;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: declare **obj3 = &obj2;
+// CHECK-NEXT: #pragma omp end declare target
+// CHECK-NEXT: #pragma omp declare target
+// CHECK-NEXT: target *S1 = &S;
+// CHECK-NEXT: #pragma omp end declare target
Index: clang/test/OpenMP/declare_target_messages.cpp
===================================================================
--- clang/test/OpenMP/declare_target_messages.cpp
+++ clang/test/OpenMP/declare_target_messages.cpp
@@ -233,6 +233,42 @@
#pragma omp declare target to(MultiDevTy) device_type(host) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp5-error {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}} omp51-error {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}}
#pragma omp declare target to(MultiDevTy) device_type(nohost) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp5-error {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}} // omp51-error {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}}
+static int variable = 100; //expected-warning {{declaration is not declared in any declare target region}}
+static float variable1 = 200;
+static float variable2 = variable1; //expected-warning {{declaration is not declared in any declare target region}}
+
+static int var = 1; //expected-warning {{declaration is not declared in any declare target region}}
+
+static int var1 = 10;
+static int *var2 = &var1;
+static int **ptr1 = &var2; //expected-warning {{declaration is not declared in any declare target region}}
+
+int arr[2] = {1,2};
+int (*arrptr)[2] = &arr; //expected-warning {{declaration is not declared in any declare target region}}
+
+class declare{
+ public: int x;
+ void print();
+};
+declare obj1;
+declare *obj2 = &obj1; //expected-warning {{declaration is not declared in any declare target region}}
+
+struct target{
+ int x;
+ void print();
+};
+static target S; //expected-warning {{declaration is not declared in any declare target region}}
+
+#pragma omp declare target
+int target_var = variable; //expected-note {{used here}}
+float target_var1 = variable2; //expected-note {{used here}}
+int *ptr = &var; //expected-note {{used here}}
+int ***ptr2 = &ptr1; //expected-note {{used here}}
+int (**ptr3)[2] = &arrptr; //expected-note {{used here}}
+declare **obj3 = &obj2; //expected-note {{used here}}
+target *S1 = &S; //expected-note {{used here}}
+#pragma omp end declare target
+
#if TESTENDINC
#include "unterminated_declare_target_include.h"
#elif TESTEND
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -23088,6 +23088,58 @@
checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
}
+class GlobalDeclRefChecker final
+ : public ConstStmtVisitor<GlobalDeclRefChecker> {
+public:
+ SmallVector<VarDecl *> DeclVector;
+ Decl *TargetDecl;
+ void VisitDeclRefExpr(const DeclRefExpr *Node) {
+ Decl *DeclVar = nullptr;
+ if (auto *VD = const_cast<VarDecl *>(dyn_cast<VarDecl>(Node->getDecl()))) {
+ VD->addAttr(this->TargetDecl->getAttr<OMPDeclareTargetDeclAttr>());
+ this->DeclVector.push_back(VD);
+ }
+ }
+ void VisitExpr(const Expr *Ex) {
+ for (Expr::const_child_iterator it = Ex->child_begin();
+ it != Ex->child_end(); ++it) {
+ if (isa<Expr>(*it))
+ VisitExpr(dyn_cast<Expr>(*it));
+ if (isa<DeclRefExpr>(*it))
+ Visit(*it);
+ }
+ }
+};
+
+/// Adding OMPDeclareTargetDeclAttr to variables with static storage
+/// duration that are referenced in the initializer expression list of
+/// variables with static storage duration in declare target directive.
+void Sema::ActOnOpenMPImplicitDeclareTarget(Decl *TargetDecl) {
+ GlobalDeclRefChecker Checker;
+ Checker.TargetDecl = TargetDecl;
+ VarDecl *TargetVarDecl = nullptr;
+ if (TargetVarDecl = dyn_cast_or_null<VarDecl>(TargetDecl))
+ Checker.DeclVector.push_back(TargetVarDecl);
+ while (!Checker.DeclVector.empty()) {
+ VarDecl *TargetVarDecl = Checker.DeclVector.pop_back_val();
+ if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>()) {
+ if (TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
+ Expr *Ex = TargetVarDecl->getInit();
+ const DeclRefExpr *DeclRef = nullptr;
+ if (Ex) {
+ if (isa<DeclRefExpr>(Ex)) {
+ DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(Ex);
+ Checker.Visit(DeclRef);
+ continue;
+ }
+ Checker.VisitExpr(Ex);
+ }
+ }
+ }
+ }
+ return;
+}
+
OMPClause *Sema::ActOnOpenMPToClause(
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
ArrayRef<SourceLocation> MotionModifiersLoc,
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14468,6 +14468,13 @@
for (unsigned i = 0, e = Group.size(); i != e; ++i) {
if (Decl *D = Group[i]) {
+ // Check if the Decl has been declared in '#pragma omp declare target'
+ // directive and has static storage duration.
+ if (auto *VD = dyn_cast<VarDecl>(D);
+ LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
+ VD->hasGlobalStorage()) {
+ ActOnOpenMPImplicitDeclareTarget(D);
+ }
// For declarators, there are some additional syntactic-ish checks we need
// to perform.
if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -11323,6 +11323,11 @@
void
checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
SourceLocation IdLoc = SourceLocation());
+
+ /// Adds OMPDeclareTargetDeclAttr to referenced variables in declare target
+ /// directive.
+ void ActOnOpenMPImplicitDeclareTarget(Decl *D);
+
/// Finishes analysis of the deferred functions calls that may be declared as
/// host/nohost during device/host compilation.
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits