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 *> 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 | |
64 | private: |
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. |
75 | class BaseRecord { |
76 | public: |
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 | |
99 | protected: |
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. |
105 | class Directive : public BaseRecord { |
106 | public: |
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. |
128 | class Clause : public BaseRecord { |
129 | public: |
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. |
196 | class VersionedClause { |
197 | public: |
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 | |
207 | private: |
208 | const llvm::Record *Def; |
209 | }; |
210 | |
211 | class ClauseVal : public BaseRecord { |
212 | public: |
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 |