r352906 - [OpenMP 5.0] Parsing/sema support for "omp declare mapper" directive.

Michael Kruse via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 1 13:11:59 PST 2019


Hi,

I never used modules. Can you give me hint where it exactly breaks? Is
it line 294 and 298 where it calls getExternalSource of ASTContext?

Michael



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


More information about the cfe-commits mailing list