r210925 - Adds a Pragma spelling for attributes to tablegen and makes use of it for loop
Tyler Nowicki
tnowicki at apple.com
Fri Jun 13 10:57:25 PDT 2014
Author: tnowicki
Date: Fri Jun 13 12:57:25 2014
New Revision: 210925
URL: http://llvm.org/viewvc/llvm-project?rev=210925&view=rev
Log:
Adds a Pragma spelling for attributes to tablegen and makes use of it for loop
hint attributes. Includes tests for pragma printing and for attribute order
which is incorrectly reversed by ParsedAttributes.
Reviewed by Aaron Ballman
Added:
cfe/trunk/test/Misc/ast-print-pragmas-xfail.cpp
cfe/trunk/test/Misc/ast-print-pragmas.cpp
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/Attributes.h
cfe/trunk/include/clang/Sema/AttributeList.h
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Fri Jun 13 12:57:25 2014
@@ -190,6 +190,9 @@ class CXX11<string namespace, string nam
string Namespace = namespace;
}
class Keyword<string name> : Spelling<name, "Keyword">;
+class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
+ string Namespace = namespace;
+}
// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
@@ -1769,9 +1772,7 @@ def LoopHint : Attr {
/// unroll: unroll loop if 'value != 0'.
/// unroll_count: unrolls loop 'value' times.
- /// FIXME: Add Pragma spelling to tablegen and
- /// use it here.
- let Spellings = [Keyword<"loop">];
+ let Spellings = [Pragma<"clang", "loop">];
/// State of the loop optimization specified by the spelling.
let Args = [EnumArgument<"Option", "OptionType",
@@ -1800,9 +1801,8 @@ def LoopHint : Attr {
return "disable";
}
- // 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) << "(";
if (option == VectorizeWidth || option == InterleaveCount ||
option == UnrollCount)
OS << value;
Modified: cfe/trunk/include/clang/Basic/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attributes.h?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attributes.h (original)
+++ cfe/trunk/include/clang/Basic/Attributes.h Fri Jun 13 12:57:25 2014
@@ -25,7 +25,9 @@ enum class AttrSyntax {
/// Is the identifier known as a __declspec-style attribute?
Declspec,
// Is the identifier known as a C++-style attribute?
- CXX
+ CXX,
+ // Is the identifier known as a pragma attribute?
+ Pragma
};
/// \brief Return true if we recognize and implement the attribute specified by
Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Fri Jun 13 12:57:25 2014
@@ -80,7 +80,9 @@ public:
/// __declspec(...)
AS_Declspec,
/// __ptr16, alignas(...), etc.
- AS_Keyword
+ AS_Keyword,
+ /// #pragma ...
+ AS_Pragma
};
private:
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Jun 13 12:57:25 2014
@@ -168,22 +168,10 @@ void StmtPrinter::VisitLabelStmt(LabelSt
}
void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
- std::string raw_attr_os;
- llvm::raw_string_ostream AttrOS(raw_attr_os);
for (const auto *Attr : Node->getAttrs()) {
- // 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);
}
- // Print attributes after pragmas.
- StringRef AttrStr = AttrOS.str();
- if (!AttrStr.empty())
- OS << AttrStr;
-
PrintStmt(Node->getSubStmt(), 0);
}
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Jun 13 12:57:25 2014
@@ -1765,9 +1765,8 @@ StmtResult Parser::ParsePragmaLoopHint(S
ArgsUnion ArgHints[] = {Hint.OptionLoc, Hint.ValueLoc,
ArgsUnion(Hint.ValueExpr)};
- // FIXME: Replace AS_Keyword with Pragma spelling AS_Pragma.
TempAttrs.addNew(Hint.LoopLoc->Ident, Hint.Range, nullptr,
- Hint.LoopLoc->Loc, ArgHints, 3, AttributeList::AS_Keyword);
+ Hint.LoopLoc->Loc, ArgHints, 3, AttributeList::AS_Pragma);
}
// Get the next statement.
Added: cfe/trunk/test/Misc/ast-print-pragmas-xfail.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-print-pragmas-xfail.cpp?rev=210925&view=auto
==============================================================================
--- cfe/trunk/test/Misc/ast-print-pragmas-xfail.cpp (added)
+++ cfe/trunk/test/Misc/ast-print-pragmas-xfail.cpp Fri Jun 13 12:57:25 2014
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -ast-print -o - | FileCheck %s
+
+// FIXME: Test fails because attribute order is reversed by ParsedAttributes.
+// XFAIL: *
+
+void run1(int *List, int Length) {
+ int i = 0;
+// CEHCK: #pragma loop vectorize(4)
+// CHECK-NEXT: #pragma loop interleave(8)
+// CHECK-NEXT: #pragma loop vectorize(enable)
+// CHECK-NEXT: #pragma loop interleave(enable)
+#pragma loop vectorize(4)
+#pragma loop interleave(8)
+#pragma loop vectorize(enable)
+#pragma loop interleave(enable)
+// CHECK-NEXT: while (i < Length)
+ while (i < Length) {
+ List[i] = i;
+ i++;
+ }
+}
Added: cfe/trunk/test/Misc/ast-print-pragmas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-print-pragmas.cpp?rev=210925&view=auto
==============================================================================
--- cfe/trunk/test/Misc/ast-print-pragmas.cpp (added)
+++ cfe/trunk/test/Misc/ast-print-pragmas.cpp Fri Jun 13 12:57:25 2014
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK-NEXT: #pragma clang loop vectorize_width(4)
+
+void test(int *List, int Length) {
+ int i = 0;
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+// CHECK-NEXT: while (i < Length)
+ while (i < Length) {
+ List[i] = i * 2;
+ i++;
+ }
+
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK-NEXT: #pragma clang loop vectorize(enable)
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(disable)
+// CHECK-NEXT: while (i - 1 < Length)
+ while (i - 1 < Length) {
+ List[i] = i * 2;
+ i++;
+ }
+
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK-NEXT: #pragma clang loop vectorize(disable)
+
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(enable)
+// CHECK-NEXT: while (i - 2 < Length)
+ while (i - 2 < Length) {
+ List[i] = i * 2;
+ i++;
+ }
+}
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=210925&r1=210924&r2=210925&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Fri Jun 13 12:57:25 2014
@@ -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(RecordKeep
// 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(RecordKeep
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(RecordKeep
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(Reco
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(Record
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(Record
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(Record
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 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 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 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.
More information about the cfe-commits
mailing list