Index: include/clang/Sema/AttributeList.h =================================================================== --- include/clang/Sema/AttributeList.h +++ include/clang/Sema/AttributeList.h @@ -88,6 +88,8 @@ struct ParsedAttrInfo { /// Which spelling of the attribute this ParsedAttrInfo corresponds to unsigned SpellingListIndex; + /// Corresponds to the Spelling enum of the corresponding Attr class + unsigned SemanticSpelling; /// Corresponds to the AttributeList::Kind enum unsigned AttrKind : 16; /// Corresponds to the AttributeList::Syntax enum @@ -117,9 +119,9 @@ unsigned IsLateParsed : 1; ParsedAttrInfo() - : SpellingListIndex(0), AttrKind(0), Syntax(0), NumArgs(0), OptArgs(0), - HasCustomParsing(0), IsTargetSpecific(0), IsType(0), IsStmt(0), - IsKnownToGCC(0), IsUnevaluatedArgContext(0), IsIdentifierArg(0), + : SpellingListIndex(0), SemanticSpelling(0), AttrKind(0), Syntax(0), + NumArgs(0), OptArgs(0), HasCustomParsing(0), IsTargetSpecific(0), IsType(0), + IsStmt(0), IsKnownToGCC(0), IsUnevaluatedArgContext(0), IsIdentifierArg(0), IsTypeArg(0), IsLateParsed(0) { } virtual ~ParsedAttrInfo() {} @@ -138,11 +140,6 @@ virtual bool existsInTarget(const TargetInfo &Target) const { return true; } - /// Convert the spelling index of Attr to a semantic spelling enum value - virtual unsigned - spellingIndexToSemanticSpelling(const AttributeList &Attr) const { - return UINT_MAX; - } }; /// AttributeList - Represents a syntactic attribute. Index: lib/Sema/AttributeList.cpp =================================================================== --- lib/Sema/AttributeList.cpp +++ lib/Sema/AttributeList.cpp @@ -207,7 +207,7 @@ } unsigned AttributeList::getSemanticSpelling() const { - return getInfo()->spellingIndexToSemanticSpelling(*this); + return getInfo()->SemanticSpelling; } bool AttributeList::hasVariadicArg() const { Index: utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -2712,32 +2712,6 @@ OS << " }\n\n"; } -static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr, - raw_ostream &OS) { - // If the attribute does not have a semantic form, we can bail out early. - if (!Attr.getValueAsBit("ASTNode")) - return; - - std::vector Spellings = GetFlattenedSpellings(Attr); - - // If there are zero or one spellings, or all of the spellings share the same - // name, we can also bail out early. - if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings)) - return; - - // Generate the enumeration we will use for the mapping. - SemanticSpellingMap SemanticToSyntacticMap; - std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); - std::string Name = Attr.getName().str() + "AttrSpellingMap"; - - OS << " virtual unsigned spellingIndexToSemanticSpelling("; - OS << "const AttributeList &Attr) const {\n"; - OS << Enum; - OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n"; - WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS); - OS << " }\n\n"; -} - static bool IsKnownToGCC(const Record &Attr) { // Look at the spellings for this subject; if there are any spellings which // claim to be known to GCC, the attribute is known to GCC. @@ -2765,6 +2739,8 @@ const Record &Attr = *I.second; const std::string &AttrName = I.first; std::vector Spellings = GetFlattenedSpellings(Attr); + SemanticSpellingMap SemanticToSyntacticMap; + CreateSemanticSpellings(Spellings, SemanticToSyntacticMap); unsigned SpellingIdx = 0; for (const auto &S : Spellings) { std::string Spelling; @@ -2777,6 +2753,16 @@ OS << "struct " << AttrInfoName << " : public ParsedAttrInfo {\n"; OS << " " << AttrInfoName << "() {\n"; OS << " SpellingListIndex = " << SpellingIdx << ";\n"; + // If the attribute does not have a semantic form, has at most one + // spelling, or all spellings share the same name then it has no semantic + // spelling. + if (!Attr.getValueAsBit("ASTNode") || Spellings.size() <= 1 || + SpellingNamesAreCommon(Spellings)) { + OS << " SemanticSpelling = UINT_MAX;\n"; + } else { + OS << " SemanticSpelling = " << Attr.getName() << "Attr::" + << SemanticToSyntacticMap[SpellingIdx] << ";\n"; + } if (Attr.getValueAsBit("Ignored")) { OS << " AttrKind = AttributeList::IgnoredAttribute;\n"; } else { @@ -2806,7 +2792,6 @@ GenerateAppertainsTo(Attr, OS); GenerateLangOptRequirements(Attr, OS); GenerateTargetRequirements(Attr, Dupes, OS); - GenerateSpellingIndexToSemanticSpelling(Attr, OS); OS << "};\n"; OS << "static AttrInfoRegistry::Add<" << AttrInfoName << "> " << AttrInfoName << "Instance(\"" << Spelling << "\",\"\");\n"; ++SpellingIdx;