<div dir="ltr">This breaks my build (I have modules enabled).<div><br></div><div>DeclOpenMP.h uses ASTContext while it's still incomplete.</div><div>Could you please fix this?</div><div><br></div><div>/Eric</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Feb 1, 2019 at 3:24 PM Michael Kruse via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: meinersbur<br>
Date: Fri Feb  1 12:25:04 2019<br>
New Revision: 352906<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=352906&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=352906&view=rev</a><br>
Log:<br>
[OpenMP 5.0] Parsing/sema support for "omp declare mapper" directive.<br>
<br>
This patch implements parsing and sema for "omp declare mapper"<br>
directive. User defined mapper, i.e., declare mapper directive, is a new<br>
feature in OpenMP 5.0. It is introduced to extend existing map clauses<br>
for the purpose of simplifying the copy of complex data structures<br>
between host and device (i.e., deep copy). An example is shown below:<br>
<br>
    struct S {  int len;  int *d; };<br>
    #pragma omp declare mapper(struct S s) map(s, s.d[0:s.len]) // Memory region that d points to is also mapped using this mapper.<br>
<br>
Contributed-by: Lingda Li <<a href="mailto:lildmh@gmail.com" target="_blank">lildmh@gmail.com</a>><br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D56326" rel="noreferrer" target="_blank">https://reviews.llvm.org/D56326</a><br>
<br>
Added:<br>
    cfe/trunk/test/OpenMP/declare_mapper_ast_print.c<br>
    cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp<br>
    cfe/trunk/test/OpenMP/declare_mapper_messages.c<br>
    cfe/trunk/test/OpenMP/declare_mapper_messages.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/DeclBase.h<br>
    cfe/trunk/include/clang/AST/DeclCXX.h<br>
    cfe/trunk/include/clang/AST/DeclOpenMP.h<br>
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/Basic/DeclNodes.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
    cfe/trunk/include/clang/Parse/Parser.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/ASTDumper.cpp<br>
    cfe/trunk/lib/AST/CXXInheritance.cpp<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
    cfe/trunk/lib/AST/DeclOpenMP.cpp<br>
    cfe/trunk/lib/AST/DeclPrinter.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/AST/MicrosoftMangle.cpp<br>
    cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
    cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
    cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>
    cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
    cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaLookup.cpp<br>
    cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
    cfe/trunk/lib/Serialization/ASTCommon.cpp<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
    cfe/trunk/tools/libclang/CIndex.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Feb  1 12:25:04 2019<br>
@@ -175,7 +175,10 @@ public:<br>
     IDNS_LocalExtern         = 0x0800,<br>
<br>
     /// This declaration is an OpenMP user defined reduction construction.<br>
-    IDNS_OMPReduction        = 0x1000<br>
+    IDNS_OMPReduction        = 0x1000,<br>
+<br>
+    /// This declaration is an OpenMP user defined mapper.<br>
+    IDNS_OMPMapper           = 0x2000,<br>
   };<br>
<br>
   /// ObjCDeclQualifier - 'Qualifiers' written next to the return and<br>
@@ -323,7 +326,7 @@ protected:<br>
   unsigned FromASTFile : 1;<br>
<br>
   /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.<br>
-  unsigned IdentifierNamespace : 13;<br>
+  unsigned IdentifierNamespace : 14;<br>
<br>
   /// If 0, we have not computed the linkage of this declaration.<br>
   /// Otherwise, it is the linkage + 1.<br>
@@ -1251,6 +1254,7 @@ public:<br>
 ///   NamespaceDecl<br>
 ///   TagDecl<br>
 ///   OMPDeclareReductionDecl<br>
+///   OMPDeclareMapperDecl<br>
 ///   FunctionDecl<br>
 ///   ObjCMethodDecl<br>
 ///   ObjCContainerDecl<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclCXX.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Feb  1 12:25:04 2019<br>
@@ -1828,6 +1828,14 @@ public:<br>
                                      CXXBasePath &Path, DeclarationName Name);<br>
<br>
   /// Base-class lookup callback that determines whether there exists<br>
+  /// an OpenMP declare mapper member with the given name.<br>
+  ///<br>
+  /// This callback can be used with \c lookupInBases() to find members<br>
+  /// of the given name within a C++ class hierarchy.<br>
+  static bool FindOMPMapperMember(const CXXBaseSpecifier *Specifier,<br>
+                                  CXXBasePath &Path, DeclarationName Name);<br>
+<br>
+  /// Base-class lookup callback that determines whether there exists<br>
   /// a member with the given name that can be used in a nested-name-specifier.<br>
   ///<br>
   /// This callback can be used with \c lookupInBases() to find members of<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclOpenMP.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclOpenMP.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclOpenMP.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclOpenMP.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclOpenMP.h Fri Feb  1 12:25:04 2019<br>
@@ -206,6 +206,108 @@ public:<br>
   }<br>
 };<br>
<br>
+/// This represents '#pragma omp declare mapper ...' directive. Map clauses are<br>
+/// allowed to use with this directive. The following example declares a user<br>
+/// defined mapper for the type 'struct vec'. This example instructs the fields<br>
+/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.<br>
+///<br>
+/// \code<br>
+/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])<br>
+/// \endcode<br>
+class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {<br>
+  friend class ASTDeclReader;<br>
+<br>
+  /// Clauses assoicated with this mapper declaration<br>
+  MutableArrayRef<OMPClause *> Clauses;<br>
+<br>
+  /// Mapper variable, which is 'v' in the example above<br>
+  Expr *MapperVarRef = nullptr;<br>
+<br>
+  /// Name of the mapper variable<br>
+  DeclarationName VarName;<br>
+<br>
+  LazyDeclPtr PrevDeclInScope;<br>
+<br>
+  virtual void anchor();<br>
+<br>
+  OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L,<br>
+                       DeclarationName Name, QualType Ty,<br>
+                       DeclarationName VarName,<br>
+                       OMPDeclareMapperDecl *PrevDeclInScope)<br>
+      : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName),<br>
+        PrevDeclInScope(PrevDeclInScope) {}<br>
+<br>
+  void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {<br>
+    PrevDeclInScope = Prev;<br>
+  }<br>
+<br>
+  /// Sets an array of clauses to this mapper declaration<br>
+  void setClauses(ArrayRef<OMPClause *> CL);<br>
+<br>
+public:<br>
+  /// Creates declare mapper node.<br>
+  static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,<br>
+                                      SourceLocation L, DeclarationName Name,<br>
+                                      QualType T, DeclarationName VarName,<br>
+                                      OMPDeclareMapperDecl *PrevDeclInScope);<br>
+  /// Creates deserialized declare mapper node.<br>
+  static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,<br>
+                                                  unsigned N);<br>
+<br>
+  /// Creates an array of clauses to this mapper declaration and intializes<br>
+  /// them.<br>
+  void CreateClauses(ASTContext &C, ArrayRef<OMPClause *> CL);<br>
+<br>
+  using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;<br>
+  using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;<br>
+  using clauselist_range = llvm::iterator_range<clauselist_iterator>;<br>
+  using clauselist_const_range =<br>
+      llvm::iterator_range<clauselist_const_iterator>;<br>
+<br>
+  unsigned clauselist_size() const { return Clauses.size(); }<br>
+  bool clauselist_empty() const { return Clauses.empty(); }<br>
+<br>
+  clauselist_range clauselists() {<br>
+    return clauselist_range(clauselist_begin(), clauselist_end());<br>
+  }<br>
+  clauselist_const_range clauselists() const {<br>
+    return clauselist_const_range(clauselist_begin(), clauselist_end());<br>
+  }<br>
+  clauselist_iterator clauselist_begin() { return Clauses.begin(); }<br>
+  clauselist_iterator clauselist_end() { return Clauses.end(); }<br>
+  clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); }<br>
+  clauselist_const_iterator clauselist_end() const { return Clauses.end(); }<br>
+<br>
+  /// Get the variable declared in the mapper<br>
+  Expr *getMapperVarRef() { return MapperVarRef; }<br>
+  const Expr *getMapperVarRef() const { return MapperVarRef; }<br>
+  /// Set the variable declared in the mapper<br>
+  void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; }<br>
+<br>
+  /// Get the name of the variable declared in the mapper<br>
+  DeclarationName getVarName() { return VarName; }<br>
+<br>
+  /// Get reference to previous declare mapper construct in the same<br>
+  /// scope with the same name.<br>
+  OMPDeclareMapperDecl *getPrevDeclInScope() {<br>
+    return cast_or_null<OMPDeclareMapperDecl>(<br>
+        PrevDeclInScope.get(getASTContext().getExternalSource()));<br>
+  }<br>
+  const OMPDeclareMapperDecl *getPrevDeclInScope() const {<br>
+    return cast_or_null<OMPDeclareMapperDecl>(<br>
+        PrevDeclInScope.get(getASTContext().getExternalSource()));<br>
+  }<br>
+<br>
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }<br>
+  static bool classofKind(Kind K) { return K == OMPDeclareMapper; }<br>
+  static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {<br>
+    return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));<br>
+  }<br>
+  static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {<br>
+    return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));<br>
+  }<br>
+};<br>
+<br>
 /// Pseudo declaration for capturing expressions. Also is used for capturing of<br>
 /// non-static data members in non-static member functions.<br>
 ///<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Feb  1 12:25:04 2019<br>
@@ -1590,7 +1590,7 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl,<br>
     TRY_TO(TraverseStmt(I));<br>
   }<br>
  })<br>
- <br>
+<br>
 DEF_TRAVERSE_DECL(OMPRequiresDecl, {<br>
   for (auto *C : D->clauselists()) {<br>
     TRY_TO(TraverseOMPClause(C));<br>
@@ -1604,6 +1604,13 @@ DEF_TRAVERSE_DECL(OMPDeclareReductionDec<br>
   TRY_TO(TraverseType(D->getType()));<br>
   return true;<br>
 })<br>
+<br>
+DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {<br>
+  for (auto *C : D->clauselists())<br>
+    TRY_TO(TraverseOMPClause(C));<br>
+  TRY_TO(TraverseType(D->getType()));<br>
+  return true;<br>
+})<br>
<br>
 DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DeclNodes.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Fri Feb  1 12:25:04 2019<br>
@@ -41,6 +41,7 @@ def Named : Decl<"named declarations", 1<br>
     def IndirectField : DDecl<Value>;<br>
     def Binding : DDecl<Value>;<br>
     def OMPDeclareReduction : DDecl<Value>, DeclContext;<br>
+    def OMPDeclareMapper : DDecl<Value>, DeclContext;<br>
     def Declarator : DDecl<Value, "declarators", 1>;<br>
       def Field : DDecl<Declarator, "non-static data members">;<br>
         def ObjCIvar : DDecl<Field>;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Feb  1 12:25:04 2019<br>
@@ -1176,6 +1176,10 @@ def err_omp_declare_target_unexpected_cl<br>
   "unexpected '%0' clause, only 'to' or 'link' clauses expected">;<br>
 def err_omp_expected_clause: Error<<br>
   "expected at least one clause on '#pragma omp %0' directive">;<br>
+def err_omp_mapper_illegal_identifier : Error<<br>
+  "illegal identifier on 'omp declare mapper' directive">;<br>
+def err_omp_mapper_expected_declarator : Error<<br>
+  "expected declarator on 'omp declare mapper' directive">;<br>
<br>
 // Pragma loop support.<br>
 def err_pragma_loop_missing_argument : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb  1 12:25:04 2019<br>
@@ -8977,6 +8977,12 @@ def err_omp_parent_cancel_region_ordered<br>
 def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">;<br>
 def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">;<br>
 def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">;<br>
+def err_omp_mapper_wrong_type : Error<<br>
+  "mapper type must be of struct, union or class type">;<br>
+def err_omp_declare_mapper_wrong_var : Error<<br>
+  "only variable %0 is allowed in map clauses of this 'omp declare mapper' directive">;<br>
+def err_omp_declare_mapper_redefinition : Error<<br>
+  "redefinition of user-defined mapper for type %0 with name %1">;<br>
 def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;<br>
 def err_omp_typecheck_section_value : Error<<br>
   "subscripted value is not an array or pointer">;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)<br>
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Fri Feb  1 12:25:04 2019<br>
@@ -179,6 +179,9 @@<br>
 #ifndef OPENMP_TASKGROUP_CLAUSE<br>
 #define OPENMP_TASKGROUP_CLAUSE(Name)<br>
 #endif<br>
+#ifndef OPENMP_DECLARE_MAPPER_CLAUSE<br>
+#define OPENMP_DECLARE_MAPPER_CLAUSE(Name)<br>
+#endif<br>
<br>
 // OpenMP directives.<br>
 OPENMP_DIRECTIVE(threadprivate)<br>
@@ -214,6 +217,7 @@ OPENMP_DIRECTIVE_EXT(parallel_sections,<br>
 OPENMP_DIRECTIVE_EXT(for_simd, "for simd")<br>
 OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point")<br>
 OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction")<br>
+OPENMP_DIRECTIVE_EXT(declare_mapper, "declare mapper")<br>
 OPENMP_DIRECTIVE_EXT(declare_simd, "declare simd")<br>
 OPENMP_DIRECTIVE(taskloop)<br>
 OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd")<br>
@@ -887,6 +891,10 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAU<br>
 // Clauses allowed for OpenMP directive 'taskgroup'.<br>
 OPENMP_TASKGROUP_CLAUSE(task_reduction)<br>
<br>
+// Clauses allowed for OpenMP directive 'declare mapper'.<br>
+OPENMP_DECLARE_MAPPER_CLAUSE(map)<br>
+<br>
+#undef OPENMP_DECLARE_MAPPER_CLAUSE<br>
 #undef OPENMP_TASKGROUP_CLAUSE<br>
 #undef OPENMP_TASKLOOP_SIMD_CLAUSE<br>
 #undef OPENMP_TASKLOOP_CLAUSE<br>
<br>
Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Feb  1 12:25:04 2019<br>
@@ -2803,6 +2803,13 @@ private:<br>
   /// initializer.<br>
   void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);<br>
<br>
+  /// Parses 'omp declare mapper' directive.<br>
+  DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);<br>
+  /// Parses variable declaration in 'omp declare mapper' directive.<br>
+  TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range,<br>
+                                             DeclarationName &Name,<br>
+                                             AccessSpecifier AS = AS_none);<br>
+<br>
   /// Parses simple list of variables.<br>
   ///<br>
   /// \param Kind Kind of the directive.<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb  1 12:25:04 2019<br>
@@ -3155,6 +3155,8 @@ public:<br>
     LookupObjCImplicitSelfParam,<br>
     /// Look up the name of an OpenMP user-defined reduction operation.<br>
     LookupOMPReductionName,<br>
+    /// Look up the name of an OpenMP user-defined mapper.<br>
+    LookupOMPMapperName,<br>
     /// Look up any declaration with any name.<br>
     LookupAnyName<br>
   };<br>
@@ -8870,6 +8872,27 @@ public:<br>
   DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(<br>
       Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid);<br>
<br>
+  /// Check variable declaration in 'omp declare mapper' construct.<br>
+  TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D);<br>
+  /// Check if the specified type is allowed to be used in 'omp declare<br>
+  /// mapper' construct.<br>
+  QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,<br>
+                                        TypeResult ParsedType);<br>
+  /// Called on start of '#pragma omp declare mapper'.<br>
+  OMPDeclareMapperDecl *ActOnOpenMPDeclareMapperDirectiveStart(<br>
+      Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,<br>
+      SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,<br>
+      Decl *PrevDeclInScope = nullptr);<br>
+  /// Build the mapper variable of '#pragma omp declare mapper'.<br>
+  void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,<br>
+                                                Scope *S, QualType MapperType,<br>
+                                                SourceLocation StartLoc,<br>
+                                                DeclarationName VN);<br>
+  /// Called at the end of '#pragma omp declare mapper'.<br>
+  DeclGroupPtrTy<br>
+  ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,<br>
+                                       ArrayRef<OMPClause *> ClauseList);<br>
+<br>
   /// Called on the start of target region i.e. '#pragma omp declare target'.<br>
   bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc);<br>
   /// Called at the end of target region i.e. '#pragme omp end declare target'.<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Feb  1 12:25:04 2019<br>
@@ -1537,6 +1537,9 @@ namespace serialization {<br>
       /// A PragmaDetectMismatchDecl record.<br>
       DECL_PRAGMA_DETECT_MISMATCH,<br>
<br>
+      /// An OMPDeclareMapperDecl record.<br>
+      DECL_OMP_DECLARE_MAPPER,<br>
+<br>
       /// An OMPDeclareReductionDecl record.<br>
       DECL_OMP_DECLARE_REDUCTION,<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/ASTDumper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTDumper.cpp Fri Feb  1 12:25:04 2019<br>
@@ -381,6 +381,11 @@ namespace  {<br>
         Visit(Initializer);<br>
     }<br>
<br>
+    void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {<br>
+      for (const auto *C : D->clauselists())<br>
+        Visit(C);<br>
+    }<br>
+<br>
     void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {<br>
       Visit(D->getInit());<br>
     }<br>
<br>
Modified: cfe/trunk/lib/AST/CXXInheritance.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXInheritance.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/CXXInheritance.cpp (original)<br>
+++ cfe/trunk/lib/AST/CXXInheritance.cpp Fri Feb  1 12:25:04 2019<br>
@@ -486,6 +486,21 @@ bool CXXRecordDecl::FindOMPReductionMemb<br>
   return false;<br>
 }<br>
<br>
+bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier,<br>
+                                        CXXBasePath &Path,<br>
+                                        DeclarationName Name) {<br>
+  RecordDecl *BaseRecord =<br>
+      Specifier->getType()->castAs<RecordType>()->getDecl();<br>
+<br>
+  for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();<br>
+       Path.Decls = Path.Decls.slice(1)) {<br>
+    if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper))<br>
+      return true;<br>
+  }<br>
+<br>
+  return false;<br>
+}<br>
+<br>
 bool CXXRecordDecl::<br>
 FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,<br>
                               CXXBasePath &Path,<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Feb  1 12:25:04 2019<br>
@@ -780,6 +780,9 @@ unsigned Decl::getIdentifierNamespaceFor<br>
     case OMPDeclareReduction:<br>
       return IDNS_OMPReduction;<br>
<br>
+    case OMPDeclareMapper:<br>
+      return IDNS_OMPMapper;<br>
+<br>
     // Never have names.<br>
     case Friend:<br>
     case FriendTemplate:<br>
@@ -1163,6 +1166,7 @@ DeclContext *DeclContext::getPrimaryCont<br>
   case Decl::Block:<br>
   case Decl::Captured:<br>
   case Decl::OMPDeclareReduction:<br>
+  case Decl::OMPDeclareMapper:<br>
     // There is only one DeclContext for these entities.<br>
     return this;<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/DeclOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclOpenMP.cpp Fri Feb  1 12:25:04 2019<br>
@@ -123,6 +123,56 @@ OMPDeclareReductionDecl::getPrevDeclInSc<br>
 }<br>
<br>
 //===----------------------------------------------------------------------===//<br>
+// OMPDeclareMapperDecl Implementation.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+void OMPDeclareMapperDecl::anchor() {}<br>
+<br>
+OMPDeclareMapperDecl *<br>
+OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,<br>
+                             DeclarationName Name, QualType T,<br>
+                             DeclarationName VarName,<br>
+                             OMPDeclareMapperDecl *PrevDeclInScope) {<br>
+  return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,<br>
+                                          VarName, PrevDeclInScope);<br>
+}<br>
+<br>
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,<br>
+                                                               unsigned ID,<br>
+                                                               unsigned N) {<br>
+  auto *D = new (C, ID)<br>
+      OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),<br>
+                           DeclarationName(), QualType(), DeclarationName(),<br>
+                           /*PrevDeclInScope=*/nullptr);<br>
+  if (N) {<br>
+    auto **ClauseStorage = C.Allocate<OMPClause *>(N);<br>
+    D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);<br>
+  }<br>
+  return D;<br>
+}<br>
+<br>
+/// Creates an array of clauses to this mapper declaration and intializes<br>
+/// them. The space used to store clause pointers is dynamically allocated,<br>
+/// because we do not know the number of clauses when creating<br>
+/// OMPDeclareMapperDecl<br>
+void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,<br>
+                                         ArrayRef<OMPClause *> CL) {<br>
+  assert(Clauses.empty() && "Number of clauses should be 0 on initialization");<br>
+  size_t NumClauses = CL.size();<br>
+  if (NumClauses) {<br>
+    auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);<br>
+    Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);<br>
+    setClauses(CL);<br>
+  }<br>
+}<br>
+<br>
+void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {<br>
+  assert(CL.size() == Clauses.size() &&<br>
+         "Number of clauses is not the same as the preallocated buffer");<br>
+  std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
 // OMPCapturedExprDecl Implementation.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/DeclPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Fri Feb  1 12:25:04 2019<br>
@@ -101,6 +101,7 @@ namespace {<br>
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);<br>
     void VisitOMPRequiresDecl(OMPRequiresDecl *D);<br>
     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);<br>
+    void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);<br>
     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);<br>
<br>
     void printTemplateParameters(const TemplateParameterList *Params);<br>
@@ -423,7 +424,7 @@ void DeclPrinter::VisitDeclContext(DeclC<br>
     // FIXME: Need to be able to tell the DeclPrinter when<br>
     const char *Terminator = nullptr;<br>
     if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||<br>
-        isa<OMPRequiresDecl>(*D))<br>
+        isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D))<br>
       Terminator = nullptr;<br>
     else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())<br>
       Terminator = nullptr;<br>
@@ -1596,6 +1597,25 @@ void DeclPrinter::VisitOMPDeclareReducti<br>
     }<br>
   }<br>
 }<br>
+<br>
+void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {<br>
+  if (!D->isInvalidDecl()) {<br>
+    Out << "#pragma omp declare mapper (";<br>
+    D->printName(Out);<br>
+    Out << " : ";<br>
+    D->getType().print(Out, Policy);<br>
+    Out << " ";<br>
+    Out << D->getVarName();<br>
+    Out << ")";<br>
+    if (!D->clauselist_empty()) {<br>
+      OMPClausePrinter Printer(Out, Policy);<br>
+      for (auto *C : D->clauselists()) {<br>
+        Out << " ";<br>
+        Printer.Visit(C);<br>
+      }<br>
+    }<br>
+  }<br>
+}<br>
<br>
 void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {<br>
   D->getInit()->printPretty(Out, nullptr, Policy, Indentation);<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Feb  1 12:25:04 2019<br>
@@ -60,7 +60,8 @@ static const DeclContext *getEffectiveDe<br>
   }<br>
<br>
   const DeclContext *DC = D->getDeclContext();<br>
-  if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {<br>
+  if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||<br>
+      isa<OMPDeclareMapperDecl>(DC)) {<br>
     return getEffectiveDeclContext(cast<Decl>(DC));<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Feb  1 12:25:04 2019<br>
@@ -96,7 +96,8 @@ static const DeclContext *getEffectiveDe<br>
   }<br>
<br>
   const DeclContext *DC = D->getDeclContext();<br>
-  if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {<br>
+  if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||<br>
+      isa<OMPDeclareMapperDecl>(DC)) {<br>
     return getEffectiveDeclContext(cast<Decl>(DC));<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)<br>
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Fri Feb  1 12:25:04 2019<br>
@@ -766,6 +766,16 @@ bool clang::isAllowedClauseForDirective(<br>
       break;<br>
     }<br>
     break;<br>
+  case OMPD_declare_mapper:<br>
+    switch (CKind) {<br>
+#define OPENMP_DECLARE_MAPPER_CLAUSE(Name)                                     \<br>
+  case OMPC_##Name:                                                            \<br>
+    return true;<br>
+#include "clang/Basic/OpenMPKinds.def"<br>
+    default:<br>
+      break;<br>
+    }<br>
+    break;<br>
   case OMPD_declare_target:<br>
   case OMPD_end_declare_target:<br>
   case OMPD_unknown:<br>
@@ -1000,6 +1010,7 @@ void clang::getOpenMPCaptureRegions(<br>
   case OMPD_cancel:<br>
   case OMPD_flush:<br>
   case OMPD_declare_reduction:<br>
+  case OMPD_declare_mapper:<br>
   case OMPD_declare_simd:<br>
   case OMPD_declare_target:<br>
   case OMPD_end_declare_target:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Feb  1 12:25:04 2019<br>
@@ -141,6 +141,9 @@ void CodeGenFunction::EmitDecl(const Dec<br>
   case Decl::OMPDeclareReduction:<br>
     return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this);<br>
<br>
+  case Decl::OMPDeclareMapper:<br>
+    return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this);<br>
+<br>
   case Decl::Typedef:      // typedef int X;<br>
   case Decl::TypeAlias: {  // using X = int; [C++0x]<br>
     const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);<br>
@@ -2416,6 +2419,13 @@ void CodeGenModule::EmitOMPDeclareReduct<br>
   getOpenMPRuntime().emitUserDefinedReduction(CGF, D);<br>
 }<br>
<br>
+void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,<br>
+                                            CodeGenFunction *CGF) {<br>
+  if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->isUsed()))<br>
+    return;<br>
+  // FIXME: need to implement mapper code generation<br>
+}<br>
+<br>
 void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) {<br>
   getOpenMPRuntime().checkArchForUnifiedAddressing(*this, D);<br>
 }<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Fri Feb  1 12:25:04 2019<br>
@@ -8230,6 +8230,7 @@ getNestedDistributeDirective(ASTContext<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_taskloop:<br>
     case OMPD_taskloop_simd:<br>
     case OMPD_requires:<br>
@@ -8652,6 +8653,7 @@ void CGOpenMPRuntime::scanForTargetRegio<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_taskloop:<br>
     case OMPD_taskloop_simd:<br>
     case OMPD_requires:<br>
@@ -9132,6 +9134,7 @@ void CGOpenMPRuntime::emitTargetDataStan<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_taskloop:<br>
     case OMPD_taskloop_simd:<br>
     case OMPD_target:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp Fri Feb  1 12:25:04 2019<br>
@@ -858,6 +858,7 @@ static bool hasNestedSPMDDirective(ASTCo<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_taskloop:<br>
     case OMPD_taskloop_simd:<br>
     case OMPD_requires:<br>
@@ -926,6 +927,7 @@ static bool supportsSPMDExecutionMode(AS<br>
   case OMPD_declare_target:<br>
   case OMPD_end_declare_target:<br>
   case OMPD_declare_reduction:<br>
+  case OMPD_declare_mapper:<br>
   case OMPD_taskloop:<br>
   case OMPD_taskloop_simd:<br>
   case OMPD_requires:<br>
@@ -1076,6 +1078,7 @@ static bool hasNestedLightweightDirectiv<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_taskloop:<br>
     case OMPD_taskloop_simd:<br>
     case OMPD_requires:<br>
@@ -1149,6 +1152,7 @@ static bool supportsLightweightRuntime(A<br>
   case OMPD_declare_target:<br>
   case OMPD_end_declare_target:<br>
   case OMPD_declare_reduction:<br>
+  case OMPD_declare_mapper:<br>
   case OMPD_taskloop:<br>
   case OMPD_taskloop_simd:<br>
   case OMPD_requires:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb  1 12:25:04 2019<br>
@@ -2191,6 +2191,10 @@ void CodeGenModule::EmitGlobal(GlobalDec<br>
       if (MustBeEmitted(Global))<br>
         EmitOMPDeclareReduction(DRD);<br>
       return;<br>
+    } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) {<br>
+      if (MustBeEmitted(Global))<br>
+        EmitOMPDeclareMapper(DMD);<br>
+      return;<br>
     }<br>
   }<br>
<br>
@@ -5053,6 +5057,10 @@ void CodeGenModule::EmitTopLevelDecl(Dec<br>
     EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D));<br>
     break;<br>
<br>
+  case Decl::OMPDeclareMapper:<br>
+    EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(D));<br>
+    break;<br>
+<br>
   case Decl::OMPRequires:<br>
     EmitOMPRequiresDecl(cast<OMPRequiresDecl>(D));<br>
     break;<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Feb  1 12:25:04 2019<br>
@@ -1243,6 +1243,10 @@ public:<br>
   void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,<br>
                                CodeGenFunction *CGF = nullptr);<br>
<br>
+  /// Emit a code for declare mapper construct.<br>
+  void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,<br>
+                            CodeGenFunction *CGF = nullptr);<br>
+<br>
   /// Emit a code for requires directive.<br>
   /// \param D Requires declaration<br>
   void EmitOMPRequiresDecl(const OMPRequiresDecl *D);<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri Feb  1 12:25:04 2019<br>
@@ -40,7 +40,8 @@ enum OpenMPDirectiveKindEx {<br>
   OMPD_update,<br>
   OMPD_distribute_parallel,<br>
   OMPD_teams_distribute_parallel,<br>
-  OMPD_target_teams_distribute_parallel<br>
+  OMPD_target_teams_distribute_parallel,<br>
+  OMPD_mapper,<br>
 };<br>
<br>
 class ThreadprivateListParserHelper final {<br>
@@ -76,6 +77,7 @@ static unsigned getOpenMPDirectiveKindEx<br>
       .Case("point", OMPD_point)<br>
       .Case("reduction", OMPD_reduction)<br>
       .Case("update", OMPD_update)<br>
+      .Case("mapper", OMPD_mapper)<br>
       .Default(OMPD_unknown);<br>
 }<br>
<br>
@@ -86,6 +88,7 @@ static OpenMPDirectiveKind parseOpenMPDi<br>
   static const unsigned F[][3] = {<br>
       {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},<br>
       {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},<br>
+      {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},<br>
       {OMPD_declare, OMPD_simd, OMPD_declare_simd},<br>
       {OMPD_declare, OMPD_target, OMPD_declare_target},<br>
       {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},<br>
@@ -469,6 +472,141 @@ void Parser::ParseOpenMPReductionInitial<br>
   }<br>
 }<br>
<br>
+/// Parses 'omp declare mapper' directive.<br>
+///<br>
+///       declare-mapper-directive:<br>
+///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']<br>
+///         <type> <var> ')' [<clause>[[,] <clause>] ... ]<br>
+///         annot_pragma_openmp_end<br>
+/// <mapper-identifier> and <var> are base language identifiers.<br>
+///<br>
+Parser::DeclGroupPtrTy<br>
+Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {<br>
+  bool IsCorrect = true;<br>
+  // Parse '('<br>
+  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);<br>
+  if (T.expectAndConsume(diag::err_expected_lparen_after,<br>
+                         getOpenMPDirectiveName(OMPD_declare_mapper))) {<br>
+    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);<br>
+    return DeclGroupPtrTy();<br>
+  }<br>
+<br>
+  // Parse <mapper-identifier><br>
+  auto &DeclNames = Actions.getASTContext().DeclarationNames;<br>
+  DeclarationName MapperId;<br>
+  if (PP.LookAhead(0).is(tok::colon)) {<br>
+    if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {<br>
+      Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);<br>
+      IsCorrect = false;<br>
+    } else {<br>
+      MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());<br>
+    }<br>
+    ConsumeToken();<br>
+    // Consume ':'.<br>
+    ExpectAndConsume(tok::colon);<br>
+  } else {<br>
+    // If no mapper identifier is provided, its name is "default" by default<br>
+    MapperId =<br>
+        DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));<br>
+  }<br>
+<br>
+  if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))<br>
+    return DeclGroupPtrTy();<br>
+<br>
+  // Parse <type> <var><br>
+  DeclarationName VName;<br>
+  QualType MapperType;<br>
+  SourceRange Range;<br>
+  TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);<br>
+  if (ParsedType.isUsable())<br>
+    MapperType =<br>
+        Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);<br>
+  if (MapperType.isNull())<br>
+    IsCorrect = false;<br>
+  if (!IsCorrect) {<br>
+    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);<br>
+    return DeclGroupPtrTy();<br>
+  }<br>
+<br>
+  // Consume ')'.<br>
+  IsCorrect &= !T.consumeClose();<br>
+  if (!IsCorrect) {<br>
+    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);<br>
+    return DeclGroupPtrTy();<br>
+  }<br>
+<br>
+  // Enter scope.<br>
+  OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(<br>
+      getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,<br>
+      Range.getBegin(), VName, AS);<br>
+  DeclarationNameInfo DirName;<br>
+  SourceLocation Loc = Tok.getLocation();<br>
+  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |<br>
+                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;<br>
+  ParseScope OMPDirectiveScope(this, ScopeFlags);<br>
+  Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);<br>
+<br>
+  // Add the mapper variable declaration.<br>
+  Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(<br>
+      DMD, getCurScope(), MapperType, Range.getBegin(), VName);<br>
+<br>
+  // Parse map clauses.<br>
+  SmallVector<OMPClause *, 6> Clauses;<br>
+  while (Tok.isNot(tok::annot_pragma_openmp_end)) {<br>
+    OpenMPClauseKind CKind = Tok.isAnnotation()<br>
+                                 ? OMPC_unknown<br>
+                                 : getOpenMPClauseKind(PP.getSpelling(Tok));<br>
+    Actions.StartOpenMPClause(CKind);<br>
+    OMPClause *Clause =<br>
+        ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);<br>
+    if (Clause)<br>
+      Clauses.push_back(Clause);<br>
+    else<br>
+      IsCorrect = false;<br>
+    // Skip ',' if any.<br>
+    if (Tok.is(tok::comma))<br>
+      ConsumeToken();<br>
+    Actions.EndOpenMPClause();<br>
+  }<br>
+  if (Clauses.empty()) {<br>
+    Diag(Tok, diag::err_omp_expected_clause)<br>
+        << getOpenMPDirectiveName(OMPD_declare_mapper);<br>
+    IsCorrect = false;<br>
+  }<br>
+<br>
+  // Exit scope.<br>
+  Actions.EndOpenMPDSABlock(nullptr);<br>
+  OMPDirectiveScope.Exit();<br>
+<br>
+  DeclGroupPtrTy DGP =<br>
+      Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);<br>
+  if (!IsCorrect)<br>
+    return DeclGroupPtrTy();<br>
+  return DGP;<br>
+}<br>
+<br>
+TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,<br>
+                                                   DeclarationName &Name,<br>
+                                                   AccessSpecifier AS) {<br>
+  // Parse the common declaration-specifiers piece.<br>
+  Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;<br>
+  DeclSpec DS(AttrFactory);<br>
+  ParseSpecifierQualifierList(DS, AS, DSC);<br>
+<br>
+  // Parse the declarator.<br>
+  DeclaratorContext Context = DeclaratorContext::PrototypeContext;<br>
+  Declarator DeclaratorInfo(DS, Context);<br>
+  ParseDeclarator(DeclaratorInfo);<br>
+  Range = DeclaratorInfo.getSourceRange();<br>
+  if (DeclaratorInfo.getIdentifier() == nullptr) {<br>
+    Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);<br>
+    return true;<br>
+  }<br>
+  Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();<br>
+<br>
+  return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);<br>
+}<br>
+<br>
 namespace {<br>
 /// RAII that recreates function context for correct parsing of clauses of<br>
 /// 'declare simd' construct.<br>
@@ -707,6 +845,11 @@ void Parser::ParseOMPEndDeclareTargetDir<br>
 ///        annot_pragma_openmp 'declare' 'reduction' [...]<br>
 ///        annot_pragma_openmp_end<br>
 ///<br>
+///       declare-mapper-directive:<br>
+///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']<br>
+///         <type> <var> ')' [<clause>[[,] <clause>] ... ]<br>
+///         annot_pragma_openmp_end<br>
+///<br>
 ///       declare-simd-directive:<br>
 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}<br>
 ///         annot_pragma_openmp_end<br>
@@ -800,6 +943,15 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
       return Res;<br>
     }<br>
     break;<br>
+  case OMPD_declare_mapper: {<br>
+    ConsumeToken();<br>
+    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {<br>
+      // Skip the last annot_pragma_openmp_end.<br>
+      ConsumeAnnotationToken();<br>
+      return Res;<br>
+    }<br>
+    break;<br>
+  }<br>
   case OMPD_declare_simd: {<br>
     // The syntax is:<br>
     // { #pragma omp declare simd }<br>
@@ -954,6 +1106,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpen<br>
 ///         ('omp_priv' '=' <expression>|<function_call>) ')']<br>
 ///         annot_pragma_openmp_end<br>
 ///<br>
+///       declare-mapper-directive:<br>
+///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']<br>
+///         <type> <var> ')' [<clause>[[,] <clause>] ... ]<br>
+///         annot_pragma_openmp_end<br>
+///<br>
 ///       executable-directive:<br>
 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |<br>
 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |<br>
@@ -1034,6 +1191,18 @@ StmtResult Parser::ParseOpenMPDeclarativ<br>
       SkipUntil(tok::annot_pragma_openmp_end);<br>
     }<br>
     break;<br>
+  case OMPD_declare_mapper: {<br>
+    ConsumeToken();<br>
+    if (DeclGroupPtrTy Res =<br>
+            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {<br>
+      // Skip the last annot_pragma_openmp_end.<br>
+      ConsumeAnnotationToken();<br>
+      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());<br>
+    } else {<br>
+      SkipUntil(tok::annot_pragma_openmp_end);<br>
+    }<br>
+    break;<br>
+  }<br>
   case OMPD_flush:<br>
     if (PP.LookAhead(0).is(tok::l_paren)) {<br>
       FlushHasClause = true;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb  1 12:25:04 2019<br>
@@ -6192,7 +6192,8 @@ static bool isIncompleteDeclExternC(Sema<br>
<br>
 static bool shouldConsiderLinkage(const VarDecl *VD) {<br>
   const DeclContext *DC = VD->getDeclContext()->getRedeclContext();<br>
-  if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC))<br>
+  if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC) ||<br>
+      isa<OMPDeclareMapperDecl>(DC))<br>
     return VD->hasExternalStorage();<br>
   if (DC->isFileContext())<br>
     return true;<br>
@@ -6204,7 +6205,7 @@ static bool shouldConsiderLinkage(const<br>
 static bool shouldConsiderLinkage(const FunctionDecl *FD) {<br>
   const DeclContext *DC = FD->getDeclContext()->getRedeclContext();<br>
   if (DC->isFileContext() || DC->isFunctionOrMethod() ||<br>
-      isa<OMPDeclareReductionDecl>(DC))<br>
+      isa<OMPDeclareReductionDecl>(DC) || isa<OMPDeclareMapperDecl>(DC))<br>
     return true;<br>
   if (DC->isRecord())<br>
     return false;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb  1 12:25:04 2019<br>
@@ -310,6 +310,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *<br>
     return true;<br>
   }<br>
<br>
+  // [OpenMP 5.0], 2.19.7.3. declare mapper Directive, Restrictions<br>
+  //  List-items in map clauses on this construct may only refer to the declared<br>
+  //  variable var and entities that could be referenced by a procedure defined<br>
+  //  at the same location<br>
+  auto *DMD = dyn_cast<OMPDeclareMapperDecl>(CurContext);<br>
+  if (LangOpts.OpenMP && DMD && !CurContext->containsDecl(D) &&<br>
+      isa<VarDecl>(D)) {<br>
+    Diag(Loc, diag::err_omp_declare_mapper_wrong_var)<br>
+        << DMD->getVarName().getAsString();<br>
+    Diag(D->getLocation(), diag::note_entity_declared_at) << D;<br>
+    return true;<br>
+  }<br>
+<br>
   DiagnoseAvailabilityOfDecl(D, Locs, UnknownObjCClass, ObjCPropertyAccess,<br>
                              AvoidPartialAvailabilityChecks, ClassReceiver);<br>
<br>
@@ -2988,6 +3001,7 @@ ExprResult Sema::BuildDeclarationNameExp<br>
     case Decl::EnumConstant:<br>
     case Decl::UnresolvedUsingValue:<br>
     case Decl::OMPDeclareReduction:<br>
+    case Decl::OMPDeclareMapper:<br>
       valueKind = VK_RValue;<br>
       break;<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Feb  1 12:25:04 2019<br>
@@ -278,6 +278,10 @@ static inline unsigned getIDNS(Sema::Loo<br>
     IDNS = Decl::IDNS_OMPReduction;<br>
     break;<br>
<br>
+  case Sema::LookupOMPMapperName:<br>
+    IDNS = Decl::IDNS_OMPMapper;<br>
+    break;<br>
+<br>
   case Sema::LookupAnyName:<br>
     IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member<br>
       | Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol<br>
@@ -2103,6 +2107,10 @@ bool Sema::LookupQualifiedName(LookupRes<br>
       BaseCallback = &CXXRecordDecl::FindOMPReductionMember;<br>
       break;<br>
<br>
+    case LookupOMPMapperName:<br>
+      BaseCallback = &CXXRecordDecl::FindOMPMapperMember;<br>
+      break;<br>
+<br>
     case LookupUsingDeclName:<br>
       // This lookup is for redeclarations only.<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Feb  1 12:25:04 2019<br>
@@ -2808,6 +2808,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMP<br>
   case OMPD_cancel:<br>
   case OMPD_flush:<br>
   case OMPD_declare_reduction:<br>
+  case OMPD_declare_mapper:<br>
   case OMPD_declare_simd:<br>
   case OMPD_declare_target:<br>
   case OMPD_end_declare_target:<br>
@@ -3656,6 +3657,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi<br>
   case OMPD_end_declare_target:<br>
   case OMPD_threadprivate:<br>
   case OMPD_declare_reduction:<br>
+  case OMPD_declare_mapper:<br>
   case OMPD_declare_simd:<br>
   case OMPD_requires:<br>
     llvm_unreachable("OpenMP Directive is not allowed");<br>
@@ -8435,6 +8437,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8501,6 +8504,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8568,6 +8572,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8632,6 +8637,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8697,6 +8703,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8761,6 +8768,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -8824,6 +8832,7 @@ static OpenMPDirectiveKind getOpenMPCapt<br>
     case OMPD_cancellation_point:<br>
     case OMPD_flush:<br>
     case OMPD_declare_reduction:<br>
+    case OMPD_declare_mapper:<br>
     case OMPD_declare_simd:<br>
     case OMPD_declare_target:<br>
     case OMPD_end_declare_target:<br>
@@ -13464,6 +13473,143 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDe<br>
   return DeclReductions;<br>
 }<br>
<br>
+TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {<br>
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);<br>
+  QualType T = TInfo->getType();<br>
+  if (D.isInvalidType())<br>
+    return true;<br>
+<br>
+  if (getLangOpts().CPlusPlus) {<br>
+    // Check that there are no default arguments (C++ only).<br>
+    CheckExtraCXXDefaultArguments(D);<br>
+  }<br>
+<br>
+  return CreateParsedType(T, TInfo);<br>
+}<br>
+<br>
+QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,<br>
+                                            TypeResult ParsedType) {<br>
+  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");<br>
+<br>
+  QualType MapperType = GetTypeFromParser(ParsedType.get());<br>
+  assert(!MapperType.isNull() && "Expect valid mapper type");<br>
+<br>
+  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions<br>
+  //  The type must be of struct, union or class type in C and C++<br>
+  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {<br>
+    Diag(TyLoc, diag::err_omp_mapper_wrong_type);<br>
+    return QualType();<br>
+  }<br>
+  return MapperType;<br>
+}<br>
+<br>
+OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(<br>
+    Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,<br>
+    SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,<br>
+    Decl *PrevDeclInScope) {<br>
+  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,<br>
+                      forRedeclarationInCurContext());<br>
+  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions<br>
+  //  A mapper-identifier may not be redeclared in the current scope for the<br>
+  //  same type or for a type that is compatible according to the base language<br>
+  //  rules.<br>
+  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;<br>
+  OMPDeclareMapperDecl *PrevDMD = nullptr;<br>
+  bool InCompoundScope = true;<br>
+  if (S != nullptr) {<br>
+    // Find previous declaration with the same name not referenced in other<br>
+    // declarations.<br>
+    FunctionScopeInfo *ParentFn = getEnclosingFunction();<br>
+    InCompoundScope =<br>
+        (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();<br>
+    LookupName(Lookup, S);<br>
+    FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,<br>
+                         /*AllowInlineNamespace=*/false);<br>
+    llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;<br>
+    LookupResult::Filter Filter = Lookup.makeFilter();<br>
+    while (Filter.hasNext()) {<br>
+      auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());<br>
+      if (InCompoundScope) {<br>
+        auto I = UsedAsPrevious.find(PrevDecl);<br>
+        if (I == UsedAsPrevious.end())<br>
+          UsedAsPrevious[PrevDecl] = false;<br>
+        if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())<br>
+          UsedAsPrevious[D] = true;<br>
+      }<br>
+      PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =<br>
+          PrevDecl->getLocation();<br>
+    }<br>
+    Filter.done();<br>
+    if (InCompoundScope) {<br>
+      for (const auto &PrevData : UsedAsPrevious) {<br>
+        if (!PrevData.second) {<br>
+          PrevDMD = PrevData.first;<br>
+          break;<br>
+        }<br>
+      }<br>
+    }<br>
+  } else if (PrevDeclInScope) {<br>
+    auto *PrevDMDInScope = PrevDMD =<br>
+        cast<OMPDeclareMapperDecl>(PrevDeclInScope);<br>
+    do {<br>
+      PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =<br>
+          PrevDMDInScope->getLocation();<br>
+      PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();<br>
+    } while (PrevDMDInScope != nullptr);<br>
+  }<br>
+  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());<br>
+  bool Invalid = false;<br>
+  if (I != PreviousRedeclTypes.end()) {<br>
+    Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)<br>
+        << MapperType << Name;<br>
+    Diag(I->second, diag::note_previous_definition);<br>
+    Invalid = true;<br>
+  }<br>
+  auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,<br>
+                                           MapperType, VN, PrevDMD);<br>
+  DC->addDecl(DMD);<br>
+  DMD->setAccess(AS);<br>
+  if (Invalid)<br>
+    DMD->setInvalidDecl();<br>
+<br>
+  // Enter new function scope.<br>
+  PushFunctionScope();<br>
+  setFunctionHasBranchProtectedScope();<br>
+<br>
+  CurContext = DMD;<br>
+<br>
+  return DMD;<br>
+}<br>
+<br>
+void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,<br>
+                                                    Scope *S,<br>
+                                                    QualType MapperType,<br>
+                                                    SourceLocation StartLoc,<br>
+                                                    DeclarationName VN) {<br>
+  VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());<br>
+  if (S)<br>
+    PushOnScopeChains(VD, S);<br>
+  else<br>
+    DMD->addDecl(VD);<br>
+  Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);<br>
+  DMD->setMapperVarRef(MapperVarRefExpr);<br>
+}<br>
+<br>
+Sema::DeclGroupPtrTy<br>
+Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,<br>
+                                           ArrayRef<OMPClause *> ClauseList) {<br>
+  PopDeclContext();<br>
+  PopFunctionScopeInfo();<br>
+<br>
+  if (D) {<br>
+    if (S)<br>
+      PushOnScopeChains(D, S, /*AddToContext=*/false);<br>
+    D->CreateClauses(Context, ClauseList);<br>
+  }<br>
+<br>
+  return DeclGroupPtrTy::make(DeclGroupRef(D));<br>
+}<br>
+<br>
 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,<br>
                                            SourceLocation StartLoc,<br>
                                            SourceLocation LParenLoc,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Feb  1 12:25:04 2019<br>
@@ -2924,6 +2924,87 @@ Decl *TemplateDeclInstantiator::VisitOMP<br>
   return NewDRD;<br>
 }<br>
<br>
+Decl *<br>
+TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {<br>
+  // Instantiate type and check if it is allowed.<br>
+  const bool RequiresInstantiation =<br>
+      D->getType()->isDependentType() ||<br>
+      D->getType()->isInstantiationDependentType() ||<br>
+      D->getType()->containsUnexpandedParameterPack();<br>
+  QualType SubstMapperTy;<br>
+  DeclarationName VN = D->getVarName();<br>
+  if (RequiresInstantiation) {<br>
+    SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType(<br>
+        D->getLocation(),<br>
+        ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,<br>
+                                           D->getLocation(), VN)));<br>
+  } else {<br>
+    SubstMapperTy = D->getType();<br>
+  }<br>
+  if (SubstMapperTy.isNull())<br>
+    return nullptr;<br>
+  // Create an instantiated copy of mapper.<br>
+  auto *PrevDeclInScope = D->getPrevDeclInScope();<br>
+  if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {<br>
+    PrevDeclInScope = cast<OMPDeclareMapperDecl>(<br>
+        SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)<br>
+            ->get<Decl *>());<br>
+  }<br>
+  OMPDeclareMapperDecl *NewDMD = SemaRef.ActOnOpenMPDeclareMapperDirectiveStart(<br>
+      /*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),<br>
+      VN, D->getAccess(), PrevDeclInScope);<br>
+  SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDMD);<br>
+  SmallVector<OMPClause *, 6> Clauses;<br>
+  bool IsCorrect = true;<br>
+  if (!RequiresInstantiation) {<br>
+    // Copy the mapper variable.<br>
+    NewDMD->setMapperVarRef(D->getMapperVarRef());<br>
+    // Copy map clauses from the original mapper.<br>
+    for (OMPClause *C : D->clauselists())<br>
+      Clauses.push_back(C);<br>
+  } else {<br>
+    // Instantiate the mapper variable.<br>
+    DeclarationNameInfo DirName;<br>
+    SemaRef.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, /*S=*/nullptr,<br>
+                                (*D->clauselist_begin())->getBeginLoc());<br>
+    SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl(<br>
+        NewDMD, /*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);<br>
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(<br>
+        cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(),<br>
+        cast<DeclRefExpr>(NewDMD->getMapperVarRef())->getDecl());<br>
+    auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);<br>
+    Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),<br>
+                                     ThisContext);<br>
+    // Instantiate map clauses.<br>
+    for (OMPClause *C : D->clauselists()) {<br>
+      auto *OldC = cast<OMPMapClause>(C);<br>
+      SmallVector<Expr *, 4> NewVars;<br>
+      for (Expr *OE : OldC->varlists()) {<br>
+        Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get();<br>
+        if (!NE) {<br>
+          IsCorrect = false;<br>
+          break;<br>
+        }<br>
+        NewVars.push_back(NE);<br>
+      }<br>
+      if (!IsCorrect)<br>
+        break;<br>
+      OMPClause *NewC = SemaRef.ActOnOpenMPMapClause(<br>
+          OldC->getMapTypeModifiers(), OldC->getMapTypeModifiersLoc(),<br>
+          OldC->getMapType(), OldC->isImplicitMapType(), OldC->getMapLoc(),<br>
+          OldC->getColonLoc(), NewVars, OldC->getBeginLoc(),<br>
+          OldC->getLParenLoc(), OldC->getEndLoc());<br>
+      Clauses.push_back(NewC);<br>
+    }<br>
+    SemaRef.EndOpenMPDSABlock(nullptr);<br>
+  }<br>
+  (void)SemaRef.ActOnOpenMPDeclareMapperDirectiveEnd(NewDMD, /*S=*/nullptr,<br>
+                                                     Clauses);<br>
+  if (!IsCorrect)<br>
+    return nullptr;<br>
+  return NewDMD;<br>
+}<br>
+<br>
 Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl(<br>
     OMPCapturedExprDecl * /*D*/) {<br>
   llvm_unreachable("Should not be met in templates");<br>
@@ -5005,7 +5086,8 @@ NamedDecl *Sema::FindInstantiatedDecl(So<br>
   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||<br>
       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||<br>
       ((ParentDC->isFunctionOrMethod() ||<br>
-        isa<OMPDeclareReductionDecl>(ParentDC)) &&<br>
+        isa<OMPDeclareReductionDecl>(ParentDC) ||<br>
+        isa<OMPDeclareMapperDecl>(ParentDC)) &&<br>
        ParentDC->isDependentContext()) ||<br>
       (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {<br>
     // D is a local of some kind. Look into the map of local<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Fri Feb  1 12:25:04 2019<br>
@@ -390,6 +390,7 @@ bool serialization::isRedeclarableDeclKi<br>
   case Decl::OMPRequires:<br>
   case Decl::OMPCapturedExpr:<br>
   case Decl::OMPDeclareReduction:<br>
+  case Decl::OMPDeclareMapper:<br>
   case Decl::BuiltinTemplate:<br>
   case Decl::Decomposition:<br>
   case Decl::Binding:<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Feb  1 12:25:04 2019<br>
@@ -12300,7 +12300,7 @@ void OMPClauseReader::VisitOMPMapClause(<br>
   SmallVector<Expr *, 16> Vars;<br>
   Vars.reserve(NumVars);<br>
   for (unsigned i = 0; i != NumVars; ++i)<br>
-    Vars.push_back(Record.readSubExpr());<br>
+    Vars.push_back(Record.readExpr());<br>
   C->setVarRefs(Vars);<br>
<br>
   SmallVector<ValueDecl *, 16> Decls;<br>
@@ -12324,7 +12324,7 @@ void OMPClauseReader::VisitOMPMapClause(<br>
   SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;<br>
   Components.reserve(TotalComponents);<br>
   for (unsigned i = 0; i < TotalComponents; ++i) {<br>
-    Expr *AssociatedExpr = Record.readSubExpr();<br>
+    Expr *AssociatedExpr = Record.readExpr();<br>
     auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();<br>
     Components.push_back(OMPClauseMappableExprCommon::MappableComponent(<br>
         AssociatedExpr, AssociatedDecl));<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Feb  1 12:25:04 2019<br>
@@ -445,6 +445,7 @@ namespace clang {<br>
     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);<br>
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);<br>
     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);<br>
+    void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);<br>
     void VisitOMPRequiresDecl(OMPRequiresDecl *D);<br>
     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);<br>
   };<br>
@@ -2659,6 +2660,22 @@ void ASTDeclReader::VisitOMPDeclareReduc<br>
   D->PrevDeclInScope = ReadDeclID();<br>
 }<br>
<br>
+void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {<br>
+  VisitValueDecl(D);<br>
+  D->setLocation(ReadSourceLocation());<br>
+  Expr *MapperVarRefE = Record.readExpr();<br>
+  D->setMapperVarRef(MapperVarRefE);<br>
+  D->VarName = Record.readDeclarationName();<br>
+  D->PrevDeclInScope = ReadDeclID();<br>
+  unsigned NumClauses = D->clauselist_size();<br>
+  SmallVector<OMPClause *, 8> Clauses;<br>
+  Clauses.reserve(NumClauses);<br>
+  OMPClauseReader ClauseReader(Record);<br>
+  for (unsigned I = 0; I != NumClauses; ++I)<br>
+    Clauses.push_back(ClauseReader.readClause());<br>
+  D->setClauses(Clauses);<br>
+}<br>
+<br>
 void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {<br>
   VisitVarDecl(D);<br>
 }<br>
@@ -2776,7 +2793,8 @@ static bool isConsumerInterestedIn(ASTCo<br>
       isa<PragmaCommentDecl>(D) ||<br>
       isa<PragmaDetectMismatchDecl>(D))<br>
     return true;<br>
-  if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D))<br>
+  if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) ||<br>
+      isa<OMPDeclareMapperDecl>(D))<br>
     return !D->getDeclContext()->isFunctionOrMethod();<br>
   if (const auto *Var = dyn_cast<VarDecl>(D))<br>
     return Var->isFileVarDecl() &&<br>
@@ -3853,6 +3871,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I<br>
   case DECL_OMP_DECLARE_REDUCTION:<br>
     D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);<br>
     break;<br>
+  case DECL_OMP_DECLARE_MAPPER:<br>
+    D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, Record.readInt());<br>
+    break;<br>
   case DECL_OMP_CAPTUREDEXPR:<br>
     D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);<br>
     break;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Feb  1 12:25:04 2019<br>
@@ -146,6 +146,7 @@ namespace clang {<br>
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);<br>
     void VisitOMPRequiresDecl(OMPRequiresDecl *D);<br>
     void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);<br>
+    void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);<br>
     void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);<br>
<br>
     /// Add an Objective-C type parameter list to the given record.<br>
@@ -1765,6 +1766,19 @@ void ASTDeclWriter::VisitOMPDeclareReduc<br>
   Code = serialization::DECL_OMP_DECLARE_REDUCTION;<br>
 }<br>
<br>
+void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {<br>
+  Record.push_back(D->clauselist_size());<br>
+  VisitValueDecl(D);<br>
+  Record.AddSourceLocation(D->getBeginLoc());<br>
+  Record.AddStmt(D->getMapperVarRef());<br>
+  Record.AddDeclarationName(D->getVarName());<br>
+  Record.AddDeclRef(D->getPrevDeclInScope());<br>
+  OMPClauseWriter ClauseWriter(Record);<br>
+  for (OMPClause *C : D->clauselists())<br>
+    ClauseWriter.writeClause(C);<br>
+  Code = serialization::DECL_OMP_DECLARE_MAPPER;<br>
+}<br>
+<br>
 void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {<br>
   VisitVarDecl(D);<br>
   Code = serialization::DECL_OMP_CAPTUREDEXPR;<br>
<br>
Added: cfe/trunk/test/OpenMP/declare_mapper_ast_print.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_ast_print.c?rev=352906&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_ast_print.c?rev=352906&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/declare_mapper_ast_print.c (added)<br>
+++ cfe/trunk/test/OpenMP/declare_mapper_ast_print.c Fri Feb  1 12:25:04 2019<br>
@@ -0,0 +1,48 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s<br>
+// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s<br>
+<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -fopenmp-simd -emit-pch -o %t %s<br>
+// RUN: %clang_cc1 -fopenmp-simd -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s<br>
+// expected-no-diagnostics<br>
+<br>
+#ifndef HEADER<br>
+#define HEADER<br>
+<br>
+// CHECK: struct vec {<br>
+struct vec {<br>
+  int len;<br>
+  double *data;<br>
+};<br>
+// CHECK: };<br>
+<br>
+// CHECK: struct dat {<br>
+struct dat {<br>
+  int i;<br>
+  double d;<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len){{$}}<br>
+};<br>
+// CHECK: };<br>
+<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len){{$}}<br>
+#pragma omp declare mapper(default : struct vec kk) map(kk.len) map(kk.data[0:2])<br>
+// CHECK: #pragma omp declare mapper (default : struct vec kk) map(tofrom: kk.len) map(tofrom: kk.data[0:2]){{$}}<br>
+#pragma omp declare mapper(struct dat d) map(to: d.d)<br>
+// CHECK: #pragma omp declare mapper (default : struct dat d) map(to: d.d){{$}}<br>
+<br>
+// CHECK: int main() {<br>
+int main() {<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len)<br>
+  {<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len)<br>
+  }<br>
+  return 0;<br>
+}<br>
+// CHECK: }<br>
+<br>
+#endif<br>
<br>
Added: cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp?rev=352906&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp?rev=352906&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp (added)<br>
+++ cfe/trunk/test/OpenMP/declare_mapper_ast_print.cpp Fri Feb  1 12:25:04 2019<br>
@@ -0,0 +1,97 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s<br>
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s<br>
+<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s<br>
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s<br>
+// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s<br>
+// expected-no-diagnostics<br>
+<br>
+#ifndef HEADER<br>
+#define HEADER<br>
+<br>
+// CHECK: namespace N1 {<br>
+namespace N1<br>
+{<br>
+// CHECK: class vec {<br>
+class vec {<br>
+public:<br>
+  int len;<br>
+  double *data;<br>
+};<br>
+// CHECK: };<br>
+<br>
+#pragma omp declare mapper(id: vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}<br>
+};<br>
+// CHECK: }<br>
+// CHECK: ;<br>
+<br>
+template <class T><br>
+class dat {<br>
+public:<br>
+  class datin {<br>
+  public:<br>
+    T in;<br>
+  };<br>
+  int i;<br>
+  T d;<br>
+#pragma omp declare mapper(id: N1::vec v) map(v.len)<br>
+#pragma omp declare mapper(id: datin v) map(<a href="http://v.in" rel="noreferrer" target="_blank">v.in</a>)<br>
+};<br>
+<br>
+// CHECK: template <class T> class dat {<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}<br>
+// CHECK: #pragma omp declare mapper (id : dat::datin v) map(tofrom: <a href="http://v.in" rel="noreferrer" target="_blank">v.in</a>){{$}}<br>
+// CHECK: };<br>
+// CHECK: template<> class dat<double> {<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}<br>
+// CHECK: #pragma omp declare mapper (id : dat<double>::datin v) map(tofrom: <a href="http://v.in" rel="noreferrer" target="_blank">v.in</a>){{$}}<br>
+// CHECK: };<br>
+<br>
+#pragma omp declare mapper(default : N1::vec kk) map(kk.len) map(kk.data[0:2])<br>
+// CHECK: #pragma omp declare mapper (default : N1::vec kk) map(tofrom: kk.len) map(tofrom: kk.data[0:2]){{$}}<br>
+#pragma omp declare mapper(dat<double> d) map(to: d.d)<br>
+// CHECK: #pragma omp declare mapper (default : dat<double> d) map(to: d.d){{$}}<br>
+<br>
+template <typename T><br>
+T foo(T a) {<br>
+  struct foodat {<br>
+    T a;<br>
+  };<br>
+#pragma omp declare mapper(struct foodat v) map(v.a)<br>
+#pragma omp declare mapper(id: N1::vec v) map(v.len)<br>
+  {<br>
+#pragma omp declare mapper(id: N1::vec v) map(v.len)<br>
+  }<br>
+  return 0;<br>
+}<br>
+<br>
+// CHECK: template <typename T> T foo(T a) {<br>
+// CHECK: #pragma omp declare mapper (default : struct foodat v) map(tofrom: v.a)<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+// CHECK: {<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+// CHECK: }<br>
+// CHECK: }<br>
+// CHECK: template<> int foo<int>(int a) {<br>
+// CHECK: #pragma omp declare mapper (default : struct foodat v) map(tofrom: v.a)<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+// CHECK: {<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+// CHECK: }<br>
+// CHECK: }<br>
+<br>
+// CHECK: int main() {<br>
+int main() {<br>
+#pragma omp declare mapper(id: N1::vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+  {<br>
+#pragma omp declare mapper(id: N1::vec v) map(v.len)<br>
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)<br>
+  }<br>
+  return foo<int>(0);<br>
+}<br>
+// CHECK: }<br>
+<br>
+#endif<br>
<br>
Added: cfe/trunk/test/OpenMP/declare_mapper_messages.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_messages.c?rev=352906&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_messages.c?rev=352906&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/declare_mapper_messages.c (added)<br>
+++ cfe/trunk/test/OpenMP/declare_mapper_messages.c Fri Feb  1 12:25:04 2019<br>
@@ -0,0 +1,41 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s<br>
+<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s<br>
+<br>
+int temp; // expected-note {{'temp' declared here}}<br>
+<br>
+struct vec {                                                            // expected-note {{definition of 'struct vec' is not complete until the closing '}'}}<br>
+  int len;<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)                 // expected-error {{incomplete definition of type 'struct vec'}}<br>
+  double *data;<br>
+};<br>
+<br>
+#pragma omp declare mapper                                              // expected-error {{expected '(' after 'declare mapper'}}<br>
+#pragma omp declare mapper {                                            // expected-error {{expected '(' after 'declare mapper'}}<br>
+#pragma omp declare mapper(                                             // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(#                                            // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(struct v                                     // expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(struct vec                                   // expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(S v                                          // expected-error {{unknown type name 'S'}}<br>
+#pragma omp declare mapper(struct vec v                                 // expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp declare mapper(aa:struct vec v)                             // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}}<br>
+#pragma omp declare mapper(bb:struct vec v) private(v)                  // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}<br>
+#pragma omp declare mapper(cc:struct vec v) map(v) (                    // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}<br>
+<br>
+#pragma omp declare mapper(++: struct vec v) map(v.len)                 // expected-error {{illegal identifier on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(id1: struct vec v) map(v.len, temp)          // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(default : struct vec kk) map(kk.data[0:2])   // expected-note {{previous definition is here}}<br>
+#pragma omp declare mapper(struct vec v) map(v.len)                     // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'default'}}<br>
+#pragma omp declare mapper(int v) map(v)                                // expected-error {{mapper type must be of struct, union or class type}}<br>
+<br>
+int fun(int arg) {<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+  {<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)                 // expected-note {{previous definition is here}}<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)                 // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'id'}}<br>
+    {<br>
+#pragma omp declare mapper(id: struct vec v) map(v.len)<br>
+    }<br>
+  }<br>
+  return arg;<br>
+}<br>
<br>
Added: cfe/trunk/test/OpenMP/declare_mapper_messages.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_messages.cpp?rev=352906&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/declare_mapper_messages.cpp?rev=352906&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/OpenMP/declare_mapper_messages.cpp (added)<br>
+++ cfe/trunk/test/OpenMP/declare_mapper_messages.cpp Fri Feb  1 12:25:04 2019<br>
@@ -0,0 +1,70 @@<br>
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s<br>
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++98 %s<br>
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 %s<br>
+<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++98 %s<br>
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 %s<br>
+<br>
+int temp; // expected-note {{'temp' declared here}}<br>
+<br>
+class vec {                                                             // expected-note {{definition of 'vec' is not complete until the closing '}'}}<br>
+private:<br>
+  int p;                                                                // expected-note {{declared private here}}<br>
+public:<br>
+  int len;<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-error {{member access into incomplete type 'vec'}}<br>
+  double *data;<br>
+};<br>
+<br>
+#pragma omp declare mapper                                              // expected-error {{expected '(' after 'declare mapper'}}<br>
+#pragma omp declare mapper {                                            // expected-error {{expected '(' after 'declare mapper'}}<br>
+#pragma omp declare mapper(                                             // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(#                                            // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(v                                            // expected-error {{unknown type name 'v'}} expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(vec                                          // expected-error {{expected declarator on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(S v                                          // expected-error {{unknown type name 'S'}}<br>
+#pragma omp declare mapper(vec v                                        // expected-error {{expected ')'}} expected-note {{to match this '('}}<br>
+#pragma omp declare mapper(aa: vec v)                                   // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}}<br>
+#pragma omp declare mapper(bb: vec v) private(v)                        // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}<br>
+#pragma omp declare mapper(cc: vec v) map(v) (                          // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}<br>
+<br>
+#pragma omp declare mapper(++: vec v) map(v.len)                        // expected-error {{illegal identifier on 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(id1: vec v) map(v.len, temp)                 // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}<br>
+#pragma omp declare mapper(default : vec kk) map(kk.data[0:2])          // expected-note {{previous definition is here}}<br>
+#pragma omp declare mapper(vec v) map(v.len)                            // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'default'}}<br>
+#pragma omp declare mapper(int v) map(v)                                // expected-error {{mapper type must be of struct, union or class type}}<br>
+#pragma omp declare mapper(id2: vec v) map(v.len, v.p)                  // expected-error {{'p' is a private member of 'vec'}}<br>
+<br>
+namespace N1 {<br>
+template <class T><br>
+class stack {                                                           // expected-note {{template is declared here}}<br>
+public:<br>
+  int len;<br>
+  T *data;<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-note {{previous definition is here}}<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}<br>
+};<br>
+};<br>
+<br>
+#pragma omp declare mapper(default : N1::stack s) map(s.len)            // expected-error {{use of class template 'N1::stack' requires template arguments}}<br>
+#pragma omp declare mapper(id1: N1::stack<int> s) map(s.data)<br>
+#pragma omp declare mapper(default : S<int> s) map(s.len)               // expected-error {{no template named 'S'}}<br>
+<br>
+template <class T><br>
+T foo(T a) {<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-note {{previous definition is here}}<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}<br>
+}<br>
+<br>
+int fun(int arg) {<br>
+#pragma omp declare mapper(id: vec v) map(v.len)<br>
+  {<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-note {{previous definition is here}}<br>
+    {<br>
+#pragma omp declare mapper(id: vec v) map(v.len)<br>
+    }<br>
+#pragma omp declare mapper(id: vec v) map(v.len)                        // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}<br>
+  }<br>
+  return arg;<br>
+}<br>
<br>
Modified: cfe/trunk/tools/libclang/CIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=352906&r1=352905&r2=352906&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=352906&r1=352905&r2=352906&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Feb  1 12:25:04 2019<br>
@@ -6229,6 +6229,7 @@ CXCursor clang_getCursorDefinition(CXCur<br>
   case Decl::Import:<br>
   case Decl::OMPThreadPrivate:<br>
   case Decl::OMPDeclareReduction:<br>
+  case Decl::OMPDeclareMapper:<br>
   case Decl::OMPRequires:<br>
   case Decl::ObjCTypeParam:<br>
   case Decl::BuiltinTemplate:<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>