diff options
-rw-r--r-- | clang/docs/LanguageExtensions.html | 5 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 7 | ||||
-rw-r--r-- | clang/test/Preprocessor/has_attribute.c | 14 |
3 files changed, 25 insertions, 1 deletions
diff --git a/clang/docs/LanguageExtensions.html b/clang/docs/LanguageExtensions.html index be26d624147..23aa4fe9b92 100644 --- a/clang/docs/LanguageExtensions.html +++ b/clang/docs/LanguageExtensions.html @@ -257,6 +257,11 @@ can be used like this:</p> </pre> </blockquote> +<p>The attribute name can also be specified with a preceding and +following <code>__</code> (double underscore) to avoid interference from a macro +with the same name. For instance, <code>__always_inline__</code> can be used +instead of <code>always_inline</code>.</p> + <!-- ======================================================================= --> <h2 id="has_include">Include File Checking Macros</h2> <!-- ======================================================================= --> diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 007be3bed2d..56ce407c186 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/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<bool>(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<bool>(Name) #include "clang/Lex/AttrSpellings.inc" .Default(false); } diff --git a/clang/test/Preprocessor/has_attribute.c b/clang/test/Preprocessor/has_attribute.c new file mode 100644 index 00000000000..825fa06df66 --- /dev/null +++ b/clang/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 |