xref: /freebsd/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:
DirectiveLanguage(const llvm::RecordKeeper & Records)18   explicit DirectiveLanguage(const llvm::RecordKeeper &Records)
19       : Records(Records) {
20     const auto &DirectiveLanguages = getDirectiveLanguages();
21     Def = DirectiveLanguages[0];
22   }
23 
getName()24   StringRef getName() const { return Def->getValueAsString("name"); }
25 
getCppNamespace()26   StringRef getCppNamespace() const {
27     return Def->getValueAsString("cppNamespace");
28   }
29 
getDirectivePrefix()30   StringRef getDirectivePrefix() const {
31     return Def->getValueAsString("directivePrefix");
32   }
33 
getClausePrefix()34   StringRef getClausePrefix() const {
35     return Def->getValueAsString("clausePrefix");
36   }
37 
getClauseEnumSetClass()38   StringRef getClauseEnumSetClass() const {
39     return Def->getValueAsString("clauseEnumSetClass");
40   }
41 
getFlangClauseBaseClass()42   StringRef getFlangClauseBaseClass() const {
43     return Def->getValueAsString("flangClauseBaseClass");
44   }
45 
hasMakeEnumAvailableInNamespace()46   bool hasMakeEnumAvailableInNamespace() const {
47     return Def->getValueAsBit("makeEnumAvailableInNamespace");
48   }
49 
hasEnableBitmaskEnumInNamespace()50   bool hasEnableBitmaskEnumInNamespace() const {
51     return Def->getValueAsBit("enableBitmaskEnumInNamespace");
52   }
53 
getAssociations()54   std::vector<Record *> getAssociations() const {
55     return Records.getAllDerivedDefinitions("Association");
56   }
57 
getCategories()58   std::vector<Record *> getCategories() const {
59     return Records.getAllDerivedDefinitions("Category");
60   }
61 
getDirectives()62   std::vector<Record *> getDirectives() const {
63     return Records.getAllDerivedDefinitions("Directive");
64   }
65 
getClauses()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 
getDirectiveLanguages()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:
BaseRecord(const llvm::Record * Def)85   explicit BaseRecord(const llvm::Record *Def) : Def(Def) {}
86 
getName()87   StringRef getName() const { return Def->getValueAsString("name"); }
88 
getAlternativeName()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.
getFormattedName()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 
isDefault()102   bool isDefault() const { return Def->getValueAsBit("isDefault"); }
103 
104   // Returns the record name.
getRecordName()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:
Directive(const llvm::Record * Def)115   explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {}
116 
getAllowedClauses()117   std::vector<Record *> getAllowedClauses() const {
118     return Def->getValueAsListOfDefs("allowedClauses");
119   }
120 
getAllowedOnceClauses()121   std::vector<Record *> getAllowedOnceClauses() const {
122     return Def->getValueAsListOfDefs("allowedOnceClauses");
123   }
124 
getAllowedExclusiveClauses()125   std::vector<Record *> getAllowedExclusiveClauses() const {
126     return Def->getValueAsListOfDefs("allowedExclusiveClauses");
127   }
128 
getRequiredClauses()129   std::vector<Record *> getRequiredClauses() const {
130     return Def->getValueAsListOfDefs("requiredClauses");
131   }
132 
getLeafConstructs()133   std::vector<Record *> getLeafConstructs() const {
134     return Def->getValueAsListOfDefs("leafConstructs");
135   }
136 
getAssociation()137   Record *getAssociation() const { return Def->getValueAsDef("association"); }
138 
getCategory()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:
Clause(const llvm::Record * Def)146   explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {}
147 
148   // Optional field.
getClangClass()149   StringRef getClangClass() const {
150     return Def->getValueAsString("clangClass");
151   }
152 
153   // Optional field.
getFlangClass()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
getFormattedParserClassName()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.
getEnumName()181   StringRef getEnumName() const {
182     return Def->getValueAsString("enumClauseValue");
183   }
184 
getClauseVals()185   std::vector<Record *> getClauseVals() const {
186     return Def->getValueAsListOfDefs("allowedClauseValues");
187   }
188 
isValueOptional()189   bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
190 
isValueList()191   bool isValueList() const { return Def->getValueAsBit("isValueList"); }
192 
getDefaultValue()193   StringRef getDefaultValue() const {
194     return Def->getValueAsString("defaultValue");
195   }
196 
isImplicit()197   bool isImplicit() const { return Def->getValueAsBit("isImplicit"); }
198 
getAliases()199   std::vector<StringRef> getAliases() const {
200     return Def->getValueAsListOfStrings("aliases");
201   }
202 
getPrefix()203   StringRef getPrefix() const { return Def->getValueAsString("prefix"); }
204 
isPrefixOptional()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:
VersionedClause(const llvm::Record * Def)214   explicit VersionedClause(const llvm::Record *Def) : Def(Def) {}
215 
216   // Return the specific clause record wrapped in the Clause class.
getClause()217   Clause getClause() const { return Clause{Def->getValueAsDef("clause")}; }
218 
getMinVersion()219   int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); }
220 
getMaxVersion()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:
ClauseVal(const llvm::Record * Def)229   explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {}
230 
getValue()231   int getValue() const { return Def->getValueAsInt("value"); }
232 
isUserVisible()233   bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); }
234 };
235 
236 } // namespace llvm
237 
238 #endif
239