RitanyaB created this revision.
RitanyaB added reviewers: sandeepkosuri, koops, soumitra, dreachem, ABataev, 
cchen.
Herald added subscribers: sunshaoce, mattd, asavonic, guansong, yaxunl.
Herald added a project: All.
RitanyaB requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, jplehr, sstefan1.
Herald added a project: clang.

Initial support for OpenMP 5.0 declare target "as if" behavior for "initializer 
expressions".
If a variable with static storage duration or a function (except lambda for 
C++) is referenced in the initializer expression list of a variable with static 
storage duration that appears as a list item in a to clause on a declare target 
directive then the name of the referenced variable or function is treated as if 
it had appeared in a to clause on a declare target directive.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146418

Files:
  clang/lib/Parse/ParseDecl.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,88 @@
+// RUN: %clang_cc1 -w -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK
+// expected-no-diagnostics
+
+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 *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 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 *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,36 @@
 #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 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 *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/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -2087,6 +2087,33 @@
   }
 }
 
+/// Adding OMPDeclareTargetDeclAttr to variables with static storage
+/// duration that is referenced in the initializer expression list of
+/// variables with static storage duration in declare target directive.
+void ParseImplicitDeclareTargetAttr(Decl *TargetDecl) {
+  if (TargetDecl && TargetDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
+      isa<VarDecl>(TargetDecl)) {
+    VarDecl *TargetVarDecl = cast<VarDecl>(TargetDecl);
+    Expr *Ex = TargetVarDecl->getInit()->IgnoreCasts();
+    const DeclRefExpr *DeclRef = nullptr;
+    if (Ex && isa<UnaryOperator>(Ex) && TargetVarDecl->hasGlobalStorage()) {
+      if (auto *unary = cast<UnaryOperator>(Ex)) {
+        if (unary->getOpcode() == UnaryOperator::Opcode::UO_AddrOf) {
+          for (auto child : unary->children()) {
+            if (isa<DeclRefExpr>(child)) {
+              DeclRef = dyn_cast<DeclRefExpr>(child);
+              Decl *DeclVar = (Decl *)DeclRef->getDecl();
+              DeclVar->addAttr(TargetDecl->getAttr<OMPDeclareTargetDeclAttr>());
+              ParseImplicitDeclareTargetAttr(DeclVar);
+            }
+          }
+        }
+      }
+    }
+  }
+  return;
+}
+
 /// ParseDeclGroup - Having concluded that this is either a function
 /// definition or a group of object declarations, actually parse the
 /// result.
@@ -2242,6 +2269,12 @@
   SmallVector<Decl *, 8> DeclsInGroup;
   Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
       D, ParsedTemplateInfo(), FRI);
+  if (FirstDecl && FirstDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
+      isa<VarDecl>(FirstDecl)) {
+    VarDecl *VarFirstDecl = cast<VarDecl>(FirstDecl);
+    if (VarFirstDecl->hasGlobalStorage())
+      ParseImplicitDeclareTargetAttr(FirstDecl);
+  }
   if (LateParsedAttrs.size() > 0)
     ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
   D.complete(FirstDecl);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to