r223467 - 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.
Aaron Ballman
aaron at aaronballman.com
Fri Dec 5 07:05:30 PST 2014
Author: aaronballman
Date: Fri Dec 5 09:05:29 2014
New Revision: 223467
URL: http://llvm.org/viewvc/llvm-project?rev=223467&view=rev
Log:
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.
Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/test/Preprocessor/has_attribute.cpp
Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=223467&r1=223466&r2=223467&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Fri Dec 5 09:05:29 2014
@@ -164,6 +164,33 @@ The attribute name can also be specified
(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``
-------------------
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=223467&r1=223466&r2=223467&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Dec 5 09:05:29 2014
@@ -136,6 +136,7 @@ class Preprocessor : public RefCountedBa
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.
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=223467&r1=223466&r2=223467&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Dec 5 09:05:29 2014
@@ -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(To
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(To
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 {
Modified: cfe/trunk/test/Preprocessor/has_attribute.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/has_attribute.cpp?rev=223467&r1=223466&r2=223467&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/has_attribute.cpp (original)
+++ cfe/trunk/test/Preprocessor/has_attribute.cpp Fri Dec 5 09:05:29 2014
@@ -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
More information about the cfe-commits
mailing list