From: Jean-Daniel Dupas Date: Thu, 1 Mar 2012 14:53:16 +0000 (+0000) Subject: Implement double underscore names support in __has_attribute X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8a5e7fdd2c7d3f46685396e13ed76798f4573c02;p=clang Implement double underscore names support in __has_attribute git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151809 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html index be26d62414..23aa4fe9b9 100644 --- a/docs/LanguageExtensions.html +++ b/docs/LanguageExtensions.html @@ -257,6 +257,11 @@ can be used like this:

+

The attribute name can also be specified with a preceding and +following __ (double underscore) to avoid interference from a macro +with the same name. For instance, __always_inline__ can be used +instead of always_inline.

+

Include File Checking Macros

diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 007be3bed2..56ce407c18 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -760,7 +760,12 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { /// HasAttribute - Return true if we recognize and implement the attribute /// specified by the given identifier. static bool HasAttribute(const IdentifierInfo *II) { - return llvm::StringSwitch(II->getName()) + StringRef Name = II->getName(); + // Normalize the attribute name, __foo__ becomes foo. + if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4) + Name = Name.substr(2, Name.size() - 4); + + return llvm::StringSwitch(Name) #include "clang/Lex/AttrSpellings.inc" .Default(false); } diff --git a/test/Preprocessor/has_attribute.c b/test/Preprocessor/has_attribute.c new file mode 100644 index 0000000000..825fa06df6 --- /dev/null +++ b/test/Preprocessor/has_attribute.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s +// RUN: %clang_cc1 %s -E +#ifndef __has_attribute +#error Should have __has_attribute +#endif + +#if __has_attribute(something_we_dont_have) +#error Bad +#endif + +#if !__has_attribute(__always_inline__) || \ + !__has_attribute(always_inline) +#error Clang should have this +#endif