Skip to content

[flang][OpenMP] Implement OmpDirectiveName, use in OmpDirectiveSpecif… #130121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 7, 2025

Conversation

kparzysz
Copy link
Contributor

@kparzysz kparzysz commented Mar 6, 2025

…ication

The OmpDirectiveName class has a source in addition to wrapping the llvm::omp::Directive.

…ication

The `OmpDirectiveName` class has a source in addition to wrapping the
llvm::omp::Directive.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:semantics flang:parser labels Mar 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-flang-parser

@llvm/pr-subscribers-flang-openmp

Author: Krzysztof Parzyszek (kparzysz)

Changes

…ication

The OmpDirectiveName class has a source in addition to wrapping the llvm::omp::Directive.


Full diff: https://github.com/llvm/llvm-project/pull/130121.diff

11 Files Affected:

  • (modified) flang/include/flang/Parser/dump-parse-tree.h (+1)
  • (modified) flang/include/flang/Parser/parse-tree.h (+16-1)
  • (modified) flang/lib/Parser/openmp-parsers.cpp (+31-7)
  • (modified) flang/lib/Parser/parse-tree.cpp (+15)
  • (modified) flang/lib/Parser/unparse.cpp (+1-1)
  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+1-1)
  • (modified) flang/lib/Semantics/resolve-directives.cpp (+1-1)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+1-2)
  • (modified) flang/test/Parser/OpenMP/metadirective-dirspec.f90 (+8-8)
  • (modified) flang/test/Parser/OpenMP/metadirective-v50.f90 (+2-2)
  • (modified) flang/test/Parser/OpenMP/metadirective.f90 (+12-12)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 3b3c6bdc448d7..a154794e41e9d 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -489,6 +489,7 @@ class ParseTreeDumper {
   NODE(parser, OmpOtherwiseClause)
   NODE(parser, OmpWhenClause)
   NODE(OmpWhenClause, Modifier)
+  NODE(parser, OmpDirectiveName)
   NODE(parser, OmpDirectiveSpecification)
   NODE(parser, OmpTraitPropertyName)
   NODE(parser, OmpTraitScore)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index f11859bb09ddb..346299b8e5215 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3464,6 +3464,18 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 struct OmpClause;
 struct OmpDirectiveSpecification;
 
+struct OmpDirectiveName {
+  // No boilerplates: this class should be copyable, movable, etc.
+  constexpr OmpDirectiveName() = default;
+  constexpr OmpDirectiveName(const OmpDirectiveName &) = default;
+  // Construct from an already parsed text. Use Verbatim for this because
+  // Verbatim's source corresponds to an actual source location.
+  OmpDirectiveName(const Verbatim &name);
+  using WrapperTrait = std::true_type;
+  CharBlock source;
+  llvm::omp::Directive v{llvm::omp::Directive::OMPD_unknown};
+};
+
 // 2.1 Directives or clauses may accept a list or extended-list.
 //     A list item is a variable, array section or common block name (enclosed
 //     in slashes). An extended list item is a list item or a procedure Name.
@@ -4493,7 +4505,10 @@ struct OmpClauseList {
 struct OmpDirectiveSpecification {
   CharBlock source;
   TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
-  std::tuple<llvm::omp::Directive, std::optional<std::list<OmpArgument>>,
+  llvm::omp::Directive DirId() const { //
+    return std::get<OmpDirectiveName>(t).v;
+  }
+  std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>,
       std::optional<OmpClauseList>>
       t;
 };
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 43cd2ea1eb0e6..b3e76d70c8064 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -27,15 +27,38 @@ namespace Fortran::parser {
 constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
 constexpr auto endOmpLine = space >> endOfLine;
 
+template <typename Parser> struct UnwrapParser {
+  static_assert(
+      Parser::resultType::WrapperTrait::value && "Wrapper class required");
+  using resultType = decltype(Parser::resultType::v);
+  constexpr UnwrapParser(Parser p) : parser_(p) {}
+
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto result{parser_.Parse(state)}) {
+      return result->v;
+    }
+    return std::nullopt;
+  }
+
+private:
+  const Parser parser_;
+};
+
+template <typename Parser> constexpr auto unwrap(const Parser &p) {
+  return UnwrapParser<Parser>(p);
+}
+
 /// Parse OpenMP directive name (this includes compound directives).
 struct OmpDirectiveNameParser {
-  using resultType = llvm::omp::Directive;
+  using resultType = OmpDirectiveName;
   using Token = TokenStringMatch<false, false>;
 
   std::optional<resultType> Parse(ParseState &state) const {
     for (const NameWithId &nid : directives()) {
       if (attempt(Token(nid.first.data())).Parse(state)) {
-        return nid.second;
+        OmpDirectiveName n;
+        n.v = nid.second;
+        return n;
       }
     }
     return std::nullopt;
@@ -218,7 +241,7 @@ TYPE_PARSER(construct<OmpTraitSelectorName::Value>(
 TYPE_PARSER(sourced(construct<OmpTraitSelectorName>(
     // Parse predefined names first (because of SIMD).
     construct<OmpTraitSelectorName>(Parser<OmpTraitSelectorName::Value>{}) ||
-    construct<OmpTraitSelectorName>(OmpDirectiveNameParser{}) ||
+    construct<OmpTraitSelectorName>(unwrap(OmpDirectiveNameParser{})) ||
     // identifier-or-string for extensions
     construct<OmpTraitSelectorName>(
         applyFunction(nameToString, Parser<Name>{})) ||
@@ -480,7 +503,8 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
 TYPE_PARSER(sourced(
     construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
 
-TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))
+TYPE_PARSER(
+    sourced(construct<OmpIfClause::Modifier>(unwrap(OmpDirectiveNameParser{}))))
 
 TYPE_PARSER(sourced(construct<OmpInReductionClause::Modifier>(
     Parser<OmpReductionIdentifier>{})))
@@ -775,9 +799,9 @@ TYPE_PARSER(construct<OmpMessageClause>(expr))
 
 TYPE_PARSER(construct<OmpHoldsClause>(indirect(expr)))
 TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
-    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(unwrap(OmpDirectiveNameParser{})))))
 TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
-    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(unwrap(OmpDirectiveNameParser{})))))
 
 TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
                             parenthesized(Parser<OmpAbsentClause>{}))) ||
@@ -972,7 +996,7 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
 // --- Parsers for directives and constructs --------------------------
 
 TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
-    OmpDirectiveNameParser{},
+    sourced(OmpDirectiveNameParser{}),
     maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
     maybe(Parser<OmpClauseList>{}))))
 
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 251b6919cf52f..e42022ceffa28 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -253,6 +253,21 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Name &x) {
   return os << x.ToString();
 }
 
+OmpDirectiveName::OmpDirectiveName(const Verbatim &name) {
+  std::string_view nameView{name.source.begin(), name.source.size()};
+  std::string nameLower{ToLowerCaseLetters(nameView)};
+  // If the name was actually "unknown" then accept it, otherwise flag
+  // OMPD_unknown (the default return value from getOpenMPDirectiveKind)
+  // as an error.
+  if (nameLower != "unknown") {
+    v = llvm::omp::getOpenMPDirectiveKind(nameLower);
+    assert(v != llvm::omp::Directive::OMPD_unknown && "Unrecognized directive");
+  } else {
+    v = llvm::omp::Directive::OMPD_unknown;
+  }
+  source = name.source;
+}
+
 OmpDependenceType::Value OmpDoacross::GetDepType() const {
   return common::visit( //
       common::visitors{
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1df17b6d7382b..4f5c05dc2aa25 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2095,7 +2095,7 @@ class UnparseVisitor {
   }
   void Unparse(const OmpDirectiveSpecification &x) {
     using ArgList = std::list<parser::OmpArgument>;
-    Walk(std::get<llvm::omp::Directive>(x.t));
+    Walk(std::get<OmpDirectiveName>(x.t));
     if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
       Put("(");
       Walk(*args);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c6ed211549401..64a0be703744d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -625,7 +625,7 @@ void OmpStructureChecker::CheckHintClause(
 }
 
 void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
-  PushContextAndClauseSets(x.source, std::get<llvm::omp::Directive>(x.t));
+  PushContextAndClauseSets(x.source, x.DirId());
 }
 
 void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 38888a4dc1461..977c2fef34091 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -352,7 +352,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   }
 
   bool Pre(const parser::OmpDirectiveSpecification &x) {
-    PushContext(x.source, std::get<llvm::omp::Directive>(x.t));
+    PushContext(x.source, x.DirId());
     return true;
   }
   void Post(const parser::OmpDirectiveSpecification &) { PopContext(); }
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4f80cdca0f4bb..e57abf8ac0912 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1775,11 +1775,10 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
   // Disable the semantic analysis for it for now to allow the compiler to
   // parse METADIRECTIVE without flagging errors.
   AddOmpSourceRange(x.source);
-  auto dirId{std::get<llvm::omp::Directive>(x.t)};
   auto &maybeArgs{std::get<std::optional<std::list<parser::OmpArgument>>>(x.t)};
   auto &maybeClauses{std::get<std::optional<parser::OmpClauseList>>(x.t)};
 
-  switch (dirId) {
+  switch (x.DirId()) {
   case llvm::omp::Directive::OMPD_declare_mapper:
     if (maybeArgs && maybeClauses) {
       const parser::OmpArgument &first{maybeArgs->front()};
diff --git a/flang/test/Parser/OpenMP/metadirective-dirspec.f90 b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
index 73520c41fe77d..bf749d1f48c10 100644
--- a/flang/test/Parser/OpenMP/metadirective-dirspec.f90
+++ b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
@@ -25,7 +25,7 @@ subroutine f00(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = allocate
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = allocate
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpClauseList ->
 
@@ -51,7 +51,7 @@ subroutine f01(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = critical
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = critical
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpClauseList ->
 
@@ -76,7 +76,7 @@ subroutine f02
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare mapper
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare mapper
 !PARSE-TREE: | | | OmpArgument -> OmpMapperSpecifier
 !PARSE-TREE: | | | | Name = 'mymapper'
 !PARSE-TREE: | | | | TypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
@@ -120,7 +120,7 @@ subroutine f03
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare reduction
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare reduction
 !PARSE-TREE: | | | OmpArgument -> OmpReductionSpecifier
 !PARSE-TREE: | | | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE: | | | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
@@ -158,7 +158,7 @@ subroutine f04
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare simd
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare simd
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'f04'
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: ImplicitPart ->
@@ -183,7 +183,7 @@ subroutine f05
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare target
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare target
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'f05'
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: ImplicitPart ->
@@ -210,7 +210,7 @@ subroutine f06(x, y)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = flush
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'y'
 !PARSE-TREE: | | | OmpClauseList ->
@@ -237,6 +237,6 @@ subroutine f07
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = threadprivate
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = threadprivate
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 't'
 !PARSE-TREE: | | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/metadirective-v50.f90 b/flang/test/Parser/OpenMP/metadirective-v50.f90
index d7c3121b8f1b8..6fef3376470a6 100644
--- a/flang/test/Parser/OpenMP/metadirective-v50.f90
+++ b/flang/test/Parser/OpenMP/metadirective-v50.f90
@@ -24,8 +24,8 @@ subroutine f01
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> Default -> OmpDefaultClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/metadirective.f90 b/flang/test/Parser/OpenMP/metadirective.f90
index dce31c2e7db26..1185ac897ecf6 100644
--- a/flang/test/Parser/OpenMP/metadirective.f90
+++ b/flang/test/Parser/OpenMP/metadirective.f90
@@ -20,7 +20,7 @@ subroutine f00
 !PARSE-TREE: | | | OmpTraitSelector
 !PARSE-TREE: | | | | OmpTraitSelectorName -> llvm::omp::Directive = parallel
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f01
@@ -47,7 +47,7 @@ subroutine f01
 !PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '1_4'
 !PARSE-TREE: | | | | | | LiteralConstant -> IntLiteralConstant = '1'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f02
@@ -74,7 +74,7 @@ subroutine f02
 !PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '7_4'
 !PARSE-TREE: | | | | | | LiteralConstant -> IntLiteralConstant = '7'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f03
@@ -98,7 +98,7 @@ subroutine f03
 !PARSE-TREE: | | | | Properties
 !PARSE-TREE: | | | | | OmpTraitProperty -> OmpClause -> AcqRel
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f04
@@ -132,7 +132,7 @@ subroutine f04
 !PARSE-TREE: | | | | | | | OmpTraitPropertyExtension -> Scalar -> Expr = '1_4'
 !PARSE-TREE: | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f05(x)
@@ -168,12 +168,12 @@ subroutine f05(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = parallel do
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = parallel do
 !PARSE-TREE: | | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
 !PARSE-TREE: | | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | OmpClause -> Otherwise -> OmpOtherwiseClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | OmpClauseList ->
 
 subroutine f06
@@ -207,7 +207,7 @@ subroutine f06
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f07
@@ -232,7 +232,7 @@ subroutine f07
 !PARSE-TREE: | | | | Properties
 !PARSE-TREE: | | | | | OmpTraitProperty -> OmpTraitPropertyName -> string = 'amd'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare simd
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare simd
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> When -> OmpWhenClause
 !PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
@@ -244,8 +244,8 @@ subroutine f07
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare target
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare target
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> Otherwise -> OmpOtherwiseClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
-!PARSE-TREE: | | OmpClauseList ->
\ No newline at end of file
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpClauseList ->

@llvmbot
Copy link
Member

llvmbot commented Mar 6, 2025

@llvm/pr-subscribers-flang-semantics

Author: Krzysztof Parzyszek (kparzysz)

Changes

…ication

The OmpDirectiveName class has a source in addition to wrapping the llvm::omp::Directive.


Full diff: https://github.com/llvm/llvm-project/pull/130121.diff

11 Files Affected:

  • (modified) flang/include/flang/Parser/dump-parse-tree.h (+1)
  • (modified) flang/include/flang/Parser/parse-tree.h (+16-1)
  • (modified) flang/lib/Parser/openmp-parsers.cpp (+31-7)
  • (modified) flang/lib/Parser/parse-tree.cpp (+15)
  • (modified) flang/lib/Parser/unparse.cpp (+1-1)
  • (modified) flang/lib/Semantics/check-omp-structure.cpp (+1-1)
  • (modified) flang/lib/Semantics/resolve-directives.cpp (+1-1)
  • (modified) flang/lib/Semantics/resolve-names.cpp (+1-2)
  • (modified) flang/test/Parser/OpenMP/metadirective-dirspec.f90 (+8-8)
  • (modified) flang/test/Parser/OpenMP/metadirective-v50.f90 (+2-2)
  • (modified) flang/test/Parser/OpenMP/metadirective.f90 (+12-12)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 3b3c6bdc448d7..a154794e41e9d 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -489,6 +489,7 @@ class ParseTreeDumper {
   NODE(parser, OmpOtherwiseClause)
   NODE(parser, OmpWhenClause)
   NODE(OmpWhenClause, Modifier)
+  NODE(parser, OmpDirectiveName)
   NODE(parser, OmpDirectiveSpecification)
   NODE(parser, OmpTraitPropertyName)
   NODE(parser, OmpTraitScore)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index f11859bb09ddb..346299b8e5215 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3464,6 +3464,18 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 struct OmpClause;
 struct OmpDirectiveSpecification;
 
+struct OmpDirectiveName {
+  // No boilerplates: this class should be copyable, movable, etc.
+  constexpr OmpDirectiveName() = default;
+  constexpr OmpDirectiveName(const OmpDirectiveName &) = default;
+  // Construct from an already parsed text. Use Verbatim for this because
+  // Verbatim's source corresponds to an actual source location.
+  OmpDirectiveName(const Verbatim &name);
+  using WrapperTrait = std::true_type;
+  CharBlock source;
+  llvm::omp::Directive v{llvm::omp::Directive::OMPD_unknown};
+};
+
 // 2.1 Directives or clauses may accept a list or extended-list.
 //     A list item is a variable, array section or common block name (enclosed
 //     in slashes). An extended list item is a list item or a procedure Name.
@@ -4493,7 +4505,10 @@ struct OmpClauseList {
 struct OmpDirectiveSpecification {
   CharBlock source;
   TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
-  std::tuple<llvm::omp::Directive, std::optional<std::list<OmpArgument>>,
+  llvm::omp::Directive DirId() const { //
+    return std::get<OmpDirectiveName>(t).v;
+  }
+  std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>,
       std::optional<OmpClauseList>>
       t;
 };
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 43cd2ea1eb0e6..b3e76d70c8064 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -27,15 +27,38 @@ namespace Fortran::parser {
 constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
 constexpr auto endOmpLine = space >> endOfLine;
 
+template <typename Parser> struct UnwrapParser {
+  static_assert(
+      Parser::resultType::WrapperTrait::value && "Wrapper class required");
+  using resultType = decltype(Parser::resultType::v);
+  constexpr UnwrapParser(Parser p) : parser_(p) {}
+
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto result{parser_.Parse(state)}) {
+      return result->v;
+    }
+    return std::nullopt;
+  }
+
+private:
+  const Parser parser_;
+};
+
+template <typename Parser> constexpr auto unwrap(const Parser &p) {
+  return UnwrapParser<Parser>(p);
+}
+
 /// Parse OpenMP directive name (this includes compound directives).
 struct OmpDirectiveNameParser {
-  using resultType = llvm::omp::Directive;
+  using resultType = OmpDirectiveName;
   using Token = TokenStringMatch<false, false>;
 
   std::optional<resultType> Parse(ParseState &state) const {
     for (const NameWithId &nid : directives()) {
       if (attempt(Token(nid.first.data())).Parse(state)) {
-        return nid.second;
+        OmpDirectiveName n;
+        n.v = nid.second;
+        return n;
       }
     }
     return std::nullopt;
@@ -218,7 +241,7 @@ TYPE_PARSER(construct<OmpTraitSelectorName::Value>(
 TYPE_PARSER(sourced(construct<OmpTraitSelectorName>(
     // Parse predefined names first (because of SIMD).
     construct<OmpTraitSelectorName>(Parser<OmpTraitSelectorName::Value>{}) ||
-    construct<OmpTraitSelectorName>(OmpDirectiveNameParser{}) ||
+    construct<OmpTraitSelectorName>(unwrap(OmpDirectiveNameParser{})) ||
     // identifier-or-string for extensions
     construct<OmpTraitSelectorName>(
         applyFunction(nameToString, Parser<Name>{})) ||
@@ -480,7 +503,8 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
 TYPE_PARSER(sourced(
     construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
 
-TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))
+TYPE_PARSER(
+    sourced(construct<OmpIfClause::Modifier>(unwrap(OmpDirectiveNameParser{}))))
 
 TYPE_PARSER(sourced(construct<OmpInReductionClause::Modifier>(
     Parser<OmpReductionIdentifier>{})))
@@ -775,9 +799,9 @@ TYPE_PARSER(construct<OmpMessageClause>(expr))
 
 TYPE_PARSER(construct<OmpHoldsClause>(indirect(expr)))
 TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
-    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(unwrap(OmpDirectiveNameParser{})))))
 TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
-    construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
+    construct<llvm::omp::Directive>(unwrap(OmpDirectiveNameParser{})))))
 
 TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
                             parenthesized(Parser<OmpAbsentClause>{}))) ||
@@ -972,7 +996,7 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
 // --- Parsers for directives and constructs --------------------------
 
 TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( //
-    OmpDirectiveNameParser{},
+    sourced(OmpDirectiveNameParser{}),
     maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))),
     maybe(Parser<OmpClauseList>{}))))
 
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index 251b6919cf52f..e42022ceffa28 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -253,6 +253,21 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Name &x) {
   return os << x.ToString();
 }
 
+OmpDirectiveName::OmpDirectiveName(const Verbatim &name) {
+  std::string_view nameView{name.source.begin(), name.source.size()};
+  std::string nameLower{ToLowerCaseLetters(nameView)};
+  // If the name was actually "unknown" then accept it, otherwise flag
+  // OMPD_unknown (the default return value from getOpenMPDirectiveKind)
+  // as an error.
+  if (nameLower != "unknown") {
+    v = llvm::omp::getOpenMPDirectiveKind(nameLower);
+    assert(v != llvm::omp::Directive::OMPD_unknown && "Unrecognized directive");
+  } else {
+    v = llvm::omp::Directive::OMPD_unknown;
+  }
+  source = name.source;
+}
+
 OmpDependenceType::Value OmpDoacross::GetDepType() const {
   return common::visit( //
       common::visitors{
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 1df17b6d7382b..4f5c05dc2aa25 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2095,7 +2095,7 @@ class UnparseVisitor {
   }
   void Unparse(const OmpDirectiveSpecification &x) {
     using ArgList = std::list<parser::OmpArgument>;
-    Walk(std::get<llvm::omp::Directive>(x.t));
+    Walk(std::get<OmpDirectiveName>(x.t));
     if (auto &args{std::get<std::optional<ArgList>>(x.t)}) {
       Put("(");
       Walk(*args);
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index c6ed211549401..64a0be703744d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -625,7 +625,7 @@ void OmpStructureChecker::CheckHintClause(
 }
 
 void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
-  PushContextAndClauseSets(x.source, std::get<llvm::omp::Directive>(x.t));
+  PushContextAndClauseSets(x.source, x.DirId());
 }
 
 void OmpStructureChecker::Leave(const parser::OmpDirectiveSpecification &) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 38888a4dc1461..977c2fef34091 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -352,7 +352,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
   }
 
   bool Pre(const parser::OmpDirectiveSpecification &x) {
-    PushContext(x.source, std::get<llvm::omp::Directive>(x.t));
+    PushContext(x.source, x.DirId());
     return true;
   }
   void Post(const parser::OmpDirectiveSpecification &) { PopContext(); }
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 4f80cdca0f4bb..e57abf8ac0912 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1775,11 +1775,10 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
   // Disable the semantic analysis for it for now to allow the compiler to
   // parse METADIRECTIVE without flagging errors.
   AddOmpSourceRange(x.source);
-  auto dirId{std::get<llvm::omp::Directive>(x.t)};
   auto &maybeArgs{std::get<std::optional<std::list<parser::OmpArgument>>>(x.t)};
   auto &maybeClauses{std::get<std::optional<parser::OmpClauseList>>(x.t)};
 
-  switch (dirId) {
+  switch (x.DirId()) {
   case llvm::omp::Directive::OMPD_declare_mapper:
     if (maybeArgs && maybeClauses) {
       const parser::OmpArgument &first{maybeArgs->front()};
diff --git a/flang/test/Parser/OpenMP/metadirective-dirspec.f90 b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
index 73520c41fe77d..bf749d1f48c10 100644
--- a/flang/test/Parser/OpenMP/metadirective-dirspec.f90
+++ b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
@@ -25,7 +25,7 @@ subroutine f00(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = allocate
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = allocate
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpClauseList ->
 
@@ -51,7 +51,7 @@ subroutine f01(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = critical
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = critical
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpClauseList ->
 
@@ -76,7 +76,7 @@ subroutine f02
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare mapper
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare mapper
 !PARSE-TREE: | | | OmpArgument -> OmpMapperSpecifier
 !PARSE-TREE: | | | | Name = 'mymapper'
 !PARSE-TREE: | | | | TypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
@@ -120,7 +120,7 @@ subroutine f03
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare reduction
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare reduction
 !PARSE-TREE: | | | OmpArgument -> OmpReductionSpecifier
 !PARSE-TREE: | | | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE: | | | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
@@ -158,7 +158,7 @@ subroutine f04
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare simd
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare simd
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'f04'
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: ImplicitPart ->
@@ -183,7 +183,7 @@ subroutine f05
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare target
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare target
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'f05'
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: ImplicitPart ->
@@ -210,7 +210,7 @@ subroutine f06(x, y)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = flush
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'y'
 !PARSE-TREE: | | | OmpClauseList ->
@@ -237,6 +237,6 @@ subroutine f07
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = threadprivate
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = threadprivate
 !PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 't'
 !PARSE-TREE: | | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/metadirective-v50.f90 b/flang/test/Parser/OpenMP/metadirective-v50.f90
index d7c3121b8f1b8..6fef3376470a6 100644
--- a/flang/test/Parser/OpenMP/metadirective-v50.f90
+++ b/flang/test/Parser/OpenMP/metadirective-v50.f90
@@ -24,8 +24,8 @@ subroutine f01
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> Default -> OmpDefaultClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/metadirective.f90 b/flang/test/Parser/OpenMP/metadirective.f90
index dce31c2e7db26..1185ac897ecf6 100644
--- a/flang/test/Parser/OpenMP/metadirective.f90
+++ b/flang/test/Parser/OpenMP/metadirective.f90
@@ -20,7 +20,7 @@ subroutine f00
 !PARSE-TREE: | | | OmpTraitSelector
 !PARSE-TREE: | | | | OmpTraitSelectorName -> llvm::omp::Directive = parallel
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f01
@@ -47,7 +47,7 @@ subroutine f01
 !PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '1_4'
 !PARSE-TREE: | | | | | | LiteralConstant -> IntLiteralConstant = '1'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f02
@@ -74,7 +74,7 @@ subroutine f02
 !PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '7_4'
 !PARSE-TREE: | | | | | | LiteralConstant -> IntLiteralConstant = '7'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f03
@@ -98,7 +98,7 @@ subroutine f03
 !PARSE-TREE: | | | | Properties
 !PARSE-TREE: | | | | | OmpTraitProperty -> OmpClause -> AcqRel
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f04
@@ -132,7 +132,7 @@ subroutine f04
 !PARSE-TREE: | | | | | | | OmpTraitPropertyExtension -> Scalar -> Expr = '1_4'
 !PARSE-TREE: | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f05(x)
@@ -168,12 +168,12 @@ subroutine f05(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = parallel do
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = parallel do
 !PARSE-TREE: | | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause
 !PARSE-TREE: | | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
 !PARSE-TREE: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | OmpClause -> Otherwise -> OmpOtherwiseClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | OmpClauseList ->
 
 subroutine f06
@@ -207,7 +207,7 @@ subroutine f06
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = nothing
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = nothing
 !PARSE-TREE: | | | OmpClauseList ->
 
 subroutine f07
@@ -232,7 +232,7 @@ subroutine f07
 !PARSE-TREE: | | | | Properties
 !PARSE-TREE: | | | | | OmpTraitProperty -> OmpTraitPropertyName -> string = 'amd'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare simd
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare simd
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> When -> OmpWhenClause
 !PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector
@@ -244,8 +244,8 @@ subroutine f07
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | llvm::omp::Directive = declare target
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = declare target
 !PARSE-TREE: | | | OmpClauseList ->
 !PARSE-TREE: | OmpClause -> Otherwise -> OmpOtherwiseClause -> OmpDirectiveSpecification
-!PARSE-TREE: | | llvm::omp::Directive = nothing
-!PARSE-TREE: | | OmpClauseList ->
\ No newline at end of file
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = nothing
+!PARSE-TREE: | | OmpClauseList ->

Copy link
Contributor

@Leporacanthicus Leporacanthicus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I've got one question for my own education, and one "not sure how to fix it, but it's hard to match the code with the comment"

OmpDirectiveName::OmpDirectiveName(const Verbatim &name) {
std::string_view nameView{name.source.begin(), name.source.size()};
std::string nameLower{ToLowerCaseLetters(nameView)};
// If the name was actually "unknown" then accept it, otherwise flag
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads a bit "akward", at first I thought it was in fact backwards. Perhaps If the name is not "unknown", look up the kind. Result should not be OMPD_unknown. Accept "unknown" if that is the name.

Or, perhaps rearrange the code so it says if (nameLower == "unknown") v = OMPD_unkown; else ... .

Feel free to fix in any other way that you see fit.

Or, could we just do something like this:

   v = omp::getOpenMPDIrectiveKind(nameLower)
   assert(v != llvm::omp::Directive::OMPD_unknown || nameLower == "unknown" && "Unrecognized directive");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it. Let me rephrase that in a clearer way...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm just going to assert on "unknown" as well. There is no need to treat it as a special case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, simpler code with much clearer comment = good thing! :)

@@ -27,15 +27,38 @@ namespace Fortran::parser {
constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
constexpr auto endOmpLine = space >> endOfLine;

template <typename Parser> struct UnwrapParser {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my understanding, this is basically just a way to get to the .v (Directive) of the outer directive struct, becuse we used to directly store the id and without the wrapper.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's the .v part, but in a form of a parser, so that it is composable with other parsers.

Copy link
Contributor

@Leporacanthicus Leporacanthicus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kparzysz kparzysz merged commit 90f45a1 into main Mar 7, 2025
11 checks passed
@kparzysz kparzysz deleted the users/kparzysz/spr/o01-directive-name branch March 7, 2025 13:56
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 7, 2025

LLVM Buildbot has detected a new failure on builder ppc64le-flang-rhel-clang running on ppc64le-flang-rhel-test while building flang at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/21794

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
52.445 [126/121/6501] Linking CXX executable bin/mlir-transform-opt
52.553 [126/120/6502] Linking CXX executable bin/clang-21
52.711 [125/120/6503] Creating executable symlink bin/clang
52.916 [125/119/6504] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-namelist.cpp.o
52.977 [125/118/6505] Linking CXX executable bin/mlir-opt
53.036 [125/117/6506] Linking CXX shared library lib/libclang-cpp.so.21.0git
53.111 [124/117/6507] Creating library symlink lib/libclang-cpp.so
53.234 [124/116/6508] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/debug-parser.cpp.o
58.673 [124/115/6509] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/user-state.cpp.o
60.027 [124/114/6510] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o
FAILED: tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o 
ccache /home/buildbots/llvm-external-buildbots/clang.19.1.7/bin/clang++ -DFLANG_INCLUDE_TESTS=1 -DFLANG_LITTLE_ENDIAN=1 -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/tools/flang/lib/Parser -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/lib/Parser -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/include -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/tools/flang/include -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/include -I/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/llvm/include -isystem /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/../mlir/include -isystem /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/tools/mlir/include -isystem /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/tools/clang/include -isystem /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/llvm/../clang/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Werror -Wno-deprecated-copy -Wno-string-conversion -Wno-ctad-maybe-unsupported -Wno-unused-command-line-argument -Wstring-conversion           -Wcovered-switch-default -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o -MF tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o.d -o tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o -c /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/lib/Parser/parse-tree.cpp
/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/lib/Parser/parse-tree.cpp:341:30: error: moving a temporary object prevents copy elision [-Werror,-Wpessimizing-move]
  341 |   static OmpClauseList empty{std::move(decltype(OmpClauseList::v){})};
      |                              ^
/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/lib/Parser/parse-tree.cpp:341:30: note: remove std::move call here
  341 |   static OmpClauseList empty{std::move(decltype(OmpClauseList::v){})};
      |                              ^~~~~~~~~~                            ~
1 error generated.
61.180 [124/113/6511] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parsing.cpp.o
63.316 [124/112/6512] Building CXX object tools/flang/lib/Optimizer/Builder/CMakeFiles/FIRBuilder.dir/Runtime/Intrinsics.cpp.o
63.390 [124/111/6513] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-return.cpp.o
64.707 [124/110/6514] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-purity.cpp.o
66.069 [124/109/6515] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-allocate.cpp.o
68.487 [124/108/6516] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/io-parsers.cpp.o
73.731 [124/107/6517] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-nullify.cpp.o
74.333 [124/106/6518] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/program-tree.cpp.o
77.408 [124/105/6519] Building CXX object tools/flang/tools/flang-driver/CMakeFiles/flang.dir/driver.cpp.o
78.393 [124/104/6520] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/expr-parsers.cpp.o
78.540 [124/103/6521] Building CXX object tools/flang/tools/flang-driver/CMakeFiles/flang.dir/fc1_main.cpp.o
82.499 [124/102/6522] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/symbol.cpp.o
82.807 [124/101/6523] Building CXX object tools/flang/lib/Evaluate/CMakeFiles/FortranEvaluate.dir/expression.cpp.o
83.546 [124/100/6524] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/scope.cpp.o
84.180 [124/99/6525] Building CXX object tools/flang/lib/Frontend/CMakeFiles/flangFrontend.dir/FrontendAction.cpp.o
84.940 [124/98/6526] Building CXX object tools/flang/lib/Frontend/CMakeFiles/flangFrontend.dir/CompilerInvocation.cpp.o
84.976 [124/97/6527] Building CXX object tools/flang/lib/FrontendTool/CMakeFiles/flangFrontendTool.dir/ExecuteCompilerInvocation.cpp.o
85.048 [124/96/6528] Building CXX object tools/flang/lib/Frontend/CMakeFiles/flangFrontend.dir/CompilerInstance.cpp.o
89.157 [124/95/6529] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-deallocate.cpp.o
89.223 [124/94/6530] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/runtime-type-info.cpp.o
89.376 [124/93/6531] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-arithmeticif.cpp.o
89.532 [124/92/6532] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/executable-parsers.cpp.o
89.846 [124/91/6533] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-if-stmt.cpp.o
89.951 [124/90/6534] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/type.cpp.o
91.812 [124/89/6535] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/compute-offsets.cpp.o
92.010 [124/88/6536] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-modifiers.cpp.o
92.556 [124/87/6537] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/tools.cpp.o
92.940 [124/86/6538] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-stop.cpp.o
93.195 [124/85/6539] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-select-rank.cpp.o
94.084 [124/84/6540] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/unparse-with-symbols.cpp.o

@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 7, 2025

LLVM Buildbot has detected a new failure on builder flang-aarch64-libcxx running on linaro-flang-aarch64-libcxx while building flang at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/89/builds/18113

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
86.191 [732/103/6538] Linking CXX executable bin/diagtool
86.192 [732/102/6539] Linking CXX shared library lib/libclangTooling.so.21.0git
86.464 [732/101/6540] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/attr.cpp.o
86.933 [732/100/6541] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/dump-expr.cpp.o
87.845 [732/99/6542] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
88.403 [732/98/6543] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/preprocessor.cpp.o
107.255 [732/97/6544] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/instrumented-parser.cpp.o
108.018 [732/96/6545] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/debug-parser.cpp.o
119.473 [732/95/6546] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parsing.cpp.o
122.705 [732/94/6547] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o
FAILED: tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o 
/usr/local/bin/c++ -DFLANG_INCLUDE_TESTS=1 -DFLANG_LITTLE_ENDIAN=1 -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/tools/flang/lib/Parser -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/flang/lib/Parser -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/flang/include -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/tools/flang/include -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/include -I/home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/llvm/include -isystem /home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/flang/../mlir/include -isystem /home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/tools/mlir/include -isystem /home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/tools/clang/include -isystem /home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/llvm/../clang/include -stdlib=libc++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Werror -Wno-deprecated-copy -Wno-string-conversion -Wno-ctad-maybe-unsupported -Wno-unused-command-line-argument -Wstring-conversion           -Wcovered-switch-default -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17 -fPIC  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o -MF tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o.d -o tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/parse-tree.cpp.o -c /home/tcwg-buildbot/worker/flang-aarch64-libcxx/llvm-project/flang/lib/Parser/parse-tree.cpp
../llvm-project/flang/lib/Parser/parse-tree.cpp:341:30: error: moving a temporary object prevents copy elision [-Werror,-Wpessimizing-move]
  341 |   static OmpClauseList empty{std::move(decltype(OmpClauseList::v){})};
      |                              ^
../llvm-project/flang/lib/Parser/parse-tree.cpp:341:30: note: remove std::move call here
  341 |   static OmpClauseList empty{std::move(decltype(OmpClauseList::v){})};
      |                              ^~~~~~~~~~                            ~
1 error generated.
123.374 [732/93/6548] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/tools.cpp.o
125.833 [732/92/6549] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/expr-parsers.cpp.o
128.733 [732/91/6550] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/io-parsers.cpp.o
128.825 [732/90/6551] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/user-state.cpp.o
140.105 [732/89/6552] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/canonicalize-do.cpp.o
142.197 [732/88/6553] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/openacc-parsers.cpp.o
144.975 [732/87/6554] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/canonicalize-omp.cpp.o
184.342 [732/86/6555] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-arithmeticif.cpp.o
184.962 [732/85/6556] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-modifiers.cpp.o
185.233 [732/84/6557] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-return.cpp.o
186.617 [732/83/6558] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-io.cpp.o
191.323 [732/82/6559] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-stop.cpp.o
191.333 [732/81/6560] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-allocate.cpp.o
193.548 [732/80/6561] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/compute-offsets.cpp.o
197.602 [732/79/6562] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-deallocate.cpp.o
200.917 [732/78/6563] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-if-stmt.cpp.o
203.069 [732/77/6564] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-nullify.cpp.o
203.287 [732/76/6565] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-purity.cpp.o
204.120 [732/75/6566] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-namelist.cpp.o
206.203 [732/74/6567] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/program-tree.cpp.o
207.461 [732/73/6568] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/OpenMP/PrivateReductionUtils.cpp.o
213.813 [732/72/6569] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/IterationSpace.cpp.o
214.063 [732/71/6570] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/Mangler.cpp.o
220.128 [732/70/6571] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/program-parsers.cpp.o
221.102 [732/69/6572] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-select-type.cpp.o
221.782 [732/68/6573] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/Coarray.cpp.o
223.914 [732/67/6574] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/definable.cpp.o
225.325 [732/66/6575] Building CXX object tools/flang/lib/Evaluate/CMakeFiles/FortranEvaluate.dir/formatting.cpp.o
227.745 [732/65/6576] Building CXX object tools/flang/lib/Lower/CMakeFiles/FortranLower.dir/CustomIntrinsicCall.cpp.o
228.132 [732/64/6577] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/canonicalize-directives.cpp.o

jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
llvm#130121)

…ication

The `OmpDirectiveName` class has a source in addition to wrapping the
llvm::omp::Directive.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:openmp flang:parser flang:semantics flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants