-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][TableGen] Change AttrEmitter to use const RecordKeeper #108269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
5c7d69a
to
0360eda
Compare
0360eda
to
5ea8e28
Compare
@llvm/pr-subscribers-clang Author: Rahul Joshi (jurahul) ChangesChange AttrEmitter to use const RecordKeeper. This is a part of effort to have better const correctness in TableGen backends: 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:
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]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
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