r325391 - [OPENMP] Do not emit messages for templates in declare target

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 16 13:23:23 PST 2018


Author: abataev
Date: Fri Feb 16 13:23:23 2018
New Revision: 325391

URL: http://llvm.org/viewvc/llvm-project?rev=325391&view=rev
Log:
[OPENMP] Do not emit messages for templates in declare target
constructs.

The compiler may emit some extra warnings for functions, that are
implicit specialization of the templates, declared in the target region.

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/declare_target_messages.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=325391&r1=325390&r2=325391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Feb 16 13:23:23 2018
@@ -12798,7 +12798,7 @@ static void checkDeclInTargetContext(Sou
                                      Sema &SemaRef, Decl *D) {
   if (!D)
     return;
-  Decl *LD = nullptr;
+  const Decl *LD = nullptr;
   if (isa<TagDecl>(D)) {
     LD = cast<TagDecl>(D)->getDefinition();
   } else if (isa<VarDecl>(D)) {
@@ -12814,22 +12814,29 @@ static void checkDeclInTargetContext(Sou
         ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
       return;
     }
-
-  } else if (isa<FunctionDecl>(D)) {
+  } else if (auto *F = dyn_cast<FunctionDecl>(D)) {
     const FunctionDecl *FD = nullptr;
-    if (cast<FunctionDecl>(D)->hasBody(FD))
-      LD = const_cast<FunctionDecl *>(FD);
-
-    // If the definition is associated with the current declaration in the
-    // target region (it can be e.g. a lambda) that is legal and we do not need
-    // to do anything else.
-    if (LD == D) {
-      Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
-          SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
-      D->addAttr(A);
-      if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
-        ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
-      return;
+    if (cast<FunctionDecl>(D)->hasBody(FD)) {
+      LD = FD;
+      // If the definition is associated with the current declaration in the
+      // target region (it can be e.g. a lambda) that is legal and we do not
+      // need to do anything else.
+      if (LD == D) {
+        Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
+            SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
+        D->addAttr(A);
+        if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
+          ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
+        return;
+      }
+    } else if (F->isFunctionTemplateSpecialization() &&
+               F->getTemplateSpecializationKind() ==
+                   TSK_ImplicitInstantiation) {
+      // Check if the function is implicitly instantiated from the template
+      // defined in the declare target region.
+      const FunctionTemplateDecl *FTD = F->getPrimaryTemplate();
+      if (FTD && FTD->hasAttr<OMPDeclareTargetDeclAttr>())
+        return;
     }
   }
   if (!LD)
@@ -12841,7 +12848,7 @@ static void checkDeclInTargetContext(Sou
       SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
       SemaRef.Diag(SL, diag::note_used_here) << SR;
     } else {
-      DeclContext *DC = LD->getDeclContext();
+      const DeclContext *DC = LD->getDeclContext();
       while (DC) {
         if (isa<FunctionDecl>(DC) &&
             cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
@@ -12894,7 +12901,8 @@ void Sema::checkDeclIsAllowedInOpenMPTar
     if ((E || !VD->getType()->isIncompleteType()) &&
         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
       // Mark decl as declared target to prevent further diagnostic.
-      if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
+      if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) ||
+          isa<FunctionTemplateDecl>(VD)) {
         Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
             Context, OMPDeclareTargetDeclAttr::MT_To);
         VD->addAttr(A);
@@ -12914,10 +12922,21 @@ void Sema::checkDeclIsAllowedInOpenMPTar
       return;
     }
   }
+  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
+    if (FTD->hasAttr<OMPDeclareTargetDeclAttr>() &&
+        (FTD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
+         OMPDeclareTargetDeclAttr::MT_Link)) {
+      assert(IdLoc.isValid() && "Source location is expected");
+      Diag(IdLoc, diag::err_omp_function_in_link_clause);
+      Diag(FTD->getLocation(), diag::note_defined_here) << FTD;
+      return;
+    }
+  }
   if (!E) {
     // Checking declaration inside declare target region.
     if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
-        (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
+        (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
+         isa<FunctionTemplateDecl>(D))) {
       Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
           Context, OMPDeclareTargetDeclAttr::MT_To);
       D->addAttr(A);

Modified: cfe/trunk/test/OpenMP/declare_target_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_target_messages.cpp?rev=325391&r1=325390&r2=325391&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_target_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_target_messages.cpp Fri Feb 16 13:23:23 2018
@@ -33,6 +33,33 @@ struct NonT {
 
 typedef int sint;
 
+template <typename T>
+T bla1() { return 0; }
+
+#pragma omp declare target
+template <typename T>
+T bla2() { return 0; }
+#pragma omp end declare target
+
+template<>
+float bla2() { return 1.0; }
+
+#pragma omp declare target
+void blub2() {
+  bla2<float>();
+  bla2<int>();
+}
+#pragma omp end declare target
+
+void t2() {
+#pragma omp target
+  {
+    bla2<float>();
+    bla2<long>();
+  }
+}
+
+
 #pragma omp declare target // expected-note {{to match this '#pragma omp declare target'}}
 #pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}}
 extern int b;




More information about the cfe-commits mailing list