From: Aaron Ballman Date: Fri, 5 Dec 2014 15:05:29 +0000 (+0000) Subject: Added a new preprocessor macro: __has_declspec_attribute. This can be used as a way... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3c0f9b4a7d0b26f23ea2227d6c58cec00d9c3459;p=platform%2Fupstream%2Fllvm.git Added a new preprocessor macro: __has_declspec_attribute. This can be used as a way to determine whether Clang supports a __declspec spelling for a given attribute, similar to __has_attribute and __has_cpp_attribute. llvm-svn: 223467 --- diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 5636b89..3ca1010 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -164,6 +164,33 @@ 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``. + +``__has_declspec_attribute`` +---------------------------- + +This function-like macro takes a single identifier argument that is the name of +an attribute implemented as a Microsoft-style ``__declspec`` attribute. It +evaluates to 1 if the attribute is supported by the current compilation target, +or 0 if not. It can be used like this: + +.. code-block:: c++ + + #ifndef __has_declspec_attribute // Optional of course. + #define __has_declspec_attribute(x) 0 // Compatibility with non-clang compilers. + #endif + + ... + #if __has_declspec_attribute(dllexport) + #define DLLEXPORT __declspec(dllexport) + #else + #define DLLEXPORT + #endif + ... + +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, ``__dllexport__`` can be used instead of ``dllexport``. + ``__is_identifier`` ------------------- diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index cfbc2c8..b6dcaa0 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -136,6 +136,7 @@ class Preprocessor : public RefCountedBase { IdentifierInfo *Ident__building_module; // __building_module IdentifierInfo *Ident__MODULE__; // __MODULE__ IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute + IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute SourceLocation DATELoc, TIMELoc; unsigned CounterValue; // Next __COUNTER__ value. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 37460f5..26cf543 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -118,6 +118,7 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension"); Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin"); Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute"); + Ident__has_declspec = RegisterBuiltinMacro(*this, "__has_declspec_attribute"); Ident__has_include = RegisterBuiltinMacro(*this, "__has_include"); Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next"); Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning"); @@ -1381,6 +1382,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { II == Ident__has_builtin || II == Ident__is_identifier || II == Ident__has_attribute || + II == Ident__has_declspec || II == Ident__has_cpp_attribute) { // The argument to these builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); @@ -1428,6 +1430,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { else if (II == Ident__has_cpp_attribute) Value = hasAttribute(AttrSyntax::CXX, ScopeII, FeatureII, getTargetInfo().getTriple(), getLangOpts()); + else if (II == Ident__has_declspec) + Value = hasAttribute(AttrSyntax::Declspec, nullptr, FeatureII, + getTargetInfo().getTriple(), getLangOpts()); else if (II == Ident__has_extension) Value = HasExtension(*this, FeatureII); else { diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp index 75f72c7..1ab4502 100644 --- a/clang/test/Preprocessor/has_attribute.cpp +++ b/clang/test/Preprocessor/has_attribute.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c++11 -E %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -fms-compatibility -std=c++11 -E %s -o - | FileCheck %s // CHECK: has_cxx11_carries_dep #if __has_cpp_attribute(carries_dependency) @@ -51,3 +51,18 @@ #if __has_cpp_attribute(deprecated) == 201309 int has_cxx14_deprecated_vers(); #endif + +// CHECK: has_declspec_uuid +#if __has_declspec_attribute(uuid) + int has_declspec_uuid(); +#endif + +// CHECK: has_declspec_uuid2 +#if __has_declspec_attribute(__uuid__) + int has_declspec_uuid2(); +#endif + +// CHECK: does_not_have_declspec_fallthrough +#if !__has_declspec_attribute(fallthrough) + int does_not_have_declspec_fallthrough(); +#endif