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