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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits