diff options
Diffstat (limited to 'clang/utils')
-rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 11c64eac7b7..d7ab4fa1b19 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -41,7 +41,7 @@ public: assert(V != "GCC" && "Given a GCC spelling, which means this hasn't been" "flattened!"); - if (V == "CXX11") + if (V == "CXX11" || V == "Pragma") NS = Spelling.getValueAsString("Namespace"); bool Unset; K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset); @@ -1055,7 +1055,7 @@ writePrettyPrintFunction(Record &R, OS << "void " << R.getName() << "Attr::printPretty(" << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; - if (Spellings.size() == 0) { + if (Spellings.empty()) { OS << "}\n\n"; return; } @@ -1082,7 +1082,7 @@ writePrettyPrintFunction(Record &R, Prefix = " [["; Suffix = "]]"; std::string Namespace = Spellings[I].nameSpace(); - if (Namespace != "") { + if (!Namespace.empty()) { Spelling += Namespace; Spelling += "::"; } @@ -1092,6 +1092,14 @@ writePrettyPrintFunction(Record &R, } else if (Variety == "Keyword") { Prefix = " "; Suffix = ""; + } else if (Variety == "Pragma") { + Prefix = "#pragma "; + Suffix = "\n"; + std::string Namespace = Spellings[I].nameSpace(); + if (!Namespace.empty()) { + Spelling += Namespace; + Spelling += " "; + } } else { llvm_unreachable("Unknown attribute syntax variety!"); } @@ -1102,6 +1110,14 @@ writePrettyPrintFunction(Record &R, " case " << I << " : {\n" " OS << \"" + Prefix.str() + Spelling.str(); + if (Variety == "Pragma") { + OS << " \";\n"; + OS << " printPrettyPragma(OS, Policy);\n"; + OS << " break;\n"; + OS << " }\n"; + continue; + } + if (!Args.empty()) OS << "("; if (Spelling == "availability") { @@ -1782,7 +1798,7 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) { // Separate all of the attributes out into four group: generic, C++11, GNU, // and declspecs. Then generate a big switch statement for each of them. std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector<Record *> Declspec, GNU; + std::vector<Record *> Declspec, GNU, Pragma; std::map<std::string, std::vector<Record *>> CXX; // Walk over the list of all attributes, and split them out based on the @@ -1795,9 +1811,10 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) { GNU.push_back(R); else if (Variety == "Declspec") Declspec.push_back(R); - else if (Variety == "CXX11") { + else if (Variety == "CXX11") CXX[SI.nameSpace()].push_back(R); - } + else if (Variety == "Pragma") + Pragma.push_back(R); } } @@ -1811,6 +1828,9 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << "case AttrSyntax::Declspec:\n"; OS << " return llvm::StringSwitch<bool>(Name)\n"; GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec"); + OS << "case AttrSyntax::Pragma:\n"; + OS << " return llvm::StringSwitch<bool>(Name)\n"; + GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma"); OS << "case AttrSyntax::CXX: {\n"; // C++11-style attributes are further split out based on the Scope. for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin(), @@ -1846,17 +1866,17 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); OS << " case AT_" << I.first << ": {\n"; for (unsigned I = 0; I < Spellings.size(); ++ I) { - OS << " if (Name == \"" - << Spellings[I].name() << "\" && " - << "SyntaxUsed == " - << StringSwitch<unsigned>(Spellings[I].variety()) - .Case("GNU", 0) - .Case("CXX11", 1) - .Case("Declspec", 2) - .Case("Keyword", 3) - .Default(0) - << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n" - << " return " << I << ";\n"; + OS << " if (Name == \"" << Spellings[I].name() << "\" && " + << "SyntaxUsed == " + << StringSwitch<unsigned>(Spellings[I].variety()) + .Case("GNU", 0) + .Case("CXX11", 1) + .Case("Declspec", 2) + .Case("Keyword", 3) + .Case("Pragma", 4) + .Default(0) + << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n" + << " return " << I << ";\n"; } OS << " break;\n"; @@ -2476,7 +2496,7 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("Attribute name matcher", OS); std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords; + std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma; std::set<std::string> Seen; for (const auto *A : Attrs) { const Record &Attr = *A; @@ -2519,6 +2539,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { Matches = &Declspec; else if (Variety == "Keyword") Matches = &Keywords; + else if (Variety == "Pragma") + Matches = &Pragma; assert(Matches && "Unsupported spelling variety found"); @@ -2543,6 +2565,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { StringMatcher("Name", CXX11, OS).Emit(); OS << " } else if (AttributeList::AS_Keyword == Syntax) {\n"; StringMatcher("Name", Keywords, OS).Emit(); + OS << " } else if (AttributeList::AS_Pragma == Syntax) {\n"; + StringMatcher("Name", Pragma, OS).Emit(); OS << " }\n"; OS << " return AttributeList::UnknownAttribute;\n" << "}\n"; @@ -2648,7 +2672,8 @@ enum SpellingKind { GNU = 1 << 0, CXX11 = 1 << 1, Declspec = 1 << 2, - Keyword = 1 << 3 + Keyword = 1 << 3, + Pragma = 1 << 4 }; static void WriteDocumentation(const DocumentationData &Doc, @@ -2693,10 +2718,11 @@ static void WriteDocumentation(const DocumentationData &Doc, unsigned SupportedSpellings = 0; for (const auto &I : Spellings) { SpellingKind Kind = StringSwitch<SpellingKind>(I.variety()) - .Case("GNU", GNU) - .Case("CXX11", CXX11) - .Case("Declspec", Declspec) - .Case("Keyword", Keyword); + .Case("GNU", GNU) + .Case("CXX11", CXX11) + .Case("Declspec", Declspec) + .Case("Keyword", Keyword) + .Case("Pragma", Pragma); // Mask in the supported spelling. SupportedSpellings |= Kind; @@ -2731,7 +2757,8 @@ static void WriteDocumentation(const DocumentationData &Doc, // List what spelling syntaxes the attribute supports. OS << ".. csv-table:: Supported Syntaxes\n"; - OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\"\n\n"; + OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\","; + OS << " \"Pragma\"\n\n"; OS << " \""; if (SupportedSpellings & GNU) OS << "X"; OS << "\",\""; @@ -2741,6 +2768,8 @@ static void WriteDocumentation(const DocumentationData &Doc, OS << "\",\""; if (SupportedSpellings & Keyword) OS << "X"; OS << "\"\n\n"; + if (SupportedSpellings & Pragma) OS << "X"; + OS << "\"\n\n"; // If the attribute is deprecated, print a message about it, and possibly // provide a replacement attribute. |