Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:35

0001 //===- DirectiveEmitter.h - Directive Language Emitter ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // DirectiveEmitter uses the descriptions of directives and clauses to construct
0010 // common code declarations to be used in Frontends.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_TABLEGEN_DIRECTIVEEMITTER_H
0015 #define LLVM_TABLEGEN_DIRECTIVEEMITTER_H
0016 
0017 #include "llvm/ADT/STLExtras.h"
0018 #include "llvm/ADT/StringExtras.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/TableGen/Record.h"
0021 #include <algorithm>
0022 #include <string>
0023 #include <vector>
0024 
0025 namespace llvm {
0026 
0027 // Wrapper class that contains DirectiveLanguage's information defined in
0028 // DirectiveBase.td and provides helper methods for accessing it.
0029 class DirectiveLanguage {
0030 public:
0031   explicit DirectiveLanguage(const RecordKeeper &Records) : Records(Records) {
0032     const auto &DirectiveLanguages = getDirectiveLanguages();
0033     Def = DirectiveLanguages[0];
0034   }
0035 
0036   StringRef getName() const { return Def->getValueAsString("name"); }
0037 
0038   StringRef getCppNamespace() const {
0039     return Def->getValueAsString("cppNamespace");
0040   }
0041 
0042   StringRef getDirectivePrefix() const {
0043     return Def->getValueAsString("directivePrefix");
0044   }
0045 
0046   StringRef getClausePrefix() const {
0047     return Def->getValueAsString("clausePrefix");
0048   }
0049 
0050   StringRef getClauseEnumSetClass() const {
0051     return Def->getValueAsString("clauseEnumSetClass");
0052   }
0053 
0054   StringRef getFlangClauseBaseClass() const {
0055     return Def->getValueAsString("flangClauseBaseClass");
0056   }
0057 
0058   bool hasMakeEnumAvailableInNamespace() const {
0059     return Def->getValueAsBit("makeEnumAvailableInNamespace");
0060   }
0061 
0062   bool hasEnableBitmaskEnumInNamespace() const {
0063     return Def->getValueAsBit("enableBitmaskEnumInNamespace");
0064   }
0065 
0066   ArrayRef<const Record *> getAssociations() const {
0067     return Records.getAllDerivedDefinitions("Association");
0068   }
0069 
0070   ArrayRef<const Record *> getCategories() const {
0071     return Records.getAllDerivedDefinitions("Category");
0072   }
0073 
0074   ArrayRef<const Record *> getDirectives() const {
0075     return Records.getAllDerivedDefinitions("Directive");
0076   }
0077 
0078   ArrayRef<const Record *> getClauses() const {
0079     return Records.getAllDerivedDefinitions("Clause");
0080   }
0081 
0082   bool HasValidityErrors() const;
0083 
0084 private:
0085   const Record *Def;
0086   const RecordKeeper &Records;
0087 
0088   ArrayRef<const Record *> getDirectiveLanguages() const {
0089     return Records.getAllDerivedDefinitions("DirectiveLanguage");
0090   }
0091 };
0092 
0093 // Note: In all the classes below, allow implicit construction from Record *,
0094 // to allow writing code like:
0095 //  for (const Directive D : getDirectives()) {
0096 //
0097 //  instead of:
0098 //
0099 //  for (const Record *R : getDirectives()) {
0100 //    Directive D(R);
0101 
0102 // Base record class used for Directive and Clause class defined in
0103 // DirectiveBase.td.
0104 class BaseRecord {
0105 public:
0106   BaseRecord(const Record *Def) : Def(Def) {}
0107 
0108   StringRef getName() const { return Def->getValueAsString("name"); }
0109 
0110   StringRef getAlternativeName() const {
0111     return Def->getValueAsString("alternativeName");
0112   }
0113 
0114   // Returns the name of the directive formatted for output. Whitespace are
0115   // replaced with underscores.
0116   std::string getFormattedName() const {
0117     StringRef Name = Def->getValueAsString("name");
0118     std::string N = Name.str();
0119     std::replace(N.begin(), N.end(), ' ', '_');
0120     return N;
0121   }
0122 
0123   bool isDefault() const { return Def->getValueAsBit("isDefault"); }
0124 
0125   // Returns the record name.
0126   StringRef getRecordName() const { return Def->getName(); }
0127 
0128 protected:
0129   const Record *Def;
0130 };
0131 
0132 // Wrapper class that contains a Directive's information defined in
0133 // DirectiveBase.td and provides helper methods for accessing it.
0134 class Directive : public BaseRecord {
0135 public:
0136   Directive(const Record *Def) : BaseRecord(Def) {}
0137 
0138   std::vector<const Record *> getAllowedClauses() const {
0139     return Def->getValueAsListOfDefs("allowedClauses");
0140   }
0141 
0142   std::vector<const Record *> getAllowedOnceClauses() const {
0143     return Def->getValueAsListOfDefs("allowedOnceClauses");
0144   }
0145 
0146   std::vector<const Record *> getAllowedExclusiveClauses() const {
0147     return Def->getValueAsListOfDefs("allowedExclusiveClauses");
0148   }
0149 
0150   std::vector<const Record *> getRequiredClauses() const {
0151     return Def->getValueAsListOfDefs("requiredClauses");
0152   }
0153 
0154   std::vector<const Record *> getLeafConstructs() const {
0155     return Def->getValueAsListOfDefs("leafConstructs");
0156   }
0157 
0158   const Record *getAssociation() const {
0159     return Def->getValueAsDef("association");
0160   }
0161 
0162   const Record *getCategory() const { return Def->getValueAsDef("category"); }
0163 };
0164 
0165 // Wrapper class that contains Clause's information defined in DirectiveBase.td
0166 // and provides helper methods for accessing it.
0167 class Clause : public BaseRecord {
0168 public:
0169   Clause(const Record *Def) : BaseRecord(Def) {}
0170 
0171   // Optional field.
0172   StringRef getClangClass() const {
0173     return Def->getValueAsString("clangClass");
0174   }
0175 
0176   // Optional field.
0177   StringRef getFlangClass() const {
0178     return Def->getValueAsString("flangClass");
0179   }
0180 
0181   // Get the formatted name for Flang parser class. The generic formatted class
0182   // name is constructed from the name were the first letter of each word is
0183   // captitalized and the underscores are removed.
0184   // ex: async -> Async
0185   //     num_threads -> NumThreads
0186   std::string getFormattedParserClassName() const {
0187     StringRef Name = Def->getValueAsString("name");
0188     std::string N = Name.str();
0189     bool Cap = true;
0190     std::transform(N.begin(), N.end(), N.begin(), [&Cap](unsigned char C) {
0191       if (Cap == true) {
0192         C = toUpper(C);
0193         Cap = false;
0194       } else if (C == '_') {
0195         Cap = true;
0196       }
0197       return C;
0198     });
0199     erase(N, '_');
0200     return N;
0201   }
0202 
0203   // Optional field.
0204   StringRef getEnumName() const {
0205     return Def->getValueAsString("enumClauseValue");
0206   }
0207 
0208   std::vector<const Record *> getClauseVals() const {
0209     return Def->getValueAsListOfDefs("allowedClauseValues");
0210   }
0211 
0212   bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
0213 
0214   bool isValueList() const { return Def->getValueAsBit("isValueList"); }
0215 
0216   StringRef getDefaultValue() const {
0217     return Def->getValueAsString("defaultValue");
0218   }
0219 
0220   bool isImplicit() const { return Def->getValueAsBit("isImplicit"); }
0221 
0222   std::vector<StringRef> getAliases() const {
0223     return Def->getValueAsListOfStrings("aliases");
0224   }
0225 
0226   StringRef getPrefix() const { return Def->getValueAsString("prefix"); }
0227 
0228   bool isPrefixOptional() const {
0229     return Def->getValueAsBit("isPrefixOptional");
0230   }
0231 };
0232 
0233 // Wrapper class that contains VersionedClause's information defined in
0234 // DirectiveBase.td and provides helper methods for accessing it.
0235 class VersionedClause {
0236 public:
0237   VersionedClause(const Record *Def) : Def(Def) {}
0238 
0239   // Return the specific clause record wrapped in the Clause class.
0240   Clause getClause() const { return Clause(Def->getValueAsDef("clause")); }
0241 
0242   int64_t getMinVersion() const { return Def->getValueAsInt("minVersion"); }
0243 
0244   int64_t getMaxVersion() const { return Def->getValueAsInt("maxVersion"); }
0245 
0246 private:
0247   const Record *Def;
0248 };
0249 
0250 class ClauseVal : public BaseRecord {
0251 public:
0252   ClauseVal(const Record *Def) : BaseRecord(Def) {}
0253 
0254   int getValue() const { return Def->getValueAsInt("value"); }
0255 
0256   bool isUserVisible() const { return Def->getValueAsBit("isUserValue"); }
0257 };
0258 
0259 } // namespace llvm
0260 
0261 #endif // LLVM_TABLEGEN_DIRECTIVEEMITTER_H