r268925 - [OpenMP] Parse+Sema for '#pragma omp declare target' syntax version 4.5

Dmitry Polukhin via cfe-commits cfe-commits at lists.llvm.org
Mon May 9 07:59:13 PDT 2016


Author: dpolukhin
Date: Mon May  9 09:59:13 2016
New Revision: 268925

URL: http://llvm.org/viewvc/llvm-project?rev=268925&view=rev
Log:
[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

Modified:
    cfe/trunk/include/clang/AST/ASTMutationListener.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
    cfe/trunk/lib/Parse/ParseOpenMP.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/OpenMP/declare_target_ast_print.cpp
    cfe/trunk/test/OpenMP/declare_target_messages.cpp

Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Mon May  9 09:59:13 2016
@@ -111,7 +111,9 @@ public:
   /// previously marked as declaretarget.
   ///
   /// \param D the declaration marked OpenMP declaretarget.
-  virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D) {}
+  /// \param Attr the added attribute.
+  virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
+                                                    const Attr *Attr) {}
 
   /// \brief A definition has been made visible by being redefined locally.
   ///

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon May  9 09:59:13 2016
@@ -2345,8 +2345,17 @@ def OMPDeclareTargetDecl : Attr {
   let Spellings = [Pragma<"omp", "declare target">];
   let SemaHandler = 0;
   let Documentation = [OMPDeclareTargetDocs];
+  let Args = [
+    EnumArgument<"MapType", "MapTypeTy",
+                 [ "to", "link" ],
+                 [ "MT_To", "MT_Link" ]>
+  ];
   let AdditionalMembers = [{
-    void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {}
+    void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+      // Use fake syntax because it is for testing and debugging purpose only.
+      if (getMapType() != MT_To)
+        OS << ConvertMapTypeTyToStr(getMapType()) << " ";
+    }
   }];
 }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon May  9 09:59:13 2016
@@ -967,6 +967,8 @@ def err_omp_declare_simd_inbranch_notinb
   "unexpected '%0' clause, '%1' is specified already">;
 def err_expected_end_declare_target : Error<
   "expected '#pragma omp end declare target'">;
+def err_omp_declare_target_unexpected_clause: Error<
+  "unexpected '%0' clause, only 'to' or 'link' clauses expected">;
 
 // Pragma loop support.
 def err_pragma_loop_missing_argument : Error<

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May  9 09:59:13 2016
@@ -7984,6 +7984,12 @@ def warn_omp_alignment_not_power_of_two
   InGroup<OpenMPClauses>;
 def err_omp_enclosed_declare_target : Error<
   "declare target region may not be enclosed within another declare target region">;
+def err_omp_invalid_target_decl : Error<
+  "%0 used in declare target directive is not a variable or a function name">;
+def err_omp_declare_target_multiple : Error<
+  "%0 appears multiple times in clauses on the same declare target directive">;
+def err_omp_declare_target_to_and_link : Error<
+  "%0 must not appear in both clauses 'to' and 'link'">;
 def warn_omp_not_in_target_context : Warning<
   "declaration is not declared in any declare target region">,
   InGroup<OpenMPTarget>;

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon May  9 09:59:13 2016
@@ -2466,16 +2466,19 @@ private:
       Decl *TagDecl = nullptr);
   /// \brief Parse 'omp declare reduction' construct.
   DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
+
   /// \brief Parses simple list of variables.
   ///
   /// \param Kind Kind of the directive.
-  /// \param [out] VarList List of referenced variables.
+  /// \param Callback Callback function to be called for the list elements.
   /// \param AllowScopeSpecifier true, if the variables can have fully
   /// qualified names.
   ///
-  bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
-                                SmallVectorImpl<Expr *> &VarList,
-                                bool AllowScopeSpecifier);
+  bool ParseOpenMPSimpleVarList(
+      OpenMPDirectiveKind Kind,
+      const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
+          Callback,
+      bool AllowScopeSpecifier);
   /// \brief Parses declarative or executable directive.
   ///
   /// \param Allowed ACK_Any, if any directives are allowed,

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon May  9 09:59:13 2016
@@ -7977,6 +7977,11 @@ public:
   bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc);
   /// Called at the end of target region i.e. '#pragme omp end declare target'.
   void ActOnFinishOpenMPDeclareTargetDirective();
+  /// Called on correct id-expression from the '#pragma omp declare target'.
+  void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
+                                    const DeclarationNameInfo &Id,
+                                    OMPDeclareTargetDeclAttr::MapTypeTy MT,
+                                    NamedDeclSetType &SameDirectiveDecls);
   /// Check declaration inside target region.
   void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D);
   /// Return true inside OpenMP target region.

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Mon May  9 09:59:13 2016
@@ -682,7 +682,8 @@ private:
                                     const ObjCInterfaceDecl *IFD) override;
   void DeclarationMarkedUsed(const Decl *D) override;
   void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
-  void DeclarationMarkedOpenMPDeclareTarget(const Decl *D) override;
+  void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
+                                            const Attr *Attr) override;
   void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
   void AddedAttributeToRecord(const Attr *Attr,
                               const RecordDecl *Record) override;

Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Mon May  9 09:59:13 2016
@@ -125,7 +125,8 @@ public:
   void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
   void DeclarationMarkedUsed(const Decl *D) override;
   void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
-  void DeclarationMarkedOpenMPDeclareTarget(const Decl *D) override;
+  void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
+                                            const Attr *Attr) override;
   void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
   void AddedAttributeToRecord(const Attr *Attr, 
                               const RecordDecl *Record) override;
@@ -221,9 +222,9 @@ void MultiplexASTMutationListener::Decla
     Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D);
 }
 void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget(
-    const Decl *D) {
+    const Decl *D, const Attr *Attr) {
   for (auto *L : Listeners)
-    L->DeclarationMarkedOpenMPDeclareTarget(D);
+    L->DeclarationMarkedOpenMPDeclareTarget(D, Attr);
 }
 void MultiplexASTMutationListener::RedefinedHiddenDefinition(const NamedDecl *D,
                                                              Module *M) {

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon May  9 09:59:13 2016
@@ -40,6 +40,21 @@ enum OpenMPDirectiveKindEx {
   OMPD_target_enter,
   OMPD_target_exit
 };
+
+class ThreadprivateListParserHelper final {
+  SmallVector<Expr *, 4> Identifiers;
+  Parser *P;
+
+public:
+  ThreadprivateListParserHelper(Parser *P) : P(P) {}
+  void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
+    ExprResult Res =
+        P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo);
+    if (Res.isUsable())
+      Identifiers.push_back(Res.get());
+  }
+  llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
+};
 } // namespace
 
 // Map token string to extended OMP token kind that are
@@ -525,13 +540,13 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
   SourceLocation Loc = ConsumeToken();
-  SmallVector<Expr *, 4> Identifiers;
   auto DKind = ParseOpenMPDirectiveKind(*this);
 
   switch (DKind) {
-  case OMPD_threadprivate:
+  case OMPD_threadprivate: {
     ConsumeToken();
-    if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
+    ThreadprivateListParserHelper Helper(this);
+    if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
       // The last seen token is annot_pragma_openmp_end - need to check for
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
@@ -541,9 +556,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
       }
       // Skip the last annot_pragma_openmp_end.
       ConsumeToken();
-      return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
+      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
+                                                       Helper.getIdentifiers());
     }
     break;
+  }
   case OMPD_declare_reduction:
     ConsumeToken();
     if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
@@ -599,10 +616,40 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
   case OMPD_declare_target: {
     SourceLocation DTLoc = ConsumeAnyToken();
     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
-      Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-          << getOpenMPDirectiveName(OMPD_declare_target);
+      // OpenMP 4.5 syntax with list of entities.
+      llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls;
+      while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+        OMPDeclareTargetDeclAttr::MapTypeTy MT =
+            OMPDeclareTargetDeclAttr::MT_To;
+        if (Tok.is(tok::identifier)) {
+          IdentifierInfo *II = Tok.getIdentifierInfo();
+          StringRef ClauseName = II->getName();
+          // Parse 'to|link' clauses.
+          if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
+                                                               MT)) {
+            Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
+                << ClauseName;
+            break;
+          }
+          ConsumeToken();
+        }
+        auto Callback = [this, MT, &SameDirectiveDecls](
+            CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
+          Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
+                                               SameDirectiveDecls);
+        };
+        if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true))
+          break;
+
+        // Consume optional ','.
+        if (Tok.is(tok::comma))
+          ConsumeToken();
+      }
       SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+      ConsumeAnyToken();
+      return DeclGroupPtrTy();
     }
+
     // Skip the last annot_pragma_openmp_end.
     ConsumeAnyToken();
 
@@ -716,7 +763,6 @@ StmtResult Parser::ParseOpenMPDeclarativ
     AllowedContsructsKind Allowed) {
   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
-  SmallVector<Expr *, 5> Identifiers;
   SmallVector<OMPClause *, 5> Clauses;
   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
   FirstClauses(OMPC_unknown + 1);
@@ -732,13 +778,14 @@ StmtResult Parser::ParseOpenMPDeclarativ
   bool FlushHasClause = false;
 
   switch (DKind) {
-  case OMPD_threadprivate:
+  case OMPD_threadprivate: {
     if (Allowed != ACK_Any) {
       Diag(Tok, diag::err_omp_immediate_directive)
           << getOpenMPDirectiveName(DKind) << 0;
     }
     ConsumeToken();
-    if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
+    ThreadprivateListParserHelper Helper(this);
+    if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
       // The last seen token is annot_pragma_openmp_end - need to check for
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
@@ -746,12 +793,13 @@ StmtResult Parser::ParseOpenMPDeclarativ
             << getOpenMPDirectiveName(OMPD_threadprivate);
         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
       }
-      DeclGroupPtrTy Res =
-          Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
+      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
+          Loc, Helper.getIdentifiers());
       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
     }
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
+  }
   case OMPD_declare_reduction:
     ConsumeToken();
     if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
@@ -913,16 +961,15 @@ StmtResult Parser::ParseOpenMPDeclarativ
   return Directive;
 }
 
-/// \brief Parses list of simple variables for '#pragma omp threadprivate'
-/// directive.
-///
-///   simple-variable-list:
-///         '(' id-expression {, id-expression} ')'
-///
-bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
-                                      SmallVectorImpl<Expr *> &VarList,
-                                      bool AllowScopeSpecifier) {
-  VarList.clear();
+// Parses simple list:
+//   simple-variable-list:
+//         '(' id-expression {, id-expression} ')'
+//
+bool Parser::ParseOpenMPSimpleVarList(
+    OpenMPDirectiveKind Kind,
+    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
+        Callback,
+    bool AllowScopeSpecifier) {
   // Parse '('.
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   if (T.expectAndConsume(diag::err_expected_lparen_after,
@@ -959,11 +1006,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
           << tok::identifier
           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
     } else {
-      DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
-      ExprResult Res =
-          Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
-      if (Res.isUsable())
-        VarList.push_back(Res.get());
+      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
     }
     // Consume ','.
     if (Tok.is(tok::comma)) {
@@ -979,7 +1022,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
   // Parse ')'.
   IsCorrect = !T.consumeClose() && IsCorrect;
 
-  return !IsCorrect && VarList.empty();
+  return !IsCorrect;
 }
 
 /// \brief Parsing of OpenMP clauses.

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon May  9 09:59:13 2016
@@ -1101,6 +1101,23 @@ public:
     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 @@ void Sema::ActOnFinishOpenMPDeclareTarge
   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 @@ static void checkDeclInTargetContext(Sou
     // 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 @@ static void checkDeclInTargetContext(Sou
     // 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 @@ static void checkDeclInTargetContext(Sou
       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 @@ void Sema::checkDeclIsAllowedInOpenMPTar
         !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 @@ void Sema::checkDeclIsAllowedInOpenMPTar
     // 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;
   }

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon May  9 09:59:13 2016
@@ -3890,11 +3890,6 @@ void ASTDeclReader::UpdateDecl(Decl *D,
           Reader.Context, ReadSourceRange(Record, Idx)));
       break;
 
-    case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
-      D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(
-          Reader.Context, ReadSourceRange(Record, Idx)));
-      break;
-
     case UPD_DECL_EXPORTED: {
       unsigned SubmoduleID = readSubmoduleID(Record, Idx);
       auto *Exported = cast<NamedDecl>(D);
@@ -3920,6 +3915,7 @@ void ASTDeclReader::UpdateDecl(Decl *D,
       break;
     }
 
+    case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
     case UPD_ADDED_ATTR_TO_RECORD:
       AttrVec Attrs;
       Reader.ReadAttributes(F, Attrs, Record, Idx);

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May  9 09:59:13 2016
@@ -5816,12 +5816,14 @@ void ASTWriter::DeclarationMarkedOpenMPT
   DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE));
 }
 
-void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D) {
+void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
+                                                     const Attr *Attr) {
   assert(!WritingAST && "Already writing the AST!");
   if (!D->isFromASTFile())
     return;
 
-  DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET));
+  DeclUpdates[D].push_back(
+      DeclUpdate(UPD_DECL_MARKED_OPENMP_DECLARETARGET, Attr));
 }
 
 void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {

Modified: cfe/trunk/test/OpenMP/declare_target_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_target_ast_print.cpp?rev=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_target_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_target_ast_print.cpp Mon May  9 09:59:13 2016
@@ -79,6 +79,51 @@ int test1() {
 #pragma omp end declare target
 // CHECK: #pragma omp end declare target
 
+int a1;
+void f1() {
+}
+#pragma omp declare target (a1, f1)
+// CHECK: #pragma omp declare target
+// CHECK: int a1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: void f1()
+// CHECK: #pragma omp end declare target
+
+int b1, b2, b3;
+void f2() {
+}
+#pragma omp declare target to(b1) to(b2), to(b3, f2)
+// CHECK: #pragma omp declare target
+// CHECK: int b1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: int b2;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: int b3;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target
+// CHECK: void f2()
+// CHECK: #pragma omp end declare target
+
+int c1, c2, c3;
+void f3() {
+}
+#pragma omp declare target link(c1) link(c2), link(c3, f3)
+// CHECK: #pragma omp declare target link
+// CHECK: int c1;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: int c2;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: int c3;
+// CHECK: #pragma omp end declare target
+// CHECK: #pragma omp declare target link
+// CHECK: void f3()
+// CHECK: #pragma omp end declare target
+
 int main (int argc, char **argv) {
   foo();
   foo_c();

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=268925&r1=268924&r2=268925&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/declare_target_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/declare_target_messages.cpp Mon May  9 09:59:13 2016
@@ -4,9 +4,15 @@
 
 int a, b; // expected-warning {{declaration is not declared in any declare target region}}
 __thread int t; // expected-note {{defined as threadprivate or thread local}}
-#pragma omp declare target private(a) // expected-warning {{extra tokens at the end of '#pragma omp declare target' are ignored}}
+
+#pragma omp declare target . // expected-error {{expected '(' after 'declare target'}}
+
+#pragma omp declare target
 void f();
 #pragma omp end declare target shared(a) // expected-warning {{extra tokens at the end of '#pragma omp end declare target' are ignored}}
+
+#pragma omp declare target map(a) // expected-error {{unexpected 'map' clause, only 'to' or 'link' clauses expected}}
+
 void c(); // expected-warning {{declaration is not declared in any declare target region}}
 
 extern int b;
@@ -86,4 +92,10 @@ namespace {
 } //  expected-error {{expected '#pragma omp end declare target'}}
 #pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
 
+#pragma omp declare target link(S) // expected-error {{'S' used in declare target directive is not a variable or a function name}}
+
+#pragma omp declare target (x, x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}}
+#pragma omp declare target to(x) to(x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}}
+#pragma omp declare target link(x) // expected-error {{'x' must not appear in both clauses 'to' and 'link'}}
+
 #pragma omp declare target // expected-error {{expected '#pragma omp end declare target'}} expected-note {{to match this '#pragma omp declare target'}}




More information about the cfe-commits mailing list