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