From e8743c0f389d43aeab053904c6407280bfbfd3a6 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 28 Mar 2020 18:12:28 +0100 Subject: [PATCH] Const-initialize ParsedAttrInfos Gets rid of a 150k static initializer (Release clang) --- clang/examples/Attribute/Attribute.cpp | 7 +++--- clang/include/clang/Sema/ParsedAttr.h | 8 +++---- clang/lib/Sema/ParsedAttr.cpp | 4 ++-- clang/utils/TableGen/ClangAttrEmitter.cpp | 37 +++++++++++++++++++------------ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 04e30e1..998f175 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -28,9 +28,10 @@ struct ExampleAttrInfo : public ParsedAttrInfo { OptArgs = 1; // GNU-style __attribute__(("example")) and C++-style [[example]] and // [[plugin::example]] supported. - Spellings.push_back({ParsedAttr::AS_GNU, "example"}); - Spellings.push_back({ParsedAttr::AS_CXX11, "example"}); - Spellings.push_back({ParsedAttr::AS_CXX11, "plugin::example"}); + static constexpr Spelling S[] = {{ParsedAttr::AS_GNU, "example"}, + {ParsedAttr::AS_CXX11, "example"}, + {ParsedAttr::AS_CXX11, "plugin::example"}}; + Spellings = S; } bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index 439e540..9117784 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -63,12 +63,12 @@ struct ParsedAttrInfo { /// The syntaxes supported by this attribute and how they're spelled. struct Spelling { AttributeCommonInfo::Syntax Syntax; - std::string NormalizedFullName; + const char *NormalizedFullName; }; - std::vector Spellings; + ArrayRef Spellings; - ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind = - AttributeCommonInfo::NoSemaHandlerAttribute) + constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind = + AttributeCommonInfo::NoSemaHandlerAttribute) : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0), IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {} diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp index 6d96ea9..d45777c 100644 --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -115,7 +115,7 @@ const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) { return *AttrInfoMap[A.getParsedKind()]; // If this is an ignored attribute then return an appropriate ParsedAttrInfo. - static ParsedAttrInfo IgnoredParsedAttrInfo( + static const ParsedAttrInfo IgnoredParsedAttrInfo( AttributeCommonInfo::IgnoredAttribute); if (A.getParsedKind() == AttributeCommonInfo::IgnoredAttribute) return IgnoredParsedAttrInfo; @@ -140,7 +140,7 @@ const ParsedAttrInfo &ParsedAttrInfo::get(const AttributeCommonInfo &A) { return *Ptr; // If we failed to find a match then return a default ParsedAttrInfo. - static ParsedAttrInfo DefaultParsedAttrInfo( + static const ParsedAttrInfo DefaultParsedAttrInfo( AttributeCommonInfo::UnknownAttribute); return DefaultParsedAttrInfo; } diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 32744f7..f455ef3 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3719,8 +3719,27 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) { // ParsedAttr.cpp. const std::string &AttrName = I->first; const Record &Attr = *I->second; - OS << "struct ParsedAttrInfo" << I->first << " : public ParsedAttrInfo {\n"; - OS << " ParsedAttrInfo" << I->first << "() {\n"; + auto Spellings = GetFlattenedSpellings(Attr); + if (!Spellings.empty()) { + OS << "static constexpr ParsedAttrInfo::Spelling " << I->first + << "Spellings[] = {\n"; + for (const auto &S : Spellings) { + const std::string &RawSpelling = S.name(); + std::string Spelling; + if (!S.nameSpace().empty()) + Spelling += S.nameSpace() + "::"; + if (S.variety() == "GNU") + Spelling += NormalizeGNUAttrSpelling(RawSpelling); + else + Spelling += RawSpelling; + OS << " {AttributeCommonInfo::AS_" << S.variety(); + OS << ", \"" << Spelling << "\"},\n"; + } + OS << "};\n"; + } + OS << "struct ParsedAttrInfo" << I->first + << " final : public ParsedAttrInfo {\n"; + OS << " constexpr ParsedAttrInfo" << I->first << "() {\n"; OS << " AttrKind = ParsedAttr::AT_" << AttrName << ";\n"; emitArgInfo(Attr, OS); OS << " HasCustomParsing = "; @@ -3736,18 +3755,8 @@ void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << IsKnownToGCC(Attr) << ";\n"; OS << " IsSupportedByPragmaAttribute = "; OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ";\n"; - for (const auto &S : GetFlattenedSpellings(Attr)) { - const std::string &RawSpelling = S.name(); - std::string Spelling; - if (!S.nameSpace().empty()) - Spelling += S.nameSpace() + "::"; - if (S.variety() == "GNU") - Spelling += NormalizeGNUAttrSpelling(RawSpelling); - else - Spelling += RawSpelling; - OS << " Spellings.push_back({AttributeCommonInfo::AS_" << S.variety(); - OS << ",\"" << Spelling << "\"});\n"; - } + if (!Spellings.empty()) + OS << " Spellings = " << I->first << "Spellings;\n"; OS << " }\n"; GenerateAppertainsTo(Attr, OS); GenerateLangOptRequirements(Attr, OS); -- 2.7.4