-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang][TableGen] Change ClangAttrEmitter to use const Record * #110584
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
[Clang][TableGen] Change ClangAttrEmitter to use const Record * #110584
Conversation
@llvm/pr-subscribers-clang Author: Rahul Joshi (jurahul) ChangesThis is a part of effort to have better const correctness in TableGen backends: 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:
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]
|
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
Looks like this a project-wide refactor, and since this is literally just adding const
in a bunch of places, I don’t think there is much that could go wrong here.
…#110584) 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
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