Bug 702437 - Implement MOZ_OVERRIDE to encapsulate support for the contextual override keyword on virtual member functions. r=cjones
authorJeff Walden <jwalden@mit.edu>
Mon, 14 Nov 2011 10:31:46 -0800
changeset 82325 d88e310d57815fb3312432e2fe0876ec78668008
parent 82324 cdf1844ffd59de32a87c25b67676f941e3ca0344
child 82326 67d6b8636246f6c20014194484edccbd9901f58f
push id114
push userffxbld
push dateFri, 09 Mar 2012 01:01:18 +0000
treeherdermozilla-release@c081ebf13261 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs702437
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 702437 - Implement MOZ_OVERRIDE to encapsulate support for the contextual override keyword on virtual member functions. r=cjones
gfx/layers/basic/BasicLayers.cpp
js/src/jswrapper.h
mfbt/Types.h
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -38,16 +38,18 @@
 
 #include "gfxSharedImageSurface.h"
 
 #include "mozilla/layers/PLayerChild.h"
 #include "mozilla/layers/PLayersChild.h"
 #include "mozilla/layers/PLayersParent.h"
 #include "mozilla/gfx/2D.h"
 
+#include "mozilla/Types.h"
+
 #include "ipc/ShadowLayerChild.h"
 
 #include "BasicLayers.h"
 #include "ImageLayers.h"
 
 #include "nsTArray.h"
 #include "nsGUIEvent.h"
 #include "gfxContext.h"
@@ -2204,27 +2206,27 @@ public:
   virtual void SyncFrontBufferToBackBuffer();
 
 private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
-  NS_OVERRIDE virtual void
+  virtual void
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
               const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
               bool aDidSelfCopy,
               LayerManager::DrawThebesLayerCallback aCallback,
-              void* aCallbackData);
-
-  NS_OVERRIDE virtual already_AddRefed<gfxASurface>
-  CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
+              void* aCallbackData) MOZ_OVERRIDE;
+
+  virtual already_AddRefed<gfxASurface>
+  CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize) MOZ_OVERRIDE;
 
   void DestroyBackBuffer()
   {
     if (IsSurfaceDescriptorValid(mBackBuffer)) {
       BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
     }
   }
 
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -37,16 +37,18 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jswrapper_h___
 #define jswrapper_h___
 
+#include "mozilla/Types.h"
+
 #include "jsapi.h"
 #include "jsproxy.h"
 
 namespace js {
 
 /* No-op wrapper handler base class. */
 class JS_FRIEND_API(Wrapper) : public ProxyHandler
 {
@@ -57,47 +59,47 @@ class JS_FRIEND_API(Wrapper) : public Pr
     explicit Wrapper(uintN flags);
 
     typedef enum { PermitObjectAccess, PermitPropertyAccess, DenyAccess } Permission;
 
     virtual ~Wrapper();
 
     /* ES5 Harmony fundamental wrapper traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
-                                       PropertyDescriptor *desc);
+                                       PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
-                                          PropertyDescriptor *desc);
+                                          PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
-                                PropertyDescriptor *desc);
-    virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
-    virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
-    virtual bool fix(JSContext *cx, JSObject *wrapper, Value *vp);
+                                PropertyDescriptor *desc) MOZ_OVERRIDE;
+    virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool fix(JSContext *cx, JSObject *wrapper, Value *vp) MOZ_OVERRIDE;
 
     /* ES5 Harmony derived wrapper traps. */
-    virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp);
+    virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE;
     virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
-                     Value *vp);
-    virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
-    virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp);
+                     Value *vp) MOZ_OVERRIDE;
+    virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
-    virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp);
-    virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval);
-    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
-    virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp);
-    virtual JSType typeOf(JSContext *cx, JSObject *proxy);
-    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
-    virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
-    virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
-    virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp);
+    virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp) MOZ_OVERRIDE;
+    virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval) MOZ_OVERRIDE;
+    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
+    virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
+    virtual JSType typeOf(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE;
+    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
+    virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
+    virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent) MOZ_OVERRIDE;
+    virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
 
-    virtual void trace(JSTracer *trc, JSObject *wrapper);
+    virtual void trace(JSTracer *trc, JSObject *wrapper) MOZ_OVERRIDE;
 
     /* Policy enforcement traps. */
     enum Action { GET, SET, CALL };
     virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp);
     virtual void leave(JSContext *cx, JSObject *wrapper);
 
     static Wrapper singleton;
 
@@ -120,44 +122,44 @@ class JS_FRIEND_API(CrossCompartmentWrap
 {
   public:
     CrossCompartmentWrapper(uintN flags);
 
     virtual ~CrossCompartmentWrapper();
 
     /* ES5 Harmony fundamental wrapper traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
-                                       PropertyDescriptor *desc);
+                                       PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
-                                          PropertyDescriptor *desc);
+                                          PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
-                                PropertyDescriptor *desc);
-    virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
-    virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
+                                PropertyDescriptor *desc) MOZ_OVERRIDE;
+    virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* ES5 Harmony derived wrapper traps. */
-    virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
-    virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp);
+    virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
+    virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE;
     virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
-                     Value *vp);
-    virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
-    virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp);
+                     Value *vp) MOZ_OVERRIDE;
+    virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
+    virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
-    virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp);
-    virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval);
-    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
-    virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp);
-    virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
-    virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
-    virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp);
+    virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp) MOZ_OVERRIDE;
+    virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval) MOZ_OVERRIDE;
+    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
+    virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
+    virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
+    virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent) MOZ_OVERRIDE;
+    virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
 
-    virtual void trace(JSTracer *trc, JSObject *wrapper);
+    virtual void trace(JSTracer *trc, JSObject *wrapper) MOZ_OVERRIDE;
 
     static CrossCompartmentWrapper singleton;
 };
 
 /*
  * Base class for security wrappers. A security wrapper is potentially hiding
  * all or part of some wrapped object thus SecurityWrapper defaults to denying
  * access to the wrappee. This is the opposite of Wrapper which tries to be
@@ -167,18 +169,18 @@ class JS_FRIEND_API(CrossCompartmentWrap
  * access, relying on derived SecurityWrapper to block access when necessary.
  */
 template <class Base>
 class JS_FRIEND_API(SecurityWrapper) : public Base
 {
   public:
     SecurityWrapper(uintN flags);
 
-    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
-    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
+    virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
+    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
 };
 
 typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper;
 typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper;
 
 /*
  * A hacky class that lets a friend force a fake frame. We must already be
  * in the compartment of |target| when we enter the forced frame.
--- a/mfbt/Types.h
+++ b/mfbt/Types.h
@@ -86,16 +86,53 @@
 
 
 #define MOZ_BEGIN_EXTERN_C     JS_BEGIN_EXTERN_C
 #define MOZ_END_EXTERN_C       JS_END_EXTERN_C
 
 #ifdef __cplusplus
 
 /*
+ * 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(__clang__)
+# if __clang_major__ >= 3
+#  define MOZ_HAVE_CXX11_DELETE
+#  define MOZ_HAVE_CXX11_OVERRIDE
+# elif __clang_major__ == 2
+#  if __clang_minor__ >= 9
+#   define MOZ_HAVE_CXX11_DELETE
+#  endif
+# endif
+#elif defined(__GNUC__)
+# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
+#  if __GNUC__ > 4
+#   define MOZ_HAVE_CXX11_DELETE
+#   define MOZ_HAVE_CXX11_OVERRIDE
+#  elif __GNUC__ == 4
+#   if __GNUC_MINOR__ >= 7
+#    define MOZ_HAVE_CXX11_OVERRIDE
+#   endif
+#   if __GNUC_MINOR__ >= 4
+#    define MOZ_HAVE_CXX11_DELETE
+#   endif
+#  endif
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER >= 1400
+#  define MOZ_HAVE_CXX11_OVERRIDE
+# endif
+#endif
+
+/*
  * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
  * method declaration, attempts to delete that method from the corresponding
  * class.  An attempt to use the method will always produce an error *at compile
  * time* (instead of sometimes as late as link time) when this macro can be
  * implemented.  For example, you can use MOZ_DELETE to produce classes with no
  * implicit copy constructor or assignment operator:
  *
  *   struct NonCopyable
@@ -107,30 +144,58 @@
  *
  * If MOZ_DELETE can't be implemented for the current compiler, use of the
  * annotated method will still cause an error, but the error might occur at link
  * time in some cases rather than at compile time.
  *
  * MOZ_DELETE relies on C++11 functionality not universally implemented.  As a
  * backstop, method declarations using MOZ_DELETE should be private.
  */
-#if defined(__clang__) && (__clang_major__ >= 3 || (__clang_major__ == 2 && __clang_minor__ >= 9))
+#if defined(MOZ_HAVE_CXX11_DELETE)
 # define MOZ_DELETE            = delete
-#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
- /*
-  * g++ >= 4.4 requires -std=c++0x or -std=gnu++0x to support deleted functions
-  * without warnings.  These modes are detectable by the experimental macro used
-  * below 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
-#  define MOZ_DELETE           = delete
-# else
-#  define MOZ_DELETE           /* = delete */
-# endif
 #else
-# define MOZ_DELETE            /* no = delete support, or unknown support */
+# define MOZ_DELETE            /* no support */
+#endif
+
+/*
+ * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
+ * overrides a member function of a base class, rather than potentially being a
+ * new member function.  MOZ_OVERRIDE should be placed immediately before the
+ * ';' terminating the member function's declaration, or before '= 0;' if the
+ * member function is pure.  If the member function is defined in the class
+ * definition, it should appear before the opening brace of the function body.
+ *
+ *   class Base
+ *   {
+ *     public:
+ *       virtual void f() = 0;
+ *   };
+ *   class Derived1 : public Base
+ *   {
+ *     public:
+ *       virtual void f() MOZ_OVERRIDE;
+ *   };
+ *   class Derived2 : public Base
+ *   {
+ *     public:
+ *       virtual void f() MOZ_OVERRIDE = 0;
+ *   };
+ *   class Derived3 : public Base
+ *   {
+ *     public:
+ *       virtual void f() MOZ_OVERRIDE { }
+ *   };
+ *
+ * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
+ * the function marked with it override a member function of a base class: it
+ * is a compile error if it does not.  Otherwise MOZ_OVERRIDE does not affect
+ * semantics and merely documents the override relationship to the reader (but
+ * of course must still be used correctly to not break C++11 compilers).
+ */
+#if defined(MOZ_HAVE_CXX11_OVERRIDE)
+# define MOZ_OVERRIDE          override
+#else
+# define MOZ_OVERRIDE          /* no support */
 #endif
 
 #endif /* __cplusplus */
 
 #endif  /* mozilla_Types_h_ */