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 | |
12 | namespace llvm { |
13 | |
14 | // Wrapper class that contains DirectiveLanguage's information defined in |
15 | // DirectiveBase.td and provides helper methods for accessing it. |
16 | class DirectiveLanguage { |
17 | public: |
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 *> getAssociations() const { |
55 | return Records.getAllDerivedDefinitions(ClassName: "Association"); |
56 | } |
57 | |
58 | std::vector<Record *> getDirectives() const { |
59 | return Records.getAllDerivedDefinitions(ClassName: "Directive"); |
60 | } |
61 | |
62 | std::vector<Record *> getClauses() const { |
63 | return Records.getAllDerivedDefinitions(ClassName: "Clause"); |
64 | } |
65 | |
66 | bool HasValidityErrors() const; |
67 | |
68 | private: |
69 | const llvm::Record *Def; |
70 | const llvm::RecordKeeper &Records; |
71 | |
72 | std::vector<Record *> getDirectiveLanguages() const { |
73 | return Records.getAllDerivedDefinitions(ClassName: "DirectiveLanguage"); |
74 | } |
75 | }; |
76 | |
77 | // Base record class used for Directive and Clause class defined in |
78 | // DirectiveBase.td. |
79 | class BaseRecord { |
80 | public: |
81 | explicit BaseRecord(const llvm::Record *Def) : Def(Def) {} |
82 | |
83 | StringRef getName() const { return Def->getValueAsString(FieldName: "name"); } |
84 | |
85 | StringRef getAlternativeName() const { |
86 | return Def->getValueAsString(FieldName: "alternativeName"); |
87 | } |
88 | |
89 | // Returns the name of the directive formatted for output. Whitespace are |
90 | // replaced with underscores. |
91 | std::string getFormattedName() { |
92 | StringRef Name = Def->getValueAsString(FieldName: "name"); |
93 | std::string N = Name.str(); |
94 | std::replace(first: N.begin(), last: N.end(), old_value: ' ', new_value: '_'); |
95 | return N; |
96 | } |
97 | |
98 | bool isDefault() const { return Def->getValueAsBit(FieldName: "isDefault"); } |
99 | |
100 | // Returns the record name. |
101 | StringRef getRecordName() const { return Def->getName(); } |
102 | |
103 | protected: |
104 | const llvm::Record *Def; |
105 | }; |
106 | |
107 | // Wrapper class that contains a Directive's information defined in |
108 | // DirectiveBase.td and provides helper methods for accessing it. |
109 | class Directive : public BaseRecord { |
110 | public: |
111 | explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {} |
112 | |
113 | std::vector<Record *> getAllowedClauses() const { |
114 | return Def->getValueAsListOfDefs(FieldName: "allowedClauses"); |
115 | } |
116 | |
117 | std::vector<Record *> getAllowedOnceClauses() const { |
118 | return Def->getValueAsListOfDefs(FieldName: "allowedOnceClauses"); |
119 | } |
120 | |
121 | std::vector<Record *> getAllowedExclusiveClauses() const { |
122 | return Def->getValueAsListOfDefs(FieldName: "allowedExclusiveClauses"); |
123 | } |
124 | |
125 | std::vector<Record *> getRequiredClauses() const { |
126 | return Def->getValueAsListOfDefs(FieldName: "requiredClauses"); |
127 | } |
128 | |
129 | std::vector<Record *> getLeafConstructs() const { |
130 | return Def->getValueAsListOfDefs(FieldName: "leafConstructs"); |
131 | } |
132 | |
133 | Record *getAssociation() const { return Def->getValueAsDef(FieldName: "association"); } |
134 | }; |
135 | |
136 | // Wrapper class that contains Clause's information defined in DirectiveBase.td |
137 | // and provides helper methods for accessing it. |
138 | class Clause : public BaseRecord { |
139 | public: |
140 | explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {} |
141 | |
142 | // Optional field. |
143 | StringRef getClangClass() const { |
144 | return Def->getValueAsString(FieldName: "clangClass"); |
145 | } |
146 | |
147 | // Optional field. |
148 | StringRef getFlangClass() const { |
149 | return Def->getValueAsString(FieldName: "flangClass"); |
150 | } |
151 | |
152 | // Get the formatted name for Flang parser class. The generic formatted class |
153 | // name is constructed from the name were the first letter of each word is |
154 | // captitalized and the underscores are removed. |
155 | // ex: async -> Async |
156 | // num_threads -> NumThreads |
157 | std::string getFormattedParserClassName() { |
158 | StringRef Name = Def->getValueAsString(FieldName: "name"); |
159 | std::string N = Name.str(); |
160 | bool Cap = true; |
161 | std::transform(first: N.begin(), last: N.end(), result: N.begin(), unary_op: [&Cap](unsigned char C) { |
162 | if (Cap == true) { |
163 | C = llvm::toUpper(x: C); |
164 | Cap = false; |
165 | } else if (C == '_') { |
166 | Cap = true; |
167 | } |
168 | return C; |
169 | }); |
170 | llvm::erase(C&: N, V: '_'); |
171 | return N; |
172 | } |
173 | |
174 | // Optional field. |
175 | StringRef getEnumName() const { |
176 | return Def->getValueAsString(FieldName: "enumClauseValue"); |
177 | } |
178 | |
179 | std::vector<Record *> getClauseVals() const { |
180 | return Def->getValueAsListOfDefs(FieldName: "allowedClauseValues"); |
181 | } |
182 | |
183 | bool isValueOptional() const { return Def->getValueAsBit(FieldName: "isValueOptional"); } |
184 | |
185 | bool isValueList() const { return Def->getValueAsBit(FieldName: "isValueList"); } |
186 | |
187 | StringRef getDefaultValue() const { |
188 | return Def->getValueAsString(FieldName: "defaultValue"); |
189 | } |
190 | |
191 | bool isImplicit() const { return Def->getValueAsBit(FieldName: "isImplicit"); } |
192 | |
193 | std::vector<StringRef> getAliases() const { |
194 | return Def->getValueAsListOfStrings(FieldName: "aliases"); |
195 | } |
196 | |
197 | StringRef getPrefix() const { return Def->getValueAsString(FieldName: "prefix"); } |
198 | |
199 | bool isPrefixOptional() const { |
200 | return Def->getValueAsBit(FieldName: "isPrefixOptional"); |
201 | } |
202 | }; |
203 | |
204 | // Wrapper class that contains VersionedClause's information defined in |
205 | // DirectiveBase.td and provides helper methods for accessing it. |
206 | class VersionedClause { |
207 | public: |
208 | explicit VersionedClause(const llvm::Record *Def) : Def(Def) {} |
209 | |
210 | // Return the specific clause record wrapped in the Clause class. |
211 | Clause getClause() const { return Clause{Def->getValueAsDef(FieldName: "clause")}; } |
212 | |
213 | int64_t getMinVersion() const { return Def->getValueAsInt(FieldName: "minVersion"); } |
214 | |
215 | int64_t getMaxVersion() const { return Def->getValueAsInt(FieldName: "maxVersion"); } |
216 | |
217 | private: |
218 | const llvm::Record *Def; |
219 | }; |
220 | |
221 | class ClauseVal : public BaseRecord { |
222 | public: |
223 | explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {} |
224 | |
225 | int getValue() const { return Def->getValueAsInt(FieldName: "value"); } |
226 | |
227 | bool isUserVisible() const { return Def->getValueAsBit(FieldName: "isUserValue"); } |
228 | }; |
229 | |
230 | } // namespace llvm |
231 | |
232 | #endif |
233 |