https://github.com/jayfoad updated 
https://github.com/llvm/llvm-project/pull/123072

>From f12511a0fd30c47ea08e6c126cae558215758183 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Wed, 15 Jan 2025 13:34:41 +0000
Subject: [PATCH 01/13] Change API of getSuperClasses

---
 llvm/include/llvm/TableGen/Record.h           |  5 ++--
 llvm/lib/TableGen/DetailedRecordsBackend.cpp  |  4 +--
 llvm/lib/TableGen/JSONBackend.cpp             |  4 ++-
 llvm/lib/TableGen/Record.cpp                  | 26 ++++++++++++++-----
 llvm/lib/TableGen/SetTheory.cpp               |  4 ++-
 llvm/lib/TableGen/TGParser.cpp                |  9 ++++---
 llvm/utils/TableGen/CallingConvEmitter.cpp    | 11 ++++----
 .../TableGen/Common/CodeGenRegisters.cpp      |  4 ++-
 .../utils/TableGen/SearchableTableEmitter.cpp |  5 ++--
 9 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index b15e9fc7328da0..79e9b88c34a561 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1718,8 +1718,9 @@ class Record {
   ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
   ArrayRef<DumpInfo> getDumps() const { return Dumps; }
 
-  ArrayRef<std::pair<const Record *, SMRange>> getSuperClasses() const {
-    return SuperClasses;
+  void getSuperClasses(
+      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
+    Classes.append(SuperClasses);
   }
 
   /// Determine whether this record has the specified direct superclass.
diff --git a/llvm/lib/TableGen/DetailedRecordsBackend.cpp 
b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
index 4a337248c941a1..2a1623e64e439d 100644
--- a/llvm/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -152,8 +152,8 @@ void DetailedRecordsEmitter::printTemplateArgs(const Record 
&Rec,
 // are enclosed in parentheses.
 void DetailedRecordsEmitter::printSuperclasses(const Record &Rec,
                                                raw_ostream &OS) {
-  ArrayRef<std::pair<const Record *, SMRange>> Superclasses =
-      Rec.getSuperClasses();
+  SmallVector<std::pair<const Record *, SMRange>> Superclasses;
+  Rec.getSuperClasses(Superclasses);
   if (Superclasses.empty()) {
     OS << "  Superclasses: (none)\n";
     return;
diff --git a/llvm/lib/TableGen/JSONBackend.cpp 
b/llvm/lib/TableGen/JSONBackend.cpp
index d648019ac46e8d..fecd16764fca21 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -151,7 +151,9 @@ void JSONEmitter::run(raw_ostream &OS) {
 
     json::Array SuperClasses;
     // Add this def to the instance list for each of its superclasses.
-    for (const auto &[SuperClass, Loc] : Def->getSuperClasses()) {
+    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    Def->getSuperClasses(SCs);
+    for (const auto &[SuperClass, Loc] : SCs) {
       std::string SuperName = SuperClass->getNameInitAsString();
       SuperClasses.push_back(SuperName);
       InstanceLists[SuperName].push_back(Name);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 597ccb7ca144bb..4fe2b16cd516f9 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2395,7 +2395,9 @@ const DefInit *VarDefInit::instantiate() {
   NewRec->resolveReferences(R);
 
   // Add superclasses.
-  for (const auto &[SC, Loc] : Class->getSuperClasses())
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  Class->getSuperClasses(SCs);
+  for (const auto &[SC, Loc] : SCs)
     NewRec->addSuperClass(SC, Loc);
 
   NewRec->addSuperClass(
@@ -2912,13 +2914,18 @@ void Record::setName(const Init *NewName) {
 // so we can step through the direct superclasses in reverse order.
 
 bool Record::hasDirectSuperClass(const Record *Superclass) const {
-  ArrayRef<std::pair<const Record *, SMRange>> SCs = getSuperClasses();
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  getSuperClasses(SCs);
+
+  SmallVector<std::pair<const Record *, SMRange>> SSCs;
 
   for (int I = SCs.size() - 1; I >= 0; --I) {
     const Record *SC = SCs[I].first;
     if (SC == Superclass)
       return true;
-    I -= SC->getSuperClasses().size();
+    SC->getSuperClasses(SSCs);
+    I -= SSCs.size();
+    SSCs.clear();
   }
 
   return false;
@@ -2926,11 +2933,17 @@ bool Record::hasDirectSuperClass(const Record 
*Superclass) const {
 
 void Record::getDirectSuperClasses(
     SmallVectorImpl<const Record *> &Classes) const {
-  ArrayRef<std::pair<const Record *, SMRange>> SCs = getSuperClasses();
+  SmallVector<std::pair<const Record *, SMRange>> SCVec;
+  getSuperClasses(SCVec);
+  ArrayRef<std::pair<const Record *, SMRange>> SCs = SCVec;
+
+  SmallVector<std::pair<const Record *, SMRange>> SSCs;
 
   while (!SCs.empty()) {
     const Record *SC = SCs.back().first;
-    SCs = SCs.drop_back(1 + SC->getSuperClasses().size());
+    SC->getSuperClasses(SSCs);
+    SCs = SCs.drop_back(1 + SSCs.size());
+    SSCs.clear();
     Classes.push_back(SC);
   }
 }
@@ -3008,7 +3021,8 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const 
Record &R) {
   }
 
   OS << " {";
-  ArrayRef<std::pair<const Record *, SMRange>> SC = R.getSuperClasses();
+  SmallVector<std::pair<const Record *, SMRange>> SC;
+  R.getSuperClasses(SC);
   if (!SC.empty()) {
     OS << "\t//";
     for (const auto &[SC, _] : SC)
diff --git a/llvm/lib/TableGen/SetTheory.cpp b/llvm/lib/TableGen/SetTheory.cpp
index ac7ae2cbaed57b..b3a2b9d0d6fa7e 100644
--- a/llvm/lib/TableGen/SetTheory.cpp
+++ b/llvm/lib/TableGen/SetTheory.cpp
@@ -312,7 +312,9 @@ const RecVec *SetTheory::expand(const Record *Set) {
     return &I->second;
 
   // This is the first time we see Set. Find a suitable expander.
-  for (const auto &[SuperClass, Loc] : Set->getSuperClasses()) {
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  Set->getSuperClasses(SCs);
+  for (const auto &[SuperClass, Loc] : SCs) {
     // Skip unnamed superclasses.
     if (!isa<StringInit>(SuperClass->getNameInit()))
       continue;
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 60ae11b7f42612..317cd6b5a9213b 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -330,7 +330,9 @@ bool TGParser::AddSubClass(Record *CurRec, 
SubClassReference &SubClass) {
 
   // Since everything went well, we can now set the "superclass" list for the
   // current record.
-  for (const auto &[SC, Loc] : SC->getSuperClasses()) {
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  SC->getSuperClasses(SCs);
+  for (const auto &[SC, Loc] : SCs) {
     if (CurRec->isSubClassOf(SC))
       return Error(SubClass.RefRange.Start,
                    "Already subclass of '" + SC->getName() + "'!\n");
@@ -4002,8 +4004,9 @@ bool TGParser::ParseClass() {
   Record *CurRec = const_cast<Record *>(Records.getClass(Name));
   if (CurRec) {
     // If the body was previously defined, this is an error.
-    if (!CurRec->getValues().empty() ||
-        !CurRec->getSuperClasses().empty() ||
+    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    CurRec->getSuperClasses(SCs);
+    if (!CurRec->getValues().empty() || !SCs.empty() ||
         !CurRec->getTemplateArgs().empty())
       return TokError("Class '" + CurRec->getNameInitAsString() +
                       "' already defined");
diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp 
b/llvm/utils/TableGen/CallingConvEmitter.cpp
index b315aa7d86fe91..ce97cbf17ddf8c 100644
--- a/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -109,12 +109,13 @@ void CallingConvEmitter::emitCallingConv(const Record 
*CC, raw_ostream &O) {
   // Emit all of the actions, in order.
   for (unsigned I = 0, E = CCActions->size(); I != E; ++I) {
     const Record *Action = CCActions->getElementAsRecord(I);
+    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    Action->getSuperClasses(SCs);
     SwiftAction =
-        llvm::any_of(Action->getSuperClasses(),
-                     [](const std::pair<const Record *, SMRange> &Class) {
-                       std::string Name = Class.first->getNameInitAsString();
-                       return StringRef(Name).starts_with("CCIfSwift");
-                     });
+        llvm::any_of(SCs, [](const std::pair<const Record *, SMRange> &Class) {
+          std::string Name = Class.first->getNameInitAsString();
+          return StringRef(Name).starts_with("CCIfSwift");
+        });
 
     O << "\n";
     emitAction(Action, indent(2), O);
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp 
b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 2dbee94d7e5406..237b0d415a8a65 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -703,7 +703,9 @@ struct TupleExpander : SetTheory::Expander {
                         "Register tuple redefines register '" + Name + "'.");
 
       // Copy Proto super-classes.
-      for (const auto &[Super, Loc] : Proto->getSuperClasses())
+      SmallVector<std::pair<const Record *, SMRange>> SCs;
+      Proto->getSuperClasses(SCs);
+      for (const auto &[Super, Loc] : SCs)
         NewReg->addSuperClass(Super, Loc);
 
       // Copy Proto fields.
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp 
b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 91fde0c6630577..f5ccc99a5ad645 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -839,8 +839,9 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
   const Record *SearchableTable = Records.getClass("SearchableTable");
   for (auto &NameRec : Records.getClasses()) {
     const Record *Class = NameRec.second.get();
-    if (Class->getSuperClasses().size() != 1 ||
-        !Class->isSubClassOf(SearchableTable))
+    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    Class->getSuperClasses(SCs);
+    if (SCs.size() != 1 || !Class->isSubClassOf(SearchableTable))
       continue;
 
     StringRef TableName = Class->getName();

>From 2a96ff416acc805ff40934a9b14fc6e5031fc802 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Wed, 15 Jan 2025 14:29:51 +0000
Subject: [PATCH 02/13] Change API of getDirectSuperClasses

---
 llvm/include/llvm/TableGen/Record.h |  3 ++-
 llvm/lib/TableGen/Record.cpp        | 16 +++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 79e9b88c34a561..8b49daf6374048 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1727,7 +1727,8 @@ class Record {
   bool hasDirectSuperClass(const Record *SuperClass) const;
 
   /// Append the direct superclasses of this record to Classes.
-  void getDirectSuperClasses(SmallVectorImpl<const Record *> &Classes) const;
+  void getDirectSuperClasses(
+      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const;
 
   bool isTemplateArg(const Init *Name) const {
     return llvm::is_contained(TemplateArgs, Name);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 4fe2b16cd516f9..9ad002b67765bd 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -327,13 +327,17 @@ static const RecordRecTy *resolveRecordTypes(const 
RecordRecTy *T1,
   SmallVector<const Record *, 4> CommonSuperClasses;
   SmallVector<const Record *, 4> Stack(T1->getClasses());
 
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+
   while (!Stack.empty()) {
     const Record *R = Stack.pop_back_val();
 
     if (T2->isSubClassOf(R)) {
       CommonSuperClasses.push_back(R);
     } else {
-      R->getDirectSuperClasses(Stack);
+      R->getDirectSuperClasses(SCs);
+      append_range(Stack, make_first_range(SCs));
+      SCs.clear();
     }
   }
 
@@ -2875,8 +2879,10 @@ void Record::checkName() {
 }
 
 const RecordRecTy *Record::getType() const {
+  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  getDirectSuperClasses(SCs);
   SmallVector<const Record *, 4> DirectSCs;
-  getDirectSuperClasses(DirectSCs);
+  append_range(DirectSCs, make_first_range(SCs));
   return RecordRecTy::get(TrackedRecords, DirectSCs);
 }
 
@@ -2932,7 +2938,7 @@ bool Record::hasDirectSuperClass(const Record 
*Superclass) const {
 }
 
 void Record::getDirectSuperClasses(
-    SmallVectorImpl<const Record *> &Classes) const {
+    SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
   SmallVector<std::pair<const Record *, SMRange>> SCVec;
   getSuperClasses(SCVec);
   ArrayRef<std::pair<const Record *, SMRange>> SCs = SCVec;
@@ -2940,11 +2946,11 @@ void Record::getDirectSuperClasses(
   SmallVector<std::pair<const Record *, SMRange>> SSCs;
 
   while (!SCs.empty()) {
-    const Record *SC = SCs.back().first;
+    auto [SC, Range] = SCs.back();
     SC->getSuperClasses(SSCs);
     SCs = SCs.drop_back(1 + SSCs.size());
     SSCs.clear();
-    Classes.push_back(SC);
+    Classes.emplace_back(SC, Range);
   }
 }
 

>From 683fe146465814b805224c65ca7d2e3707383b51 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Wed, 15 Jan 2025 14:04:44 +0000
Subject: [PATCH 03/13] Only store direct superclasses in Record

---
 llvm/include/llvm/TableGen/Record.h           | 35 ++++++++-----
 llvm/lib/TableGen/Record.cpp                  | 49 +------------------
 llvm/lib/TableGen/TGParser.cpp                | 13 +----
 .../TableGen/Common/CodeGenRegisters.cpp      |  4 +-
 .../utils/TableGen/SearchableTableEmitter.cpp |  2 +-
 5 files changed, 30 insertions(+), 73 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 8b49daf6374048..52c4a92c58c6a6 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1630,9 +1630,9 @@ class Record {
   SmallVector<AssertionInfo, 0> Assertions;
   SmallVector<DumpInfo, 0> Dumps;
 
-  // All superclasses in the inheritance forest in post-order (yes, it
+  // Direct superclasses, which are roots of the inheritance forest (yes, it
   // must be a forest; diamond-shaped inheritance is not allowed).
-  SmallVector<std::pair<const Record *, SMRange>, 0> SuperClasses;
+  SmallVector<std::pair<const Record *, SMRange>, 0> DirectSuperClasses;
 
   // Tracks Record instances. Not owned by Record.
   RecordKeeper &TrackedRecords;
@@ -1666,8 +1666,9 @@ class Record {
   Record(const Record &O)
       : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
         Values(O.Values), Assertions(O.Assertions),
-        SuperClasses(O.SuperClasses), TrackedRecords(O.TrackedRecords),
-        ID(getNewUID(O.getRecords())), Kind(O.Kind) {}
+        DirectSuperClasses(O.DirectSuperClasses),
+        TrackedRecords(O.TrackedRecords), ID(getNewUID(O.getRecords())),
+        Kind(O.Kind) {}
 
   static unsigned getNewUID(RecordKeeper &RK);
 
@@ -1720,15 +1721,22 @@ class Record {
 
   void getSuperClasses(
       SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
-    Classes.append(SuperClasses);
+    for (const auto &[SC, R] : DirectSuperClasses) {
+      SC->getSuperClasses(Classes);
+      Classes.emplace_back(SC, R);
+    }
   }
 
   /// Determine whether this record has the specified direct superclass.
-  bool hasDirectSuperClass(const Record *SuperClass) const;
+  bool hasDirectSuperClass(const Record *SuperClass) const {
+    return is_contained(make_first_range(DirectSuperClasses), SuperClass);
+  }
 
   /// Append the direct superclasses of this record to Classes.
   void getDirectSuperClasses(
-      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const;
+      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
+    Classes.append(DirectSuperClasses);
+  }
 
   bool isTemplateArg(const Init *Name) const {
     return llvm::is_contained(TemplateArgs, Name);
@@ -1796,29 +1804,32 @@ class Record {
   void checkUnusedTemplateArgs();
 
   bool isSubClassOf(const Record *R) const {
-    for (const auto &[SC, _] : SuperClasses)
-      if (SC == R)
+    for (const auto &[SC, _] : DirectSuperClasses) {
+      if (SC == R || SC->isSubClassOf(R))
         return true;
+    }
     return false;
   }
 
   bool isSubClassOf(StringRef Name) const {
-    for (const auto &[SC, _] : SuperClasses) {
+    for (const auto &[SC, _] : DirectSuperClasses) {
       if (const auto *SI = dyn_cast<StringInit>(SC->getNameInit())) {
         if (SI->getValue() == Name)
           return true;
       } else if (SC->getNameInitAsString() == Name) {
         return true;
       }
+      if (SC->isSubClassOf(Name))
+        return true;
     }
     return false;
   }
 
-  void addSuperClass(const Record *R, SMRange Range) {
+  void addDirectSuperClass(const Record *R, SMRange Range) {
     assert(!CorrespondingDefInit &&
            "changing type of record after it has been referenced");
     assert(!isSubClassOf(R) && "Already subclassing record!");
-    SuperClasses.push_back(std::make_pair(R, Range));
+    DirectSuperClasses.emplace_back(R, Range);
   }
 
   /// If there are any field references that refer to fields that have been
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 9ad002b67765bd..5db47b8ce6899d 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2398,13 +2398,8 @@ const DefInit *VarDefInit::instantiate() {
 
   NewRec->resolveReferences(R);
 
-  // Add superclasses.
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
-  Class->getSuperClasses(SCs);
-  for (const auto &[SC, Loc] : SCs)
-    NewRec->addSuperClass(SC, Loc);
-
-  NewRec->addSuperClass(
+  // Add superclass.
+  NewRec->addDirectSuperClass(
       Class, SMRange(Class->getLoc().back(), Class->getLoc().back()));
 
   // Resolve internal references and store in record keeper
@@ -2914,46 +2909,6 @@ void Record::setName(const Init *NewName) {
   // this.  See TGParser::ParseDef and TGParser::ParseDefm.
 }
 
-// NOTE for the next two functions:
-// Superclasses are in post-order, so the final one is a direct
-// superclass. All of its transitive superclases immediately precede it,
-// so we can step through the direct superclasses in reverse order.
-
-bool Record::hasDirectSuperClass(const Record *Superclass) const {
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
-  getSuperClasses(SCs);
-
-  SmallVector<std::pair<const Record *, SMRange>> SSCs;
-
-  for (int I = SCs.size() - 1; I >= 0; --I) {
-    const Record *SC = SCs[I].first;
-    if (SC == Superclass)
-      return true;
-    SC->getSuperClasses(SSCs);
-    I -= SSCs.size();
-    SSCs.clear();
-  }
-
-  return false;
-}
-
-void Record::getDirectSuperClasses(
-    SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
-  SmallVector<std::pair<const Record *, SMRange>> SCVec;
-  getSuperClasses(SCVec);
-  ArrayRef<std::pair<const Record *, SMRange>> SCs = SCVec;
-
-  SmallVector<std::pair<const Record *, SMRange>> SSCs;
-
-  while (!SCs.empty()) {
-    auto [SC, Range] = SCs.back();
-    SC->getSuperClasses(SSCs);
-    SCs = SCs.drop_back(1 + SSCs.size());
-    SSCs.clear();
-    Classes.emplace_back(SC, Range);
-  }
-}
-
 void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
   const Init *OldName = getNameInit();
   const Init *NewName = Name->resolveReferences(R);
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 317cd6b5a9213b..226aaa6991a188 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -330,19 +330,10 @@ bool TGParser::AddSubClass(Record *CurRec, 
SubClassReference &SubClass) {
 
   // Since everything went well, we can now set the "superclass" list for the
   // current record.
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
-  SC->getSuperClasses(SCs);
-  for (const auto &[SC, Loc] : SCs) {
-    if (CurRec->isSubClassOf(SC))
-      return Error(SubClass.RefRange.Start,
-                   "Already subclass of '" + SC->getName() + "'!\n");
-    CurRec->addSuperClass(SC, Loc);
-  }
-
   if (CurRec->isSubClassOf(SC))
     return Error(SubClass.RefRange.Start,
                  "Already subclass of '" + SC->getName() + "'!\n");
-  CurRec->addSuperClass(SC, SubClass.RefRange);
+  CurRec->addDirectSuperClass(SC, SubClass.RefRange);
   return false;
 }
 
@@ -4005,7 +3996,7 @@ bool TGParser::ParseClass() {
   if (CurRec) {
     // If the body was previously defined, this is an error.
     SmallVector<std::pair<const Record *, SMRange>> SCs;
-    CurRec->getSuperClasses(SCs);
+    CurRec->getDirectSuperClasses(SCs);
     if (!CurRec->getValues().empty() || !SCs.empty() ||
         !CurRec->getTemplateArgs().empty())
       return TokError("Class '" + CurRec->getNameInitAsString() +
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp 
b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 237b0d415a8a65..a3934d644ce3bf 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -704,9 +704,9 @@ struct TupleExpander : SetTheory::Expander {
 
       // Copy Proto super-classes.
       SmallVector<std::pair<const Record *, SMRange>> SCs;
-      Proto->getSuperClasses(SCs);
+      Proto->getDirectSuperClasses(SCs);
       for (const auto &[Super, Loc] : SCs)
-        NewReg->addSuperClass(Super, Loc);
+        NewReg->addDirectSuperClass(Super, Loc);
 
       // Copy Proto fields.
       for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp 
b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index f5ccc99a5ad645..2d0436df7cc645 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -840,7 +840,7 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
   for (auto &NameRec : Records.getClasses()) {
     const Record *Class = NameRec.second.get();
     SmallVector<std::pair<const Record *, SMRange>> SCs;
-    Class->getSuperClasses(SCs);
+    Class->getDirectSuperClasses(SCs);
     if (SCs.size() != 1 || !Class->isSubClassOf(SearchableTable))
       continue;
 

>From e235152c1de74e740ed51096fbdc2f61c4293bbb Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Wed, 15 Jan 2025 14:37:42 +0000
Subject: [PATCH 04/13] Simplify API of getDirectSuperClasses

---
 llvm/include/llvm/TableGen/Record.h             |  7 +++----
 llvm/lib/TableGen/Record.cpp                    | 10 ++--------
 llvm/lib/TableGen/TGParser.cpp                  |  5 ++---
 llvm/utils/TableGen/Common/CodeGenRegisters.cpp |  4 +---
 llvm/utils/TableGen/SearchableTableEmitter.cpp  |  5 ++---
 5 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 52c4a92c58c6a6..45da0af25894f6 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1732,10 +1732,9 @@ class Record {
     return is_contained(make_first_range(DirectSuperClasses), SuperClass);
   }
 
-  /// Append the direct superclasses of this record to Classes.
-  void getDirectSuperClasses(
-      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
-    Classes.append(DirectSuperClasses);
+  /// Return the direct superclasses of this record.
+  ArrayRef<std::pair<const Record *, SMRange>> getDirectSuperClasses() const {
+    return DirectSuperClasses;
   }
 
   bool isTemplateArg(const Init *Name) const {
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 5db47b8ce6899d..4f94b3a48f9123 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -327,17 +327,13 @@ static const RecordRecTy *resolveRecordTypes(const 
RecordRecTy *T1,
   SmallVector<const Record *, 4> CommonSuperClasses;
   SmallVector<const Record *, 4> Stack(T1->getClasses());
 
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
-
   while (!Stack.empty()) {
     const Record *R = Stack.pop_back_val();
 
     if (T2->isSubClassOf(R)) {
       CommonSuperClasses.push_back(R);
     } else {
-      R->getDirectSuperClasses(SCs);
-      append_range(Stack, make_first_range(SCs));
-      SCs.clear();
+      append_range(Stack, make_first_range(R->getDirectSuperClasses()));
     }
   }
 
@@ -2874,10 +2870,8 @@ void Record::checkName() {
 }
 
 const RecordRecTy *Record::getType() const {
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
-  getDirectSuperClasses(SCs);
   SmallVector<const Record *, 4> DirectSCs;
-  append_range(DirectSCs, make_first_range(SCs));
+  append_range(DirectSCs, make_first_range(getDirectSuperClasses()));
   return RecordRecTy::get(TrackedRecords, DirectSCs);
 }
 
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index 226aaa6991a188..b15de794408c12 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -3995,9 +3995,8 @@ bool TGParser::ParseClass() {
   Record *CurRec = const_cast<Record *>(Records.getClass(Name));
   if (CurRec) {
     // If the body was previously defined, this is an error.
-    SmallVector<std::pair<const Record *, SMRange>> SCs;
-    CurRec->getDirectSuperClasses(SCs);
-    if (!CurRec->getValues().empty() || !SCs.empty() ||
+    if (!CurRec->getValues().empty() ||
+        !CurRec->getDirectSuperClasses().empty() ||
         !CurRec->getTemplateArgs().empty())
       return TokError("Class '" + CurRec->getNameInitAsString() +
                       "' already defined");
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp 
b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index a3934d644ce3bf..ed8891d704fba0 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -703,9 +703,7 @@ struct TupleExpander : SetTheory::Expander {
                         "Register tuple redefines register '" + Name + "'.");
 
       // Copy Proto super-classes.
-      SmallVector<std::pair<const Record *, SMRange>> SCs;
-      Proto->getDirectSuperClasses(SCs);
-      for (const auto &[Super, Loc] : SCs)
+      for (const auto &[Super, Loc] : Proto->getDirectSuperClasses())
         NewReg->addDirectSuperClass(Super, Loc);
 
       // Copy Proto fields.
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp 
b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 2d0436df7cc645..caae0037de9956 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -839,9 +839,8 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
   const Record *SearchableTable = Records.getClass("SearchableTable");
   for (auto &NameRec : Records.getClasses()) {
     const Record *Class = NameRec.second.get();
-    SmallVector<std::pair<const Record *, SMRange>> SCs;
-    Class->getDirectSuperClasses(SCs);
-    if (SCs.size() != 1 || !Class->isSubClassOf(SearchableTable))
+    if (Class->getDirectSuperClasses().size() != 1 ||
+        !Class->isSubClassOf(SearchableTable))
       continue;
 
     StringRef TableName = Class->getName();

>From e169673fbcd9f2c94343d09150ac191d91d30ddc Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Wed, 15 Jan 2025 16:28:40 +0000
Subject: [PATCH 05/13] Update docs

---
 llvm/docs/TableGen/BackGuide.rst | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/docs/TableGen/BackGuide.rst b/llvm/docs/TableGen/BackGuide.rst
index c26575272ad692..52a02e0b85b3ba 100644
--- a/llvm/docs/TableGen/BackGuide.rst
+++ b/llvm/docs/TableGen/BackGuide.rst
@@ -610,29 +610,29 @@ functions returns null.
 Getting Record Superclasses
 ===========================
 
-The ``Record`` class provides a function to obtain the superclasses of a
-record. It is named ``getSuperClasses`` and returns an ``ArrayRef`` of an
-array of ``std::pair`` pairs. The superclasses are in post-order: the order
-in which the superclasses were visited while copying their fields into the
-record. Each pair consists of a pointer to the ``Record`` instance for a
-superclass record and an instance of the ``SMRange`` class. The range
-indicates the source file locations of the beginning and end of the class
-definition.
+The ``Record`` class provides a function to obtain the direct superclasses
+of a record. It is named ``getDirectSuperClasses`` and returns an
+``ArrayRef`` of an array of ``std::pair`` pairs. Each pair consists of a
+pointer to the ``Record`` instance for a superclass record and an instance
+of the ``SMRange`` class. The range indicates the source file locations of
+the beginning and end of the class definition.
 
-This example obtains the superclasses of the ``Prototype`` record and then
-iterates over the pairs in the returned array.
+This example obtains the direct superclasses of the ``Prototype`` record and
+then iterates over the pairs in the returned array.
 
 .. code-block:: text
 
   ArrayRef<std::pair<const Record *, SMRange>>
-      Superclasses = Prototype->getSuperClasses();
-  for (const auto &SuperPair : Superclasses) {
+      Superclasses = Prototype->getDirectSuperClasses();
+  for (const auto &[Super, Range] : Superclasses) {
     ...
   }
 
-The ``Record`` class also provides a function, ``getDirectSuperClasses``, to
-append the *direct* superclasses of a record to a given vector of type
-``SmallVectorImpl<Record *>``.
+The ``Record`` class also provides a function, ``getSuperClasses``, to
+append *all* superclasses of a record to a given vector of type
+``SmallVectorImpl<Record *>``. The superclasses are in post-order: the order
+in which the superclasses were visited while copying their fields into the
+record.
 
 Emitting Text to the Output Stream
 ==================================

>From 2eb135401f44e47863a734da864ac8d76bb30b3c Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Thu, 16 Jan 2025 10:25:59 +0000
Subject: [PATCH 06/13] Do not return location info from getSuperClasses

---
 llvm/include/llvm/TableGen/Record.h          |  5 ++---
 llvm/lib/TableGen/DetailedRecordsBackend.cpp |  4 ++--
 llvm/lib/TableGen/JSONBackend.cpp            |  4 ++--
 llvm/lib/TableGen/Record.cpp                 |  8 ++++----
 llvm/lib/TableGen/SetTheory.cpp              |  4 ++--
 llvm/utils/TableGen/CallingConvEmitter.cpp   | 11 +++++------
 6 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 45da0af25894f6..f1e9e83d14abf8 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1719,11 +1719,10 @@ class Record {
   ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
   ArrayRef<DumpInfo> getDumps() const { return Dumps; }
 
-  void getSuperClasses(
-      SmallVectorImpl<std::pair<const Record *, SMRange>> &Classes) const {
+  void getSuperClasses(SmallVectorImpl<const Record *> &Classes) const {
     for (const auto &[SC, R] : DirectSuperClasses) {
       SC->getSuperClasses(Classes);
-      Classes.emplace_back(SC, R);
+      Classes.push_back(SC);
     }
   }
 
diff --git a/llvm/lib/TableGen/DetailedRecordsBackend.cpp 
b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
index 2a1623e64e439d..f4618119a9d0fa 100644
--- a/llvm/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -152,7 +152,7 @@ void DetailedRecordsEmitter::printTemplateArgs(const Record 
&Rec,
 // are enclosed in parentheses.
 void DetailedRecordsEmitter::printSuperclasses(const Record &Rec,
                                                raw_ostream &OS) {
-  SmallVector<std::pair<const Record *, SMRange>> Superclasses;
+  SmallVector<const Record *> Superclasses;
   Rec.getSuperClasses(Superclasses);
   if (Superclasses.empty()) {
     OS << "  Superclasses: (none)\n";
@@ -160,7 +160,7 @@ void DetailedRecordsEmitter::printSuperclasses(const Record 
&Rec,
   }
 
   OS << "  Superclasses:";
-  for (const auto &[ClassRec, Loc] : Superclasses) {
+  for (const auto *ClassRec : Superclasses) {
     if (Rec.hasDirectSuperClass(ClassRec))
       OS << formatv(" {0}", ClassRec->getNameInitAsString());
     else
diff --git a/llvm/lib/TableGen/JSONBackend.cpp 
b/llvm/lib/TableGen/JSONBackend.cpp
index fecd16764fca21..2d6978fb55fc8c 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -151,9 +151,9 @@ void JSONEmitter::run(raw_ostream &OS) {
 
     json::Array SuperClasses;
     // Add this def to the instance list for each of its superclasses.
-    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    SmallVector<const Record *> SCs;
     Def->getSuperClasses(SCs);
-    for (const auto &[SuperClass, Loc] : SCs) {
+    for (const auto *SuperClass : SCs) {
       std::string SuperName = SuperClass->getNameInitAsString();
       SuperClasses.push_back(SuperName);
       InstanceLists[SuperName].push_back(Name);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 4f94b3a48f9123..6b476b3433bd5a 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2976,11 +2976,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const 
Record &R) {
   }
 
   OS << " {";
-  SmallVector<std::pair<const Record *, SMRange>> SC;
-  R.getSuperClasses(SC);
-  if (!SC.empty()) {
+  SmallVector<const Record *> SCs;
+  R.getSuperClasses(SCs);
+  if (!SCs.empty()) {
     OS << "\t//";
-    for (const auto &[SC, _] : SC)
+    for (const auto *SC : SCs)
       OS << " " << SC->getNameInitAsString();
   }
   OS << "\n";
diff --git a/llvm/lib/TableGen/SetTheory.cpp b/llvm/lib/TableGen/SetTheory.cpp
index b3a2b9d0d6fa7e..3131f9d00b9185 100644
--- a/llvm/lib/TableGen/SetTheory.cpp
+++ b/llvm/lib/TableGen/SetTheory.cpp
@@ -312,9 +312,9 @@ const RecVec *SetTheory::expand(const Record *Set) {
     return &I->second;
 
   // This is the first time we see Set. Find a suitable expander.
-  SmallVector<std::pair<const Record *, SMRange>> SCs;
+  SmallVector<const Record *> SCs;
   Set->getSuperClasses(SCs);
-  for (const auto &[SuperClass, Loc] : SCs) {
+  for (const auto *SuperClass : SCs) {
     // Skip unnamed superclasses.
     if (!isa<StringInit>(SuperClass->getNameInit()))
       continue;
diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp 
b/llvm/utils/TableGen/CallingConvEmitter.cpp
index ce97cbf17ddf8c..1bdfa9a85006f6 100644
--- a/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -109,13 +109,12 @@ void CallingConvEmitter::emitCallingConv(const Record 
*CC, raw_ostream &O) {
   // Emit all of the actions, in order.
   for (unsigned I = 0, E = CCActions->size(); I != E; ++I) {
     const Record *Action = CCActions->getElementAsRecord(I);
-    SmallVector<std::pair<const Record *, SMRange>> SCs;
+    SmallVector<const Record *> SCs;
     Action->getSuperClasses(SCs);
-    SwiftAction =
-        llvm::any_of(SCs, [](const std::pair<const Record *, SMRange> &Class) {
-          std::string Name = Class.first->getNameInitAsString();
-          return StringRef(Name).starts_with("CCIfSwift");
-        });
+    SwiftAction = llvm::any_of(SCs, [](const Record *Class) {
+      std::string Name = Class->getNameInitAsString();
+      return StringRef(Name).starts_with("CCIfSwift");
+    });
 
     O << "\n";
     emitAction(Action, indent(2), O);

>From 6d740504050928eae67b58f9e16f1bcead6eac12 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Thu, 16 Jan 2025 10:33:54 +0000
Subject: [PATCH 07/13] Change getSuperClasses to return a std::vector

---
 llvm/docs/TableGen/BackGuide.rst             |  7 +++----
 llvm/include/llvm/TableGen/Record.h          | 10 +++++++++-
 llvm/lib/TableGen/DetailedRecordsBackend.cpp |  3 +--
 llvm/lib/TableGen/JSONBackend.cpp            |  4 +---
 llvm/lib/TableGen/Record.cpp                 |  3 +--
 llvm/lib/TableGen/SetTheory.cpp              |  4 +---
 llvm/utils/TableGen/CallingConvEmitter.cpp   | 11 +++++------
 7 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/llvm/docs/TableGen/BackGuide.rst b/llvm/docs/TableGen/BackGuide.rst
index 52a02e0b85b3ba..4828f9b7c183a5 100644
--- a/llvm/docs/TableGen/BackGuide.rst
+++ b/llvm/docs/TableGen/BackGuide.rst
@@ -629,10 +629,9 @@ then iterates over the pairs in the returned array.
   }
 
 The ``Record`` class also provides a function, ``getSuperClasses``, to
-append *all* superclasses of a record to a given vector of type
-``SmallVectorImpl<Record *>``. The superclasses are in post-order: the order
-in which the superclasses were visited while copying their fields into the
-record.
+return a vector of *all* superclasses of a record. The superclasses are in
+post-order: the order in which the superclasses were visited while copying
+their fields into the record.
 
 Emitting Text to the Output Stream
 ==================================
diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index f1e9e83d14abf8..95d1dbaffb8a5e 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1719,13 +1719,21 @@ class Record {
   ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
   ArrayRef<DumpInfo> getDumps() const { return Dumps; }
 
-  void getSuperClasses(SmallVectorImpl<const Record *> &Classes) const {
+  /// Append all superclasses to \p Classes.
+  void getSuperClasses(std::vector<const Record *> &Classes) const {
     for (const auto &[SC, R] : DirectSuperClasses) {
       SC->getSuperClasses(Classes);
       Classes.push_back(SC);
     }
   }
 
+  /// Return all superclasses.
+  std::vector<const Record *> getSuperClasses() const {
+    std::vector<const Record *> Classes;
+    getSuperClasses(Classes);
+    return Classes;
+  }
+
   /// Determine whether this record has the specified direct superclass.
   bool hasDirectSuperClass(const Record *SuperClass) const {
     return is_contained(make_first_range(DirectSuperClasses), SuperClass);
diff --git a/llvm/lib/TableGen/DetailedRecordsBackend.cpp 
b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
index f4618119a9d0fa..c769b38583859c 100644
--- a/llvm/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -152,8 +152,7 @@ void DetailedRecordsEmitter::printTemplateArgs(const Record 
&Rec,
 // are enclosed in parentheses.
 void DetailedRecordsEmitter::printSuperclasses(const Record &Rec,
                                                raw_ostream &OS) {
-  SmallVector<const Record *> Superclasses;
-  Rec.getSuperClasses(Superclasses);
+  std::vector<const Record *> Superclasses = Rec.getSuperClasses();
   if (Superclasses.empty()) {
     OS << "  Superclasses: (none)\n";
     return;
diff --git a/llvm/lib/TableGen/JSONBackend.cpp 
b/llvm/lib/TableGen/JSONBackend.cpp
index 2d6978fb55fc8c..ddfe0b5c61bd91 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -151,9 +151,7 @@ void JSONEmitter::run(raw_ostream &OS) {
 
     json::Array SuperClasses;
     // Add this def to the instance list for each of its superclasses.
-    SmallVector<const Record *> SCs;
-    Def->getSuperClasses(SCs);
-    for (const auto *SuperClass : SCs) {
+    for (const auto *SuperClass : Def->getSuperClasses()) {
       std::string SuperName = SuperClass->getNameInitAsString();
       SuperClasses.push_back(SuperName);
       InstanceLists[SuperName].push_back(Name);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 6b476b3433bd5a..beb8b37306f949 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2976,8 +2976,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const 
Record &R) {
   }
 
   OS << " {";
-  SmallVector<const Record *> SCs;
-  R.getSuperClasses(SCs);
+  std::vector<const Record *> SCs = R.getSuperClasses();
   if (!SCs.empty()) {
     OS << "\t//";
     for (const auto *SC : SCs)
diff --git a/llvm/lib/TableGen/SetTheory.cpp b/llvm/lib/TableGen/SetTheory.cpp
index 3131f9d00b9185..c282e76446ee1c 100644
--- a/llvm/lib/TableGen/SetTheory.cpp
+++ b/llvm/lib/TableGen/SetTheory.cpp
@@ -312,9 +312,7 @@ const RecVec *SetTheory::expand(const Record *Set) {
     return &I->second;
 
   // This is the first time we see Set. Find a suitable expander.
-  SmallVector<const Record *> SCs;
-  Set->getSuperClasses(SCs);
-  for (const auto *SuperClass : SCs) {
+  for (const auto *SuperClass : Set->getSuperClasses()) {
     // Skip unnamed superclasses.
     if (!isa<StringInit>(SuperClass->getNameInit()))
       continue;
diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp 
b/llvm/utils/TableGen/CallingConvEmitter.cpp
index 1bdfa9a85006f6..c94d294db547ab 100644
--- a/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -109,12 +109,11 @@ void CallingConvEmitter::emitCallingConv(const Record 
*CC, raw_ostream &O) {
   // Emit all of the actions, in order.
   for (unsigned I = 0, E = CCActions->size(); I != E; ++I) {
     const Record *Action = CCActions->getElementAsRecord(I);
-    SmallVector<const Record *> SCs;
-    Action->getSuperClasses(SCs);
-    SwiftAction = llvm::any_of(SCs, [](const Record *Class) {
-      std::string Name = Class->getNameInitAsString();
-      return StringRef(Name).starts_with("CCIfSwift");
-    });
+    SwiftAction =
+        llvm::any_of(Action->getSuperClasses(), [](const Record *Class) {
+          std::string Name = Class->getNameInitAsString();
+          return StringRef(Name).starts_with("CCIfSwift");
+        });
 
     O << "\n";
     emitAction(Action, indent(2), O);

>From 21492b5fb8fe1dbb9b3386ace1cec82c4d9f9221 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Thu, 16 Jan 2025 14:20:26 +0000
Subject: [PATCH 08/13] Use const Record *

---
 llvm/lib/TableGen/DetailedRecordsBackend.cpp | 2 +-
 llvm/lib/TableGen/JSONBackend.cpp            | 2 +-
 llvm/lib/TableGen/Record.cpp                 | 2 +-
 llvm/lib/TableGen/SetTheory.cpp              | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/TableGen/DetailedRecordsBackend.cpp 
b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
index c769b38583859c..cf697599e53a27 100644
--- a/llvm/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -159,7 +159,7 @@ void DetailedRecordsEmitter::printSuperclasses(const Record 
&Rec,
   }
 
   OS << "  Superclasses:";
-  for (const auto *ClassRec : Superclasses) {
+  for (const Record *ClassRec : Superclasses) {
     if (Rec.hasDirectSuperClass(ClassRec))
       OS << formatv(" {0}", ClassRec->getNameInitAsString());
     else
diff --git a/llvm/lib/TableGen/JSONBackend.cpp 
b/llvm/lib/TableGen/JSONBackend.cpp
index ddfe0b5c61bd91..d7ab043cb8c90f 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -151,7 +151,7 @@ void JSONEmitter::run(raw_ostream &OS) {
 
     json::Array SuperClasses;
     // Add this def to the instance list for each of its superclasses.
-    for (const auto *SuperClass : Def->getSuperClasses()) {
+    for (const Record *SuperClass : Def->getSuperClasses()) {
       std::string SuperName = SuperClass->getNameInitAsString();
       SuperClasses.push_back(SuperName);
       InstanceLists[SuperName].push_back(Name);
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index beb8b37306f949..19f4a45fb1a3cc 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -2979,7 +2979,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const 
Record &R) {
   std::vector<const Record *> SCs = R.getSuperClasses();
   if (!SCs.empty()) {
     OS << "\t//";
-    for (const auto *SC : SCs)
+    for (const Record *SC : SCs)
       OS << " " << SC->getNameInitAsString();
   }
   OS << "\n";
diff --git a/llvm/lib/TableGen/SetTheory.cpp b/llvm/lib/TableGen/SetTheory.cpp
index c282e76446ee1c..48a35c83b086bd 100644
--- a/llvm/lib/TableGen/SetTheory.cpp
+++ b/llvm/lib/TableGen/SetTheory.cpp
@@ -312,7 +312,7 @@ const RecVec *SetTheory::expand(const Record *Set) {
     return &I->second;
 
   // This is the first time we see Set. Find a suitable expander.
-  for (const auto *SuperClass : Set->getSuperClasses()) {
+  for (const Record *SuperClass : Set->getSuperClasses()) {
     // Skip unnamed superclasses.
     if (!isa<StringInit>(SuperClass->getNameInit()))
       continue;

>From 9a645ee475266dfb5ff847e2ac492bd816571fb2 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Thu, 16 Jan 2025 14:24:28 +0000
Subject: [PATCH 09/13] Add note about post-order

---
 llvm/include/llvm/TableGen/Record.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 95d1dbaffb8a5e..80797f8dd75123 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1719,7 +1719,7 @@ class Record {
   ArrayRef<AssertionInfo> getAssertions() const { return Assertions; }
   ArrayRef<DumpInfo> getDumps() const { return Dumps; }
 
-  /// Append all superclasses to \p Classes.
+  /// Append all superclasses in post-order to \p Classes.
   void getSuperClasses(std::vector<const Record *> &Classes) const {
     for (const auto &[SC, R] : DirectSuperClasses) {
       SC->getSuperClasses(Classes);
@@ -1727,7 +1727,7 @@ class Record {
     }
   }
 
-  /// Return all superclasses.
+  /// Return all superclasses in post-order.
   std::vector<const Record *> getSuperClasses() const {
     std::vector<const Record *> Classes;
     getSuperClasses(Classes);

>From d39a1fc8957e1aae7a893aeeb5b4fe2fede03773 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Fri, 17 Jan 2025 09:36:05 +0000
Subject: [PATCH 10/13] Use make_first_range

---
 llvm/include/llvm/TableGen/Record.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/TableGen/Record.h 
b/llvm/include/llvm/TableGen/Record.h
index 80797f8dd75123..064b0261f5fc76 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1721,7 +1721,7 @@ class Record {
 
   /// Append all superclasses in post-order to \p Classes.
   void getSuperClasses(std::vector<const Record *> &Classes) const {
-    for (const auto &[SC, R] : DirectSuperClasses) {
+    for (const Record *SC : make_first_range(DirectSuperClasses)) {
       SC->getSuperClasses(Classes);
       Classes.push_back(SC);
     }
@@ -1810,7 +1810,7 @@ class Record {
   void checkUnusedTemplateArgs();
 
   bool isSubClassOf(const Record *R) const {
-    for (const auto &[SC, _] : DirectSuperClasses) {
+    for (const Record *SC : make_first_range(DirectSuperClasses)) {
       if (SC == R || SC->isSubClassOf(R))
         return true;
     }
@@ -1818,7 +1818,7 @@ class Record {
   }
 
   bool isSubClassOf(StringRef Name) const {
-    for (const auto &[SC, _] : DirectSuperClasses) {
+    for (const Record *SC : make_first_range(DirectSuperClasses)) {
       if (const auto *SI = dyn_cast<StringInit>(SC->getNameInit())) {
         if (SI->getValue() == Name)
           return true;

>From e52de293fce8a9264d656b9056a545587977d9c0 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Fri, 17 Jan 2025 10:09:38 +0000
Subject: [PATCH 11/13] Update Clang

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 63 +++++++++++++----------
 clang/utils/TableGen/NeonEmitter.cpp      |  4 +-
 2 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index cc6a8eaebd44ec..b2b3f8e1bf78c2 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1518,7 +1518,8 @@ createArgument(const Record &Arg, StringRef Attr,
 
   if (!Ptr) {
     // Search in reverse order so that the most-derived type is handled first.
-    for (const auto &[Base, _] : reverse(Search->getSuperClasses())) {
+    std::vector<const Record *> SCs = Search->getSuperClasses();
+    for (const Record *Base : reverse(SCs)) {
       if ((Ptr = createArgument(Arg, Attr, Base)))
         break;
     }
@@ -1848,17 +1849,17 @@ static LateAttrParseKind getLateAttrParseKind(const 
Record *Attr) {
   auto *LAPK = Attr->getValueAsDef(LateParsedStr);
 
   // Typecheck the `LateParsed` field.
-  SmallVector<const Record *, 1> SuperClasses;
-  LAPK->getDirectSuperClasses(SuperClasses);
+  ArrayRef<std::pair<const Record *, SMRange>> SuperClasses =
+      LAPK->getDirectSuperClasses();
   if (SuperClasses.size() != 1)
     PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) +
                               "`should only have one super class");
 
-  if (SuperClasses[0]->getName() != LateAttrParseKindStr)
+  if (SuperClasses[0].first->getName() != LateAttrParseKindStr)
     PrintFatalError(
         Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" +
                   Twine(LateAttrParseKindStr) + "` but found type `" +
-                  SuperClasses[0]->getName() + "`");
+                  SuperClasses[0].first->getName() + "`");
 
   // Get Kind and verify the enum name matches the name in `Attr.td`.
   unsigned Kind = LAPK->getValueAsInt(KindFieldStr);
@@ -2457,8 +2458,8 @@ static void emitStringSwitchCases(std::map<StringRef, 
FSIVecTy> &Map,
 }
 
 static bool isTypeArgument(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         Arg->getSuperClasses().back().first->getName() == "TypeArgument";
+  return !Arg->getDirectSuperClasses().empty() &&
+         Arg->getDirectSuperClasses().back().first->getName() == 
"TypeArgument";
 }
 
 /// Emits the first-argument-is-type property for attributes.
@@ -2499,8 +2500,9 @@ static void emitClangAttrArgContextList(const 
RecordKeeper &Records,
 }
 
 static bool isIdentifierArgument(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
+  return !Arg->getDirectSuperClasses().empty() &&
+         StringSwitch<bool>(
+             Arg->getDirectSuperClasses().back().first->getName())
              .Case("IdentifierArgument", true)
              .Case("EnumArgument", true)
              .Case("VariadicEnumArgument", true)
@@ -2508,33 +2510,35 @@ static bool isIdentifierArgument(const Record *Arg) {
 }
 
 static bool isVariadicIdentifierArgument(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
+  return !Arg->getDirectSuperClasses().empty() &&
+         StringSwitch<bool>(
+             Arg->getDirectSuperClasses().back().first->getName())
              .Case("VariadicIdentifierArgument", true)
              .Case("VariadicParamOrParamIdxArgument", true)
              .Default(false);
 }
 
 static bool isVariadicExprArgument(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
+  return !Arg->getDirectSuperClasses().empty() &&
+         StringSwitch<bool>(
+             Arg->getDirectSuperClasses().back().first->getName())
              .Case("VariadicExprArgument", true)
              .Default(false);
 }
 
 static bool isStringLiteralArgument(const Record *Arg) {
-  if (Arg->getSuperClasses().empty())
+  if (Arg->getDirectSuperClasses().empty())
     return false;
-  StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
+  StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
   if (ArgKind == "EnumArgument")
     return Arg->getValueAsBit("IsString");
   return ArgKind == "StringArgument";
 }
 
 static bool isVariadicStringLiteralArgument(const Record *Arg) {
-  if (Arg->getSuperClasses().empty())
+  if (Arg->getDirectSuperClasses().empty())
     return false;
-  StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
+  StringRef ArgKind = Arg->getDirectSuperClasses().back().first->getName();
   if (ArgKind == "VariadicEnumArgument")
     return Arg->getValueAsBit("IsString");
   return ArgKind == "VariadicStringArgument";
@@ -2623,8 +2627,9 @@ static void emitClangAttrStrictIdentifierArgList(const 
RecordKeeper &Records,
 }
 
 static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
+  return !Arg->getDirectSuperClasses().empty() &&
+         StringSwitch<bool>(
+             Arg->getDirectSuperClasses().back().first->getName())
              .Case("VariadicParamOrParamIdxArgument", true)
              .Default(false);
 }
@@ -2710,11 +2715,11 @@ static void emitAttributes(const RecordKeeper &Records, 
raw_ostream &OS,
     if (!R.getValueAsBit("ASTNode"))
       continue;
 
-    ArrayRef<std::pair<const Record *, SMRange>> Supers = R.getSuperClasses();
+    std::vector<const Record *> Supers = R.getSuperClasses();
     assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
     std::string SuperName;
     bool Inheritable = false;
-    for (const auto &[R, _] : reverse(Supers)) {
+    for (const Record *R : reverse(Supers)) {
       if (R->getName() != "TargetSpecificAttr" &&
           R->getName() != "DeclOrTypeAttr" && SuperName.empty())
         SuperName = R->getName().str();
@@ -3411,10 +3416,11 @@ namespace {
     AttrClass *findSuperClass(const Record *R) const {
       // TableGen flattens the superclass list, so we just need to walk it
       // in reverse.
-      auto SuperClasses = R->getSuperClasses();
-      for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
-        auto SuperClass = findClassByRecord(SuperClasses[e - i - 1].first);
-        if (SuperClass) return SuperClass;
+      std::vector<const Record *> SuperClasses = R->getSuperClasses();
+      for (const Record *R : reverse(SuperClasses)) {
+        AttrClass *SuperClass = findClassByRecord(R);
+        if (SuperClass)
+          return SuperClass;
       }
       return nullptr;
     }
@@ -4614,8 +4620,9 @@ static void GenerateHandleDeclAttribute(const Record 
&Attr, raw_ostream &OS) {
 }
 
 static bool isParamExpr(const Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
+  return !Arg->getDirectSuperClasses().empty() &&
+         StringSwitch<bool>(
+             Arg->getDirectSuperClasses().back().first->getName())
              .Case("ExprArgument", true)
              .Case("VariadicExprArgument", true)
              .Default(false);
@@ -4738,7 +4745,7 @@ void EmitClangAttrParsedAttrImpl(const RecordKeeper 
&Records, raw_ostream &OS) {
       if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset))
         continue;
       ArgNames.push_back(Arg->getValueAsString("Name").str());
-      for (const auto &[Class, _] : Arg->getSuperClasses()) {
+      for (const Record *Class : Arg->getSuperClasses()) {
         if (Class->getName().starts_with("Variadic")) {
           ArgNames.back().append("...");
           break;
diff --git a/clang/utils/TableGen/NeonEmitter.cpp 
b/clang/utils/TableGen/NeonEmitter.cpp
index d7d649dd2456d5..e2dcbccc6590ad 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -2020,8 +2020,8 @@ void NeonEmitter::createIntrinsic(const Record *R,
   std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types);
 
   ClassKind CK = ClassNone;
-  if (R->getSuperClasses().size() >= 2)
-    CK = ClassMap[R->getSuperClasses()[1].first];
+  if (!R->getDirectSuperClasses().empty())
+    CK = ClassMap[R->getDirectSuperClasses()[0].first];
 
   std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
   if (!CartesianProductWith.empty()) {

>From 9c70b67867ae8a1c479cd29c5cec1fa998b50f1c Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Fri, 17 Jan 2025 10:29:30 +0000
Subject: [PATCH 12/13] Update MLIR

---
 .../tblgen-lsp-server/TableGenServer.cpp      |  2 +-
 mlir/tools/mlir-tblgen/OmpOpGen.cpp           |  9 +++----
 mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp      | 25 ++++++++-----------
 3 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp 
b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp
index 6c4ec06fffb32b..de3fcac92482e1 100644
--- a/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp
+++ b/mlir/lib/Tools/tblgen-lsp-server/TableGenServer.cpp
@@ -113,7 +113,7 @@ getBaseValue(const Record *record, const RecordVal *value) {
   // On success, `record` is updated to the new parent record.
   StringRef valueName = value->getName();
   auto findValueInSupers = [&](const Record *&record) -> const RecordVal * {
-    for (auto [parentRecord, loc] : record->getSuperClasses()) {
+    for (const Record *parentRecord : record->getSuperClasses()) {
       if (auto *newBase = parentRecord->getValue(valueName)) {
         record = parentRecord;
         return newBase;
diff --git a/mlir/tools/mlir-tblgen/OmpOpGen.cpp 
b/mlir/tools/mlir-tblgen/OmpOpGen.cpp
index 04f81a4a2dce1a..91bc61bcdbb679 100644
--- a/mlir/tools/mlir-tblgen/OmpOpGen.cpp
+++ b/mlir/tools/mlir-tblgen/OmpOpGen.cpp
@@ -72,11 +72,10 @@ static StringRef extractOmpClauseName(const Record *clause) 
{
   assert(ompClause && "base OpenMP records expected to be defined");
 
   StringRef clauseClassName;
-  SmallVector<const Record *, 1> clauseSuperClasses;
-  clause->getDirectSuperClasses(clauseSuperClasses);
 
   // Check if OpenMP_Clause is a direct superclass.
-  for (const Record *superClass : clauseSuperClasses) {
+  for (const Record *superClass :
+       llvm::make_first_range(clause->getDirectSuperClasses())) {
     if (superClass == ompClause) {
       clauseClassName = clause->getName();
       break;
@@ -85,7 +84,7 @@ static StringRef extractOmpClauseName(const Record *clause) {
 
   // Support indirectly-inherited OpenMP_Clauses.
   if (clauseClassName.empty()) {
-    for (auto [superClass, _] : clause->getSuperClasses()) {
+    for (const Record *superClass : clause->getSuperClasses()) {
       if (superClass->isSubClassOf(ompClause)) {
         clauseClassName = superClass->getName();
         break;
@@ -214,7 +213,7 @@ static StringRef translateArgumentType(ArrayRef<SMLoc> loc,
   const Record *def = cast<DefInit>(init)->getDef();
 
   llvm::StringSet<> superClasses;
-  for (auto [sc, _] : def->getSuperClasses())
+  for (const Record *sc : def->getSuperClasses())
     superClasses.insert(sc->getNameInitAsString());
 
   // Handle wrapper-style superclasses.
diff --git a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp 
b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
index 75b8829be4da59..0fba145ca0d972 100644
--- a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
+++ b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
@@ -114,13 +114,12 @@ Availability::Availability(const Record *def) : def(def) {
 }
 
 StringRef Availability::getClass() const {
-  SmallVector<const Record *, 1> parentClass;
-  def->getDirectSuperClasses(parentClass);
-  if (parentClass.size() != 1) {
+  if (def->getDirectSuperClasses().size() != 1) {
     PrintFatalError(def->getLoc(),
                     "expected to only have one direct superclass");
   }
-  return parentClass.front()->getName();
+  const Record *parentClass = def->getDirectSuperClasses().front().first;
+  return parentClass->getName();
 }
 
 StringRef Availability::getInterfaceClassNamespace() const {
@@ -204,18 +203,17 @@ static bool emitInterfaceDefs(const RecordKeeper 
&records, raw_ostream &os) {
   auto defs = records.getAllDerivedDefinitions("Availability");
   SmallVector<const Record *, 1> handledClasses;
   for (const Record *def : defs) {
-    SmallVector<const Record *, 1> parent;
-    def->getDirectSuperClasses(parent);
-    if (parent.size() != 1) {
+    if (def->getDirectSuperClasses().size() != 1) {
       PrintFatalError(def->getLoc(),
                       "expected to only have one direct superclass");
     }
-    if (llvm::is_contained(handledClasses, parent.front()))
+    const Record *parent = def->getDirectSuperClasses().front().first;
+    if (llvm::is_contained(handledClasses, parent))
       continue;
 
     Availability availability(def);
     emitInterfaceDef(availability, os);
-    handledClasses.push_back(parent.front());
+    handledClasses.push_back(parent);
   }
   return false;
 }
@@ -293,18 +291,17 @@ static bool emitInterfaceDecls(const RecordKeeper 
&records, raw_ostream &os) {
   auto defs = records.getAllDerivedDefinitions("Availability");
   SmallVector<const Record *, 4> handledClasses;
   for (const Record *def : defs) {
-    SmallVector<const Record *, 1> parent;
-    def->getDirectSuperClasses(parent);
-    if (parent.size() != 1) {
+    if (def->getDirectSuperClasses().size() != 1) {
       PrintFatalError(def->getLoc(),
                       "expected to only have one direct superclass");
     }
-    if (llvm::is_contained(handledClasses, parent.front()))
+    const Record *parent = def->getDirectSuperClasses().front().first;
+    if (llvm::is_contained(handledClasses, parent))
       continue;
 
     Availability avail(def);
     emitInterfaceDecl(avail, os);
-    handledClasses.push_back(parent.front());
+    handledClasses.push_back(parent);
   }
   return false;
 }

>From 834a3375667e842d2ca6ed38ef05e93732a00b06 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.f...@amd.com>
Date: Fri, 17 Jan 2025 10:46:38 +0000
Subject: [PATCH 13/13] Tweak Clang changes

---
 clang/utils/TableGen/ClangAttrEmitter.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp 
b/clang/utils/TableGen/ClangAttrEmitter.cpp
index b2b3f8e1bf78c2..896c90dd4a1f9b 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1849,17 +1849,16 @@ static LateAttrParseKind getLateAttrParseKind(const 
Record *Attr) {
   auto *LAPK = Attr->getValueAsDef(LateParsedStr);
 
   // Typecheck the `LateParsed` field.
-  ArrayRef<std::pair<const Record *, SMRange>> SuperClasses =
-      LAPK->getDirectSuperClasses();
-  if (SuperClasses.size() != 1)
+  if (LAPK->getDirectSuperClasses().size() != 1)
     PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) +
                               "`should only have one super class");
 
-  if (SuperClasses[0].first->getName() != LateAttrParseKindStr)
+  const Record *SuperClass = LAPK->getDirectSuperClasses()[0].first;
+  if (SuperClass->getName() != LateAttrParseKindStr)
     PrintFatalError(
         Attr, "Field `" + Twine(LateParsedStr) + "`should only have type `" +
                   Twine(LateAttrParseKindStr) + "` but found type `" +
-                  SuperClasses[0].first->getName() + "`");
+                  SuperClass->getName() + "`");
 
   // Get Kind and verify the enum name matches the name in `Attr.td`.
   unsigned Kind = LAPK->getValueAsInt(KindFieldStr);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to