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