[clang] [Clang][TableGen] Change ClangAttrEmitter to use const Record * (PR #110584)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 30 18:53:30 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Rahul Joshi (jurahul)
<details>
<summary>Changes</summary>
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 23.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110584.diff
2 Files Affected:
- (modified) clang/utils/TableGen/ASTTableGen.h (+2-2)
- (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+64-66)
``````````diff
diff --git a/clang/utils/TableGen/ASTTableGen.h b/clang/utils/TableGen/ASTTableGen.h
index 143d779a8a64f8..827fce9e213cba 100644
--- a/clang/utils/TableGen/ASTTableGen.h
+++ b/clang/utils/TableGen/ASTTableGen.h
@@ -319,8 +319,8 @@ class PropertyType : public WrappedRecord {
return get()->getValueAsString(UnpackOptionalCodeFieldName);
}
- std::vector<llvm::Record*> getBufferElementTypes() const {
- return get()->getValueAsListOfDefs(BufferElementTypesFieldName);
+ std::vector<const llvm::Record *> getBufferElementTypes() const {
+ return get()->getValueAsListOfConstDefs(BufferElementTypesFieldName);
}
static llvm::StringRef getTableGenNodeClassName() {
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 7f950c3b08a4b0..e5d92b343b3dde 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -99,10 +99,9 @@ static bool isVariadicStringLiteralArgument(const Record *Arg);
static std::vector<FlattenedSpelling>
GetFlattenedSpellings(const Record &Attr) {
- std::vector<Record *> Spellings = Attr.getValueAsListOfDefs("Spellings");
std::vector<FlattenedSpelling> Ret;
- for (const auto &Spelling : Spellings) {
+ for (const auto &Spelling : Attr.getValueAsListOfDefs("Spellings")) {
StringRef Variety = Spelling->getValueAsString("Variety");
StringRef Name = Spelling->getValueAsString("Name");
if (Variety == "GCC") {
@@ -1747,7 +1746,8 @@ getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
}
static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
- std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
+ std::vector<const Record *> Accessors =
+ R.getValueAsListOfConstDefs("Accessors");
if (Accessors.empty())
return;
@@ -1962,20 +1962,21 @@ struct AttributeSubjectMatchRule {
bool isSubRule() const { return Constraint != nullptr; }
- std::vector<Record *> getSubjects() const {
+ std::vector<const Record *> getSubjects() const {
return (Constraint ? Constraint : MetaSubject)
- ->getValueAsListOfDefs("Subjects");
+ ->getValueAsListOfConstDefs("Subjects");
}
- std::vector<Record *> getLangOpts() const {
+ std::vector<const Record *> getLangOpts() const {
if (Constraint) {
// Lookup the options in the sub-rule first, in case the sub-rule
// overrides the rules options.
- std::vector<Record *> Opts = Constraint->getValueAsListOfDefs("LangOpts");
+ std::vector<const Record *> Opts =
+ Constraint->getValueAsListOfConstDefs("LangOpts");
if (!Opts.empty())
return Opts;
}
- return MetaSubject->getValueAsListOfDefs("LangOpts");
+ return MetaSubject->getValueAsListOfConstDefs("LangOpts");
}
// Abstract rules are used only for sub-rules
@@ -2103,9 +2104,8 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
const Record *MetaSubject,
const Record *Constraint) {
Rules.emplace_back(MetaSubject, Constraint);
- std::vector<Record *> ApplicableSubjects =
- SubjectContainer->getValueAsListOfDefs("Subjects");
- for (const auto *Subject : ApplicableSubjects) {
+ for (const Record *Subject :
+ SubjectContainer->getValueAsListOfConstDefs("Subjects")) {
bool Inserted =
SubjectsToRules
.try_emplace(Subject, RuleOrAggregateRuleSet::getRule(
@@ -2121,9 +2121,8 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
for (const auto *MetaSubject :
Records.getAllDerivedDefinitions("AttrSubjectMatcherRule")) {
MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr);
- std::vector<Record *> Constraints =
- MetaSubject->getValueAsListOfDefs("Constraints");
- for (const auto *Constraint : Constraints)
+ for (const Record *Constraint :
+ MetaSubject->getValueAsListOfDefs("Constraints"))
MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
}
@@ -2131,7 +2130,7 @@ PragmaClangAttributeSupport::PragmaClangAttributeSupport(
Records.getAllDerivedDefinitions(DeclNodeClassName);
for (const auto *Aggregate :
Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule")) {
- Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
+ const Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
// Gather sub-classes of the aggregate subject that act as attribute
// subject rules.
@@ -2218,9 +2217,8 @@ bool PragmaClangAttributeSupport::isAttributedSupported(
if (Attribute.isValueUnset("Subjects"))
return false;
const Record *SubjectObj = Attribute.getValueAsDef("Subjects");
- std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
bool HasAtLeastOneValidSubject = false;
- for (const auto *Subject : Subjects) {
+ for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) {
if (!isSupportedPragmaClangAttributeSubject(*Subject))
continue;
if (!SubjectsToRules.contains(Subject))
@@ -2230,7 +2228,7 @@ bool PragmaClangAttributeSupport::isAttributedSupported(
return HasAtLeastOneValidSubject;
}
-static std::string GenerateTestExpression(ArrayRef<Record *> LangOpts) {
+static std::string GenerateTestExpression(ArrayRef<const Record *> LangOpts) {
std::string Test;
for (auto *E : LangOpts) {
@@ -2271,8 +2269,7 @@ PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
<< AttributeSubjectMatchRule::EnumName
<< ", bool>> &MatchRules, const LangOptions &LangOpts) const override {\n";
const Record *SubjectObj = Attr.getValueAsDef("Subjects");
- std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
- for (const auto *Subject : Subjects) {
+ for (const auto *Subject : SubjectObj->getValueAsListOfDefs("Subjects")) {
if (!isSupportedPragmaClangAttributeSubject(*Subject))
continue;
auto It = SubjectsToRules.find(Subject);
@@ -2281,7 +2278,7 @@ PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
for (const auto &Rule : It->getSecond().getAggregateRuleSet()) {
// The rule might be language specific, so only subtract it from the given
// rules if the specific language options are specified.
- std::vector<Record *> LangOpts = Rule.getLangOpts();
+ std::vector<const Record *> LangOpts = Rule.getLangOpts();
OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue()
<< ", /*IsSupported=*/" << GenerateTestExpression(LangOpts)
<< "));\n";
@@ -2506,7 +2503,7 @@ static void emitClangAttrTypeArgList(const RecordKeeper &Records,
std::map<std::string, FSIVecTy> FSIMap;
for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
// Determine whether the first argument is a type.
- std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = Attr->getValueAsListOfConstDefs("Args");
if (Args.empty())
continue;
@@ -2584,7 +2581,7 @@ static void emitClangAttrVariadicIdentifierArgList(const RecordKeeper &Records,
std::map<std::string, FSIVecTy> FSIMap;
for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
// Determine whether the first argument is a variadic identifier.
- std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = A->getValueAsListOfConstDefs("Args");
if (Args.empty() || !isVariadicIdentifierArgument(Args[0]))
continue;
generateFlattenedSpellingInfo(*A, FSIMap);
@@ -2600,7 +2597,7 @@ emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records,
raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n";
- auto MakeMask = [](ArrayRef<Record *> Args) {
+ auto MakeMask = [](ArrayRef<const Record *> Args) {
uint32_t Bits = 0;
assert(Args.size() <= 32 && "unsupported number of arguments in attribute");
for (uint32_t N = 0; N < Args.size(); ++N) {
@@ -2617,7 +2614,7 @@ emitClangAttrUnevaluatedStringLiteralList(const RecordKeeper &Records,
std::map<std::string, FSIVecTy> FSIMap;
for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
// Determine whether there are any string arguments.
- uint32_t ArgMask = MakeMask(Attr->getValueAsListOfDefs("Args"));
+ uint32_t ArgMask = MakeMask(Attr->getValueAsListOfConstDefs("Args"));
if (!ArgMask)
continue;
generateFlattenedSpellingInfo(*Attr, FSIMap, ArgMask);
@@ -2633,7 +2630,7 @@ static void emitClangAttrIdentifierArgList(const RecordKeeper &Records,
std::map<std::string, FSIVecTy> FSIMap;
for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
// Determine whether the first argument is an identifier.
- std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = Attr->getValueAsListOfConstDefs("Args");
if (Args.empty() || !isIdentifierArgument(Args[0]))
continue;
generateFlattenedSpellingInfo(*Attr, FSIMap);
@@ -2651,8 +2648,8 @@ static void emitClangAttrStrictIdentifierArgList(const RecordKeeper &Records,
if (!Attr->getValueAsBit("StrictEnumParameters"))
continue;
// Check that there is really an identifier argument.
- std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
- if (none_of(Args, [&](Record *R) { return isIdentifierArgument(R); }))
+ std::vector<const Record *> Args = Attr->getValueAsListOfConstDefs("Args");
+ if (none_of(Args, [&](const Record *R) { return isIdentifierArgument(R); }))
continue;
generateFlattenedSpellingInfo(*Attr, FSIMap);
}
@@ -2673,7 +2670,7 @@ static void emitClangAttrThisIsaIdentifierArgList(const RecordKeeper &Records,
std::map<std::string, FSIVecTy> FSIMap;
for (const auto *A : Records.getAllDerivedDefinitions("Attr")) {
// Determine whether the first argument is a variadic identifier.
- std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = A->getValueAsListOfConstDefs("Args");
if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0]))
continue;
generateFlattenedSpellingInfo(*A, FSIMap);
@@ -2766,7 +2763,8 @@ static void emitAttributes(const RecordKeeper &Records, raw_ostream &OS,
else
OS << "\n// " << R.getName() << "Attr implementation\n\n";
- std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+ std::vector<const Record *> ArgRecords =
+ R.getValueAsListOfConstDefs("Args");
std::vector<std::unique_ptr<Argument>> Args;
Args.reserve(ArgRecords.size());
@@ -3389,7 +3387,7 @@ namespace {
AttrClassHierarchy(const RecordKeeper &Records) {
// Find records for all the classes.
for (auto &Descriptor : AttrClassDescriptors) {
- Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
+ const Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
AttrClass *Class = new AttrClass(Descriptor, ClassRecord);
Classes.emplace_back(Class);
}
@@ -3519,8 +3517,8 @@ void EmitClangAttrSubjectMatchRuleList(const RecordKeeper &Records,
void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute deserialization code", OS, Records);
- Record *InhClass = Records.getClass("InheritableAttr");
- std::vector<Record *> ArgRecords;
+ const Record *InhClass = Records.getClass("InheritableAttr");
+ std::vector<const Record *> ArgRecords;
std::vector<std::unique_ptr<Argument>> Args;
std::unique_ptr<VariadicExprArgument> DelayedArgs;
@@ -3541,7 +3539,7 @@ void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {
std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName());
DelayedArgs->writePCHReadDecls(OS);
}
- ArgRecords = R.getValueAsListOfDefs("Args");
+ ArgRecords = R.getValueAsListOfConstDefs("Args");
Args.clear();
for (const auto *Arg : ArgRecords) {
Args.emplace_back(createArgument(*Arg, R.getName()));
@@ -3573,14 +3571,14 @@ void EmitClangAttrPCHRead(const RecordKeeper &Records, raw_ostream &OS) {
void EmitClangAttrPCHWrite(const RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute serialization code", OS, Records);
- Record *InhClass = Records.getClass("InheritableAttr");
+ const Record *InhClass = Records.getClass("InheritableAttr");
OS << " switch (A->getKind()) {\n";
for (const auto *Attr : Records.getAllDerivedDefinitions("Attr")) {
const Record &R = *Attr;
if (!R.getValueAsBit("ASTNode"))
continue;
OS << " case attr::" << R.getName() << ": {\n";
- std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = R.getValueAsListOfConstDefs("Args");
if (R.isSubClassOf(InhClass) || !Args.empty())
OS << " const auto *SA = cast<" << R.getName()
<< "Attr>(A);\n";
@@ -3731,9 +3729,8 @@ static void GenerateHasAttrSpellingStringSwitch(
GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr);
} else if (!Attr->getValueAsListOfDefs("TargetSpecificSpellings").empty()) {
// Add target checks if this spelling is target-specific.
- const std::vector<Record *> TargetSpellings =
- Attr->getValueAsListOfDefs("TargetSpecificSpellings");
- for (const auto &TargetSpelling : TargetSpellings) {
+ for (const auto &TargetSpelling :
+ Attr->getValueAsListOfDefs("TargetSpecificSpellings")) {
// Find spelling that matches current scope and name.
for (const auto &Spelling : GetFlattenedSpellings(*TargetSpelling)) {
if (Scope == Spelling.nameSpace() && Name == Spelling.name()) {
@@ -3772,7 +3769,7 @@ void EmitClangRegularKeywordAttributeInfo(const RecordKeeper &Records,
for (const auto &S : GetFlattenedSpellings(*R)) {
if (!isRegularKeywordAttribute(S))
continue;
- std::vector<Record *> Args = R->getValueAsListOfDefs("Args");
+ std::vector<const Record *> Args = R->getValueAsListOfConstDefs("Args");
bool HasArgs = any_of(
Args, [](const Record *Arg) { return !Arg->getValueAsBit("Fake"); });
@@ -3938,8 +3935,7 @@ void EmitClangAttrASTVisitor(const RecordKeeper &Records, raw_ostream &OS) {
<< " if (!getDerived().Visit" << R.getName() << "Attr(A))\n"
<< " return false;\n";
- std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
- for (const auto *Arg : ArgRecords)
+ for (const auto *Arg : R.getValueAsListOfDefs("Args"))
createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);
if (Attr->getValueAsBit("AcceptsExprPack"))
@@ -4003,7 +3999,8 @@ void EmitClangAttrTemplateInstantiateHelper(ArrayRef<const Record *> Attrs,
continue;
}
- std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+ std::vector<const Record *> ArgRecords =
+ R.getValueAsListOfConstDefs("Args");
std::vector<std::unique_ptr<Argument>> Args;
Args.reserve(ArgRecords.size());
@@ -4073,10 +4070,9 @@ static void emitArgInfo(const Record &R, raw_ostream &OS) {
// This function will count the number of arguments specified for the
// attribute and emit the number of required arguments followed by the
// number of optional arguments.
- std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
unsigned ArgCount = 0, OptCount = 0, ArgMemberCount = 0;
bool HasVariadic = false;
- for (const auto *Arg : Args) {
+ for (const auto *Arg : R.getValueAsListOfDefs("Args")) {
// If the arg is fake, it's the user's job to supply it: general parsing
// logic shouldn't need to know anything about it.
if (Arg->getValueAsBit("Fake"))
@@ -4116,8 +4112,7 @@ static std::string CalculateDiagnostic(const Record &S) {
return ("\"" + Twine(CustomDiag) + "\"").str();
std::vector<std::string> DiagList;
- std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
- for (const auto *Subject : Subjects) {
+ for (const auto *Subject : S.getValueAsListOfDefs("Subjects")) {
const Record &R = *Subject;
// Get the diagnostic text from the Decl or Stmt node given.
std::string V = GetDiagnosticSpelling(R);
@@ -4182,7 +4177,7 @@ static void GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) {
return;
// This only works with non-root Decls.
- Record *Base = Subject.getValueAsDef(BaseFieldName);
+ const Record *Base = Subject.getValueAsDef(BaseFieldName);
// Not currently support custom subjects within custom subjects.
if (Base->isSubClassOf("SubsetSubject")) {
@@ -4209,7 +4204,8 @@ static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
return;
const Record *SubjectObj = Attr.getValueAsDef("Subjects");
- std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
+ std::vector<const Record *> Subjects =
+ SubjectObj->getValueAsListOfConstDefs("Subjects");
// If the list of subjects is empty, it is assumed that the attribute
// appertains to everything.
@@ -4222,7 +4218,7 @@ static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
// FIXME: subset subjects are added to the declaration list until there are
// enough statement attributes with custom subject needs to warrant
// the implementation effort.
- std::vector<Record *> DeclSubjects, StmtSubjects;
+ std::vector<const Record *> DeclSubjects, StmtSubjects;
copy_if(Subjects, std::back_inserter(DeclSubjects), [](const Record *R) {
return R->isSubClassOf("SubsetSubject") || !R->isSubClassOf("StmtNode");
});
@@ -4340,8 +4336,8 @@ static void GenerateMutualExclusionsChecks(const Record &Attr,
// diagMutualExclusion() check.
for (const Record *Exclusion :
Records.getAllDerivedDefinitions("MutualExclusions")) {
- std::vector<Record *> MutuallyExclusiveAttrs =
- Exclusion->getValueAsListOfDefs("Exclusions");
+ std::vector<const Record *> MutuallyExclusiveAttrs =
+ Exclusion->getValueAsListOfConstDefs("Exclusions");
auto IsCurAttr = [Attr](const Record *R) {
return R->getName() == Attr.getName();
};
@@ -4460,7 +4456,7 @@ emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
OS << " return false;\n";
continue;
}
- std::vector<Record *> Subjects = Rule.getSubjects();
+ std::vector<const Record *> Subjects = Rule.getSubjects();
assert(!Subjects.empty() && "Missing subjects");
OS << " case " << Rule.getEnumValue() << ":\n";
OS << " return ";
@@ -4487,7 +4483,8 @@ static void GenerateLangOptRequirements(const Record &R,
raw_ostream &OS) {
// If the attribute has an empty or unset list of language requirements,
// use the default handler.
- std::vector<Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
+ std::vector<const Record *> LangOpts =
+ R.getValueAsListOfConstDefs("LangOpts");
if (LangOpts.empty())
return;
@@ -4539,7 +4536,7 @@ static void GenerateTargetRequirements(const Record &Attr,
static void
GenerateSpellingTargetRequirements(const Record &Attr,
- const std::vector<Record *> &TargetSpellings,
+ ArrayRef<const Record *> TargetSpellings,
raw_ostream &OS) {
// If there are no target specific spellings, use the default target handler.
if (TargetSpellings.empty())
@@ -4632,7 +4629,7 @@ static bool isParamExpr(const Record *Arg) {
void GenerateIsParamExpr(const Record &Attr, raw_ostream &OS) {
OS << "bool isParamExpr(size_t N) const override {\n";
OS << " return ";
- auto Args = Attr.getValueAsListOfDefs("Args");
+ auto Args = Attr.getValueAsListOfConstDefs("Args");
for (size_t I = 0; I < Args.size(); ++I)
if (isParamExpr(Args[I]))
OS << "(N == " << I << ") || ";
@@ -4698,7 +4695,7 @@ void EmitClangAttrParsedAttrImpl(const RecordKeeper &Records, raw_ostream &OS) {
if (Attr.isValueUnset("Subjects"))
continue;
const Record *SubjectObj = Att...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/110584
More information about the cfe-commits
mailing list