1#ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H
2#define LLVM_TABLEGEN_DIRECTIVEEMITTER_H
3
4#include "llvm/ADT/STLExtras.h"
5#include "llvm/ADT/StringExtras.h"
6#include "llvm/ADT/StringRef.h"
7#include "llvm/TableGen/Record.h"
8#include <algorithm>
9#include <string>
10#include <vector>
11
12namespace llvm {
13
14// Wrapper class that contains DirectiveLanguage's information defined in
15// DirectiveBase.td and provides helper methods for accessing it.
16class DirectiveLanguage {
17public:
18 explicit DirectiveLanguage(const llvm::RecordKeeper &Records)
19 : Records(Records) {
20 const auto &DirectiveLanguages = getDirectiveLanguages();
21 Def = DirectiveLanguages[0];
22 }
23
24 StringRef getName() const { return Def->getValueAsString(FieldName: "name"); }
25
26 StringRef getCppNamespace() const {
27 return Def->getValueAsString(FieldName: "cppNamespace");
28 }
29
30 StringRef getDirectivePrefix() const {
31 return Def->getValueAsString(FieldName: "directivePrefix");
32 }
33
34 StringRef getClausePrefix() const {
35 return Def->getValueAsString(FieldName: "clausePrefix");
36 }
37
38 StringRef getClauseEnumSetClass() const {
39 return Def->getValueAsString(FieldName: "clauseEnumSetClass");
40 }
41
42 StringRef getFlangClauseBaseClass() const {
43 return Def->getValueAsString(FieldName: "flangClauseBaseClass");
44 }
45
46 bool hasMakeEnumAvailableInNamespace() const {
47 return Def->getValueAsBit(FieldName: "makeEnumAvailableInNamespace");
48 }
49
50 bool hasEnableBitmaskEnumInNamespace() const {
51 return Def->getValueAsBit(FieldName: "enableBitmaskEnumInNamespace");
52 }
53
54 std::vector<Record *> getDirectives() const {
55 return Records.getAllDerivedDefinitions(ClassName: "Directive");
56 }
57
58 std::vector<Record *> getClauses() const {
59 return Records.getAllDerivedDefinitions(ClassName: "Clause");
60 }
61
62 bool HasValidityErrors() const;
63
64private:
65 const llvm::Record *Def;
66 const llvm::RecordKeeper &Records;
67
68 std::vector<Record *> getDirectiveLanguages() const {
69 return Records.getAllDerivedDefinitions(ClassName: "DirectiveLanguage");
70 }
71};
72
73// Base record class used for Directive and Clause class defined in
74// DirectiveBase.td.
75class BaseRecord {
76public:
77 explicit BaseRecord(const llvm::Record *Def) : Def(Def) {}
78
79 StringRef getName() const { return Def->getValueAsString(FieldName: "name"); }
80
81 StringRef getAlternativeName() const {
82 return Def->getValueAsString(FieldName: "alternativeName");
83 }
84
85 // Returns the name of the directive formatted for output. Whitespace are
86 // replaced with underscores.
87 std::string getFormattedName() {
88 StringRef Name = Def->getValueAsString(FieldName: "name");
89 std::string N = Name.str();
90 std::replace(first: N.begin(), last: N.end(), old_value: ' ', new_value: '_');
91 return N;
92 }
93
94 bool isDefault() const { return Def->getValueAsBit(FieldName: "isDefault"); }
95
96 // Returns the record name.
97 StringRef getRecordName() const { return Def->getName(); }
98
99protected:
100 const llvm::Record *Def;
101};
102
103// Wrapper class that contains a Directive's information defined in
104// DirectiveBase.td and provides helper methods for accessing it.
105class Directive : public BaseRecord {
106public:
107 explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {}
108
109 std::vector<Record *> getAllowedClauses() const {
110 return Def->getValueAsListOfDefs(FieldName: "allowedClauses");
111 }
112
113 std::vector<Record *> getAllowedOnceClauses() const {
114 return Def->getValueAsListOfDefs(FieldName: "allowedOnceClauses");
115 }
116
117 std::vector<Record *> getAllowedExclusiveClauses() const {
118 return Def->getValueAsListOfDefs(FieldName: "allowedExclusiveClauses");
119 }
120
121 std::vector<Record *> getRequiredClauses() const {
122 return Def->getValueAsListOfDefs(FieldName: "requiredClauses");
123 }
124};
125
126// Wrapper class that contains Clause's information defined in DirectiveBase.td
127// and provides helper methods for accessing it.
128class Clause : public BaseRecord {
129public:
130 explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {}
131
132 // Optional field.
133 StringRef getClangClass() const {
134 return Def->getValueAsString(FieldName: "clangClass");
135 }
136
137 // Optional field.
138 StringRef getFlangClass() const {
139 return Def->getValueAsString(FieldName: "flangClass");
140 }
141
142 // Get the formatted name for Flang parser class. The generic formatted class
143 // name is constructed from the name were the first letter of each word is
144 // captitalized and the underscores are removed.
145 // ex: async -> Async
146 // num_threads -> NumThreads
147 std::string getFormattedParserClassName() {
148 StringRef Name = Def->getValueAsString(FieldName: "name");
149 std::string N = Name.str();
150 bool Cap = true;
151 std::transform(first: N.begin(), last: N.end(), result: N.begin(), unary_op: [&Cap](unsigned char C) {
152 if (Cap == true) {
153 C = llvm::toUpper(x: C);
154 Cap = false;
155 } else if (C == '_') {
156 Cap = true;
157 }
158 return C;
159 });
160 llvm::erase(C&: N, V: '_');
161 return N;
162 }
163
164 // Optional field.
165 StringRef getEnumName() const {
166 return Def->getValueAsString(FieldName: "enumClauseValue");
167 }
168
169 std::vector<Record *> getClauseVals() const {
170 return Def->getValueAsListOfDefs(FieldName: "allowedClauseValues");
171 }
172
173 bool isValueOptional() const { return Def->getValueAsBit(FieldName: "isValueOptional"); }
174
175 bool isValueList() const { return Def->getValueAsBit(FieldName: "isValueList"); }
176
177 StringRef getDefaultValue() const {
178 return Def->getValueAsString(FieldName: "defaultValue");
179 }
180
181 bool isImplicit() const { return Def->getValueAsBit(FieldName: "isImplicit"); }
182
183 std::vector<StringRef> getAliases() const {
184 return Def->getValueAsListOfStrings(FieldName: "aliases");
185 }
186
187 StringRef getPrefix() const { return Def->getValueAsString(FieldName: "prefix"); }
188
189 bool isPrefixOptional() const {
190 return Def->getValueAsBit(FieldName: "isPrefixOptional");
191 }
192};
193
194// Wrapper class that contains VersionedClause's information defined in
195// DirectiveBase.td and provides helper methods for accessing it.
196class VersionedClause {
197public:
198 explicit VersionedClause(const llvm::Record *Def) : Def(Def) {}
199
200 // Return the specific clause record wrapped in the Clause class.
201 Clause getClause() const { return Clause{Def->getValueAsDef(FieldName: "clause")}; }
202
203 int64_t getMinVersion() const { return Def->getValueAsInt(FieldName: "minVersion"); }
204
205 int64_t getMaxVersion() const { return Def->getValueAsInt(FieldName: "maxVersion"); }
206
207private:
208 const llvm::Record *Def;
209};
210
211class ClauseVal : public BaseRecord {
212public:
213 explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {}
214
215 int getValue() const { return Def->getValueAsInt(FieldName: "value"); }
216
217 bool isUserVisible() const { return Def->getValueAsBit(FieldName: "isUserValue"); }
218};
219
220} // namespace llvm
221
222#endif
223

source code of llvm/include/llvm/TableGen/DirectiveEmitter.h