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