r355952 - [OPENMP 5.0]Initial support for 'allocator' clause.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 12 11:52:33 PDT 2019


Author: abataev
Date: Tue Mar 12 11:52:33 2019
New Revision: 355952

URL: http://llvm.org/viewvc/llvm-project?rev=355952&view=rev
Log:
[OPENMP 5.0]Initial support for 'allocator' clause.

Added parsing/sema analysis/serialization/deserialization for the
'allocator' clause of the 'allocate' directive.

Added:
    cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp
    cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTNodeTraverser.h
    cfe/trunk/include/clang/AST/DeclOpenMP.h
    cfe/trunk/include/clang/AST/OpenMPClause.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/OpenMPKinds.def
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/DeclOpenMP.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/AST/OpenMPClause.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Basic/OpenMPKinds.cpp
    cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/trunk/lib/Parse/ParseOpenMP.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/PCH/chain-openmp-allocate.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
+++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Tue Mar 12 11:52:33 2019
@@ -396,6 +396,8 @@ public:
   void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
     for (const auto *E : D->varlists())
       Visit(E);
+    for (const auto *C : D->clauselists())
+      Visit(C);
   }
 
   template <typename SpecializationDecl>

Modified: cfe/trunk/include/clang/AST/DeclOpenMP.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclOpenMP.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclOpenMP.h (original)
+++ cfe/trunk/include/clang/AST/DeclOpenMP.h Tue Mar 12 11:52:33 2019
@@ -421,12 +421,21 @@ public:
 ///
 class OMPAllocateDecl final
     : public Decl,
-      private llvm::TrailingObjects<OMPAllocateDecl, Expr *> {
+      private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> {
   friend class ASTDeclReader;
   friend TrailingObjects;
 
   /// Number of variable within the allocate directive.
   unsigned NumVars = 0;
+  /// Number of clauses associated with the allocate directive.
+  unsigned NumClauses = 0;
+
+  size_t numTrailingObjects(OverloadToken<Expr *>) const {
+    return NumVars;
+  }
+  size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
+    return NumClauses;
+  }
 
   virtual void anchor();
 
@@ -443,19 +452,41 @@ class OMPAllocateDecl final
 
   void setVars(ArrayRef<Expr *> VL);
 
+  /// Returns an array of immutable clauses associated with this directive.
+  ArrayRef<OMPClause *> getClauses() const {
+    return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
+  }
+
+  /// Returns an array of clauses associated with this directive.
+  MutableArrayRef<OMPClause *> getClauses() {
+    return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
+                                        NumClauses);
+  }
+
+  /// Sets an array of clauses to this requires declaration
+  void setClauses(ArrayRef<OMPClause *> CL);
+
 public:
   static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
-                                 SourceLocation L, ArrayRef<Expr *> VL);
+                                 SourceLocation L, ArrayRef<Expr *> VL,
+                                 ArrayRef<OMPClause *> CL);
   static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
-                                             unsigned N);
+                                             unsigned NVars, unsigned NClauses);
 
   typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
   typedef llvm::iterator_range<varlist_iterator> varlist_range;
   typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
+  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
+  using clauselist_range = llvm::iterator_range<clauselist_iterator>;
+  using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
+
 
   unsigned varlist_size() const { return NumVars; }
   bool varlist_empty() const { return NumVars == 0; }
+  unsigned clauselist_size() const { return NumClauses; }
+  bool clauselist_empty() const { return NumClauses == 0; }
 
   varlist_range varlists() {
     return varlist_range(varlist_begin(), varlist_end());
@@ -468,6 +499,21 @@ public:
   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
   varlist_const_iterator varlist_end() const { return getVars().end(); }
 
+  clauselist_range clauselists() {
+    return clauselist_range(clauselist_begin(), clauselist_end());
+  }
+  clauselist_const_range clauselists() const {
+    return clauselist_const_range(clauselist_begin(), clauselist_end());
+  }
+  clauselist_iterator clauselist_begin() { return getClauses().begin(); }
+  clauselist_iterator clauselist_end() { return getClauses().end(); }
+  clauselist_const_iterator clauselist_begin() const {
+    return getClauses().begin();
+  }
+  clauselist_const_iterator clauselist_end() const {
+    return getClauses().end();
+  }
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == OMPAllocate; }
 };

Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Tue Mar 12 11:52:33 2019
@@ -243,6 +243,58 @@ public:
   }
 };
 
+/// This represents 'allocator' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp allocate(a) allocator(omp_default_mem_alloc)
+/// \endcode
+/// In this example directive '#pragma omp allocate' has simple 'allocator'
+/// clause with the allocator 'omp_default_mem_alloc'.
+class OMPAllocatorClause : public OMPClause {
+  friend class OMPClauseReader;
+
+  /// Location of '('.
+  SourceLocation LParenLoc;
+
+  /// Expression with the allocator.
+  Stmt *Allocator = nullptr;
+
+  /// Set allocator.
+  void setAllocator(Expr *A) { Allocator = A; }
+
+public:
+  /// Build 'allocator' clause with the given allocator.
+  ///
+  /// \param A Allocator.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
+                     SourceLocation EndLoc)
+      : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Allocator(A) {}
+
+  /// Build an empty clause.
+  OMPAllocatorClause()
+      : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {}
+
+  /// Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+  /// Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// Returns allocator.
+  Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
+
+  child_range children() { return child_range(&Allocator, &Allocator + 1); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_allocator;
+  }
+};
+
 /// This represents 'if' clause in the '#pragma omp ...' directive.
 ///
 /// \code

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Mar 12 11:52:33 2019
@@ -1614,9 +1614,10 @@ DEF_TRAVERSE_DECL(OMPDeclareMapperDecl,
 DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
 
 DEF_TRAVERSE_DECL(OMPAllocateDecl, {
-  for (auto *I : D->varlists()) {
+  for (auto *I : D->varlists())
     TRY_TO(TraverseStmt(I));
-  }
+  for (auto *C : D->clauselists())
+    TRY_TO(TraverseOMPClause(C));
 })
 
 // A helper method for TemplateDecl's children.
@@ -2826,6 +2827,13 @@ bool RecursiveASTVisitor<Derived>::Visit
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
+    OMPAllocatorClause *C) {
+  TRY_TO(TraverseStmt(C->getAllocator()));
+  return true;
+}
+
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
   TRY_TO(VisitOMPClauseWithPreInit(C));

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Tue Mar 12 11:52:33 2019
@@ -3156,6 +3156,7 @@ def OMPAllocateDecl : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let SemaHandler = 0;
+  let Args = [ExprArgument<"Allocator">];
   let Documentation = [Undocumented];
 }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 12 11:52:33 2019
@@ -9135,6 +9135,8 @@ def note_omp_invalid_subscript_on_this_p
   "expected 'this' subscript expression on map clause to be 'this[0]'">;
 def err_omp_invalid_map_this_expr : Error <
   "invalid 'this' expression on 'map' clause">;
+def err_implied_omp_allocator_handle_t_not_found : Error<
+  "omp_allocator_handle_t type not found; include <omp.h>">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Tue Mar 12 11:52:33 2019
@@ -188,6 +188,9 @@
 #ifndef OPENMP_DECLARE_MAPPER_CLAUSE
 #define OPENMP_DECLARE_MAPPER_CLAUSE(Name)
 #endif
+#ifndef OPENMP_ALLOCATE_CLAUSE
+# define OPENMP_ALLOCATE_CLAUSE(Name)
+#endif
 
 // OpenMP directives.
 OPENMP_DIRECTIVE(threadprivate)
@@ -247,6 +250,7 @@ OPENMP_DIRECTIVE_EXT(target_teams_distri
 OPENMP_DIRECTIVE(allocate)
 
 // OpenMP clauses.
+OPENMP_CLAUSE(allocator, OMPAllocatorClause)
 OPENMP_CLAUSE(if, OMPIfClause)
 OPENMP_CLAUSE(final, OMPFinalClause)
 OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
@@ -489,6 +493,9 @@ OPENMP_REQUIRES_CLAUSE(reverse_offload)
 OPENMP_REQUIRES_CLAUSE(dynamic_allocators)
 OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order)
 
+// Clauses allowed for OpenMP directive 'allocate'.
+OPENMP_ALLOCATE_CLAUSE(allocator)
+
 // Modifiers for 'atomic_default_mem_order' clause.
 OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
 OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
@@ -910,6 +917,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
 // Clauses allowed for OpenMP directive 'declare mapper'.
 OPENMP_DECLARE_MAPPER_CLAUSE(map)
 
+#undef OPENMP_ALLOCATE_CLAUSE
 #undef OPENMP_DECLARE_MAPPER_CLAUSE
 #undef OPENMP_TASKGROUP_CLAUSE
 #undef OPENMP_TASKLOOP_SIMD_CLAUSE

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar 12 11:52:33 2019
@@ -8781,6 +8781,8 @@ public:
   //
 private:
   void *VarDataSharingAttributesStack;
+  /// omp_allocator_handle_t type.
+  QualType OMPAllocatorHandleT;
   /// Number of nested '#pragma omp declare target' directives.
   unsigned DeclareTargetNestingLevel = 0;
   /// Initialization of data-sharing attributes stack.
@@ -8892,6 +8894,7 @@ public:
   /// Called on well-formed '#pragma omp allocate'.
   DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc,
                                               ArrayRef<Expr *> VarList,
+                                              ArrayRef<OMPClause *> Clauses,
                                               DeclContext *Owner = nullptr);
   /// Called on well-formed '#pragma omp requires'.
   DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
@@ -9247,6 +9250,11 @@ public:
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          SourceLocation EndLoc);
+  /// Called on well-formed 'allocator' clause.
+  OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator,
+                                        SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc);
   /// Called on well-formed 'if' clause.
   OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
                                  Expr *Condition, SourceLocation StartLoc,

Modified: cfe/trunk/lib/AST/DeclOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclOpenMP.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclOpenMP.cpp (original)
+++ cfe/trunk/lib/AST/DeclOpenMP.cpp Tue Mar 12 11:52:33 2019
@@ -59,20 +59,26 @@ void OMPThreadPrivateDecl::setVars(Array
 void OMPAllocateDecl::anchor() { }
 
 OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC,
-                                         SourceLocation L,
-                                         ArrayRef<Expr *> VL) {
-  OMPAllocateDecl *D = new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
+                                         SourceLocation L, ArrayRef<Expr *> VL,
+                                         ArrayRef<OMPClause *> CL) {
+  OMPAllocateDecl *D = new (
+      C, DC, additionalSizeToAlloc<Expr *, OMPClause *>(VL.size(), CL.size()))
       OMPAllocateDecl(OMPAllocate, DC, L);
   D->NumVars = VL.size();
   D->setVars(VL);
+  D->NumClauses = CL.size();
+  D->setClauses(CL);
   return D;
 }
 
 OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
-                                                     unsigned N) {
-  OMPAllocateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
-      OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
-  D->NumVars = N;
+                                                     unsigned NVars,
+                                                     unsigned NClauses) {
+  OMPAllocateDecl *D =
+      new (C, ID, additionalSizeToAlloc<Expr *, OMPClause *>(NVars, NClauses))
+          OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
+  D->NumVars = NVars;
+  D->NumClauses = NClauses;
   return D;
 }
 
@@ -82,6 +88,13 @@ void OMPAllocateDecl::setVars(ArrayRef<E
   std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
 }
 
+void OMPAllocateDecl::setClauses(ArrayRef<OMPClause *> CL) {
+  assert(CL.size() == NumClauses &&
+         "Number of variables is not the same as the preallocated buffer");
+  std::uninitialized_copy(CL.begin(), CL.end(),
+                          getTrailingObjects<OMPClause *>());
+}
+
 //===----------------------------------------------------------------------===//
 // OMPRequiresDecl Implementation.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Mar 12 11:52:33 2019
@@ -1560,6 +1560,12 @@ void DeclPrinter::VisitOMPAllocateDecl(O
     }
     Out << ")";
   }
+  if (!D->clauselist_empty()) {
+    Out << " ";
+    OMPClausePrinter Printer(Out, Policy);
+    for (OMPClause *C : D->clauselists())
+      Printer.Visit(C);
+  }
 }
 
 void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {

Modified: cfe/trunk/lib/AST/OpenMPClause.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/AST/OpenMPClause.cpp (original)
+++ cfe/trunk/lib/AST/OpenMPClause.cpp Tue Mar 12 11:52:33 2019
@@ -73,6 +73,7 @@ const OMPClauseWithPreInit *OMPClauseWit
   case OMPC_final:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_shared:
@@ -145,6 +146,7 @@ const OMPClauseWithPostUpdate *OMPClause
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_shared:
@@ -1086,6 +1088,12 @@ void OMPClausePrinter::VisitOMPSimdlenCl
   OS << ")";
 }
 
+void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
+  OS << "allocator(";
+  Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
 void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
   OS << "collapse(";
   Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Tue Mar 12 11:52:33 2019
@@ -457,6 +457,11 @@ void OMPClauseProfiler::VisitOMPSimdlenC
     Profiler->VisitStmt(C->getSimdlen());
 }
 
+void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
+  if (C->getAllocator())
+    Profiler->VisitStmt(C->getAllocator());
+}
+
 void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
   if (C->getNumForLoops())
     Profiler->VisitStmt(C->getNumForLoops());

Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Tue Mar 12 11:52:33 2019
@@ -155,6 +155,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
@@ -337,6 +338,7 @@ const char *clang::getOpenMPSimpleClause
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
@@ -810,11 +812,20 @@ bool clang::isAllowedClauseForDirective(
       break;
     }
     break;
+  case OMPD_allocate:
+    switch (CKind) {
+#define OPENMP_ALLOCATE_CLAUSE(Name)                                           \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
   case OMPD_declare_target:
   case OMPD_end_declare_target:
   case OMPD_unknown:
   case OMPD_threadprivate:
-  case OMPD_allocate:
   case OMPD_section:
   case OMPD_master:
   case OMPD_taskyield:

Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Tue Mar 12 11:52:33 2019
@@ -3948,6 +3948,7 @@ static void emitOMPAtomicExpr(CodeGenFun
   case OMPC_in_reduction:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_default:
   case OMPC_seq_cst:

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Tue Mar 12 11:52:33 2019
@@ -842,7 +842,7 @@ void Parser::ParseOMPEndDeclareTargetDir
 ///         annot_pragma_openmp_end
 ///
 ///       allocate-directive:
-///         annot_pragma_openmp 'allocate' simple-variable-list
+///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
 ///         annot_pragma_openmp_end
 ///
 ///       declare-reduction-directive:
@@ -897,16 +897,44 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
     DeclDirectiveListParserHelper Helper(this, DKind);
     if (!ParseOpenMPSimpleVarList(DKind, Helper,
                                   /*AllowScopeSpecifier=*/true)) {
-      // The last seen token is annot_pragma_openmp_end - need to check for
-      // extra tokens.
+      SmallVector<OMPClause *, 1> Clauses;
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
-        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-            << getOpenMPDirectiveName(DKind);
-        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
+                    OMPC_unknown + 1>
+            FirstClauses(OMPC_unknown + 1);
+        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+          OpenMPClauseKind CKind =
+              Tok.isAnnotation() ? OMPC_unknown
+                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
+          Actions.StartOpenMPClause(CKind);
+          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
+                                                !FirstClauses[CKind].getInt());
+          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+                    StopBeforeMatch);
+          FirstClauses[CKind].setInt(true);
+          if (Clause != nullptr)
+            Clauses.push_back(Clause);
+          if (Tok.is(tok::annot_pragma_openmp_end)) {
+            Actions.EndOpenMPClause();
+            break;
+          }
+          // Skip ',' if any.
+          if (Tok.is(tok::comma))
+            ConsumeToken();
+          Actions.EndOpenMPClause();
+        }
+        // The last seen token is annot_pragma_openmp_end - need to check for
+        // extra tokens.
+        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+              << getOpenMPDirectiveName(DKind);
+          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+        }
       }
       // Skip the last annot_pragma_openmp_end.
       ConsumeAnnotationToken();
-      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
+      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
+                                                  Clauses);
     }
     break;
   }
@@ -925,9 +953,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
                                    ? OMPC_unknown
                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
       Actions.StartOpenMPClause(CKind);
-      OMPClause *Clause =
-          ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
-      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
+      OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
+                                            !FirstClauses[CKind].getInt());
+      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+                StopBeforeMatch);
       FirstClauses[CKind].setInt(true);
       if (Clause != nullptr)
         Clauses.push_back(Clause);
@@ -1214,15 +1243,42 @@ Parser::ParseOpenMPDeclarativeOrExecutab
     DeclDirectiveListParserHelper Helper(this, DKind);
     if (!ParseOpenMPSimpleVarList(DKind, Helper,
                                   /*AllowScopeSpecifier=*/false)) {
-      // The last seen token is annot_pragma_openmp_end - need to check for
-      // extra tokens.
+      SmallVector<OMPClause *, 1> Clauses;
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
-        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-            << getOpenMPDirectiveName(DKind);
-        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
+                    OMPC_unknown + 1>
+            FirstClauses(OMPC_unknown + 1);
+        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+          OpenMPClauseKind CKind =
+              Tok.isAnnotation() ? OMPC_unknown
+                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
+          Actions.StartOpenMPClause(CKind);
+          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
+                                                !FirstClauses[CKind].getInt());
+          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+                    StopBeforeMatch);
+          FirstClauses[CKind].setInt(true);
+          if (Clause != nullptr)
+            Clauses.push_back(Clause);
+          if (Tok.is(tok::annot_pragma_openmp_end)) {
+            Actions.EndOpenMPClause();
+            break;
+          }
+          // Skip ',' if any.
+          if (Tok.is(tok::comma))
+            ConsumeToken();
+          Actions.EndOpenMPClause();
+        }
+        // The last seen token is annot_pragma_openmp_end - need to check for
+        // extra tokens.
+        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+              << getOpenMPDirectiveName(DKind);
+          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+        }
       }
-      DeclGroupPtrTy Res =
-          Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
+      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
+          Loc, Helper.getIdentifiers(), Clauses);
       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
     }
     SkipUntil(tok::annot_pragma_openmp_end);
@@ -1506,7 +1562,7 @@ bool Parser::ParseOpenMPSimpleVarList(
 ///       thread_limit-clause | priority-clause | grainsize-clause |
 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
-///       in_reduction-clause
+///       in_reduction-clause | allocator-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
@@ -1535,6 +1591,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   case OMPC_grainsize:
   case OMPC_num_tasks:
   case OMPC_hint:
+  case OMPC_allocator:
     // OpenMP [2.5, Restrictions]
     //  At most one num_threads clause can appear on the directive.
     // OpenMP [2.8.1, simd construct, Restrictions]
@@ -1555,6 +1612,8 @@ OMPClause *Parser::ParseOpenMPClause(Ope
     // At most one grainsize clause can appear on the directive.
     // OpenMP [2.9.2, taskloop Construct, Restrictions]
     // At most one num_tasks clause can appear on the directive.
+    // OpenMP [2.11.3, allocate Directive, Restrictions]
+    // At most one allocator clause can appear on the directive.
     if (!FirstClause) {
       Diag(Tok, diag::err_omp_more_one_clause)
           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
@@ -1722,6 +1781,9 @@ ExprResult Parser::ParseOpenMPParensExpr
 ///    hint-clause:
 ///      'hint' '(' expression ')'
 ///
+///    allocator-clause:
+///      'allocator' '(' expression ')'
+///
 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
                                                bool ParseOnly) {
   SourceLocation Loc = ConsumeToken();

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Mar 12 11:52:33 2019
@@ -2194,9 +2194,13 @@ Sema::CheckOMPThreadPrivateDecl(SourceLo
   return D;
 }
 
-Sema::DeclGroupPtrTy
-Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
-                                   DeclContext *Owner) {
+Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
+    SourceLocation Loc, ArrayRef<Expr *> VarList,
+    ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
+  assert(Clauses.size() <= 1 && "Expected at most one clause.");
+  Expr *Allocator = nullptr;
+  if (!Clauses.empty())
+    Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
   SmallVector<Expr *, 8> Vars;
   for (Expr *RefExpr : VarList) {
     auto *DE = cast<DeclRefExpr>(RefExpr);
@@ -2213,17 +2217,18 @@ Sema::ActOnOpenMPAllocateDirective(Sourc
       continue;
 
     Vars.push_back(RefExpr);
-    VD->addAttr(
-        OMPAllocateDeclAttr::CreateImplicit(Context, DE->getSourceRange()));
+    Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator,
+                                                  DE->getSourceRange());
+    VD->addAttr(A);
     if (ASTMutationListener *ML = Context.getASTMutationListener())
-      ML->DeclarationMarkedOpenMPAllocate(VD,
-                                          VD->getAttr<OMPAllocateDeclAttr>());
+      ML->DeclarationMarkedOpenMPAllocate(VD, A);
   }
   if (Vars.empty())
     return nullptr;
   if (!Owner)
     Owner = getCurLexicalContext();
-  OMPAllocateDecl *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars);
+  OMPAllocateDecl *D =
+      OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
   D->setAccess(AS_public);
   Owner->addDecl(D);
   return DeclGroupPtrTy::make(DeclGroupRef(D));
@@ -8436,6 +8441,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
   case OMPC_simdlen:
     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_allocator:
+    Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_collapse:
     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
     break;
@@ -9009,6 +9017,7 @@ static OpenMPDirectiveKind getOpenMPCapt
   case OMPC_final:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_private:
   case OMPC_shared:
@@ -9259,6 +9268,43 @@ OMPClause *Sema::ActOnOpenMPSimdlenClaus
       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
 }
 
+/// Tries to find omp_allocator_handle_t type.
+static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
+                                    QualType &OMPAllocatorHandleT) {
+  if (!OMPAllocatorHandleT.isNull())
+    return true;
+  DeclarationName OMPAllocatorHandleTName =
+      &S.getASTContext().Idents.get("omp_allocator_handle_t");
+  auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName(
+      S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName));
+  if (!TD) {
+    S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
+    return false;
+  }
+  OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD);
+  return true;
+}
+
+OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
+                                            SourceLocation LParenLoc,
+                                            SourceLocation EndLoc) {
+  // OpenMP [2.11.3, allocate Directive, Description]
+  // allocator is an expression of omp_allocator_handle_t type.
+  if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT))
+    return nullptr;
+
+  ExprResult Allocator = DefaultLvalueConversion(A);
+  if (Allocator.isInvalid())
+    return nullptr;
+  Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT,
+                                        Sema::AA_Initializing,
+                                        /*AllowExplicit=*/true);
+  if (Allocator.isInvalid())
+    return nullptr;
+  return new (Context)
+      OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
                                            SourceLocation StartLoc,
                                            SourceLocation LParenLoc,
@@ -9326,6 +9372,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_schedule:
   case OMPC_private:
@@ -9503,6 +9550,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWi
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_default:
   case OMPC_proc_bind:
@@ -9724,6 +9772,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenM
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_schedule:
   case OMPC_private:
@@ -9928,6 +9977,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_default:
   case OMPC_proc_bind:

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Mar 12 11:52:33 2019
@@ -2883,9 +2883,20 @@ Decl *TemplateDeclInstantiator::VisitOMP
     assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr");
     Vars.push_back(Var);
   }
+  SmallVector<OMPClause *, 4> Clauses;
+  // Copy map clauses from the original mapper.
+  for (OMPClause *C : D->clauselists()) {
+    auto *AC = cast<OMPAllocatorClause>(C);
+    ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
+    if (!NewE.isUsable())
+      continue;
+    OMPClause *IC = SemaRef.ActOnOpenMPAllocatorClause(
+        NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
+    Clauses.push_back(IC);
+  }
 
-  Sema::DeclGroupPtrTy Res =
-      SemaRef.ActOnOpenMPAllocateDirective(D->getLocation(), Vars, Owner);
+  Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective(
+      D->getLocation(), Vars, Clauses, Owner);
   if (Res.get().isNull())
     return nullptr;
   return Res.get().getSingleDecl();

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Mar 12 11:52:33 2019
@@ -1554,6 +1554,16 @@ public:
     return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
   }
 
+  /// Build a new OpenMP 'allocator' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
+  }
+
   /// Build a new OpenMP 'collapse' clause.
   ///
   /// By default, performs semantic analysis to build the new OpenMP clause.
@@ -8343,6 +8353,16 @@ TreeTransform<Derived>::TransformOMPSafe
       E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
 }
 
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getAllocator());
+  if (E.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPAllocatorClause(
+      E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+}
+
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 12 11:52:33 2019
@@ -11704,6 +11704,9 @@ OMPClause *OMPClauseReader::readClause()
   case OMPC_simdlen:
     C = new (Context) OMPSimdlenClause();
     break;
+  case OMPC_allocator:
+    C = new (Context) OMPAllocatorClause();
+    break;
   case OMPC_collapse:
     C = new (Context) OMPCollapseClause();
     break;
@@ -11929,6 +11932,11 @@ void OMPClauseReader::VisitOMPSimdlenCla
   C->setLParenLoc(Record.readSourceLocation());
 }
 
+void OMPClauseReader::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
+  C->setAllocator(Record.readExpr());
+  C->setLParenLoc(Record.readSourceLocation());
+}
+
 void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
   C->setNumForLoops(Record.readSubExpr());
   C->setLParenLoc(Record.readSourceLocation());

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Mar 12 11:52:33 2019
@@ -2637,12 +2637,19 @@ void ASTDeclReader::VisitOMPThreadPrivat
 void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
   VisitDecl(D);
   unsigned NumVars = D->varlist_size();
+  unsigned NumClauses = D->clauselist_size();
   SmallVector<Expr *, 16> Vars;
   Vars.reserve(NumVars);
   for (unsigned i = 0; i != NumVars; ++i) {
     Vars.push_back(Record.readExpr());
   }
   D->setVars(Vars);
+  SmallVector<OMPClause *, 8> Clauses;
+  Clauses.reserve(NumClauses);
+  OMPClauseReader ClauseReader(Record);
+  for (unsigned I = 0; I != NumClauses; ++I)
+    Clauses.push_back(ClauseReader.readClause());
+  D->setClauses(Clauses);
 }
 
 void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
@@ -3878,9 +3885,12 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
   case DECL_OMP_THREADPRIVATE:
     D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
-  case DECL_OMP_ALLOCATE:
-    D = OMPAllocateDecl::CreateDeserialized(Context, ID, Record.readInt());
+  case DECL_OMP_ALLOCATE: {
+    unsigned NumVars = Record.readInt();
+    unsigned NumClauses = Record.readInt();
+    D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses);
     break;
+  }
   case DECL_OMP_REQUIRES:
     D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
     break;
@@ -4481,8 +4491,8 @@ void ASTDeclReader::UpdateDecl(Decl *D,
       break;
 
     case UPD_DECL_MARKED_OPENMP_ALLOCATE:
-      D->addAttr(OMPAllocateDeclAttr::CreateImplicit(Reader.getContext(),
-                                                     ReadSourceRange()));
+      D->addAttr(OMPAllocateDeclAttr::CreateImplicit(
+          Reader.getContext(), Record.readExpr(), ReadSourceRange()));
       break;
 
     case UPD_DECL_EXPORTED: {

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 12 11:52:33 2019
@@ -5291,6 +5291,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(R
         break;
 
       case UPD_DECL_MARKED_OPENMP_ALLOCATE:
+        Record.AddStmt(D->getAttr<OMPAllocateDeclAttr>()->getAllocator());
         Record.AddSourceRange(D->getAttr<OMPAllocateDeclAttr>()->getRange());
         break;
 
@@ -6534,6 +6535,11 @@ void OMPClauseWriter::VisitOMPSimdlenCla
   Record.AddSourceLocation(C->getLParenLoc());
 }
 
+void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
+  Record.AddStmt(C->getAllocator());
+  Record.AddSourceLocation(C->getLParenLoc());
+}
+
 void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
   Record.AddStmt(C->getNumForLoops());
   Record.AddSourceLocation(C->getLParenLoc());

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Mar 12 11:52:33 2019
@@ -1747,9 +1747,13 @@ void ASTDeclWriter::VisitOMPThreadPrivat
 
 void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
   Record.push_back(D->varlist_size());
+  Record.push_back(D->clauselist_size());
   VisitDecl(D);
   for (auto *I : D->varlists())
     Record.AddStmt(I);
+  OMPClauseWriter ClauseWriter(Record);
+  for (OMPClause *C : D->clauselists())
+    ClauseWriter.writeClause(C);
   Code = serialization::DECL_OMP_ALLOCATE;
 }
 

Added: cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp?rev=355952&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp (added)
+++ cfe/trunk/test/OpenMP/allocate_allocator_ast_print.cpp Tue Mar 12 11:52:33 2019
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+// CHECK: static int b;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(St1::b) allocator(omp_default_mem_alloc){{$}}
+} d;
+
+int a, b;
+// CHECK: int a;
+// CHECK: int b;
+#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(a) allocator(omp_const_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_const_mem_alloc)
+#pragma omp allocate(d, b) allocator(omp_high_bw_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(d,b) allocator(omp_high_bw_mem_alloc)
+
+template <class T>
+struct ST {
+  static T m;
+  #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
+};
+
+template <class T> T foo() {
+  T v;
+  #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+  v = ST<T>::m;
+  return v;
+}
+//CHECK: template <class T> T foo() {
+//CHECK-NEXT: T v;
+//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+//CHECK: template<> int foo<int>() {
+//CHECK-NEXT: int v;
+//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+
+namespace ns{
+  int a;
+}
+// CHECK: namespace ns {
+// CHECK-NEXT: int a;
+// CHECK-NEXT: }
+#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+
+int main () {
+  static int a;
+// CHECK: static int a;
+#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+  a=2;
+  return (foo<int>());
+}
+
+extern template int ST<int>::m;
+#endif

Added: cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp?rev=355952&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/allocate_allocator_messages.cpp Tue Mar 12 11:52:33 2019
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 -o - %s
+
+struct St{
+ int a;
+};
+
+int sss;
+#pragma omp allocate(sss) allocate // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(sss) allocator // expected-error {{expected '(' after 'allocator'}}
+#pragma omp allocate(sss) allocator(0,  // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(0,sss  // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(0,sss)  // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(sss)  // expected-error {{omp_allocator_handle_t type not found; include <omp.h>}}
+
+typedef void *omp_allocator_handle_t;
+
+struct St1{
+ int a;
+ static int b;
+#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'omp_allocator_handle_t' (aka 'void *') with an expression of incompatible type 'int'}}
+} d;
+
+#pragma omp allocate(d) allocator(nullptr)
+extern void *allocator;
+#pragma omp allocate(d) allocator(allocator)

Modified: cfe/trunk/test/PCH/chain-openmp-allocate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/chain-openmp-allocate.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/test/PCH/chain-openmp-allocate.cpp (original)
+++ cfe/trunk/test/PCH/chain-openmp-allocate.cpp Tue Mar 12 11:52:33 2019
@@ -12,14 +12,17 @@
 #if !defined(PASS1)
 #define PASS1
 
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+
 int a;
 // CHECK: int a;
 
 #elif !defined(PASS2)
 #define PASS2
 
-#pragma omp allocate(a)
-// CHECK: #pragma omp allocate(a)
+#pragma omp allocate(a) allocator(omp_default_mem_alloc)
+// CHECK: #pragma omp allocate(a) allocator(omp_default_mem_alloc)
 
 #else
 

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=355952&r1=355951&r2=355952&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Mar 12 11:52:33 2019
@@ -2168,6 +2168,10 @@ void OMPClauseEnqueue::VisitOMPSimdlenCl
   Visitor->AddStmt(C->getSimdlen());
 }
 
+void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
+  Visitor->AddStmt(C->getAllocator());
+}
+
 void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
   Visitor->AddStmt(C->getNumForLoops());
 }




More information about the cfe-commits mailing list