diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -84,6 +84,20 @@ } const char *getSpelling() const; + enum class Variety { + None, + GNU, // __attribute__((...)) + Declspec, // __declspec(...) + Microsoft, // [...] + CXX11, // [[...]] + C2x, // [[...]] + Keyword, // e.g. _Noreturn, final, __fastcall, etc. + Pragma, // #pragma ... + HLSLSemantic, // :... + }; + + Variety getVariety() const; + SourceLocation getLocation() const { return getRange().getBegin(); } bool isInherited() const { return Inherited; } diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1498,6 +1498,30 @@ OS << "}\n\n"; } +static void writeGetVarietyFunction(const Record &R, raw_ostream &OS) { + std::vector Spellings = GetFlattenedSpellings(R); + + OS << "Attr::Variety " << R.getName() << "Attr::getVariety() const {\n"; + if (Spellings.empty()) { + OS << " return Variety::None;\n}\n\n"; + return; + } + + OS << " switch (getAttributeSpellingListIndex()) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute spelling!\");\n" + " return Variety::None;\n"; + + for (unsigned I = 0; I < Spellings.size(); ++I) { + OS << " case " << I << ":\n"; + OS << " return Variety::" << Spellings[I].variety() << ";\n"; + } + // End of the switch statement. + OS << " }\n"; + // End of the getVariety function. + OS << "}\n\n"; +} + static void writePrettyPrintFunction(const Record &R, const std::vector> &Args, @@ -2798,6 +2822,7 @@ OS << " void printPretty(raw_ostream &OS,\n" << " const PrintingPolicy &Policy) const;\n"; OS << " const char *getSpelling() const;\n"; + OS << " Variety getVariety() const;\n"; } if (!ElideSpelling) { @@ -2872,6 +2897,7 @@ writePrettyPrintFunction(R, Args, OS); writeGetSpellingFunction(R, OS); + writeGetVarietyFunction(R, OS); } } } @@ -2919,6 +2945,9 @@ OS << "Attr *Attr::clone(ASTContext &C) const {\n"; EmitFunc("clone(C)"); + OS << "Attr::Variety Attr::getVariety() const {\n"; + EmitFunc("getVariety()"); + OS << "void Attr::printPretty(raw_ostream &OS, " "const PrintingPolicy &Policy) const {\n"; EmitFunc("printPretty(OS, Policy)");