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