[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/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 32e493e..68ee887 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2194,9 +2194,13 @@
   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 @@
       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 @@
   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 @@
   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 @@
       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 @@
   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 @@
   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 @@
   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 @@
   case OMPC_num_threads:
   case OMPC_safelen:
   case OMPC_simdlen:
+  case OMPC_allocator:
   case OMPC_collapse:
   case OMPC_default:
   case OMPC_proc_bind: