[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