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 *> 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
68private:
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.
79class BaseRecord {
80public:
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
103protected:
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.
109class Directive : public BaseRecord {
110public:
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.
138class Clause : public BaseRecord {
139public:
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.
206class VersionedClause {
207public:
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
217private:
218 const llvm::Record *Def;
219};
220
221class ClauseVal : public BaseRecord {
222public:
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

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