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