[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