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

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

llvm-svn: 355952
diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp
index f50775b..af32128 100644
--- a/clang/lib/AST/DeclOpenMP.cpp
+++ b/clang/lib/AST/DeclOpenMP.cpp
@@ -59,20 +59,26 @@
 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 @@
   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.
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index d023a03..2009673 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -1560,6 +1560,12 @@
     }
     Out << ")";
   }
+  if (!D->clauselist_empty()) {
+    Out << " ";
+    OMPClausePrinter Printer(Out, Policy);
+    for (OMPClause *C : D->clauselists())
+      Printer.Visit(C);
+  }
 }
 
 void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 4016dd0..5ee10fb 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -73,6 +73,7 @@
   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 @@
   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 @@
   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);
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index c064ea9..53655a1 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -457,6 +457,11 @@
     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());