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