[clang] [clang][TableGen] Change AttrEmitter to use const RecordKeeper (PR #108269)

via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 11 20:26:47 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Rahul Joshi (jurahul)

<details>
<summary>Changes</summary>

Change AttrEmitter to use const RecordKeeper.

This is a part of effort to have better const correctness in TableGen backends:

https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089


---

Patch is 38.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108269.diff


2 Files Affected:

- (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+104-126) 
- (modified) clang/utils/TableGen/TableGenBackends.h (+29-22) 


``````````diff
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index d24215d10f17c7..9b2249ac90bc5c 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -189,13 +189,12 @@ static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
 
 typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;
 
-static ParsedAttrMap getParsedAttrList(RecordKeeper &Records,
+static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
                                        ParsedAttrMap *Dupes = nullptr,
                                        bool SemaOnly = true) {
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
   std::set<std::string> Seen;
   ParsedAttrMap R;
-  for (const auto *Attr : Attrs) {
+  for (const Record *Attr : Records.getAllDerivedDefinitions("Attr")) {
     if (!SemaOnly || Attr->getValueAsBit("SemaHandler")) {
       std::string AN;
       if (Attr->isSubClassOf("TargetSpecificAttr") &&
@@ -1911,12 +1910,10 @@ static LateAttrParseKind getLateAttrParseKind(const Record *Attr) {
 }
 
 // Emits the LateParsed property for attributes.
-static void emitClangAttrLateParsedListImpl(RecordKeeper &Records,
+static void emitClangAttrLateParsedListImpl(const RecordKeeper &Records,
                                             raw_ostream &OS,
                                             LateAttrParseKind LateParseMode) {
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     if (LateAttrParseKind LateParsed = getLateAttrParseKind(Attr);
         LateParsed != LateParseMode)
       continue;
@@ -1932,14 +1929,14 @@ static void emitClangAttrLateParsedListImpl(RecordKeeper &Records,
   }
 }
 
-static void emitClangAttrLateParsedList(RecordKeeper &Records,
+static void emitClangAttrLateParsedList(const RecordKeeper &Records,
                                         raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
   emitClangAttrLateParsedListImpl(Records, OS, LateAttrParseKind::Standard);
   OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
 }
 
-static void emitClangAttrLateParsedExperimentalList(RecordKeeper &Records,
+static void emitClangAttrLateParsedExperimentalList(const RecordKeeper &Records,
                                                     raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST)\n";
   emitClangAttrLateParsedListImpl(Records, OS,
@@ -2066,7 +2063,7 @@ struct PragmaClangAttributeSupport {
   };
   llvm::DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules;
 
-  PragmaClangAttributeSupport(RecordKeeper &Records);
+  PragmaClangAttributeSupport(const RecordKeeper &Records);
 
   bool isAttributedSupported(const Record &Attribute);
 
@@ -2105,9 +2102,7 @@ static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {
 }
 
 PragmaClangAttributeSupport::PragmaClangAttributeSupport(
-    RecordKeeper &Records) {
-  std::vector<Record *> MetaSubjects =
-      Records.getAllDerivedDefinitions("AttrSubjectMatcherRule");
+    const RecordKeeper &Records) {
   auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
                                        const Record *MetaSubject,
                                        const Record *Constraint) {
@@ -2127,7 +2122,8 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
       }
     }
   };
-  for (const auto *MetaSubject : MetaSubjects) {
+  for (const auto *MetaSubject :
+       Records.getAllDerivedDefinitions("AttrSubjectMatcherRule")) {
     MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr);
     std::vector<Record *> Constraints =
         MetaSubject->getValueAsListOfDefs("Constraints");
@@ -2135,11 +2131,10 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
       MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
   }
 
-  std::vector<Record *> Aggregates =
-      Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule");
-  std::vector<Record *> DeclNodes =
-    Records.getAllDerivedDefinitions(DeclNodeClassName);
-  for (const auto *Aggregate : Aggregates) {
+  ArrayRef<const Record *> DeclNodes =
+      Records.getAllDerivedDefinitions(DeclNodeClassName);
+  for (const auto *Aggregate :
+       Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule")) {
     Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
 
     // Gather sub-classes of the aggregate subject that act as attribute
@@ -2169,7 +2164,7 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
 }
 
 static PragmaClangAttributeSupport &
-getPragmaAttributeSupport(RecordKeeper &Records) {
+getPragmaAttributeSupport(const RecordKeeper &Records) {
   static PragmaClangAttributeSupport Instance(Records);
   return Instance;
 }
@@ -2403,9 +2398,8 @@ std::map<std::string, std::vector<const Record *>> NameToAttrsMap;
 /// Build a map from the attribute name to the Attrs that use that name. If more
 /// than one Attr use a name, the arguments could be different so a more complex
 /// check is needed in the generated switch.
-void generateNameToAttrsMap(RecordKeeper &Records) {
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-  for (const auto *A : Attrs) {
+void generateNameToAttrsMap(const RecordKeeper &Records) {
+  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*A);
     for (const auto &S : Spellings) {
       auto It = NameToAttrsMap.find(S.name());
@@ -2510,12 +2504,11 @@ static bool isTypeArgument(const Record *Arg) {
 }
 
 /// Emits the first-argument-is-type property for attributes.
-static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
+static void emitClangAttrTypeArgList(const RecordKeeper &Records,
+                                     raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
   std::map<std::string, FSIVecTy> FSIMap;
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     // Determine whether the first argument is a type.
     std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
     if (Args.empty())
@@ -2531,7 +2524,8 @@ static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
 
 /// Emits the parse-arguments-in-unevaluated-context property for
 /// attributes.
-static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
+static void emitClangAttrArgContextList(const RecordKeeper &Records,
+                                        raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
   std::map<std::string, FSIVecTy> FSIMap;
   ParsedAttrMap Attrs = getParsedAttrList(Records);
@@ -2590,12 +2584,11 @@ static bool isVariadicStringLiteralArgument(const Record *Arg) {
   return ArgKind == "VariadicStringArgument";
 }
 
-static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
+static void emitClangAttrVariadicIdentifierArgList(const RecordKeeper &Records,
                                                    raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST)\n";
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
   std::map<std::string, FSIVecTy> FSIMap;
-  for (const auto *A : Attrs) {
+  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     // Determine whether the first argument is a variadic identifier.
     std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
     if (Args.empty() || !isVariadicIdentifierArgument(Args[0]))
@@ -2608,8 +2601,9 @@ static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
 
 // Emits the list of arguments that should be parsed as unevaluated string
 // literals for each attribute.
-static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
-                                                      raw_ostream &OS) {
+static void
+emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records,
+                                          raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n";
 
   auto MakeMask = [](ArrayRef<Record *> Args) {
@@ -2626,9 +2620,8 @@ static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
     return Bits;
   };
 
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
   std::map<std::string, FSIVecTy> FSIMap;
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     // Determine whether there are any string arguments.
     uint32_t ArgMask = MakeMask(Attr->getValueAsListOfDefs("Args"));
     if (!ArgMask)
@@ -2640,12 +2633,11 @@ static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
 }
 
 // Emits the first-argument-is-identifier property for attributes.
-static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
+static void emitClangAttrIdentifierArgList(const RecordKeeper &Records,
+                                           raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-
   std::map<std::string, FSIVecTy> FSIMap;
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     // Determine whether the first argument is an identifier.
     std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
     if (Args.empty() || !isIdentifierArgument(Args[0]))
@@ -2657,13 +2649,11 @@ static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &O
 }
 
 // Emits the list for attributes having StrictEnumParameters.
-static void emitClangAttrStrictIdentifierArgList(RecordKeeper &Records,
+static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records,
                                                  raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST)\n";
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-
   std::map<std::string, FSIVecTy> FSIMap;
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     if (!Attr->getValueAsBit("StrictEnumParameters"))
       continue;
     // Check that there is really an identifier argument.
@@ -2684,12 +2674,11 @@ static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
              .Default(false);
 }
 
-static void emitClangAttrThisIsaIdentifierArgList(RecordKeeper &Records,
+static void emitClangAttrThisIsaIdentifierArgList(const RecordKeeper &Records,
                                                   raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST)\n";
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
   std::map<std::string, FSIVecTy> FSIMap;
-  for (const auto *A : Attrs) {
+  for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
     // Determine whether the first argument is a variadic identifier.
     std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
     if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0]))
@@ -2700,7 +2689,7 @@ static void emitClangAttrThisIsaIdentifierArgList(RecordKeeper &Records,
   OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n";
 }
 
-static void emitClangAttrAcceptsExprPack(RecordKeeper &Records,
+static void emitClangAttrAcceptsExprPack(const RecordKeeper &Records,
                                          raw_ostream &OS) {
   OS << "#if defined(CLANG_ATTR_ACCEPTS_EXPR_PACK)\n";
   ParsedAttrMap Attrs = getParsedAttrList(Records);
@@ -2733,9 +2722,8 @@ static void emitFormInitializer(raw_ostream &OS,
      << " /*IsRegularKeywordAttribute*/}";
 }
 
-static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
+static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
                            bool Header) {
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
   ParsedAttrMap AttrMap = getParsedAttrList(Records);
 
   // Helper to print the starting character of an attribute argument. If there
@@ -2750,7 +2738,7 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
      << "    OS << \", \";\n"
      << "}\n";
 
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     const Record &R = *Attr;
 
     // FIXME: Currently, documentation is generated as-needed due to the fact
@@ -3235,7 +3223,7 @@ static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
   }
 }
 // Emits the class definitions for attributes.
-void clang::EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
+void clang::EmitClangAttrClass(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute classes' definitions", OS, Records);
 
   OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
@@ -3247,19 +3235,17 @@ void clang::EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
 }
 
 // Emits the class method definitions for attributes.
-void clang::EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
+void clang::EmitClangAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute classes' member function definitions", OS,
                        Records);
 
   emitAttributes(Records, OS, false);
 
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-
   // Instead of relying on virtual dispatch we just create a huge dispatch
   // switch. This is both smaller and faster than virtual functions.
   auto EmitFunc = [&](const char *Method) {
     OS << "  switch (getKind()) {\n";
-    for (const auto *Attr : Attrs) {
+    for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
       const Record &R = *Attr;
       if (!R.getValueAsBit("ASTNode"))
         continue;
@@ -3285,7 +3271,7 @@ void clang::EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
 }
 
 static void emitAttrList(raw_ostream &OS, StringRef Class,
-                         const std::vector<Record*> &AttrList) {
+                         ArrayRef<const Record *> AttrList) {
   for (auto Cur : AttrList) {
     OS << Class << "(" << Cur->getName() << ")\n";
   }
@@ -3333,13 +3319,13 @@ namespace {
   /// A class of attributes.
   struct AttrClass {
     const AttrClassDescriptor &Descriptor;
-    Record *TheRecord;
+    const Record *TheRecord;
     AttrClass *SuperClass = nullptr;
     std::vector<AttrClass*> SubClasses;
-    std::vector<Record*> Attrs;
+    std::vector<const Record *> Attrs;
 
-    AttrClass(const AttrClassDescriptor &Descriptor, Record *R)
-      : Descriptor(Descriptor), TheRecord(R) {}
+    AttrClass(const AttrClassDescriptor &Descriptor, const Record *R)
+        : Descriptor(Descriptor), TheRecord(R) {}
 
     void emitDefaultDefines(raw_ostream &OS) const {
       // Default the macro unless this is a root class (i.e. Attr).
@@ -3361,7 +3347,7 @@ namespace {
       ::emitAttrList(OS, Descriptor.MacroName, Attrs);
     }
 
-    void classifyAttrOnRoot(Record *Attr) {
+    void classifyAttrOnRoot(const Record *Attr) {
       bool result = classifyAttr(Attr);
       assert(result && "failed to classify on root"); (void) result;
     }
@@ -3373,7 +3359,7 @@ namespace {
     }
 
   private:
-    bool classifyAttr(Record *Attr) {
+    bool classifyAttr(const Record *Attr) {
       // Check all the subclasses.
       for (auto SubClass : SubClasses) {
         if (SubClass->classifyAttr(Attr))
@@ -3389,13 +3375,13 @@ namespace {
       return false;
     }
 
-    Record *getFirstAttr() const {
+    const Record *getFirstAttr() const {
       if (!SubClasses.empty())
         return SubClasses.front()->getFirstAttr();
       return Attrs.front();
     }
 
-    Record *getLastAttr() const {
+    const Record *getLastAttr() const {
       if (!Attrs.empty())
         return Attrs.back();
       return SubClasses.back()->getLastAttr();
@@ -3407,7 +3393,7 @@ namespace {
     std::vector<std::unique_ptr<AttrClass>> Classes;
 
   public:
-    AttrClassHierarchy(RecordKeeper &Records) {
+    AttrClassHierarchy(const RecordKeeper &Records) {
       // Find records for all the classes.
       for (auto &Descriptor : AttrClassDescriptors) {
         Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
@@ -3453,7 +3439,7 @@ namespace {
         Class->emitAttrRange(OS);
     }
 
-    void classifyAttr(Record *Attr) {
+    void classifyAttr(const Record *Attr) {
       // Add the attribute to the root class.
       Classes[0]->classifyAttrOnRoot(Attr);
     }
@@ -3467,7 +3453,7 @@ namespace {
       return nullptr;
     }
 
-    AttrClass *findSuperClass(Record *R) const {
+    AttrClass *findSuperClass(const Record *R) const {
       // TableGen flattens the superclass list, so we just need to walk it
       // in reverse.
       auto SuperClasses = R->getSuperClasses();
@@ -3484,7 +3470,7 @@ namespace {
 namespace clang {
 
 // Emits the enumeration list for attributes.
-void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
+void EmitClangAttrList(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("List of all attributes that Clang recognizes", OS,
                        Records);
 
@@ -3494,9 +3480,8 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
   Hierarchy.emitDefaultDefines(OS);
   emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr);
 
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-  std::vector<Record *> PragmaAttrs;
-  for (auto *Attr : Attrs) {
+  std::vector<const Record *> PragmaAttrs;
+  for (auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     if (!Attr->getValueAsBit("ASTNode"))
       continue;
 
@@ -3525,7 +3510,8 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
 }
 
 // Emits the enumeration list for attributes.
-void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
+void EmitClangAttrSubjectMatchRuleList(const RecordKeeper &Records,
+                                       raw_ostream &OS) {
   emitSourceFileHeader(
       "List of all attribute subject matching rules that Clang recognizes", OS,
       Records);
@@ -3537,17 +3523,16 @@ void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
 }
 
 // Emits the code to read an attribute from a precompiled header.
-void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
+void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute deserialization code", OS, Records);
 
   Record *InhClass = Records.getClass("InheritableAttr");
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
-                       ArgRecords;
+  std::vector<Record *> ArgRecords;
   std::vector<std::unique_ptr<Argument>> Args;
   std::unique_ptr<VariadicExprArgument> DelayedArgs;
 
   OS << "  switch (Kind) {\n";
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
@@ -3592,19 +3577,17 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
 }
 
 // Emits the code to write an attribute to a precompiled header.
-void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
+void EmitClangAttrPCHWrite(const RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute serialization code", OS, Records);
 
   Record *InhClass = Records.getClass("InheritableAttr");
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
-
   OS << "  switch (A->getKind()) {\n";
-  for (const auto *Attr : Attrs) {
+  for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
     OS << "  case attr::" << R.getName() << ": {\n";
-    Args = R.getValueAsListOfDefs("Args");
+    std::...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/108269


More information about the cfe-commits mailing list