Index: clang/include/clang/Sema/CMakeLists.txt =================================================================== --- clang/include/clang/Sema/CMakeLists.txt +++ clang/include/clang/Sema/CMakeLists.txt @@ -8,11 +8,6 @@ SOURCE ../Basic/Attr.td TARGET ClangAttrParsedAttrList) -clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE ../Basic/Attr.td - TARGET ClangAttrParsedAttrKinds) - clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE ../Basic/Attr.td Index: clang/include/clang/Sema/ParsedAttr.h =================================================================== --- clang/include/clang/Sema/ParsedAttr.h +++ clang/include/clang/Sema/ParsedAttr.h @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Registry.h" #include "llvm/Support/VersionTuple.h" #include #include @@ -37,6 +38,74 @@ class Expr; class IdentifierInfo; class LangOptions; +class ParsedAttr; +class Sema; + +struct ParsedAttrInfo { + /// Corresponds to the Kind enum + unsigned AttrKind : 16; + /// The number of required arguments of this attribute + unsigned NumArgs : 4; + /// The number of optional arguments of this attributes + unsigned OptArgs : 4; + /// True if the parsing does not match the semantic content + unsigned HasCustomParsing : 1; + /// True if this attribute is only available for certain targets + unsigned IsTargetSpecific : 1; + /// True if this attribute applies to types + unsigned IsType : 1; + /// True if this attribute applies to statements + unsigned IsStmt : 1; + /// True if this attribute has any spellings that are known to gcc + unsigned IsKnownToGCC : 1; + /// True if this attribute is supported by #pragma clang attribute + unsigned IsSupportedByPragmaAttribute : 1; + // The syntaxes supported by this attribute and how they're spelt + struct Spelling { + AttributeCommonInfo::Syntax Syntax; + std::string Spelling; + }; + std::vector Spellings; + + ParsedAttrInfo() + : AttrKind(AttributeCommonInfo::UnknownAttribute), NumArgs(0), OptArgs(0), + HasCustomParsing(0), IsTargetSpecific(0), IsType(0), IsStmt(0), + IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {} + + virtual ~ParsedAttrInfo() = default; + + /// Check if this attribute appertains to D, and issue a diagnostic if not + virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, + const Decl *D) const { + return true; + } + /// Check if this attribute is allowed by the language we are compiling, and + /// issue a diagnostic if not + virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const { + return true; + } + /// Check if this attribute is allowed when compiling for the given target + 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 ParsedAttr &Attr) const { + return UINT_MAX; + } + /// Populate Rules with the match rules of this attribute + virtual void getPragmaAttributeMatchRules( + llvm::SmallVectorImpl> &Rules, + const LangOptions &LangOpts) const { + } + + static std::unique_ptr get(AttributeCommonInfo::Kind); + static std::unique_ptr + get(const IdentifierInfo *Name, const IdentifierInfo *ScopeName, + AttributeCommonInfo::Syntax SyntaxUsed); +}; + +typedef llvm::Registry ParsedAttrInfoRegistry; /// Represents information about a change in availability for /// an entity, which is part of the encoding of the 'availability' @@ -181,6 +250,8 @@ const Expr *MessageExpr; + std::unique_ptr Info; + ArgsUnion *getArgsBuffer() { return getTrailingObjects(); } ArgsUnion const *getArgsBuffer() const { return getTrailingObjects(); @@ -207,7 +278,8 @@ EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - HasProcessingCache(false), IsPragmaClangAttribute(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(getParsedKind())) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); } @@ -225,7 +297,8 @@ NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), HasProcessingCache(false), IsPragmaClangAttribute(false), - UnavailableLoc(unavailable), MessageExpr(messageExpr) { + UnavailableLoc(unavailable), MessageExpr(messageExpr), + Info(ParsedAttrInfo::get(getParsedKind())) { ArgsUnion PVal(Parm); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (getAvailabilityData()) detail::AvailabilityData( @@ -242,7 +315,8 @@ NumArgs(3), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(getParsedKind())) { ArgsUnion *Args = getArgsBuffer(); Args[0] = Parm1; Args[1] = Parm2; @@ -259,7 +333,8 @@ NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(getParsedKind())) { ArgsUnion PVal(ArgKind); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -277,7 +352,8 @@ NumArgs(0), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(getParsedKind())) { new (&getTypeBuffer()) ParsedType(typeArg); } @@ -291,7 +367,8 @@ NumArgs(0), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(getParsedKind())) { new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId); } @@ -535,6 +612,7 @@ } AttributeCommonInfo::Kind getKind() const { return getParsedKind(); } + ParsedAttrInfo &getInfo() const { return *Info; } }; class AttributePool; Index: clang/lib/Basic/Attributes.cpp =================================================================== --- clang/lib/Basic/Attributes.cpp +++ clang/lib/Basic/Attributes.cpp @@ -2,9 +2,12 @@ #include "clang/Basic/AttrSubjectMatchRules.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Sema/ParsedAttr.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; +LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) + int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts) { @@ -72,12 +75,10 @@ return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__")); } -#include "clang/Sema/AttrParsedAttrKinds.inc" - -AttributeCommonInfo::Kind -AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name, - const IdentifierInfo *ScopeName, - Syntax SyntaxUsed) { +std::unique_ptr +ParsedAttrInfo::get(const IdentifierInfo *Name, + const IdentifierInfo *ScopeName, + AttributeCommonInfo::Syntax SyntaxUsed) { StringRef AttrName = Name->getName(); SmallString<64> FullName; @@ -88,11 +89,51 @@ // Ensure that in the case of C++11 attributes, we look for '::foo' if it is // unscoped. - if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x) + if (ScopeName || SyntaxUsed == AttributeCommonInfo::AS_CXX11 || + SyntaxUsed == AttributeCommonInfo::AS_C2x) FullName += "::"; FullName += AttrName; - return ::getAttrKind(FullName, SyntaxUsed); + if (SyntaxUsed == AttributeCommonInfo::AS_ContextSensitiveKeyword) + SyntaxUsed = AttributeCommonInfo::AS_Keyword; + + // Search for a ParsedAttrInfo whose name and syntax match + for (ParsedAttrInfoRegistry::iterator it = ParsedAttrInfoRegistry::begin(), + ie = ParsedAttrInfoRegistry::end(); + it != ie; ++it) { + std::unique_ptr P = it->instantiate(); + for (auto &S : P->Spellings) { + if (S.Syntax == SyntaxUsed && FullName.equals(S.Spelling)) { + return P; + } + } + } + + // If we failed to find a match then the attribute is unknown + return std::make_unique(); +} + +std::unique_ptr +ParsedAttrInfo::get(AttributeCommonInfo::Kind K) { + // Search for a ParsedAttrInfo whose kind matches + for (ParsedAttrInfoRegistry::iterator it = ParsedAttrInfoRegistry::begin(), + ie = ParsedAttrInfoRegistry::end(); + it != ie; ++it) { + std::unique_ptr P = it->instantiate(); + if (P->AttrKind == K) { + return P; + } + } + + // If we failed to find a match then the attribute is unknown + return std::make_unique(); +} + +AttributeCommonInfo::Kind +AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name, + const IdentifierInfo *ScopeName, + Syntax SyntaxUsed) { + return Kind(ParsedAttrInfo::get(Name, ScopeName, SyntaxUsed)->AttrKind); } unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const { Index: clang/lib/Sema/ParsedAttr.cpp =================================================================== --- clang/lib/Sema/ParsedAttr.cpp +++ clang/lib/Sema/ParsedAttr.cpp @@ -100,65 +100,24 @@ pool.Attrs.clear(); } -struct ParsedAttrInfo { - unsigned NumArgs : 4; - unsigned OptArgs : 4; - unsigned HasCustomParsing : 1; - unsigned IsTargetSpecific : 1; - unsigned IsType : 1; - unsigned IsStmt : 1; - unsigned IsKnownToGCC : 1; - unsigned IsSupportedByPragmaAttribute : 1; - - virtual ~ParsedAttrInfo() = default; - - virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, - const Decl *) const { - return true; - } - virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const { - return true; - } - virtual bool existsInTarget(const TargetInfo &Target) const { - return true; - } - virtual unsigned - spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const { - return UINT_MAX; - } - virtual void getPragmaAttributeMatchRules( - llvm::SmallVectorImpl> &Rules, - const LangOptions &LangOpts) const { - } -}; - namespace { #include "clang/Sema/AttrParsedAttrImpl.inc" } // namespace -static ParsedAttrInfo DefaultParsedAttrInfo; -static const ParsedAttrInfo &getInfo(const ParsedAttr &A) { - // If we have a ParsedAttrInfo for this ParsedAttr then return that, - // otherwise return a default ParsedAttrInfo. - if (A.getKind() < sizeof(AttrInfoMap)/sizeof(AttrInfoMap[0])) - return *AttrInfoMap[A.getKind()]; - return DefaultParsedAttrInfo; -} - -unsigned ParsedAttr::getMinArgs() const { return getInfo(*this).NumArgs; } +unsigned ParsedAttr::getMinArgs() const { return getInfo().NumArgs; } unsigned ParsedAttr::getMaxArgs() const { - return getMinArgs() + getInfo(*this).OptArgs; + return getMinArgs() + getInfo().OptArgs; } bool ParsedAttr::hasCustomParsing() const { - return getInfo(*this).HasCustomParsing; + return getInfo().HasCustomParsing; } bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const { - return getInfo(*this).diagAppertainsToDecl(S, *this, D); + return getInfo().diagAppertainsToDecl(S, *this, D); } bool ParsedAttr::appliesToDecl(const Decl *D, @@ -170,33 +129,33 @@ const LangOptions &LangOpts, SmallVectorImpl> &MatchRules) const { - return getInfo(*this).getPragmaAttributeMatchRules(MatchRules, LangOpts); + return getInfo().getPragmaAttributeMatchRules(MatchRules, LangOpts); } bool ParsedAttr::diagnoseLangOpts(Sema &S) const { - return getInfo(*this).diagLangOpts(S, *this); + return getInfo().diagLangOpts(S, *this); } bool ParsedAttr::isTargetSpecificAttr() const { - return getInfo(*this).IsTargetSpecific; + return getInfo().IsTargetSpecific; } -bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; } +bool ParsedAttr::isTypeAttr() const { return getInfo().IsType; } -bool ParsedAttr::isStmtAttr() const { return getInfo(*this).IsStmt; } +bool ParsedAttr::isStmtAttr() const { return getInfo().IsStmt; } bool ParsedAttr::existsInTarget(const TargetInfo &Target) const { - return getInfo(*this).existsInTarget(Target); + return getInfo().existsInTarget(Target); } -bool ParsedAttr::isKnownToGCC() const { return getInfo(*this).IsKnownToGCC; } +bool ParsedAttr::isKnownToGCC() const { return getInfo().IsKnownToGCC; } bool ParsedAttr::isSupportedByPragmaAttribute() const { - return getInfo(*this).IsSupportedByPragmaAttribute; + return getInfo().IsSupportedByPragmaAttribute; } unsigned ParsedAttr::getSemanticSpelling() const { - return getInfo(*this).spellingIndexToSemanticSpelling(*this); + return getInfo().spellingIndexToSemanticSpelling(*this); } bool ParsedAttr::hasVariadicArg() const { @@ -204,5 +163,5 @@ // claim that as being variadic. If we someday get an attribute that // legitimately bumps up against that maximum, we can use another bit to track // whether it's truly variadic or not. - return getInfo(*this).OptArgs == 15; + return getInfo().OptArgs == 15; } Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -158,12 +158,14 @@ typedef std::vector> ParsedAttrMap; static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records, - ParsedAttrMap *Dupes = nullptr) { + ParsedAttrMap *Dupes = nullptr, + bool IncludeIgnored = false) { std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); std::set Seen; ParsedAttrMap R; for (const auto *Attr : Attrs) { - if (Attr->getValueAsBit("SemaHandler")) { + if (Attr->getValueAsBit("SemaHandler") || + (IncludeIgnored && Attr->getValueAsBit("Ignored"))) { std::string AN; if (Attr->isSubClassOf("TargetSpecificAttr") && !Attr->isValueUnset("ParseKind")) { @@ -3590,9 +3592,10 @@ getPragmaAttributeSupport(Records); // Get the list of parsed attributes, and accept the optional list of - // duplicates due to the ParseKind. + // duplicates due to the ParseKind. We also want to include ignored + // attributes as we want them to be successfully matched. ParsedAttrMap Dupes; - ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes); + ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes, true); // Generate the appertainsTo diagnostic methods and write their names into // another mapping. At the same time, generate the AttrInfoMap object @@ -3608,10 +3611,18 @@ // the spellings are identical, and custom parsing rules match, etc. // We need to generate struct instances based off ParsedAttrInfo from - // ParsedAttr.cpp. + // ParsedAttr.h. const Record &Attr = *I->second; - SS << "struct ParsedAttrInfo" << I->first << " : public ParsedAttrInfo {\n"; - SS << " ParsedAttrInfo" << I->first << "() {\n"; + const std::string &AttrName = I->first; + std::vector Spellings = GetFlattenedSpellings(Attr); + std::string AttrInfoName = "AttrInfo" + AttrName; + SS << "struct " << AttrInfoName << " : public ParsedAttrInfo {\n"; + SS << " " << AttrInfoName << "() {\n"; + if (Attr.getValueAsBit("Ignored")) { + SS << " AttrKind = ParsedAttr::IgnoredAttribute;\n"; + } else { + SS << " AttrKind = ParsedAttr::AT_" << AttrName << ";\n"; + } emitArgInfo(Attr, SS); SS << " HasCustomParsing = "; SS << Attr.getValueAsBit("HasCustomParsing") << ";\n"; @@ -3626,126 +3637,36 @@ SS << IsKnownToGCC(Attr) << ";\n"; SS << " IsSupportedByPragmaAttribute = "; SS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ";\n"; + for (const auto &S : Spellings) { + const std::string &RawSpelling = S.name(); + std::string Spelling; + if (S.variety() == "CXX11" || S.variety() == "C2x") { + Spelling += S.nameSpace(); + Spelling += "::"; + } + if (S.variety() == "GNU") + Spelling += NormalizeGNUAttrSpelling(RawSpelling); + else + Spelling += RawSpelling; + SS << " Spellings.push_back({AttributeCommonInfo::AS_" << S.variety(); + SS << ",\"" << Spelling << "\"});\n"; + } SS << " }\n"; GenerateAppertainsTo(Attr, SS, OS); GenerateLangOptRequirements(Attr, SS); GenerateTargetRequirements(Attr, Dupes, SS); GenerateSpellingIndexToSemanticSpelling(Attr, SS); PragmaAttributeSupport.generateStrictConformsTo(*I->second, SS); - SS << "static ParsedAttrInfo" << I->first << " Instance;\n"; SS << "};\n"; - SS << "ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first << "::Instance;\n"; + SS << "static ParsedAttrInfoRegistry::Add<" << AttrInfoName << "> "; + SS << AttrInfoName << "Instance(\"" << AttrName << "\",\"\");\n"; } OS << SS.str(); - OS << "static const ParsedAttrInfo *AttrInfoMap[] = {\n"; - for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { - OS << "&ParsedAttrInfo" << I->first << "::Instance,\n"; - } - OS << "};\n\n"; - // Generate the attribute match rules. emitAttributeMatchRules(PragmaAttributeSupport, OS); } -// Emits the kind list of parsed attributes -void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { - emitSourceFileHeader("Attribute name matcher", OS); - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector GNU, Declspec, Microsoft, CXX11, - Keywords, Pragma, C2x; - std::set Seen; - for (const auto *A : Attrs) { - const Record &Attr = *A; - - bool SemaHandler = Attr.getValueAsBit("SemaHandler"); - bool Ignored = Attr.getValueAsBit("Ignored"); - if (SemaHandler || Ignored) { - // Attribute spellings can be shared between target-specific attributes, - // and can be shared between syntaxes for the same attribute. For - // instance, an attribute can be spelled GNU<"interrupt"> for an ARM- - // specific attribute, or MSP430-specific attribute. Additionally, an - // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport"> - // for the same semantic attribute. Ultimately, we need to map each of - // these to a single AttributeCommonInfo::Kind value, but the - // StringMatcher class cannot handle duplicate match strings. So we - // generate a list of string to match based on the syntax, and emit - // multiple string matchers depending on the syntax used. - std::string AttrName; - if (Attr.isSubClassOf("TargetSpecificAttr") && - !Attr.isValueUnset("ParseKind")) { - AttrName = Attr.getValueAsString("ParseKind"); - if (Seen.find(AttrName) != Seen.end()) - continue; - Seen.insert(AttrName); - } else - AttrName = NormalizeAttrName(StringRef(Attr.getName())).str(); - - std::vector Spellings = GetFlattenedSpellings(Attr); - for (const auto &S : Spellings) { - const std::string &RawSpelling = S.name(); - std::vector *Matches = nullptr; - std::string Spelling; - const std::string &Variety = S.variety(); - if (Variety == "CXX11") { - Matches = &CXX11; - Spelling += S.nameSpace(); - Spelling += "::"; - } else if (Variety == "C2x") { - Matches = &C2x; - Spelling += S.nameSpace(); - Spelling += "::"; - } else if (Variety == "GNU") - Matches = &GNU; - else if (Variety == "Declspec") - Matches = &Declspec; - else if (Variety == "Microsoft") - Matches = &Microsoft; - else if (Variety == "Keyword") - Matches = &Keywords; - else if (Variety == "Pragma") - Matches = &Pragma; - - assert(Matches && "Unsupported spelling variety found"); - - if (Variety == "GNU") - Spelling += NormalizeGNUAttrSpelling(RawSpelling); - else - Spelling += RawSpelling; - - if (SemaHandler) - Matches->push_back(StringMatcher::StringPair( - Spelling, "return AttributeCommonInfo::AT_" + AttrName + ";")); - else - Matches->push_back(StringMatcher::StringPair( - Spelling, "return AttributeCommonInfo::IgnoredAttribute;")); - } - } - } - - OS << "static AttributeCommonInfo::Kind getAttrKind(StringRef Name, "; - OS << "AttributeCommonInfo::Syntax Syntax) {\n"; - OS << " if (AttributeCommonInfo::AS_GNU == Syntax) {\n"; - StringMatcher("Name", GNU, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_Declspec == Syntax) {\n"; - StringMatcher("Name", Declspec, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_Microsoft == Syntax) {\n"; - StringMatcher("Name", Microsoft, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_CXX11 == Syntax) {\n"; - StringMatcher("Name", CXX11, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_C2x == Syntax) {\n"; - StringMatcher("Name", C2x, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_Keyword == Syntax || "; - OS << "AttributeCommonInfo::AS_ContextSensitiveKeyword == Syntax) {\n"; - StringMatcher("Name", Keywords, OS).Emit(); - OS << " } else if (AttributeCommonInfo::AS_Pragma == Syntax) {\n"; - StringMatcher("Name", Pragma, OS).Emit(); - OS << " }\n"; - OS << " return AttributeCommonInfo::UnknownAttribute;\n" - << "}\n"; -} - // Emits the code to dump an attribute. void EmitClangAttrTextNodeDump(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("Attribute text node dumper", OS); Index: clang/utils/TableGen/TableGen.cpp =================================================================== --- clang/utils/TableGen/TableGen.cpp +++ clang/utils/TableGen/TableGen.cpp @@ -39,7 +39,6 @@ GenClangAttrTemplateInstantiate, GenClangAttrParsedAttrList, GenClangAttrParsedAttrImpl, - GenClangAttrParsedAttrKinds, GenClangAttrTextNodeDump, GenClangAttrNodeTraverse, GenClangBasicReader, @@ -122,9 +121,6 @@ clEnumValN(GenClangAttrParsedAttrImpl, "gen-clang-attr-parsed-attr-impl", "Generate the clang parsed attribute helpers"), - clEnumValN(GenClangAttrParsedAttrKinds, - "gen-clang-attr-parsed-attr-kinds", - "Generate a clang parsed attribute kinds"), clEnumValN(GenClangAttrTextNodeDump, "gen-clang-attr-text-node-dump", "Generate clang attribute text node dumper"), clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse", @@ -257,9 +253,6 @@ case GenClangAttrParsedAttrImpl: EmitClangAttrParsedAttrImpl(Records, OS); break; - case GenClangAttrParsedAttrKinds: - EmitClangAttrParsedAttrKinds(Records, OS); - break; case GenClangAttrTextNodeDump: EmitClangAttrTextNodeDump(Records, OS); break; Index: clang/utils/TableGen/TableGenBackends.h =================================================================== --- clang/utils/TableGen/TableGenBackends.h +++ clang/utils/TableGen/TableGenBackends.h @@ -55,8 +55,6 @@ llvm::raw_ostream &OS); void EmitClangAttrParsedAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); -void EmitClangAttrParsedAttrKinds(llvm::RecordKeeper &Records, - llvm::raw_ostream &OS); void EmitClangAttrTextNodeDump(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitClangAttrNodeTraverse(llvm::RecordKeeper &Records,