1e8d8bef9SDimitry Andric #ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H 2e8d8bef9SDimitry Andric #define LLVM_TABLEGEN_DIRECTIVEEMITTER_H 3e8d8bef9SDimitry Andric 406c3fb27SDimitry Andric #include "llvm/ADT/STLExtras.h" 5e8d8bef9SDimitry Andric #include "llvm/ADT/StringExtras.h" 606c3fb27SDimitry Andric #include "llvm/ADT/StringRef.h" 7e8d8bef9SDimitry Andric #include "llvm/TableGen/Record.h" 806c3fb27SDimitry Andric #include <algorithm> 906c3fb27SDimitry Andric #include <string> 1006c3fb27SDimitry Andric #include <vector> 11e8d8bef9SDimitry Andric 12e8d8bef9SDimitry Andric namespace llvm { 13e8d8bef9SDimitry Andric 14e8d8bef9SDimitry Andric // Wrapper class that contains DirectiveLanguage's information defined in 15e8d8bef9SDimitry Andric // DirectiveBase.td and provides helper methods for accessing it. 16e8d8bef9SDimitry Andric class DirectiveLanguage { 17e8d8bef9SDimitry Andric public: DirectiveLanguage(const llvm::RecordKeeper & Records)18e8d8bef9SDimitry Andric explicit DirectiveLanguage(const llvm::RecordKeeper &Records) 19e8d8bef9SDimitry Andric : Records(Records) { 20e8d8bef9SDimitry Andric const auto &DirectiveLanguages = getDirectiveLanguages(); 21e8d8bef9SDimitry Andric Def = DirectiveLanguages[0]; 22e8d8bef9SDimitry Andric } 23e8d8bef9SDimitry Andric getName()24e8d8bef9SDimitry Andric StringRef getName() const { return Def->getValueAsString("name"); } 25e8d8bef9SDimitry Andric getCppNamespace()26e8d8bef9SDimitry Andric StringRef getCppNamespace() const { 27e8d8bef9SDimitry Andric return Def->getValueAsString("cppNamespace"); 28e8d8bef9SDimitry Andric } 29e8d8bef9SDimitry Andric getDirectivePrefix()30e8d8bef9SDimitry Andric StringRef getDirectivePrefix() const { 31e8d8bef9SDimitry Andric return Def->getValueAsString("directivePrefix"); 32e8d8bef9SDimitry Andric } 33e8d8bef9SDimitry Andric getClausePrefix()34e8d8bef9SDimitry Andric StringRef getClausePrefix() const { 35e8d8bef9SDimitry Andric return Def->getValueAsString("clausePrefix"); 36e8d8bef9SDimitry Andric } 37e8d8bef9SDimitry Andric getClauseEnumSetClass()38e8d8bef9SDimitry Andric StringRef getClauseEnumSetClass() const { 39e8d8bef9SDimitry Andric return Def->getValueAsString("clauseEnumSetClass"); 40e8d8bef9SDimitry Andric } 41e8d8bef9SDimitry Andric getFlangClauseBaseClass()42e8d8bef9SDimitry Andric StringRef getFlangClauseBaseClass() const { 43e8d8bef9SDimitry Andric return Def->getValueAsString("flangClauseBaseClass"); 44e8d8bef9SDimitry Andric } 45e8d8bef9SDimitry Andric hasMakeEnumAvailableInNamespace()46e8d8bef9SDimitry Andric bool hasMakeEnumAvailableInNamespace() const { 47e8d8bef9SDimitry Andric return Def->getValueAsBit("makeEnumAvailableInNamespace"); 48e8d8bef9SDimitry Andric } 49e8d8bef9SDimitry Andric hasEnableBitmaskEnumInNamespace()50e8d8bef9SDimitry Andric bool hasEnableBitmaskEnumInNamespace() const { 51e8d8bef9SDimitry Andric return Def->getValueAsBit("enableBitmaskEnumInNamespace"); 52e8d8bef9SDimitry Andric } 53e8d8bef9SDimitry Andric getDirectives()54fe6060f1SDimitry Andric std::vector<Record *> getDirectives() const { 55e8d8bef9SDimitry Andric return Records.getAllDerivedDefinitions("Directive"); 56e8d8bef9SDimitry Andric } 57e8d8bef9SDimitry Andric getClauses()58fe6060f1SDimitry Andric std::vector<Record *> getClauses() const { 59e8d8bef9SDimitry Andric return Records.getAllDerivedDefinitions("Clause"); 60e8d8bef9SDimitry Andric } 61e8d8bef9SDimitry Andric 62e8d8bef9SDimitry Andric bool HasValidityErrors() const; 63e8d8bef9SDimitry Andric 64e8d8bef9SDimitry Andric private: 65e8d8bef9SDimitry Andric const llvm::Record *Def; 66e8d8bef9SDimitry Andric const llvm::RecordKeeper &Records; 67e8d8bef9SDimitry Andric getDirectiveLanguages()68fe6060f1SDimitry Andric std::vector<Record *> getDirectiveLanguages() const { 69e8d8bef9SDimitry Andric return Records.getAllDerivedDefinitions("DirectiveLanguage"); 70e8d8bef9SDimitry Andric } 71e8d8bef9SDimitry Andric }; 72e8d8bef9SDimitry Andric 73e8d8bef9SDimitry Andric // Base record class used for Directive and Clause class defined in 74e8d8bef9SDimitry Andric // DirectiveBase.td. 75e8d8bef9SDimitry Andric class BaseRecord { 76e8d8bef9SDimitry Andric public: BaseRecord(const llvm::Record * Def)77e8d8bef9SDimitry Andric explicit BaseRecord(const llvm::Record *Def) : Def(Def) {} 78e8d8bef9SDimitry Andric getName()79e8d8bef9SDimitry Andric StringRef getName() const { return Def->getValueAsString("name"); } 80e8d8bef9SDimitry Andric getAlternativeName()81e8d8bef9SDimitry Andric StringRef getAlternativeName() const { 82e8d8bef9SDimitry Andric return Def->getValueAsString("alternativeName"); 83e8d8bef9SDimitry Andric } 84e8d8bef9SDimitry Andric 85e8d8bef9SDimitry Andric // Returns the name of the directive formatted for output. Whitespace are 86e8d8bef9SDimitry Andric // replaced with underscores. getFormattedName()87e8d8bef9SDimitry Andric std::string getFormattedName() { 88e8d8bef9SDimitry Andric StringRef Name = Def->getValueAsString("name"); 89e8d8bef9SDimitry Andric std::string N = Name.str(); 90e8d8bef9SDimitry Andric std::replace(N.begin(), N.end(), ' ', '_'); 91e8d8bef9SDimitry Andric return N; 92e8d8bef9SDimitry Andric } 93e8d8bef9SDimitry Andric isDefault()94e8d8bef9SDimitry Andric bool isDefault() const { return Def->getValueAsBit("isDefault"); } 95e8d8bef9SDimitry Andric 96e8d8bef9SDimitry Andric // Returns the record name. getRecordName()97fe6060f1SDimitry Andric StringRef getRecordName() const { return Def->getName(); } 98e8d8bef9SDimitry Andric 99e8d8bef9SDimitry Andric protected: 100e8d8bef9SDimitry Andric const llvm::Record *Def; 101e8d8bef9SDimitry Andric }; 102e8d8bef9SDimitry Andric 103e8d8bef9SDimitry Andric // Wrapper class that contains a Directive's information defined in 104e8d8bef9SDimitry Andric // DirectiveBase.td and provides helper methods for accessing it. 105e8d8bef9SDimitry Andric class Directive : public BaseRecord { 106e8d8bef9SDimitry Andric public: Directive(const llvm::Record * Def)107e8d8bef9SDimitry Andric explicit Directive(const llvm::Record *Def) : BaseRecord(Def) {} 108e8d8bef9SDimitry Andric getAllowedClauses()109e8d8bef9SDimitry Andric std::vector<Record *> getAllowedClauses() const { 110e8d8bef9SDimitry Andric return Def->getValueAsListOfDefs("allowedClauses"); 111e8d8bef9SDimitry Andric } 112e8d8bef9SDimitry Andric getAllowedOnceClauses()113e8d8bef9SDimitry Andric std::vector<Record *> getAllowedOnceClauses() const { 114e8d8bef9SDimitry Andric return Def->getValueAsListOfDefs("allowedOnceClauses"); 115e8d8bef9SDimitry Andric } 116e8d8bef9SDimitry Andric getAllowedExclusiveClauses()117e8d8bef9SDimitry Andric std::vector<Record *> getAllowedExclusiveClauses() const { 118e8d8bef9SDimitry Andric return Def->getValueAsListOfDefs("allowedExclusiveClauses"); 119e8d8bef9SDimitry Andric } 120e8d8bef9SDimitry Andric getRequiredClauses()121e8d8bef9SDimitry Andric std::vector<Record *> getRequiredClauses() const { 122e8d8bef9SDimitry Andric return Def->getValueAsListOfDefs("requiredClauses"); 123e8d8bef9SDimitry Andric } 124e8d8bef9SDimitry Andric }; 125e8d8bef9SDimitry Andric 126e8d8bef9SDimitry Andric // Wrapper class that contains Clause's information defined in DirectiveBase.td 127e8d8bef9SDimitry Andric // and provides helper methods for accessing it. 128e8d8bef9SDimitry Andric class Clause : public BaseRecord { 129e8d8bef9SDimitry Andric public: Clause(const llvm::Record * Def)130e8d8bef9SDimitry Andric explicit Clause(const llvm::Record *Def) : BaseRecord(Def) {} 131e8d8bef9SDimitry Andric 132e8d8bef9SDimitry Andric // Optional field. getClangClass()133e8d8bef9SDimitry Andric StringRef getClangClass() const { 134e8d8bef9SDimitry Andric return Def->getValueAsString("clangClass"); 135e8d8bef9SDimitry Andric } 136e8d8bef9SDimitry Andric 137e8d8bef9SDimitry Andric // Optional field. getFlangClass()138e8d8bef9SDimitry Andric StringRef getFlangClass() const { 139e8d8bef9SDimitry Andric return Def->getValueAsString("flangClass"); 140e8d8bef9SDimitry Andric } 141e8d8bef9SDimitry Andric 142e8d8bef9SDimitry Andric // Get the formatted name for Flang parser class. The generic formatted class 143e8d8bef9SDimitry Andric // name is constructed from the name were the first letter of each word is 144e8d8bef9SDimitry Andric // captitalized and the underscores are removed. 145e8d8bef9SDimitry Andric // ex: async -> Async 146e8d8bef9SDimitry Andric // num_threads -> NumThreads getFormattedParserClassName()147e8d8bef9SDimitry Andric std::string getFormattedParserClassName() { 148e8d8bef9SDimitry Andric StringRef Name = Def->getValueAsString("name"); 149e8d8bef9SDimitry Andric std::string N = Name.str(); 150e8d8bef9SDimitry Andric bool Cap = true; 151e8d8bef9SDimitry Andric std::transform(N.begin(), N.end(), N.begin(), [&Cap](unsigned char C) { 152e8d8bef9SDimitry Andric if (Cap == true) { 153e8d8bef9SDimitry Andric C = llvm::toUpper(C); 154e8d8bef9SDimitry Andric Cap = false; 155e8d8bef9SDimitry Andric } else if (C == '_') { 156e8d8bef9SDimitry Andric Cap = true; 157e8d8bef9SDimitry Andric } 158e8d8bef9SDimitry Andric return C; 159e8d8bef9SDimitry Andric }); 160*5f757f3fSDimitry Andric llvm::erase(N, '_'); 161e8d8bef9SDimitry Andric return N; 162e8d8bef9SDimitry Andric } 163e8d8bef9SDimitry Andric 164e8d8bef9SDimitry Andric // Optional field. getEnumName()165e8d8bef9SDimitry Andric StringRef getEnumName() const { 166e8d8bef9SDimitry Andric return Def->getValueAsString("enumClauseValue"); 167e8d8bef9SDimitry Andric } 168e8d8bef9SDimitry Andric getClauseVals()169e8d8bef9SDimitry Andric std::vector<Record *> getClauseVals() const { 170e8d8bef9SDimitry Andric return Def->getValueAsListOfDefs("allowedClauseValues"); 171e8d8bef9SDimitry Andric } 172e8d8bef9SDimitry Andric isValueOptional()173e8d8bef9SDimitry Andric bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); } 174e8d8bef9SDimitry Andric isValueList()175e8d8bef9SDimitry Andric bool isValueList() const { return Def->getValueAsBit("isValueList"); } 176e8d8bef9SDimitry Andric getDefaultValue()177e8d8bef9SDimitry Andric StringRef getDefaultValue() const { 178e8d8bef9SDimitry Andric return Def->getValueAsString("defaultValue"); 179e8d8bef9SDimitry Andric } 180e8d8bef9SDimitry Andric isImplicit()181e8d8bef9SDimitry Andric bool isImplicit() const { return Def->getValueAsBit("isImplicit"); } 182fcaf7f86SDimitry Andric getAliases()183fcaf7f86SDimitry Andric std::vector<StringRef> getAliases() const { 184fcaf7f86SDimitry Andric return Def->getValueAsListOfStrings("aliases"); 185fcaf7f86SDimitry Andric } 186fcaf7f86SDimitry Andric getPrefix()187fcaf7f86SDimitry Andric StringRef getPrefix() const { return Def->getValueAsString("prefix"); } 188fcaf7f86SDimitry Andric isPrefixOptional()189fcaf7f86SDimitry Andric bool isPrefixOptional() const { 190fcaf7f86SDimitry Andric return Def->getValueAsBit("isPrefixOptional"); 191fcaf7f86SDimitry Andric } 192e8d8bef9SDimitry Andric }; 193e8d8bef9SDimitry Andric 194e8d8bef9SDimitry Andric // Wrapper class that contains VersionedClause's information defined in 195e8d8bef9SDimitry Andric // DirectiveBase.td and provides helper methods for accessing it. 196e8d8bef9SDimitry Andric class VersionedClause { 197e8d8bef9SDimitry Andric public: VersionedClause(const llvm::Record * Def)198e8d8bef9SDimitry Andric explicit VersionedClause(const llvm::Record *Def) : Def(Def) {} 199e8d8bef9SDimitry Andric 200e8d8bef9SDimitry Andric // Return the specific clause record wrapped in the Clause class. getClause()201e8d8bef9SDimitry Andric Clause getClause() const { return Clause{Def->getValueAsDef("clause")}; } 202e8d8bef9SDimitry Andric getMinVersion()203e8d8bef9SDimitry Andric int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); } 204e8d8bef9SDimitry Andric getMaxVersion()205e8d8bef9SDimitry Andric int64_t getMaxVersion() const { return Def->getValueAsInt("maxVersion"); } 206e8d8bef9SDimitry Andric 207e8d8bef9SDimitry Andric private: 208e8d8bef9SDimitry Andric const llvm::Record *Def; 209e8d8bef9SDimitry Andric }; 210e8d8bef9SDimitry Andric 211e8d8bef9SDimitry Andric class ClauseVal : public BaseRecord { 212e8d8bef9SDimitry Andric public: ClauseVal(const llvm::Record * Def)213e8d8bef9SDimitry Andric explicit ClauseVal(const llvm::Record *Def) : BaseRecord(Def) {} 214e8d8bef9SDimitry Andric getValue()215e8d8bef9SDimitry Andric int getValue() const { return Def->getValueAsInt("value"); } 216e8d8bef9SDimitry Andric isUserVisible()217e8d8bef9SDimitry Andric bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); } 218e8d8bef9SDimitry Andric }; 219e8d8bef9SDimitry Andric 220e8d8bef9SDimitry Andric } // namespace llvm 221e8d8bef9SDimitry Andric 222e8d8bef9SDimitry Andric #endif 223