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