summaryrefslogtreecommitdiffstats
path: root/clang/utils/TableGen/ClangAttrEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/utils/TableGen/ClangAttrEmitter.cpp')
-rw-r--r--clang/utils/TableGen/ClangAttrEmitter.cpp78
1 files changed, 50 insertions, 28 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index abbef617bb1..015cc4dd1fc 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -58,7 +58,7 @@ public:
assert(V != "GCC" && "Given a GCC spelling, which means this hasn't been"
"flattened!");
- if (V == "CXX11" || V == "Pragma")
+ if (V == "CXX11" || V == "C2x" || V == "Pragma")
NS = Spelling.getValueAsString("Namespace");
bool Unset;
K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset);
@@ -1326,7 +1326,7 @@ writePrettyPrintFunction(Record &R,
if (Variety == "GNU") {
Prefix = " __attribute__((";
Suffix = "))";
- } else if (Variety == "CXX11") {
+ } else if (Variety == "CXX11" || Variety == "C2x") {
Prefix = " [[";
Suffix = "]]";
std::string Namespace = Spellings[I].nameSpace();
@@ -2716,10 +2716,14 @@ static void GenerateHasAttrSpellingStringSwitch(
// If this is the C++11 variety, also add in the LangOpts test.
if (Variety == "CXX11")
Test += " && LangOpts.CPlusPlus11";
+ else if (Variety == "C2x")
+ Test += " && LangOpts.DoubleSquareBracketAttributes";
} else if (Variety == "CXX11")
// C++11 mode should be checked against LangOpts, which is presumed to be
// present in the caller.
Test = "LangOpts.CPlusPlus11";
+ else if (Variety == "C2x")
+ Test = "LangOpts.DoubleSquareBracketAttributes";
std::string TestStr =
!Test.empty() ? Test + " ? " + llvm::itostr(Version) + " : 0" : "1";
@@ -2740,7 +2744,7 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
// and declspecs. Then generate a big switch statement for each of them.
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
std::vector<Record *> Declspec, Microsoft, GNU, Pragma;
- std::map<std::string, std::vector<Record *>> CXX;
+ std::map<std::string, std::vector<Record *>> CXX, C2x;
// Walk over the list of all attributes, and split them out based on the
// spelling variety.
@@ -2756,6 +2760,8 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
Microsoft.push_back(R);
else if (Variety == "CXX11")
CXX[SI.nameSpace()].push_back(R);
+ else if (Variety == "C2x")
+ C2x[SI.nameSpace()].push_back(R);
else if (Variety == "Pragma")
Pragma.push_back(R);
}
@@ -2775,20 +2781,25 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
OS << "case AttrSyntax::Pragma:\n";
OS << " return llvm::StringSwitch<int>(Name)\n";
GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
- OS << "case AttrSyntax::CXX: {\n";
- // C++11-style attributes are further split out based on the Scope.
- for (auto I = CXX.cbegin(), E = CXX.cend(); I != E; ++I) {
- if (I != CXX.begin())
- OS << " else ";
- if (I->first.empty())
- OS << "if (!Scope || Scope->getName() == \"\") {\n";
- else
- OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
- OS << " return llvm::StringSwitch<int>(Name)\n";
- GenerateHasAttrSpellingStringSwitch(I->second, OS, "CXX11", I->first);
- OS << "}";
- }
- OS << "\n}\n";
+ auto fn = [&OS](const char *Spelling, const char *Variety,
+ const std::map<std::string, std::vector<Record *>> &List) {
+ OS << "case AttrSyntax::" << Variety << ": {\n";
+ // C++11-style attributes are further split out based on the Scope.
+ for (auto I = List.cbegin(), E = List.cend(); I != E; ++I) {
+ if (I != List.cbegin())
+ OS << " else ";
+ if (I->first.empty())
+ OS << "if (!Scope || Scope->getName() == \"\") {\n";
+ else
+ OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
+ OS << " return llvm::StringSwitch<int>(Name)\n";
+ GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
+ OS << "}";
+ }
+ OS << "\n}\n";
+ };
+ fn("CXX11", "CXX", CXX);
+ fn("C2x", "C", C2x);
OS << "}\n";
}
@@ -2809,10 +2820,11 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
<< StringSwitch<unsigned>(Spellings[I].variety())
.Case("GNU", 0)
.Case("CXX11", 1)
- .Case("Declspec", 2)
- .Case("Microsoft", 3)
- .Case("Keyword", 4)
- .Case("Pragma", 5)
+ .Case("C2x", 2)
+ .Case("Declspec", 3)
+ .Case("Microsoft", 4)
+ .Case("Keyword", 5)
+ .Case("Pragma", 6)
.Default(0)
<< " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
<< " return " << I << ";\n";
@@ -3505,7 +3517,7 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11,
- Keywords, Pragma;
+ Keywords, Pragma, C2x;
std::set<std::string> Seen;
for (const auto *A : Attrs) {
const Record &Attr = *A;
@@ -3543,6 +3555,10 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
Matches = &CXX11;
Spelling += S.nameSpace();
Spelling += "::";
+ } else if (Variety == "C2x") {
+ Matches = &C2x;
+ Spelling += S.nameSpace();
+ Spelling += "::";
} else if (Variety == "GNU")
Matches = &GNU;
else if (Variety == "Declspec")
@@ -3581,6 +3597,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
StringMatcher("Name", Microsoft, OS).Emit();
OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n";
StringMatcher("Name", CXX11, OS).Emit();
+ OS << " } else if (AttributeList::AS_C2x == Syntax) {\n";
+ StringMatcher("Name", C2x, OS).Emit();
OS << " } else if (AttributeList::AS_Keyword == Syntax || ";
OS << "AttributeList::AS_ContextSensitiveKeyword == Syntax) {\n";
StringMatcher("Name", Keywords, OS).Emit();
@@ -3666,10 +3684,11 @@ static void WriteCategoryHeader(const Record *DocCategory,
enum SpellingKind {
GNU = 1 << 0,
CXX11 = 1 << 1,
- Declspec = 1 << 2,
- Microsoft = 1 << 3,
- Keyword = 1 << 4,
- Pragma = 1 << 5
+ C2x = 1 << 2,
+ Declspec = 1 << 3,
+ Microsoft = 1 << 4,
+ Keyword = 1 << 5,
+ Pragma = 1 << 6
};
static void WriteDocumentation(RecordKeeper &Records,
@@ -3716,6 +3735,7 @@ static void WriteDocumentation(RecordKeeper &Records,
SpellingKind Kind = StringSwitch<SpellingKind>(I.variety())
.Case("GNU", GNU)
.Case("CXX11", CXX11)
+ .Case("C2x", C2x)
.Case("Declspec", Declspec)
.Case("Microsoft", Microsoft)
.Case("Keyword", Keyword)
@@ -3725,7 +3745,7 @@ static void WriteDocumentation(RecordKeeper &Records,
SupportedSpellings |= Kind;
std::string Name;
- if (Kind == CXX11 && !I.nameSpace().empty())
+ if ((Kind == CXX11 || Kind == C2x) && !I.nameSpace().empty())
Name = I.nameSpace() + "::";
Name += I.name();
@@ -3754,13 +3774,15 @@ static void WriteDocumentation(RecordKeeper &Records,
// List what spelling syntaxes the attribute supports.
OS << ".. csv-table:: Supported Syntaxes\n";
- OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
+ OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\",";
OS << " \"Pragma\", \"Pragma clang attribute\"\n\n";
OS << " \"";
if (SupportedSpellings & GNU) OS << "X";
OS << "\",\"";
if (SupportedSpellings & CXX11) OS << "X";
OS << "\",\"";
+ if (SupportedSpellings & C2x) OS << "X";
+ OS << "\",\"";
if (SupportedSpellings & Declspec) OS << "X";
OS << "\",\"";
if (SupportedSpellings & Keyword) OS << "X";
OpenPOWER on IntegriCloud