diff options
-rw-r--r-- | clang/docs/LanguageExtensions.html | 5 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/AttributeList.cpp | 3 | ||||
-rw-r--r-- | clang/test/Lexer/has_extension.c | 6 | ||||
-rw-r--r-- | clang/test/Preprocessor/feature_tests.c | 4 |
5 files changed, 29 insertions, 4 deletions
diff --git a/clang/docs/LanguageExtensions.html b/clang/docs/LanguageExtensions.html index 2471c60776c..cdd197956fe 100644 --- a/clang/docs/LanguageExtensions.html +++ b/clang/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/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index bc346927027..c7c8e00f409 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/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/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp index a3791dedf73..9b74fc03cef 100644 --- a/clang/lib/Sema/AttributeList.cpp +++ b/clang/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/clang/test/Lexer/has_extension.c b/clang/test/Lexer/has_extension.c index 4c322c7ce7a..3b08510aa44 100644 --- a/clang/test/Lexer/has_extension.c +++ b/clang/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/clang/test/Preprocessor/feature_tests.c b/clang/test/Preprocessor/feature_tests.c index 35592bd8e1c..be9c62d7808 100644 --- a/clang/test/Preprocessor/feature_tests.c +++ b/clang/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). |