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

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 1 12:57:51 PST 2019


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190201/d6b5c7cf/attachment-0001.html>


More information about the cfe-commits mailing list