aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-25 10:41:10 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-25 10:41:10 +0000
commit5297d71e8c85f9b04dc31c690e91c6a2f7eddb90 (patch)
treefe2bb53479b6b942a2beac20e8251e83fe29ce99
parentd390de9c6312684c5e5b333f434199e193c7467a (diff)
Accept __has_feature(__feature__) as a synonym for __has_feature(feature) (and
likewise for __has_extension). Patch by Jonathan Sauer! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151445 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/LanguageExtensions.html5
-rw-r--r--lib/Lex/PPMacroExpansion.cpp15
-rw-r--r--lib/Sema/AttributeList.cpp3
-rw-r--r--test/Lexer/has_extension.c6
-rw-r--r--test/Preprocessor/feature_tests.c4
5 files changed, 29 insertions, 4 deletions
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 2471c60776..cdd197956f 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -228,6 +228,11 @@ not related to the language standard, such as e.g.
<p>The feature tag is described along with the language feature below.</p>
+<p>The feature name or extension 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>
+
<!-- ======================================================================= -->
<h3><a name="__has_attribute">__has_attribute</a></h3>
<!-- ======================================================================= -->
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index bc34692702..c7c8e00f40 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -589,8 +589,13 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
/// specified by the identifier as a standard language feature.
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
const LangOptions &LangOpts = PP.getLangOptions();
+ StringRef Feature = II->getName();
- return llvm::StringSwitch<bool>(II->getName())
+ // Normalize the feature name, __foo__ becomes foo.
+ if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4)
+ Feature = Feature.substr(2, Feature.size() - 4);
+
+ return llvm::StringSwitch<bool>(Feature)
.Case("address_sanitizer", LangOpts.AddressSanitizer)
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
@@ -724,10 +729,16 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
return false;
const LangOptions &LangOpts = PP.getLangOptions();
+ StringRef Extension = II->getName();
+
+ // Normalize the extension name, __foo__ becomes foo.
+ if (Extension.startswith("__") && Extension.endswith("__") &&
+ Extension.size() >= 4)
+ Extension = Extension.substr(2, Extension.size() - 4);
// Because we inherit the feature list from HasFeature, this string switch
// must be less restrictive than HasFeature's.
- return llvm::StringSwitch<bool>(II->getName())
+ return llvm::StringSwitch<bool>(Extension)
// C11 features supported by other languages as extensions.
.Case("c_alignas", true)
.Case("c_atomic", true)
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index a3791dedf7..9b74fc03ce 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -101,7 +101,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
StringRef AttrName = Name->getName();
// Normalize the attribute name, __foo__ becomes foo.
- if (AttrName.startswith("__") && AttrName.endswith("__"))
+ if (AttrName.startswith("__") && AttrName.endswith("__") &&
+ AttrName.size() >= 4)
AttrName = AttrName.substr(2, AttrName.size() - 4);
return llvm::StringSwitch<AttributeList::Kind>(AttrName)
diff --git a/test/Lexer/has_extension.c b/test/Lexer/has_extension.c
index 4c322c7ce7..3b08510aa4 100644
--- a/test/Lexer/has_extension.c
+++ b/test/Lexer/has_extension.c
@@ -36,3 +36,9 @@ int has_c_alignas();
int no_c_alignas();
#endif
+// Arbitrary feature to test that the extension name can be surrounded with
+// double underscores.
+// CHECK-PED-NONE: has_double_underscores
+#if __has_extension(__c_alignas__)
+int has_double_underscores();
+#endif
diff --git a/test/Preprocessor/feature_tests.c b/test/Preprocessor/feature_tests.c
index 35592bd8e1..be9c62d780 100644
--- a/test/Preprocessor/feature_tests.c
+++ b/test/Preprocessor/feature_tests.c
@@ -21,7 +21,9 @@
#error Clang should not have this
#endif
-
+#if !__has_feature(__attribute_deprecated_with_message__)
+#error Feature name in double underscores does not work
+#endif
// Make sure we have x86 builtins only (forced with target triple).