llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-openacc

Author: Krzysztof Parzyszek (kparzysz)

<details>
<summary>Changes</summary>

In "get&lt;lang&gt;DirectiveName(Kind, Version)", return the spelling that 
corresponds to Version, and in "get&lt;lang&gt;DirectiveKindAndVersions(Name)" 
return the pair {Kind, VersionRange}, where VersionRange contains the minimum 
and the maximum versions that allow "Name" as a spelling. This applies to 
clauses as well. In general it applies to classes that have spellings (defined 
via TableGen class "Spelling").

Given a Kind and a Version, getting the corresponding spelling requires a 
runtime search (which can fail in a general case). To avoid generating the 
search function inline, a small additional component of llvm/Frontent was 
added: LLVMFrontendDirective. The corresponding header file also defines C++ 
classes "Spelling" and "VersionRange", which are used in 
TableGen/DirectiveEmitter as well.

For background information see
https://discourse.llvm.org/t/rfc-alternative-spellings-of-openmp-directives/85507

---

Patch is 26.55 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/141766.diff


10 Files Affected:

- (added) llvm/include/llvm/Frontend/Directive/Spelling.h (+39) 
- (modified) llvm/include/llvm/TableGen/DirectiveEmitter.h (+8-17) 
- (modified) llvm/lib/Frontend/CMakeLists.txt (+1) 
- (added) llvm/lib/Frontend/Directive/CMakeLists.txt (+6) 
- (added) llvm/lib/Frontend/Directive/Spelling.cpp (+31) 
- (modified) llvm/lib/Frontend/OpenACC/CMakeLists.txt (+1-1) 
- (modified) llvm/lib/Frontend/OpenMP/CMakeLists.txt (+1) 
- (modified) llvm/test/TableGen/directive1.td (+20-14) 
- (modified) llvm/test/TableGen/directive2.td (+12-12) 
- (modified) llvm/utils/TableGen/Basic/DirectiveEmitter.cpp (+93-53) 


``````````diff
diff --git a/llvm/include/llvm/Frontend/Directive/Spelling.h 
b/llvm/include/llvm/Frontend/Directive/Spelling.h
new file mode 100644
index 0000000000000..3ba0ae2296535
--- /dev/null
+++ b/llvm/include/llvm/Frontend/Directive/Spelling.h
@@ -0,0 +1,39 @@
+//===-- Spelling.h ------------------------------------------------ C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_FRONTEND_DIRECTIVE_SPELLING_H
+#define LLVM_FRONTEND_DIRECTIVE_SPELLING_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+
+#include <limits>
+
+namespace llvm::directive {
+
+struct VersionRange {
+  static constexpr int MaxValue = std::numeric_limits<int>::max();
+  int Min = 1;
+  int Max = MaxValue;
+};
+
+inline bool operator<(const VersionRange &A, const VersionRange &B) {
+  if (A.Min != B.Min)
+    return A.Min < B.Min;
+  return A.Max < B.Max;
+}
+
+struct Spelling {
+  StringRef Name;
+  VersionRange Versions;
+};
+
+StringRef FindName(llvm::iterator_range<const Spelling *>, unsigned Version);
+
+} // namespace llvm::directive
+
+#endif // LLVM_FRONTEND_DIRECTIVE_SPELLING_H
diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h 
b/llvm/include/llvm/TableGen/DirectiveEmitter.h
index 1235b7638e761..c7d7460087723 100644
--- a/llvm/include/llvm/TableGen/DirectiveEmitter.h
+++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Frontend/Directive/Spelling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/TableGen/Record.h"
 #include <algorithm>
@@ -113,29 +114,19 @@ class Versioned {
   constexpr static int IntWidth = 8 * sizeof(int);
 };
 
-// Range of specification versions: [Min, Max]
-// Default value: all possible versions.
-// This is the same structure as the one emitted into the generated sources.
-#define STRUCT_VERSION_RANGE                                                   
\
-  struct VersionRange {                                                        
\
-    int Min = 1;                                                               
\
-    int Max = INT_MAX;                                                         
\
-  }
-
-STRUCT_VERSION_RANGE;
-
 class Spelling : public Versioned {
 public:
-  using Value = std::pair<StringRef, VersionRange>;
+  using Value = llvm::directive::Spelling;
 
   Spelling(const Record *Def) : Def(Def) {}
 
   StringRef getText() const { return Def->getValueAsString("spelling"); }
-  VersionRange getVersions() const {
-    return VersionRange{getMinVersion(Def), getMaxVersion(Def)};
+  llvm::directive::VersionRange getVersions() const {
+    return llvm::directive::VersionRange{getMinVersion(Def),
+                                         getMaxVersion(Def)};
   }
 
-  Value get() const { return std::make_pair(getText(), getVersions()); }
+  Value get() const { return Value{getText(), getVersions()}; }
 
 private:
   const Record *Def;
@@ -177,11 +168,11 @@ class BaseRecord {
     // are added.
     Spelling::Value Oldest{"not found", {/*Min=*/INT_MAX, 0}};
     for (auto V : getSpellings()) {
-      if (V.second.Min < Oldest.second.Min) {
+      if (V.Versions.Min < Oldest.Versions.Min) {
         Oldest = V;
       }
     }
-    return Oldest.first;
+    return Oldest.Name;
   }
 
   // Returns the name of the directive formatted for output. Whitespace are
diff --git a/llvm/lib/Frontend/CMakeLists.txt b/llvm/lib/Frontend/CMakeLists.txt
index b305ce7d771ce..3b31e6f8dec96 100644
--- a/llvm/lib/Frontend/CMakeLists.txt
+++ b/llvm/lib/Frontend/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(Atomic)
+add_subdirectory(Directive)
 add_subdirectory(Driver)
 add_subdirectory(HLSL)
 add_subdirectory(OpenACC)
diff --git a/llvm/lib/Frontend/Directive/CMakeLists.txt 
b/llvm/lib/Frontend/Directive/CMakeLists.txt
new file mode 100644
index 0000000000000..a567e1affb171
--- /dev/null
+++ b/llvm/lib/Frontend/Directive/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_llvm_component_library(LLVMFrontendDirective
+  Spelling.cpp
+
+  LINK_COMPONENTS
+  Support
+)
diff --git a/llvm/lib/Frontend/Directive/Spelling.cpp 
b/llvm/lib/Frontend/Directive/Spelling.cpp
new file mode 100644
index 0000000000000..c808e625ee4fd
--- /dev/null
+++ b/llvm/lib/Frontend/Directive/Spelling.cpp
@@ -0,0 +1,31 @@
+//===-- Spelling.cpp ---------------------------------------------- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/Directive/Spelling.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
+
+#include <cassert>
+
+llvm::StringRef llvm::directive::FindName(
+    llvm::iterator_range<const llvm::directive::Spelling *> Range,
+    unsigned Version) {
+  assert(llvm::isInt<8 * sizeof(int)>(Version) && "Version value out of 
range");
+
+  int V = Version;
+  Spelling Tmp{StringRef(), {V, V}};
+  auto F =
+      llvm::lower_bound(Range, Tmp, [](const Spelling &A, const Spelling &B) {
+        return A.Versions < B.Versions;
+      });
+  if (F != Range.end())
+    return F->Name;
+  return StringRef();
+}
diff --git a/llvm/lib/Frontend/OpenACC/CMakeLists.txt 
b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
index f352014978690..4664b71407c48 100644
--- a/llvm/lib/Frontend/OpenACC/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenACC/CMakeLists.txt
@@ -9,5 +9,5 @@ add_llvm_component_library(LLVMFrontendOpenACC
   acc_gen
 )
 
-target_link_libraries(LLVMFrontendOpenACC LLVMSupport)
+target_link_libraries(LLVMFrontendOpenACC LLVMSupport LLVMFrontendDirective)
 
diff --git a/llvm/lib/Frontend/OpenMP/CMakeLists.txt 
b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
index 35c607866a94e..5bf15ca3a8991 100644
--- a/llvm/lib/Frontend/OpenMP/CMakeLists.txt
+++ b/llvm/lib/Frontend/OpenMP/CMakeLists.txt
@@ -23,4 +23,5 @@ add_llvm_component_library(LLVMFrontendOpenMP
   BitReader
   FrontendOffloading
   FrontendAtomic
+  FrontendDirective
   )
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
index 8196a30d03df4..1c8da26f50f4b 100644
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -54,6 +54,7 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:  #include "llvm/ADT/ArrayRef.h"
 // CHECK-NEXT:  #include "llvm/ADT/BitmaskEnum.h"
 // CHECK-NEXT:  #include "llvm/ADT/StringRef.h"
+// CHECK-NEXT:  #include "llvm/Frontend/Directive/Spelling.h"
 // CHECK-NEXT:  #include "llvm/Support/Compiler.h"
 // CHECK-NEXT:  #include <cstddef>
 // CHECK-NEXT:  #include <utility>
@@ -63,8 +64,6 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
 // CHECK-EMPTY:
-// CHECK-NEXT:  struct VersionRange { int Min = 1; int Max = 0x7fffffff; };
-// CHECK-EMPTY:
 // CHECK-NEXT:  enum class Association {
 // CHECK-NEXT:    Block,
 // CHECK-NEXT:    Declaration,
@@ -126,14 +125,14 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:  constexpr auto TDLCV_valc = AKind::TDLCV_valc;
 // CHECK-EMPTY:
 // CHECK-NEXT:  // Enumeration helper functions
-// CHECK-NEXT:  LLVM_ABI std::pair<Directive, VersionRange> 
getTdlDirectiveKindAndVersions(StringRef Str);
+// CHECK-NEXT:  LLVM_ABI std::pair<Directive, directive::VersionRange> 
getTdlDirectiveKindAndVersions(StringRef Str);
 // CHECK-NEXT:  inline Directive getTdlDirectiveKind(StringRef Str) {
 // CHECK-NEXT:   return getTdlDirectiveKindAndVersions(Str).first;
 // CHECK-NEXT:  }
 // CHECK-EMPTY:
 // CHECK-NEXT:  LLVM_ABI StringRef getTdlDirectiveName(Directive D, unsigned 
Ver = 0);
 // CHECK-EMPTY:
-// CHECK-NEXT:  LLVM_ABI std::pair<Clause, VersionRange> 
getTdlClauseKindAndVersions(StringRef Str);
+// CHECK-NEXT:  LLVM_ABI std::pair<Clause, directive::VersionRange> 
getTdlClauseKindAndVersions(StringRef Str);
 // CHECK-EMPTY:
 // CHECK-NEXT:  inline Clause getTdlClauseKind(StringRef Str) {
 // CHECK-NEXT:    return getTdlClauseKindAndVersions(Str).first;
@@ -320,17 +319,18 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // IMPL:       #ifdef GEN_DIRECTIVES_IMPL
 // IMPL-NEXT:  #undef GEN_DIRECTIVES_IMPL
 // IMPL-EMPTY:
+// IMPL-NEXT:  #include "llvm/Frontend/Directive/Spelling.h"
 // IMPL-NEXT:  #include "llvm/Support/ErrorHandling.h"
 // IMPL-NEXT:  #include <utility>
 // IMPL-EMPTY:
-// IMPL-NEXT: std::pair<llvm::tdl::Directive, llvm::tdl::VersionRange> 
llvm::tdl::getTdlDirectiveKindAndVersions(llvm::StringRef Str) {
-// IMPL-NEXT:   VersionRange All{}; // Default-initialized to "all-versions"
-// IMPL-NEXT:   return StringSwitch<std::pair<Directive, VersionRange>>(Str)
+// IMPL-NEXT: std::pair<llvm::tdl::Directive, llvm::directive::VersionRange> 
llvm::tdl::getTdlDirectiveKindAndVersions(llvm::StringRef Str) {
+// IMPL-NEXT:   directive::VersionRange All; // Default-initialized to "all 
versions"
+// IMPL-NEXT:   return StringSwitch<std::pair<Directive, 
directive::VersionRange>>(Str)
 // IMPL-NEXT:     .Case("dira", {TDLD_dira, All})
 // IMPL-NEXT:     .Default({TDLD_dira, All});
 // IMPL-NEXT: }
 // IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef 
llvm::tdl::getTdlDirectiveName(llvm::tdl::Directive Kind, unsigned) {
+// IMPL-NEXT:  llvm::StringRef 
llvm::tdl::getTdlDirectiveName(llvm::tdl::Directive Kind, unsigned Version) {
 // IMPL-NEXT:    switch (Kind) {
 // IMPL-NEXT:      case TDLD_dira:
 // IMPL-NEXT:        return "dira";
@@ -338,23 +338,29 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
 // IMPL-NEXT:  }
 // IMPL-EMPTY:
-// IMPL-NEXT: std::pair<llvm::tdl::Clause, llvm::tdl::VersionRange> 
llvm::tdl::getTdlClauseKindAndVersions(llvm::StringRef Str) {
-// IMPL-NEXT:   VersionRange All{}; // Default-initialized to "all-versions"
-// IMPL-NEXT:   return StringSwitch<std::pair<Clause, VersionRange>>(Str)
+// IMPL-NEXT: std::pair<llvm::tdl::Clause, llvm::directive::VersionRange> 
llvm::tdl::getTdlClauseKindAndVersions(llvm::StringRef Str) {
+// IMPL-NEXT:   directive::VersionRange All; // Default-initialized to "all 
versions"
+// IMPL-NEXT:   return StringSwitch<std::pair<Clause, 
directive::VersionRange>>(Str)
 // IMPL-NEXT:     .Case("clausea", {TDLC_clausea, All})
 // IMPL-NEXT:     .Case("clauseb", {TDLC_clauseb, All})
 // IMPL-NEXT:     .Case("clausec", {TDLC_clausec, All})
+// IMPL-NEXT:     .Case("ccccccc", {TDLC_clausec, All})
 // IMPL-NEXT:     .Default({TDLC_clauseb, All});
 // IMPL-NEXT: }
 // IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(llvm::tdl::Clause 
Kind, unsigned) {
+// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(llvm::tdl::Clause 
Kind, unsigned Version) {
 // IMPL-NEXT:    switch (Kind) {
 // IMPL-NEXT:      case TDLC_clausea:
 // IMPL-NEXT:        return "clausea";
 // IMPL-NEXT:      case TDLC_clauseb:
 // IMPL-NEXT:        return "clauseb";
-// IMPL-NEXT:      case TDLC_clausec:
-// IMPL-NEXT:        return "clausec";
+// IMPL-NEXT:      case TDLC_clausec: {
+// IMPL-NEXT:        static const llvm::directive::Spelling 
TDLC_clausec_spellings[] = {
+// IMPL-NEXT:            {"clausec", {1, 2147483647}},
+// IMPL-NEXT:            {"ccccccc", {1, 2147483647}},
+// IMPL-NEXT:        };
+// IMPL-NEXT:        return llvm::directive::FindName(TDLC_clausec_spellings, 
Version);
+// IMPL-NEXT:      }
 // IMPL-NEXT:    }
 // IMPL-NEXT:    llvm_unreachable("Invalid Tdl Clause kind");
 // IMPL-NEXT:  }
diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td
index ead6aa2637b76..3a64bb3900a31 100644
--- a/llvm/test/TableGen/directive2.td
+++ b/llvm/test/TableGen/directive2.td
@@ -47,6 +47,7 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-EMPTY:
 // CHECK-NEXT:  #include "llvm/ADT/ArrayRef.h"
 // CHECK-NEXT:  #include "llvm/ADT/StringRef.h"
+// CHECK-NEXT:  #include "llvm/Frontend/Directive/Spelling.h"
 // CHECK-NEXT:  #include "llvm/Support/Compiler.h"
 // CHECK-NEXT:  #include <cstddef>
 // CHECK-NEXT:  #include <utility>
@@ -54,8 +55,6 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:  namespace llvm {
 // CHECK-NEXT:  namespace tdl {
 // CHECK-EMPTY:
-// CHECK-NEXT:  struct VersionRange { int Min = 1; int Max = 0x7fffffff; };
-// CHECK-EMPTY:
 // CHECK-NEXT:  enum class Association {
 // CHECK-NEXT:    Block,
 // CHECK-NEXT:    Declaration,
@@ -102,14 +101,14 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // CHECK-NEXT:  static constexpr std::size_t Clause_enumSize = 4;
 // CHECK-EMPTY:
 // CHECK-NEXT:  // Enumeration helper functions
-// CHECK-NEXT:  LLVM_ABI std::pair<Directive, VersionRange> 
getTdlDirectiveKindAndVersions(StringRef Str);
+// CHECK-NEXT:  LLVM_ABI std::pair<Directive, directive::VersionRange> 
getTdlDirectiveKindAndVersions(StringRef Str);
 // CHECK-NEXT:  inline Directive getTdlDirectiveKind(StringRef Str) {
 // CHECK-NEXT:    return getTdlDirectiveKindAndVersions(Str).first;
 // CHECK-NEXT:  }
 // CHECK-EMPTY:
 // CHECK-NEXT:  LLVM_ABI StringRef getTdlDirectiveName(Directive D, unsigned 
Ver = 0);
 // CHECK-EMPTY:
-// CHECK-NEXT:  LLVM_ABI std::pair<Clause, VersionRange> 
getTdlClauseKindAndVersions(StringRef Str);
+// CHECK-NEXT:  LLVM_ABI std::pair<Clause, directive::VersionRange> 
getTdlClauseKindAndVersions(StringRef Str);
 // CHECK-EMPTY:
 // CHECK-NEXT:  inline Clause getTdlClauseKind(StringRef Str) {
 // CHECK-NEXT:    return getTdlClauseKindAndVersions(Str).first;
@@ -267,17 +266,18 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // IMPL:       #ifdef GEN_DIRECTIVES_IMPL
 // IMPL-NEXT:  #undef GEN_DIRECTIVES_IMPL
 // IMPL-EMPTY:
+// IMPL-NEXT:  #include "llvm/Frontend/Directive/Spelling.h"
 // IMPL-NEXT:  #include "llvm/Support/ErrorHandling.h"
 // IMPL-NEXT:  #include <utility>
 // IMPL-EMPTY:
-// IMPL-NEXT: std::pair<llvm::tdl::Directive, llvm::tdl::VersionRange> 
llvm::tdl::getTdlDirectiveKindAndVersions(llvm::StringRef Str) {
-// IMPL-NEXT:   VersionRange All{}; // Default-initialized to "all-versions"
-// IMPL-NEXT:   return StringSwitch<std::pair<Directive, VersionRange>>(Str)
+// IMPL-NEXT: std::pair<llvm::tdl::Directive, llvm::directive::VersionRange> 
llvm::tdl::getTdlDirectiveKindAndVersions(llvm::StringRef Str) {
+// IMPL-NEXT:   directive::VersionRange All; // Default-initialized to "all 
versions"
+// IMPL-NEXT:   return StringSwitch<std::pair<Directive, 
directive::VersionRange>>(Str)
 // IMPL-NEXT:     .Case("dira", {TDLD_dira, All})
 // IMPL-NEXT:     .Default({TDLD_dira, All});
 // IMPL-NEXT: }
 // IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef 
llvm::tdl::getTdlDirectiveName(llvm::tdl::Directive Kind, unsigned) {
+// IMPL-NEXT:  llvm::StringRef 
llvm::tdl::getTdlDirectiveName(llvm::tdl::Directive Kind, unsigned Version) {
 // IMPL-NEXT:    switch (Kind) {
 // IMPL-NEXT:      case TDLD_dira:
 // IMPL-NEXT:        return "dira";
@@ -285,9 +285,9 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // IMPL-NEXT:    llvm_unreachable("Invalid Tdl Directive kind");
 // IMPL-NEXT:  }
 // IMPL-EMPTY:
-// IMPL-NEXT: std::pair<llvm::tdl::Clause, llvm::tdl::VersionRange> 
llvm::tdl::getTdlClauseKindAndVersions(llvm::StringRef Str) {
-// IMPL-NEXT:   VersionRange All{}; // Default-initialized to "all-versions"
-// IMPL-NEXT:   return StringSwitch<std::pair<Clause, VersionRange>>(Str)
+// IMPL-NEXT: std::pair<llvm::tdl::Clause, llvm::directive::VersionRange> 
llvm::tdl::getTdlClauseKindAndVersions(llvm::StringRef Str) {
+// IMPL-NEXT:   directive::VersionRange All; // Default-initialized to "all 
versions"
+// IMPL-NEXT:   return StringSwitch<std::pair<Clause, 
directive::VersionRange>>(Str)
 // IMPL-NEXT:     .Case("clausea", {TDLC_clauseb, All})
 // IMPL-NEXT:     .Case("clauseb", {TDLC_clauseb, All})
 // IMPL-NEXT:     .Case("clausec", {TDLC_clausec, All})
@@ -295,7 +295,7 @@ def TDL_DirA : Directive<[Spelling<"dira">]> {
 // IMPL-NEXT:     .Default({TDLC_clauseb, All});
 // IMPL-NEXT: }
 // IMPL-EMPTY:
-// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(llvm::tdl::Clause 
Kind, unsigned) {
+// IMPL-NEXT:  llvm::StringRef llvm::tdl::getTdlClauseName(llvm::tdl::Clause 
Kind, unsigned Version) {
 // IMPL-NEXT:    switch (Kind) {
 // IMPL-NEXT:      case TDLC_clausea:
 // IMPL-NEXT:        return "clausea";
diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp 
b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
index e1e41b3ecb584..84438de067dce 100644
--- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp
@@ -77,6 +77,19 @@ static std::string getIdentifierName(const Record *Rec, 
StringRef Prefix) {
   return Prefix.str() + BaseRecord(Rec).getFormattedName();
 }
 
+using RecordWithSpelling = std::pair<const Record *, Spelling::Value>;
+
+static std::vector<RecordWithSpelling>
+getSpellings(ArrayRef<const Record *> Records) {
+  std::vector<RecordWithSpelling> List;
+  for (const Record *R : Records) {
+    Clause C(R);
+    llvm::transform(C.getSpellings(), std::back_inserter(List),
+                    [R](Spelling::Value V) { return std::make_pair(R, V); });
+  }
+  return List;
+}
+
 static void generateEnumExports(ArrayRef<const Record *> Records,
                                 raw_ostream &OS, StringRef Enum,
                                 StringRef Prefix) {
@@ -270,6 +283,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, 
raw_ostream &OS) {
     OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n";
 
   OS << "#include \"llvm/ADT/StringRef.h\"\n";
+  OS << "#include \"llvm/Frontend/Directive/Spelling.h\"\n";
   OS << "#include \"llvm/Support/Compiler.h\"\n";
   OS << "#include <cstddef>\n"; // for size_t
   OS << "#include <utility>\n"; // for std::pair
@@ -285,13 +299,6 @@ static void emitDirectivesDecl(const RecordKeeper 
&Records, raw_ostream &OS) {
   if (DirLang.hasEnableBitmaskEnumInNamespace())
     OS << "\nLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n";
 
-#define AS_STRING_HELPER_TO_GET_THE_ARGUMENT_MACRO_EXPANDED(x) #x
-#define AS_STRING(x) AS_STRING_HELPER_TO_GET_THE_ARGUMENT_MACRO_EXPANDED(x)
-  OS << "\n";
-  OS << AS_STRING(STRUCT_VERSION_RANGE) << ";\n";
-#undef AS_STRING
-#undef AS_STRING_HELPER_TO_GET_THE_ARGUMENT_MACRO_EXPANDED
-
   // Emit Directive associations
   std::vector<const Record *> Associations;
   copy_if(DirLang.getAssociations(), std::back_inserter(Associations),
@@ -324,7 +331,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, 
raw_ostream &OS) {
   OS << "\n";
   OS << "// Enumeration helper functions\n";
 
-  OS << "LLVM_ABI std::pair<Directive, VersionRange> get" << Lang
+  OS << "LLVM_ABI std::pair<Directive, directive::VersionRange> get" << Lang
      << "DirectiveKindAndVersions(StringRef Str);\n";
 
   OS << "inline Directive get" << Lang << "DirectiveKind(StringRef Str) {\n";
@@ -336,7 +343,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, 
raw_ostream &OS) {
      << "DirectiveName(Directive D, unsigned Ver = 0);\n";
   OS << "\n";
 
-  OS << "LLVM_ABI std::pair<Clause, VersionRange> get" << Lang
+  OS << "LLVM_ABI std::pair<Clause, directive::VersionRange> get" << Lang
      << "ClauseKindAndVersions(StringRef Str);\n";
   OS << "\n";
 
@@ -373,6 +380,33 @@ static void emitDirectivesDecl(const RecordKeeper 
&Records, raw_ostream &OS) {
   OS << "#endif // LLVM_" << Lang << "_INC\n";
 }
 
+// Given a list of spellings (for a given clause/directive), order them
+// in a way that allows the use of binary search to locate a spelling
+// for a specified version.
+static std::vector<Spelling::Value>
+orderSpellings(ArrayRef<Spelling::Value> Spellings) {
+  std::vector<Spelling::Value> List(Spellings.begin(), Spellings.end());
+
+  // There are two intertwined orderings: (1) the order between spellings
+  // (used here), and (2) the order between a spelling and a version (used
+  // at runtime).
+  // Define order (2) as such that the first A that is not less than V
+  // will be the selected spelling given V. Specifically,
+  //   V <(2) A  <=>  V < A.Min
+  //   A <(2) V  <=>  A.Max < V
+  //
+  // Th...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/141766
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to