Commit 125d3390 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

Improve detection of C++11 features.

Also improve detection of V8_INFINITY while we're at it.

R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/23323003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16254 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 09668ec3
...@@ -30,7 +30,8 @@ ...@@ -30,7 +30,8 @@
#include <string.h> #include <string.h>
#include "../include/v8stdint.h" #include "globals.h"
extern "C" void V8_Fatal(const char* file, int line, const char* format, ...); extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during // The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
...@@ -232,7 +233,7 @@ inline void CheckNonEqualsHelper(const char* file, ...@@ -232,7 +233,7 @@ inline void CheckNonEqualsHelper(const char* file,
// Use C++11 static_assert if possible, which gives error // Use C++11 static_assert if possible, which gives error
// messages that are easier to understand on first sight. // messages that are easier to understand on first sight.
#if __cplusplus >= 201103L #if defined(V8_HAVE_CXX11_STATIC_ASSERT)
#define STATIC_CHECK(test) static_assert(test, #test) #define STATIC_CHECK(test) static_assert(test, #test)
#else #else
// This is inspired by the static assertion facility in boost. This // This is inspired by the static assertion facility in boost. This
......
...@@ -28,32 +28,88 @@ ...@@ -28,32 +28,88 @@
#ifndef V8_GLOBALS_H_ #ifndef V8_GLOBALS_H_
#define V8_GLOBALS_H_ #define V8_GLOBALS_H_
// Define V8_INFINITY
#define V8_INFINITY INFINITY
// GCC specific stuff // Compiler feature/bug detection.
#ifdef __GNUC__ #if defined(__clang__)
// Don't treat clang as GCC.
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
# if __has_feature(cxx_deleted_functions)
# define V8_HAVE_CXX11_DELETE
# endif
# if __has_feature(cxx_override_control)
# define V8_HAVE_CXX11_FINAL
# define V8_HAVE_CXX11_OVERRIDE
# endif
# if __has_feature(cxx_static_assert)
# define V8_HAVE_CXX11_STATIC_ASSERT
# endif
# define V8_INFINITY INFINITY
#define __GNUC_VERSION_FOR_INFTY__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) #elif defined(__GNUC__)
// GCC version detection.
# define V8_GNUC_PREREQ(major, minor, patchlevel) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
((major) * 10000 + (minor) * 100 + (patchlevel)))
// g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
// without warnings (functionality used by the macros below). These modes
// are detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or,
// more standardly, by checking whether __cplusplus has a C++11 or greater
// value. Current versions of g++ do not correctly set __cplusplus, so we check
// both for forward compatibility.
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if V8_GNUC_PREREQ(4, 3, 0)
# define V8_HAVE_CXX11_STATIC_ASSERT
# endif
# if V8_GNUC_PREREQ(4, 4, 0)
# define V8_HAVE_CXX11_DELETE
# endif
# if V8_GNUC_PREREQ(4, 7, 0)
# define V8_HAVE_CXX11_OVERRIDE
# define V8_HAVE_CXX11_FINAL
# endif
# else
// '__final' is a non-C++11 GCC synonym for 'final', per GCC r176655.
# if V8_GNUC_PREREQ(4, 7, 0)
# define V8_HAVE_GXX_FINAL
# endif
# endif
// Unfortunately, the INFINITY macro cannot be used with the '-pedantic' // Unfortunately, the INFINITY macro cannot be used with the '-pedantic'
// warning flag and certain versions of GCC due to a bug: // warning flag and certain versions of GCC due to a bug:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931
// For now, we use the more involved template-based version from <limits>, but // For now, we use the more involved template-based version from <limits>, but
// only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x) // only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x)
// __GNUC_PREREQ is not defined in GCC for Mac OS X, so we define our own macro # if V8_GNUC_PREREQ(2, 96, 0) && !V8_GNUC_PREREQ(4, 1, 0)
#if __GNUC_VERSION_FOR_INFTY__ >= 29600 && __GNUC_VERSION_FOR_INFTY__ < 40100 # include <limits>
#include <limits> # define V8_INFINITY std::numeric_limits<double>::infinity()
#undef V8_INFINITY # else
#define V8_INFINITY std::numeric_limits<double>::infinity() # define V8_INFINITY INFINITY
#endif # endif
#undef __GNUC_VERSION_FOR_INFTY__
#endif // __GNUC__ #elif defined(_MSC_VER)
# define V8_GNUC_PREREQ(major, minor, patchlevel) 0
// Override control was added with Visual Studio 2005.
# if _MSC_VER >= 1400
# if _MSC_VER >= 1700
# define V8_HAVE_CXX11_FINAL
# else
// Visual Studio 2010 and earlier spell "final" as "sealed".
# define V8_HAVE_MSVC_SEALED
# endif
# define V8_HAVE_CXX11_OVERRIDE
# endif
# define V8_INFINITY HUGE_VAL
#ifdef _MSC_VER
#undef V8_INFINITY
#define V8_INFINITY HUGE_VAL
#endif #endif
...@@ -330,62 +386,58 @@ F FUNCTION_CAST(Address addr) { ...@@ -330,62 +386,58 @@ F FUNCTION_CAST(Address addr) {
} }
// Compiler feature detection. // A macro to specify that a method is deleted from the corresponding class.
#if defined(__clang__) // Any attempt to use the method will always produce an error at compile time
// when this macro can be implemented (i.e. if the compiler supports C++11).
# if __has_feature(cxx_override_control) // If the current compiler does not support C++11, use of the annotated method
# define V8_HAVE_CXX11_FINAL // will still cause an error, but the error will most likely occur at link time
# define V8_HAVE_CXX11_OVERRIDE // rather than at compile time. As a backstop, method declarations using this
# endif // macro should be private.
// Use like:
#elif defined(__GNUC__) // class A {
// private:
// g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality // A(const A& other) V8_DELETE;
// without warnings (functionality used by the macros below). These modes // A& operator=(const A& other) V8_DELETE;
// are detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, // };
// more standardly, by checking whether __cplusplus has a C++11 or greater #if defined(V8_HAVE_CXX11_DELETE)
// value. Current versions of g++ do not correctly set __cplusplus, so we check # define V8_DELETE = delete
// both for forward compatibility. #else
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # define V8_DELETE /* NOT SUPPORTED */
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) #endif
# define V8_HAVE_CXX11_OVERRIDE
# define V8_HAVE_CXX11_FINAL
# endif
# else
// '__final' is a non-C++11 GCC synonym for 'final', per GCC r176655.
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
# define V8_HAVE_GXX_FINAL
# endif
# endif
#elif defined(_MSC_VER)
// Override control was added with Visual Studio 2005.
# if _MSC_VER >= 1400
# if _MSC_VER >= 1700
# define V8_HAVE_CXX11_FINAL
# else
// Visual Studio 2010 and earlier spell "final" as "sealed".
# define V8_HAVE_MSVC_SEALED
# endif
# define V8_HAVE_CXX11_OVERRIDE
# endif
// Annotate a virtual method indicating it must be overriding a virtual
// method in the parent class.
// Use like:
// virtual void bar() V8_OVERRIDE;
#if defined(V8_HAVE_CXX11_OVERRIDE)
# define V8_OVERRIDE override
#else
# define V8_OVERRIDE /* NOT SUPPORTED */
#endif #endif
#if __cplusplus >= 201103L // Annotate a virtual method indicating that subclasses must not override it,
#define DISALLOW_BY_DELETE = delete // or annotate a class to indicate that it cannot be subclassed.
// Use like:
// class B V8_FINAL : public A {};
// virtual void bar() V8_FINAL;
#if defined(V8_HAVE_CXX11_FINAL)
# define V8_FINAL final
#elif defined(V8_HAVE_GXX_FINAL)
# define V8_FINAL __final
#elif defined(V8_HAVE_MSVC_SEALED)
# define V8_FINAL sealed
#else #else
#define DISALLOW_BY_DELETE # define V8_FINAL /* NOT SUPPORTED */
#endif #endif
// A macro to disallow the evil copy constructor and operator= functions // A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class // This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) DISALLOW_BY_DELETE; \ TypeName(const TypeName&) V8_DELETE; \
void operator=(const TypeName&) DISALLOW_BY_DELETE void operator=(const TypeName&) V8_DELETE
// A macro to disallow all the implicit constructors, namely the // A macro to disallow all the implicit constructors, namely the
...@@ -394,8 +446,8 @@ F FUNCTION_CAST(Address addr) { ...@@ -394,8 +446,8 @@ F FUNCTION_CAST(Address addr) {
// This should be used in the private: declarations for a class // This should be used in the private: declarations for a class
// that wants to prevent anyone from instantiating it. This is // that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods. // especially useful for classes containing only static methods.
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName() DISALLOW_BY_DELETE; \ TypeName() V8_DELETE; \
DISALLOW_COPY_AND_ASSIGN(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
...@@ -419,33 +471,6 @@ F FUNCTION_CAST(Address addr) { ...@@ -419,33 +471,6 @@ F FUNCTION_CAST(Address addr) {
#endif #endif
// Annotate a virtual method indicating it must be overriding a virtual
// method in the parent class.
// Use like:
// virtual void bar() V8_OVERRIDE;
#if defined(V8_HAVE_CXX11_OVERRIDE)
#define V8_OVERRIDE override
#else
#define V8_OVERRIDE
#endif
// Annotate a virtual method indicating that subclasses must not override it,
// or annotate a class to indicate that it cannot be subclassed.
// Use like:
// class B V8_FINAL : public A {};
// virtual void bar() V8_FINAL;
#if defined(V8_HAVE_CXX11_FINAL)
#define V8_FINAL final
#elif defined(V8_HAVE_GXX_FINAL)
#define V8_FINAL __final
#elif defined(V8_HAVE_MSVC_SEALED)
#define V8_FINAL sealed
#else
#define V8_FINAL
#endif
#if defined(__GNUC__) && __GNUC__ >= 4 #if defined(__GNUC__) && __GNUC__ >= 4
#define MUST_USE_RESULT __attribute__ ((warn_unused_result)) #define MUST_USE_RESULT __attribute__ ((warn_unused_result))
#else #else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment