[PATCH] Add PragmaAttr and Pragma Spelling to Tablegen
Aaron Ballman
aaron at aaronballman.com
Tue Jun 3 07:21:19 PDT 2014
On Mon, Jun 2, 2014 at 8:19 PM, Tyler Nowicki <tnowicki at apple.com> wrote:
> Hi Aaron,
>
> Richard suggested moving pragma loop into the clang namespace so that other compilers ignore it. So I added the namespace we talked about in this thread to the Pragma spelling.
>
> I think I understood what you described below. Please let me know if it looks right to you.
Getting there!
> diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
> index fef34bd..dabf571 100644
> --- a/include/clang/Basic/Attr.td
> +++ b/include/clang/Basic/Attr.td
> @@ -192,0 +193,3 @@ class Keyword<string name> : Spelling<name, "Keyword">;
> +class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
> + string Namespace = namespace;
> +}
> @@ -1770,3 +1773 @@ def LoopHint : Attr {
> - /// FIXME: Add Pragma spelling to tablegen and
> - /// use it here.
> - let Spellings = [Keyword<"loop">];
> + let Spellings = [Pragma<"clang","loop">];
Space after the comma.
> @@ -1797,3 +1798,2 @@ def LoopHint : Attr {
> - // FIXME: Modify pretty printer to print this pragma.
> - void print(raw_ostream &OS, const PrintingPolicy &Policy) const {
> - OS << "#pragma clang loop " << getOptionName(option) << "(";
> + void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
> + OS << getOptionName(option) << "(";
> diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
> index 4a7e462..5783b3b 100644
> --- a/include/clang/Basic/Attributes.h
> +++ b/include/clang/Basic/Attributes.h
> @@ -28 +28,3 @@ enum class AttrSyntax {
> - CXX
> + CXX,
> + // Is the identifier known as a pragma attribute?
> + Pragma
> diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
> index 6872ccc..24e4cd4 100644
> --- a/include/clang/Sema/AttributeList.h
> +++ b/include/clang/Sema/AttributeList.h
> @@ -83 +83,3 @@ public:
> - AS_Keyword
> + AS_Keyword,
> + /// #pragma ...
> + AS_Pragma
> diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
> index f809036..49c9034 100644
> --- a/lib/AST/StmtPrinter.cpp
> +++ b/lib/AST/StmtPrinter.cpp
> @@ -171,2 +170,0 @@ void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
> - std::string raw_attr_os;
> - llvm::raw_string_ostream AttrOS(raw_attr_os);
> @@ -174,6 +172 @@ void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
> - // FIXME: This hack will be removed when printPretty
> - // has been modified to print pretty pragmas
> - if (const LoopHintAttr *LHA = dyn_cast<LoopHintAttr>(Attr)) {
> - LHA->print(OS, Policy);
> - } else
> - Attr->printPretty(AttrOS, Policy);
> + Attr->printPretty(OS, Policy);
> @@ -182,5 +174,0 @@ void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
> - // Print attributes after pragmas.
> - StringRef AttrStr = AttrOS.str();
> - if (!AttrStr.empty())
> - OS << AttrStr;
> -
> diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
> index 210963e..48ed8ff 100644
> --- a/lib/Parse/ParseStmt.cpp
> +++ b/lib/Parse/ParseStmt.cpp
> @@ -1784 +1783,0 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
> - // FIXME: Replace AS_Keyword with Pragma spelling AS_Pragma.
> @@ -1786 +1785 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
> - ArgHints, 3, AttributeList::AS_Keyword);
> + ArgHints, 3, AttributeList::AS_Pragma);
> diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
> index c03ff90..3a7f1a2 100644
> --- a/utils/TableGen/ClangAttrEmitter.cpp
> +++ b/utils/TableGen/ClangAttrEmitter.cpp
> @@ -44 +44 @@ public:
> - if (V == "CXX11")
> + if (V == "CXX11" || V == "Pragma")
> @@ -1056 +1056 @@ writePrettyPrintFunction(Record &R,
> - if (Spellings.size() == 0) {
> + if (Spellings.empty()) {
> @@ -1092,0 +1093,8 @@ writePrettyPrintFunction(Record &R,
> + } else if (Variety == "Pragma") {
> + Prefix = "#pragma ";
> + Suffix = "\n";
> + std::string Namespace = Spellings[I].nameSpace();
> + if (Namespace != "") {
if (!Namespace.empty()) ?
> + Spelling += Namespace;
> + Spelling += " ";
> + }
> @@ -1102,0 +1111,8 @@ writePrettyPrintFunction(Record &R,
> + if (Variety == "Pragma") {
> + OS << " \";\n";
> + OS << " printPrettyPragma(OS, Policy);\n";
> + OS << " break;\n";
> + OS << " }\n";
> + continue;
> + }
> +
> @@ -1783 +1799 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
> - std::vector<Record *> Declspec, GNU;
> + std::vector<Record *> Declspec, GNU, Pragma;
> @@ -1796 +1812 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
> - else if (Variety == "CXX11") {
> + else if (Variety == "CXX11")
> @@ -1798 +1814,2 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
> - }
> + else if (Variety == "Pragma")
> + Pragma.push_back(R);
> @@ -1811,0 +1829,3 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
> + OS << "case AttrSyntax::Pragma:\n";
> + OS << " return llvm::StringSwitch<bool>(Name)\n";
> + GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
> @@ -1847,11 +1867,11 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
> - 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";
Ahh, good catch on the formatting. :-)
> @@ -2477 +2497 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
> - std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords;
> + std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma;
> @@ -2519,0 +2540,2 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
> + else if (Variety == "Pragma")
> + Matches = &Pragma;
> @@ -2543,0 +2566,2 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
> + OS << " } else if (AttributeList::AS_Pragma == Syntax) {\n";
> + StringMatcher("Name", Pragma, OS).Emit();
> @@ -2649 +2673,2 @@ enum SpellingKind {
> - Keyword = 1 << 3
> + Keyword = 1 << 3,
> + Pragma = 1 << 4
> @@ -2694,4 +2719,5 @@ static void WriteDocumentation(const DocumentationData &Doc,
> - .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);
> @@ -2732 +2758,2 @@ static void WriteDocumentation(const DocumentationData &Doc,
> - OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\"\n\n";
> + OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
> + OS << " \"Pragma\"\n\n";
> @@ -2740,0 +2768,2 @@ static void WriteDocumentation(const DocumentationData &Doc,
> + OS << "\"\n\n";
> + if (SupportedSpellings & Pragma) OS << "X";
>
This patch needs some tests to ensure that the pragma pretty prints as expected.
~Aaron
More information about the cfe-commits
mailing list