LLVM 23.0.0git
DirectiveEmitter.h
Go to the documentation of this file.
1//===- DirectiveEmitter.h - Directive Language Emitter ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// DirectiveEmitter uses the descriptions of directives and clauses to construct
10// common code declarations to be used in Frontends.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H
15#define LLVM_TABLEGEN_DIRECTIVEEMITTER_H
16
17#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringRef.h"
23#include <string>
24#include <vector>
25
26namespace llvm {
27
28// Wrapper class that contains DirectiveLanguage's information defined in
29// DirectiveBase.td and provides helper methods for accessing it.
31public:
32 explicit DirectiveLanguage(const RecordKeeper &Records) : Records(Records) {
33 const auto &DirectiveLanguages = getDirectiveLanguages();
34 Def = DirectiveLanguages[0];
35 }
36
37 StringRef getName() const { return Def->getValueAsString("name"); }
38
40 return Def->getValueAsString("cppNamespace");
41 }
42
44 return Def->getValueAsString("directivePrefix");
45 }
46
48 return Def->getValueAsString("clausePrefix");
49 }
50
52 return Def->getValueAsString("loopModifierPrefix");
53 }
54
56 return Def->getValueAsString("clauseEnumSetClass");
57 }
58
60 return Def->getValueAsString("flangClauseBaseClass");
61 }
62
64 return Def->getValueAsBit("makeEnumAvailableInNamespace");
65 }
66
68 return Def->getValueAsBit("enableBitmaskEnumInNamespace");
69 }
70
72 return Records.getAllDerivedDefinitions("Association");
73 }
74
76 return Records.getAllDerivedDefinitions("Category");
77 }
78
80 return Records.getAllDerivedDefinitions("SourceLanguage");
81 }
82
84 return Records.getAllDerivedDefinitions("Directive");
85 }
86
88 return Records.getAllDerivedDefinitions("Clause");
89 }
90
92 return Records.getAllDerivedDefinitions("LoopModifier");
93 }
94
95 bool HasValidityErrors() const;
96
97private:
98 const Record *Def;
99 const RecordKeeper &Records;
100
101 ArrayRef<const Record *> getDirectiveLanguages() const {
102 return Records.getAllDerivedDefinitions("DirectiveLanguage");
103 }
104};
105
107public:
108 int getMinVersion(const Record *R) const {
109 int64_t Min = R->getValueAsInt("minVersion");
110 assert(llvm::isInt<IntWidth>(Min) && "Value out of range of 'int'");
111 return Min;
112 }
113
114 int getMaxVersion(const Record *R) const {
115 int64_t Max = R->getValueAsInt("maxVersion");
116 assert(llvm::isInt<IntWidth>(Max) && "Value out of range of 'int'");
117 return Max;
118 }
119
120private:
121 constexpr static int IntWidth = 8 * sizeof(int);
122};
123
124class Spelling : public Versioned {
125public:
127
128 Spelling(const Record *Def) : Def(Def) {}
129
130 StringRef getText() const { return Def->getValueAsString("spelling"); }
135
136 Value get() const { return Value{getText(), getVersions()}; }
137
138private:
139 const Record *Def;
140};
141
142// Note: In all the classes below, allow implicit construction from Record *,
143// to allow writing code like:
144// for (const Directive D : getDirectives()) {
145//
146// instead of:
147//
148// for (const Record *R : getDirectives()) {
149// Directive D(R);
150
151// Base record class used for Directive and Clause class defined in
152// DirectiveBase.td.
154public:
156
157 std::vector<Spelling::Value> getSpellings() const {
158 std::vector<Spelling::Value> List;
159 llvm::transform(Def->getValueAsListOfDefs("spellings"),
160 std::back_inserter(List),
161 [](const Record *R) { return Spelling(R).get(); });
162 return List;
163 }
164
166 // From all spellings, pick the first one with the minimum version
167 // (i.e. pick the first from all the oldest ones). This guarantees
168 // that given several equivalent (in terms of versions) names, the
169 // first one is used, e.g. given
170 // Clause<[Spelling<"foo">, Spelling<"bar">]> ...
171 // "foo" will be the selected spelling.
172 //
173 // This is a suitable spelling for generating an identifier name,
174 // since it will remain unchanged when any potential new spellings
175 // are added.
176 Spelling::Value Oldest{"not found", {/*Min=*/INT_MAX, 0}};
177 for (auto V : getSpellings())
178 if (V.Versions.Min < Oldest.Versions.Min)
179 Oldest = V;
180 return Oldest.Name;
181 }
182
183 // Returns the name of the directive formatted for output. Whitespace are
184 // replaced with underscores.
185 static std::string getSnakeName(StringRef Name) {
186 std::string N = Name.str();
187 llvm::replace(N, ' ', '_');
188 return N;
189 }
190
191 // Take a string Name with sub-words separated with characters from Sep,
192 // and return a string with each of the sub-words capitalized, and the
193 // separators removed, e.g.
194 // Name = "some_directive^name", Sep = "_^" -> "SomeDirectiveName".
195 static std::string getUpperCamelName(StringRef Name, StringRef Sep) {
196 std::string Camel = Name.str();
197 // Convert to uppercase
198 bool Cap = true;
199 llvm::transform(Camel, Camel.begin(), [&](unsigned char C) {
200 if (Sep.contains(C)) {
201 assert(!Cap && "No initial or repeated separators");
202 Cap = true;
203 } else if (Cap) {
204 C = llvm::toUpper(C);
205 Cap = false;
206 }
207 return C;
208 });
209 size_t Out = 0;
210 // Remove separators
211 for (size_t In = 0, End = Camel.size(); In != End; ++In) {
212 unsigned char C = Camel[In];
213 if (!Sep.contains(C))
214 Camel[Out++] = C;
215 }
216 Camel.resize(Out);
217 return Camel;
218 }
219
220 std::string getFormattedName() const {
221 if (auto maybeName = Def->getValueAsOptionalString("name"))
222 return getSnakeName(*maybeName);
224 }
225
226 bool isDefault() const { return Def->getValueAsBit("isDefault"); }
227
228 // Returns the record name.
229 StringRef getRecordName() const { return Def->getName(); }
230
231 const Record *getRecord() const { return Def; }
232
233protected:
234 const Record *Def;
235};
236
237// Wrapper class that contains a Directive's information defined in
238// DirectiveBase.td and provides helper methods for accessing it.
239class Directive : public BaseRecord {
240public:
242
243 std::vector<const Record *> getAllowedClauses() const {
244 return Def->getValueAsListOfDefs("allowedClauses");
245 }
246
247 std::vector<const Record *> getAllowedOnceClauses() const {
248 return Def->getValueAsListOfDefs("allowedOnceClauses");
249 }
250
251 std::vector<const Record *> getAllowedExclusiveClauses() const {
252 return Def->getValueAsListOfDefs("allowedExclusiveClauses");
253 }
254
255 std::vector<const Record *> getRequiredClauses() const {
256 return Def->getValueAsListOfDefs("requiredClauses");
257 }
258
259 std::vector<const Record *> getLeafConstructs() const {
260 return Def->getValueAsListOfDefs("leafConstructs");
261 }
262
263 const Record *getAssociation() const {
264 return Def->getValueAsDef("association");
265 }
266
267 const Record *getCategory() const { return Def->getValueAsDef("category"); }
268
269 std::vector<const Record *> getSourceLanguages() const {
270 return Def->getValueAsListOfDefs("languages");
271 }
272
273 std::vector<const Record *> getAllowedLoopModifiers() const {
274 return Def->getValueAsListOfDefs("allowedLoopModifiers");
275 }
276
277 // Clang uses a different format for names of its directives enum.
278 std::string getClangAccSpelling() const {
280
281 // Clang calls the 'unknown' value 'invalid'.
282 if (Name == "unknown")
283 return "Invalid";
284
285 return BaseRecord::getUpperCamelName(Name, " _");
286 }
287};
288
289// Wrapper class that contains Clause's information defined in DirectiveBase.td
290// and provides helper methods for accessing it.
291class Clause : public BaseRecord {
292public:
294
295 // Optional field.
297 return Def->getValueAsString("clangClass");
298 }
299
300 // Optional field.
302 return Def->getValueAsString("flangClass");
303 }
304
305 // Get the formatted name for Flang parser class. The generic formatted class
306 // name is constructed from the name were the first letter of each word is
307 // captitalized and the underscores are removed.
308 // ex: async -> Async
309 // num_threads -> NumThreads
310 std::string getFormattedParserClassName() const {
312 return BaseRecord::getUpperCamelName(Name, "_");
313 }
314
315 // Clang uses a different format for names of its clause enum, which can be
316 // overwritten with the `clangSpelling` value. So get the proper spelling
317 // here.
318 std::string getClangAccSpelling() const {
319 if (StringRef ClangSpelling = Def->getValueAsString("clangAccSpelling");
320 !ClangSpelling.empty())
321 return ClangSpelling.str();
322
324 return BaseRecord::getUpperCamelName(Name, "_");
325 }
326
327 // Optional field.
329 return Def->getValueAsString("enumClauseValue");
330 }
331
332 std::vector<const Record *> getClauseVals() const {
333 return Def->getValueAsListOfDefs("allowedClauseValues");
334 }
335
336 bool skipFlangUnparser() const {
337 return Def->getValueAsBit("skipFlangUnparser");
338 }
339
340 bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
341
342 bool isValueList() const { return Def->getValueAsBit("isValueList"); }
343
345 return Def->getValueAsString("defaultValue");
346 }
347
348 bool isImplicit() const { return Def->getValueAsBit("isImplicit"); }
349
350 std::vector<StringRef> getAliases() const {
351 return Def->getValueAsListOfStrings("aliases");
352 }
353
354 StringRef getPrefix() const { return Def->getValueAsString("prefix"); }
355
356 bool isPrefixOptional() const {
357 return Def->getValueAsBit("isPrefixOptional");
358 }
359};
360
361// Wrapper class that contains VersionedClause's information defined in
362// DirectiveBase.td and provides helper methods for accessing it.
364public:
365 VersionedClause(const Record *Def) : Def(Def) {}
366
367 // Return the specific clause record wrapped in the Clause class.
368 Clause getClause() const { return Clause(Def->getValueAsDef("clause")); }
369
370 int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); }
371
372 int64_t getMaxVersion() const { return Def->getValueAsInt("maxVersion"); }
373
374private:
375 const Record *Def;
376};
377
378class EnumVal : public BaseRecord {
379public:
381
382 int getValue() const { return Def->getValueAsInt("value"); }
383
384 bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); }
385};
386
387} // namespace llvm
388
389#endif // LLVM_TABLEGEN_DIRECTIVEEMITTER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
if(PassOpts->AAPipeline)
This file contains some templates that are useful if you are working with the STL at all.
This file contains some functions that are useful when dealing with strings.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
StringRef getSpellingForIdentifier() const
static std::string getSnakeName(StringRef Name)
StringRef getRecordName() const
static std::string getUpperCamelName(StringRef Name, StringRef Sep)
bool isDefault() const
std::string getFormattedName() const
const Record * Def
std::vector< Spelling::Value > getSpellings() const
BaseRecord(const Record *Def)
const Record * getRecord() const
StringRef getClangClass() const
std::vector< const Record * > getClauseVals() const
bool skipFlangUnparser() const
Clause(const Record *Def)
bool isImplicit() const
StringRef getDefaultValue() const
bool isValueOptional() const
bool isValueList() const
StringRef getFlangClass() const
std::vector< StringRef > getAliases() const
std::string getClangAccSpelling() const
StringRef getEnumName() const
bool isPrefixOptional() const
std::string getFormattedParserClassName() const
StringRef getPrefix() const
bool hasMakeEnumAvailableInNamespace() const
bool HasValidityErrors() const
StringRef getClausePrefix() const
StringRef getClauseEnumSetClass() const
DirectiveLanguage(const RecordKeeper &Records)
ArrayRef< const Record * > getAssociations() const
StringRef getLoopModifierPrefix() const
ArrayRef< const Record * > getDirectives() const
ArrayRef< const Record * > getClauses() const
ArrayRef< const Record * > getLoopModifiers() const
StringRef getName() const
ArrayRef< const Record * > getCategories() const
StringRef getDirectivePrefix() const
bool hasEnableBitmaskEnumInNamespace() const
StringRef getCppNamespace() const
ArrayRef< const Record * > getSourceLanguages() const
StringRef getFlangClauseBaseClass() const
const Record * getAssociation() const
std::vector< const Record * > getLeafConstructs() const
const Record * getCategory() const
std::vector< const Record * > getAllowedClauses() const
Directive(const Record *Def)
std::vector< const Record * > getAllowedOnceClauses() const
std::vector< const Record * > getRequiredClauses() const
std::vector< const Record * > getSourceLanguages() const
std::vector< const Record * > getAllowedLoopModifiers() const
std::string getClangAccSpelling() const
std::vector< const Record * > getAllowedExclusiveClauses() const
bool isUserVisible() const
int getValue() const
EnumVal(const Record *Def)
Spelling(const Record *Def)
StringRef getText() const
Value get() const
directive::Spelling Value
llvm::directive::VersionRange getVersions() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
int64_t getMinVersion() const
int64_t getMaxVersion() const
VersionedClause(const Record *Def)
int getMinVersion(const Record *R) const
int getMaxVersion(const Record *R) const
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
Definition STLExtras.h:2026
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1910
char toUpper(char x)
Returns the corresponding uppercase character if x is lowercase.
#define N
VersionRange Versions
Definition Spelling.h:34