forked from OSchip/llvm-project
Accept __has_feature(__feature__) as a synonym for __has_feature(feature) (and
likewise for __has_extension). Patch by Jonathan Sauer! llvm-svn: 151445
This commit is contained in:
parent
2a986117e9
commit
2cca7b5ca9
clang
docs
lib
test
|
@ -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 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>
|
<h3><a name="__has_attribute">__has_attribute</a></h3>
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
|
|
|
@ -589,8 +589,13 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
|
||||||
/// specified by the identifier as a standard language feature.
|
/// specified by the identifier as a standard language feature.
|
||||||
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
||||||
const LangOptions &LangOpts = PP.getLangOptions();
|
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("address_sanitizer", LangOpts.AddressSanitizer)
|
||||||
.Case("attribute_analyzer_noreturn", true)
|
.Case("attribute_analyzer_noreturn", true)
|
||||||
.Case("attribute_availability", true)
|
.Case("attribute_availability", true)
|
||||||
|
@ -724,10 +729,16 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const LangOptions &LangOpts = PP.getLangOptions();
|
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
|
// Because we inherit the feature list from HasFeature, this string switch
|
||||||
// must be less restrictive than HasFeature's.
|
// 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.
|
// C11 features supported by other languages as extensions.
|
||||||
.Case("c_alignas", true)
|
.Case("c_alignas", true)
|
||||||
.Case("c_atomic", true)
|
.Case("c_atomic", true)
|
||||||
|
|
|
@ -101,7 +101,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
||||||
StringRef AttrName = Name->getName();
|
StringRef AttrName = Name->getName();
|
||||||
|
|
||||||
// Normalize the attribute name, __foo__ becomes foo.
|
// 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);
|
AttrName = AttrName.substr(2, AttrName.size() - 4);
|
||||||
|
|
||||||
return llvm::StringSwitch<AttributeList::Kind>(AttrName)
|
return llvm::StringSwitch<AttributeList::Kind>(AttrName)
|
||||||
|
|
|
@ -36,3 +36,9 @@ int has_c_alignas();
|
||||||
int no_c_alignas();
|
int no_c_alignas();
|
||||||
#endif
|
#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
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
#error Clang should not have this
|
#error Clang should not have this
|
||||||
#endif
|
#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).
|
// Make sure we have x86 builtins only (forced with target triple).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue