Const-initialize ParsedAttrInfos
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 28 Mar 2020 17:12:28 +0000 (18:12 +0100)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 28 Mar 2020 18:04:53 +0000 (19:04 +0100)
Gets rid of a 150k static initializer (Release clang)

clang/examples/Attribute/Attribute.cpp
clang/include/clang/Sema/ParsedAttr.h
clang/lib/Sema/ParsedAttr.cpp
clang/utils/TableGen/ClangAttrEmitter.cpp

index 04e30e1..998f175 100644 (file)
@@ -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,
index 439e540..9117784 100644 (file)
@@ -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<Spelling> Spellings;
+  ArrayRef<Spelling> 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) {}
index 6d96ea9..d45777c 100644 (file)
@@ -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;
 }
index 32744f7..f455ef3 100644 (file)
@@ -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);