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