summaryrefslogtreecommitdiffstats
path: root/clang/utils
diff options
context:
space:
mode:
authorTyler Nowicki <tnowicki@apple.com>2014-06-13 17:57:25 +0000
committerTyler Nowicki <tnowicki@apple.com>2014-06-13 17:57:25 +0000
commite8b07ed080ec11a32de21ac1af5da2bbf3d62281 (patch)
tree045fab6b3187928cd890df382d63772808600c92 /clang/utils
parente595e1ade02c7581a2e2ad5392f7714b7f342c05 (diff)
downloadbcm5719-llvm-e8b07ed080ec11a32de21ac1af5da2bbf3d62281.tar.gz
bcm5719-llvm-e8b07ed080ec11a32de21ac1af5da2bbf3d62281.zip
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 llvm-svn: 210925
Diffstat (limited to 'clang/utils')
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp77
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.
OpenPOWER on IntegriCloud