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