From: Nico Weber Date: Sat, 3 Sep 2016 02:55:10 +0000 (+0000) Subject: Add plumbing for new attribute type "Microsoft". X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=69084593cd4266c09faa0af9a41c4b8363dbf540;p=clang Add plumbing for new attribute type "Microsoft". This is for attributes in []-delimited lists preceding a class, like e.g. `[uuid("...")] class Foo {};` Not used by anything yet, so no behavior change. Part of https://reviews.llvm.org/D23895 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@280575 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h index a2b86841cd..ea9e28ae68 100644 --- a/include/clang/Basic/Attributes.h +++ b/include/clang/Basic/Attributes.h @@ -22,6 +22,8 @@ enum class AttrSyntax { GNU, /// Is the identifier known as a __declspec-style attribute? Declspec, + /// Is the identifier known as a [] Microsoft-style attribute? + Microsoft, // Is the identifier known as a C++-style attribute? CXX, // Is the identifier known as a pragma attribute? diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 6e3dcd7b62..f115c722a6 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -101,12 +101,14 @@ public: AS_CXX11, /// __declspec(...) AS_Declspec, + /// [uuid("...")] class Foo + AS_Microsoft, /// __ptr16, alignas(...), etc. AS_Keyword, /// Context-sensitive version of a keyword attribute. AS_ContextSensitiveKeyword, /// #pragma ... - AS_Pragma + AS_Pragma, }; private: @@ -369,6 +371,7 @@ public: } bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } + bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); } diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 071e06dd93..7f5769cbd0 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -1312,6 +1312,9 @@ writePrettyPrintFunction(Record &R, } else if (Variety == "Declspec") { Prefix = " __declspec("; Suffix = ")"; + } else if (Variety == "Microsoft") { + Prefix = "["; + Suffix = "]"; } else if (Variety == "Keyword") { Prefix = " "; Suffix = ""; @@ -2295,7 +2298,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 Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector Declspec, GNU, Pragma; + std::vector Declspec, Microsoft, GNU, Pragma; std::map> CXX; // Walk over the list of all attributes, and split them out based on the @@ -2308,6 +2311,8 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) { GNU.push_back(R); else if (Variety == "Declspec") Declspec.push_back(R); + else if (Variety == "Microsoft") + Microsoft.push_back(R); else if (Variety == "CXX11") CXX[SI.nameSpace()].push_back(R); else if (Variety == "Pragma") @@ -2323,6 +2328,9 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << "case AttrSyntax::Declspec:\n"; OS << " return llvm::StringSwitch(Name)\n"; GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec"); + OS << "case AttrSyntax::Microsoft:\n"; + OS << " return llvm::StringSwitch(Name)\n"; + GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft"); OS << "case AttrSyntax::Pragma:\n"; OS << " return llvm::StringSwitch(Name)\n"; GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma"); @@ -2361,8 +2369,9 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { .Case("GNU", 0) .Case("CXX11", 1) .Case("Declspec", 2) - .Case("Keyword", 3) - .Case("Pragma", 4) + .Case("Microsoft", 3) + .Case("Keyword", 4) + .Case("Pragma", 5) .Default(0) << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n" << " return " << I << ";\n"; @@ -2984,7 +2993,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("Attribute name matcher", OS); std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector GNU, Declspec, CXX11, Keywords, Pragma; + std::vector GNU, Declspec, Microsoft, CXX11, + Keywords, Pragma; std::set Seen; for (const auto *A : Attrs) { const Record &Attr = *A; @@ -3026,6 +3036,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { Matches = &GNU; else if (Variety == "Declspec") Matches = &Declspec; + else if (Variety == "Microsoft") + Matches = &Microsoft; else if (Variety == "Keyword") Matches = &Keywords; else if (Variety == "Pragma") @@ -3050,6 +3062,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { StringMatcher("Name", GNU, OS).Emit(); OS << " } else if (AttributeList::AS_Declspec == Syntax) {\n"; StringMatcher("Name", Declspec, OS).Emit(); + OS << " } else if (AttributeList::AS_Microsoft == Syntax) {\n"; + StringMatcher("Name", Microsoft, OS).Emit(); OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n"; StringMatcher("Name", CXX11, OS).Emit(); OS << " } else if (AttributeList::AS_Keyword == Syntax || "; @@ -3133,8 +3147,9 @@ enum SpellingKind { GNU = 1 << 0, CXX11 = 1 << 1, Declspec = 1 << 2, - Keyword = 1 << 3, - Pragma = 1 << 4 + Microsoft = 1 << 3, + Keyword = 1 << 4, + Pragma = 1 << 5 }; static void WriteDocumentation(const DocumentationData &Doc, @@ -3182,6 +3197,7 @@ static void WriteDocumentation(const DocumentationData &Doc, .Case("GNU", GNU) .Case("CXX11", CXX11) .Case("Declspec", Declspec) + .Case("Microsoft", Microsoft) .Case("Keyword", Keyword) .Case("Pragma", Pragma);