Bug 704127 - Implement MOZ_FINAL as a modifier for classes and virtual member functions. r=cjones
authorJeff Walden <jwalden@mit.edu>
Sun, 20 Nov 2011 22:21:16 -0800
changeset 80672 3edc79afc84277486afad1fb76d007ba37e72894
parent 80671 de0efe828f9b8451050a4ae23389d39b69f57755
child 80673 47c587d6524296b4b3610e3335afacafb4ef46f9
push id344
push userrcampbell@mozilla.com
push dateThu, 24 Nov 2011 15:49:18 +0000
treeherderfx-team@1ac01535c4df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs704127
milestone11.0a1
Bug 704127 - Implement MOZ_FINAL as a modifier for classes and virtual member functions. r=cjones
content/base/src/nsTextFragment.h
ipc/glue/Shmem.h
ipc/ipdl/ipdl/builtin.py
ipc/ipdl/ipdl/cxx/cgen.py
js/src/shell/jsworkers.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsLineBox.h
layout/generic/nsSelection.cpp
layout/style/ImportRule.h
layout/style/NameSpaceRule.h
layout/style/StyleRule.h
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsCSSStyleSheet.h
layout/xul/base/src/tree/src/nsTreeBodyFrame.h
mfbt/Attributes.h
xpcom/base/nsConsoleMessage.h
xpcom/base/nsErrorService.h
xpcom/glue/GenericFactory.h
xpcom/glue/nsArrayEnumerator.cpp
xpcom/glue/nsCOMPtr.h
xpcom/glue/nsEnumeratorUtils.cpp
xpcom/glue/nsWeakReference.cpp
--- a/content/base/src/nsTextFragment.h
+++ b/content/base/src/nsTextFragment.h
@@ -38,16 +38,18 @@
  * A class which represents a fragment of text (eg inside a text
  * node); if only codepoints below 256 are used, the text is stored as
  * a char*; otherwise the text is stored as a PRUnichar*
  */
 
 #ifndef nsTextFragment_h___
 #define nsTextFragment_h___
 
+#include "mozilla/Attributes.h"
+
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsTraceRefcnt.h"
 #include "nsDOMMemoryReporter.h"
 
 class nsString;
 class nsCString;
 
@@ -75,17 +77,17 @@ class nsCString;
  * A fragment of text. If mIs2b is 1 then the m2b pointer is valid
  * otherwise the m1b pointer is valid. If m1b is used then each byte
  * of data represents a single ucs2 character with the high byte being
  * zero.
  *
  * This class does not have a virtual destructor therefore it is not
  * meant to be subclassed.
  */
-class NS_FINAL_CLASS nsTextFragment {
+class nsTextFragment MOZ_FINAL {
 public:
   static nsresult Init();
   static void Shutdown();
 
   /**
    * Default constructor. Initialize the fragment to be empty.
    */
   nsTextFragment()
--- a/ipc/glue/Shmem.h
+++ b/ipc/glue/Shmem.h
@@ -36,16 +36,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 mozilla_ipc_Shmem_h
 #define mozilla_ipc_Shmem_h
 
+#include "mozilla/Attributes.h"
+
 #include "base/basictypes.h"
 #include "base/process.h"
 
 #include "nscore.h"
 #include "nsDebug.h"
 
 #include "IPC/IPCMessageUtils.h"
 #include "mozilla/ipc/SharedMemory.h"
@@ -82,17 +84,17 @@
  * message.  The parent's |Shmem| then "dies", i.e. becomes
  * inaccessible.  This process could be compared to passing a
  * "shmem-access baton" between parent and child.
  */
 
 namespace mozilla {
 namespace ipc {
 
-class NS_FINAL_CLASS Shmem
+class Shmem MOZ_FINAL
 {
   friend struct IPC::ParamTraits<mozilla::ipc::Shmem>;
 
 public:
   typedef int32 id_t;
   // Low-level wrapper around platform shmem primitives.
   typedef mozilla::ipc::SharedMemory SharedMemory;
   typedef SharedMemory::SharedMemoryType SharedMemoryType;
--- a/ipc/ipdl/ipdl/builtin.py
+++ b/ipc/ipdl/ipdl/builtin.py
@@ -87,16 +87,17 @@ Types = (
     'int64',
     'uint64',
     'intptr',
     'uintptr',
 )
 
 
 Includes = (
+    'mozilla/Attributes.h',
     'base/basictypes.h',
     'prtime.h',
     'nscore.h',
     'IPCMessageStart.h',
     'IPC/IPCMessageUtils.h',
     'nsAutoPtr.h',
     'nsStringGlue.h',
     'nsTArray.h',
--- a/ipc/ipdl/ipdl/cxx/cgen.py
+++ b/ipc/ipdl/ipdl/cxx/cgen.py
@@ -156,19 +156,19 @@ class CxxCodeGen(CodePrinter, Visitor):
         else:
             self.printdent('class')
         if c.interface:
             # FIXME/cjones: turn this "on" when we get the analysis
             self.write(' /*NS_INTERFACE_CLASS*/')
         if c.abstract:
             # FIXME/cjones: turn this "on" when we get the analysis
             self.write(' /*NS_ABSTRACT_CLASS*/')
+        self.write(' '+ c.name)
         if c.final:
-            self.write(' NS_FINAL_CLASS')
-        self.write(' '+ c.name)
+            self.write(' MOZ_FINAL')
 
         if c.specializes is not None:
             self.write(' <')
             c.specializes.accept(self)
             self.write('>')
 
         ninh = len(c.inherits)
         if 0 < ninh:
--- a/js/src/shell/jsworkers.cpp
+++ b/js/src/shell/jsworkers.cpp
@@ -35,16 +35,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 ***** */
 
 #ifdef JS_THREADSAFE
 
+#include "mozilla/Attributes.h"
+
 #include <string.h>
 #include "prthread.h"
 #include "prlock.h"
 #include "prcvar.h"
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsstdint.h"
@@ -346,17 +348,17 @@ class Event
         jsval argv[1] = { OBJECT_TO_JSVAL(obj) };
         jsval rval = JSVAL_VOID;
         return Result(JS_CallFunctionName(cx, thisobj, methodName, 1, argv, &rval));
     }
 };
 
 typedef ThreadSafeQueue<Event *> EventQueue;
 
-class MainQueue : public EventQueue, public WorkerParent
+class MainQueue MOZ_FINAL : public EventQueue, public WorkerParent
 {
   private:
     ThreadPool *threadPool;
 
   public:
     explicit MainQueue(ThreadPool *tp) : threadPool(tp) {}
 
     ~MainQueue() {
@@ -425,17 +427,17 @@ class MainQueue : public EventQueue, pub
 };
 
 /*
  * A queue of workers.
  *
  * We keep a queue of workers with pending events, rather than a queue of
  * events, so that two threads won't try to run a Worker at the same time.
  */
-class WorkerQueue : public ThreadSafeQueue<Worker *>
+class WorkerQueue MOZ_FINAL : public ThreadSafeQueue<Worker *>
 {
   private:
     MainQueue *main;
 
   public:
     explicit WorkerQueue(MainQueue *main) : main(main) {}
 
     void work();
@@ -583,17 +585,17 @@ class ThreadPool
  *   - idle       (!terminated && current == NULL && events.empty())
  *   - enqueued   (!terminated && current == NULL && !events.empty())
  *   - busy       (!terminated && current != NULL)
  *   - terminated (terminated && current == NULL && events.empty())
  *
  * Separately, there is a terminateFlag that other threads can set
  * asynchronously to tell the Worker to terminate.
  */
-class Worker : public WorkerParent
+class Worker MOZ_FINAL : public WorkerParent
 {
   private:
     ThreadPool *threadPool;
     WorkerParent *parent;
     JSObject *object;  // Worker object exposed to parent
     JSRuntime *runtime;
     JSContext *context;
     JSLock *lock;
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -32,17 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 nsFrameSelection_h___
 #define nsFrameSelection_h___
- 
+
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsISelectionController.h"
 #include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
 #include "nsIDOMElement.h"
 #include "nsGUIEvent.h"
 #include "nsIRange.h"
@@ -205,17 +205,17 @@ class nsTypedSelection;
 class nsIScrollableFrame;
 
 /**
  * Methods which are marked with *unsafe* should be handled with special care.
  * They may cause nsFrameSelection to be deleted, if strong pointer isn't used,
  * or they may cause other objects to be deleted.
  */
 
-class NS_FINAL_CLASS nsFrameSelection : public nsISupports {
+class nsFrameSelection : public nsISupports {
 public:
   enum HINT { HINTLEFT = 0, HINTRIGHT = 1};  //end of this line or beginning of next
   /*interfaces for addref and release and queryinterface*/
   
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsFrameSelection)
 
   /** Init will initialize the frame selector with the necessary pres shell to 
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -38,16 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* representation of one line within a block frame, a CSS line box */
 
 #ifndef nsLineBox_h___
 #define nsLineBox_h___
 
+#include "mozilla/Attributes.h"
+
 #include "nsILineIterator.h"
 #include "nsIFrame.h"
 
 class nsLineBox;
 class nsFloatCache;
 class nsFloatCacheList;
 class nsFloatCacheFreeList;
 
@@ -1561,17 +1563,17 @@ nsLineList_const_reverse_iterator&
 nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iterator& aOther)
 {
   ASSIGN_FROM(aOther)
 }
 
 
 //----------------------------------------------------------------------
 
-class NS_FINAL_CLASS nsLineIterator : public nsILineIterator
+class nsLineIterator MOZ_FINAL : public nsILineIterator
 {
 public:
   nsLineIterator();
   ~nsLineIterator();
 
   virtual void DisposeLineIterator();
 
   virtual PRInt32 GetNumLines();
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -36,16 +36,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Implementation of selection: nsISelection,nsISelectionPrivate and nsFrameSelection
  */
 
+#include "mozilla/Attributes.h"
+
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 #include "nsIFactory.h"
 #include "nsIEnumerator.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsFrameSelection.h"
 #include "nsISelectionPrivate.h"
@@ -352,17 +354,17 @@ private:
   nsCOMArray<nsISelectionListener> mSelectionListeners;
   nsRevocableEventPtr<ScrollSelectionIntoViewEvent> mScrollEvent;
   CachedOffsetForFrame *mCachedOffsetForFrame;
   nsDirection mDirection;
   SelectionType mType;
 };
 
 // Stack-class to turn on/off selection batching for table selection
-class NS_STACK_CLASS NS_FINAL_CLASS nsSelectionBatcher
+class NS_STACK_CLASS nsSelectionBatcher MOZ_FINAL
 {
 private:
   nsCOMPtr<nsISelectionPrivate> mSelection;
 public:
   nsSelectionBatcher(nsISelectionPrivate *aSelection) : mSelection(aSelection)
   {
     if (mSelection) mSelection->StartBatchChanges();
   }
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -35,28 +35,30 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* class for CSS @import rules */
 
 #ifndef mozilla_css_ImportRule_h__
 #define mozilla_css_ImportRule_h__
 
+#include "mozilla/Attributes.h"
+
 #include "mozilla/css/Rule.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsCSSRules.h"
 
 class nsMediaList;
 class nsString;
 
 namespace mozilla {
 namespace css {
 
-class NS_FINAL_CLASS ImportRule : public Rule,
-                                  public nsIDOMCSSImportRule
+class ImportRule MOZ_FINAL : public Rule,
+                             public nsIDOMCSSImportRule
 {
 public:
   ImportRule(nsMediaList* aMedia, const nsString& aURLSpec);
 private:
   // for |Clone|
   ImportRule(const ImportRule& aCopy);
   ~ImportRule();
 public:
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -48,18 +48,18 @@ class nsIAtom;
 // IID for the NameSpaceRule class {f0b0dbe1-5031-4a21-b06a-dc141ef2af98}
 #define NS_CSS_NAMESPACE_RULE_IMPL_CID     \
 {0xf0b0dbe1, 0x5031, 0x4a21, {0xb0, 0x6a, 0xdc, 0x14, 0x1e, 0xf2, 0xaf, 0x98}}
 
 
 namespace mozilla {
 namespace css {
 
-class NS_FINAL_CLASS NameSpaceRule : public Rule,
-                                     public nsIDOMCSSRule
+class NameSpaceRule : public Rule,
+                      public nsIDOMCSSRule
 {
 public:
   NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec);
 private:
   // for |Clone|
   NameSpaceRule(const NameSpaceRule& aCopy);
   ~NameSpaceRule();
 public:
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -313,17 +313,17 @@ protected:
   // Not an owning reference; the StyleRule that owns this
   // ImportantRule also owns the mDeclaration, and any rule node
   // pointing to this rule keeps that StyleRule alive as well.
   Declaration* mDeclaration;
 
   friend class StyleRule;
 };
 
-class NS_FINAL_CLASS StyleRule : public Rule
+class StyleRule : public Rule
 {
  public:
   StyleRule(nsCSSSelectorList* aSelector,
             Declaration *aDeclaration);
 private:
   // for |Clone|
   StyleRule(const StyleRule& aCopy);
   // for |DeclarationChanged|
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -115,17 +115,17 @@ Rule::GetParentStyleSheet(nsIDOMCSSStyle
   return NS_OK;
 }
 
 
 // -------------------------------
 // Style Rule List for group rules
 //
 
-class NS_FINAL_CLASS GroupRuleRuleList : public nsICSSRuleList
+class GroupRuleRuleList : public nsICSSRuleList
 {
 public:
   GroupRuleRuleList(GroupRule *aGroupRule);
 
   NS_DECL_ISUPPORTS
 
   NS_DECL_NSIDOMCSSRULELIST
 
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -38,16 +38,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
 
 #ifndef nsCSSRules_h_
 #define nsCSSRules_h_
 
+#include "mozilla/Attributes.h"
+
 #include "mozilla/css/GroupRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsICSSRuleList.h"
@@ -65,18 +67,18 @@ class StyleRule;
 }
 }
 
 class nsMediaList;
 
 namespace mozilla {
 namespace css {
 
-class NS_FINAL_CLASS MediaRule : public GroupRule,
-                                 public nsIDOMCSSMediaRule
+class MediaRule : public GroupRule,
+                  public nsIDOMCSSMediaRule
 {
 public:
   MediaRule();
 private:
   MediaRule(const MediaRule& aCopy);
   ~MediaRule();
 public:
 
@@ -108,18 +110,18 @@ public:
 
   // @media rule methods
   nsresult SetMedia(nsMediaList* aMedia);
   
 protected:
   nsRefPtr<nsMediaList> mMedia;
 };
 
-class NS_FINAL_CLASS DocumentRule : public GroupRule,
-                                    public nsIDOMCSSMozDocumentRule
+class DocumentRule : public GroupRule,
+                     public nsIDOMCSSMozDocumentRule
 {
 public:
   DocumentRule();
 private:
   DocumentRule(const DocumentRule& aCopy);
   ~DocumentRule();
 public:
 
@@ -207,18 +209,18 @@ protected:
 
 private:
   // NOT TO BE IMPLEMENTED
   // This object cannot be allocated on its own, only as part of
   // nsCSSFontFaceRule.
   void* operator new(size_t size) CPP_THROW_NEW;
 };
 
-class NS_FINAL_CLASS nsCSSFontFaceRule : public mozilla::css::Rule,
-                                         public nsIDOMCSSFontFaceRule
+class nsCSSFontFaceRule MOZ_FINAL : public mozilla::css::Rule,
+                                    public nsIDOMCSSFontFaceRule
 {
 public:
   nsCSSFontFaceRule() {}
 
   nsCSSFontFaceRule(const nsCSSFontFaceRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
 
@@ -268,18 +270,18 @@ nsCSSFontFaceStyleDecl::ContainingRule()
 {
   return reinterpret_cast<const nsCSSFontFaceRule*>
     (reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 namespace mozilla {
 namespace css {
 
-class NS_FINAL_CLASS CharsetRule : public Rule,
-                                   public nsIDOMCSSCharsetRule
+class CharsetRule MOZ_FINAL : public Rule,
+                              public nsIDOMCSSCharsetRule
 {
 public:
   CharsetRule(const nsAString& aEncoding);
 private:
   // For |Clone|
   CharsetRule(const CharsetRule& aCopy);
   ~CharsetRule() {}
 
@@ -308,18 +310,17 @@ private:
   nsString  mEncoding;
 };
 
 } // namespace css
 } // namespace mozilla
 
 class nsCSSKeyframeRule;
 
-class NS_FINAL_CLASS nsCSSKeyframeStyleDeclaration
-                         : public nsDOMCSSDeclaration
+class nsCSSKeyframeStyleDeclaration : public nsDOMCSSDeclaration
 {
 public:
   nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule);
   virtual ~nsCSSKeyframeStyleDeclaration();
 
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent);
   void DropReference() { mRule = nsnull; }
   virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate);
@@ -339,18 +340,18 @@ protected:
   nsAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
   // This reference is not reference-counted. The rule object tells us
   // when it's about to go away.
   nsCSSKeyframeRule *mRule;
 };
 
-class NS_FINAL_CLASS nsCSSKeyframeRule : public mozilla::css::Rule,
-                                         public nsIDOMMozCSSKeyframeRule
+class nsCSSKeyframeRule MOZ_FINAL : public mozilla::css::Rule,
+                                    public nsIDOMMozCSSKeyframeRule
 {
 public:
   // WARNING: Steals the contents of aKeys *and* aDeclaration
   nsCSSKeyframeRule(nsTArray<float> aKeys,
                     nsAutoPtr<mozilla::css::Declaration> aDeclaration)
     : mDeclaration(aDeclaration)
   {
     mKeys.SwapElements(aKeys);
@@ -384,18 +385,18 @@ public:
 
 private:
   nsAutoTArray<float, 1>                     mKeys;
   nsAutoPtr<mozilla::css::Declaration>       mDeclaration;
   // lazily created when needed:
   nsRefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
 };
 
-class NS_FINAL_CLASS nsCSSKeyframesRule : public mozilla::css::GroupRule,
-                                          public nsIDOMMozCSSKeyframesRule
+class nsCSSKeyframesRule : public mozilla::css::GroupRule,
+                           public nsIDOMMozCSSKeyframesRule
 {
 public:
   nsCSSKeyframesRule(const nsSubstring& aName)
     : mName(aName)
   {
   }
 private:
   nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
--- a/layout/style/nsCSSStyleSheet.h
+++ b/layout/style/nsCSSStyleSheet.h
@@ -39,16 +39,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* representation of a CSS style sheet */
 
 #ifndef nsCSSStyleSheet_h_
 #define nsCSSStyleSheet_h_
 
+#include "mozilla/Attributes.h"
+
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIStyleSheet.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
@@ -127,19 +129,19 @@ struct ChildSheetListBuilder;
 
 // CID for the nsCSSStyleSheet class
 // ca926f30-2a7e-477e-8467-803fb32af20a
 #define NS_CSS_STYLE_SHEET_IMPL_CID     \
 { 0xca926f30, 0x2a7e, 0x477e, \
  { 0x84, 0x67, 0x80, 0x3f, 0xb3, 0x2a, 0xf2, 0x0a } }
 
 
-class NS_FINAL_CLASS nsCSSStyleSheet : public nsIStyleSheet,
-                                       public nsIDOMCSSStyleSheet,
-                                       public nsICSSLoaderObserver
+class nsCSSStyleSheet : public nsIStyleSheet,
+                        public nsIDOMCSSStyleSheet,
+                        public nsICSSLoaderObserver
 {
 public:
   nsCSSStyleSheet();
 
   NS_DECL_ISUPPORTS
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
 
@@ -266,19 +268,18 @@ public:
 
 private:
   nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
                   nsCSSStyleSheet* aParentToUse,
                   mozilla::css::ImportRule* aOwnerRuleToUse,
                   nsIDocument* aDocumentToUse,
                   nsIDOMNode* aOwningNodeToUse);
 
-  // These are not supported and are not implemented! 
-  nsCSSStyleSheet(const nsCSSStyleSheet& aCopy); 
-  nsCSSStyleSheet& operator=(const nsCSSStyleSheet& aCopy); 
+  nsCSSStyleSheet(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
+  nsCSSStyleSheet& operator=(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
 
 protected:
   virtual ~nsCSSStyleSheet();
 
   void ClearRuleCascades();
 
   nsresult WillDirty();
   void     DidDirty();
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.h
@@ -39,16 +39,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 nsTreeBodyFrame_h
 #define nsTreeBodyFrame_h
 
+#include "mozilla/Attributes.h"
+
 #include "nsLeafBoxFrame.h"
 #include "nsITreeView.h"
 #include "nsICSSPseudoComparator.h"
 #include "nsIScrollbarMediator.h"
 #include "nsIDragSession.h"
 #include "nsITimer.h"
 #include "nsIReflowCallback.h"
 #include "nsTArray.h"
@@ -72,17 +74,17 @@ struct nsTreeImageCacheEntry
   nsTreeImageCacheEntry(imgIRequest *aRequest, imgIDecoderObserver *aListener)
     : request(aRequest), listener(aListener) {}
 
   nsCOMPtr<imgIRequest> request;
   nsCOMPtr<imgIDecoderObserver> listener;
 };
 
 // The actual frame that paints the cells and rows.
-class NS_FINAL_CLASS nsTreeBodyFrame
+class nsTreeBodyFrame MOZ_FINAL
   : public nsLeafBoxFrame
   , public nsICSSPseudoComparator
   , public nsIScrollbarMediator
   , public nsIReflowCallback
 {
 public:
   nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   ~nsTreeBodyFrame();
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -59,38 +59,51 @@
  * 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
+#    define MOZ_HAVE_CXX11_FINAL         final
 #  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
+#      define MOZ_HAVE CXX11_FINAL       final
 #    elif __GNUC__ == 4
 #      if __GNUC_MINOR__ >= 7
 #        define MOZ_HAVE_CXX11_OVERRIDE
 #      endif
 #      if __GNUC_MINOR__ >= 4
 #        define MOZ_HAVE_CXX11_DELETE
 #      endif
 #    endif
+#  else
+     /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */
+#    if __GNUC__ > 4
+#      define MOZ_HAVE_CXX11_FINAL       __final
+#    elif __GNUC__ == 4
+#      if __GNUC_MINOR__ >= 7
+#        define MOZ_HAVE_CXX11_FINAL     __final
+#      endif
+#    endif
 #  endif
 #elif defined(_MSC_VER)
 #  if _MSC_VER >= 1400
 #    define MOZ_HAVE_CXX11_OVERRIDE
+     /* MSVC currently spells "final" as "sealed". */
+#    define MOZ_HAVE_CXX11_FINAL         sealed
 #  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
@@ -153,9 +166,78 @@
  * 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
 
+/*
+ * MOZ_FINAL indicates that some functionality cannot be overridden through
+ * inheritance.  It can be used to annotate either classes/structs or virtual
+ * member functions.
+ *
+ * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after
+ * the name of the class, before the list of classes from which it derives (if
+ * any) and before its opening brace.  MOZ_FINAL must not be used to annotate
+ * unnamed classes or structs.  (With some compilers, and with C++11 proper, the
+ * underlying expansion is ambiguous with specifying a class name.)
+ *
+ *   class Base MOZ_FINAL
+ *   {
+ *     public:
+ *       Base();
+ *       ~Base();
+ *       virtual void f() { }
+ *   };
+ *   // This will be an error in some compilers:
+ *   class Derived : public Base
+ *   {
+ *     public:
+ *       ~Derived() { }
+ *   };
+ *
+ * One particularly common reason to specify MOZ_FINAL upon a class is to tell
+ * the compiler that it's not dangerous for it to have a non-virtual destructor
+ * yet have one or more virtual functions, silencing the warning it might emit
+ * in this case.  Suppose Base above weren't annotated with MOZ_FINAL.  Because
+ * ~Base() is non-virtual, an attempt to delete a Derived* through a Base*
+ * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen.
+ * (Formally C++ says behavior is undefined, but compilers will likely just call
+ * ~Base() and not ~Derived().)  Specifying MOZ_FINAL tells the compiler that
+ * it's safe for the destructor to be non-virtual.
+ *
+ * In compilers implementing final controls, it is an error to inherit from a
+ * class annotated with MOZ_FINAL.  In other compilers it serves only as
+ * documentation.
+ *
+ * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL
+ * 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.  (This placement is identical to that for MOZ_OVERRIDE.
+ * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE'
+ * for consistency.)
+ *
+ *   class Base
+ *   {
+ *     public:
+ *       virtual void f() MOZ_FINAL;
+ *   };
+ *   class Derived
+ *   {
+ *     public:
+ *       // This will be an error in some compilers:
+ *       virtual void f();
+ *   };
+ *
+ * In compilers implementing final controls, it is an error for a derived class
+ * to override a method annotated with MOZ_FINAL.  In other compilers it serves
+ * only as documentation.
+ */
+#if defined(MOZ_HAVE_CXX11_FINAL)
+#  define MOZ_FINAL             MOZ_HAVE_CXX11_FINAL
+#else
+#  define MOZ_FINAL             /* no support */
+#endif
+
 #endif  /* mozilla_Attributes_h_ */
--- a/xpcom/base/nsConsoleMessage.h
+++ b/xpcom/base/nsConsoleMessage.h
@@ -33,20 +33,22 @@
  * 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 __nsconsolemessage_h__
 #define __nsconsolemessage_h__
 
+#include "mozilla/Attributes.h"
+
 #include "nsIConsoleMessage.h"
 #include "nsString.h"
 
-class nsConsoleMessage : public nsIConsoleMessage {
+class nsConsoleMessage MOZ_FINAL : public nsIConsoleMessage {
 public:
     nsConsoleMessage();
     nsConsoleMessage(const PRUnichar *message);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSICONSOLEMESSAGE
 
 private:
--- a/xpcom/base/nsErrorService.h
+++ b/xpcom/base/nsErrorService.h
@@ -33,33 +33,35 @@
  * 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 nsErrorService_h__
 #define nsErrorService_h__
 
+#include "mozilla/Attributes.h"
+
 #include "nsIErrorService.h"
 #include "nsHashtable.h"
 
 class nsInt2StrHashtable
 {
 public:
     nsInt2StrHashtable();
 
     nsresult  Put(PRUint32 key, const char* aData);
     char*     Get(PRUint32 key);
     nsresult  Remove(PRUint32 key);
 
 protected:
     nsObjectHashtable mHashtable;
 };
 
-class nsErrorService : public nsIErrorService
+class nsErrorService MOZ_FINAL : public nsIErrorService
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIERRORSERVICE
 
     nsErrorService() {}
 
     static nsresult
--- a/xpcom/glue/GenericFactory.h
+++ b/xpcom/glue/GenericFactory.h
@@ -33,26 +33,28 @@
  * 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 mozilla_GenericFactory_h
 #define mozilla_GenericFactory_h
 
+#include "mozilla/Attributes.h"
+
 #include "mozilla/Module.h"
 
 namespace mozilla {
 
 /**
  * A generic factory which uses a constructor function to create instances.
  * This class is intended for use by the component manager and the generic
  * module.
  */
-class GenericFactory : public nsIFactory
+class GenericFactory MOZ_FINAL : public nsIFactory
 {
 public:
   typedef Module::ConstructorProcPtr ConstructorProcPtr;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFACTORY
 
   GenericFactory(ConstructorProcPtr ctor)
--- a/xpcom/glue/nsArrayEnumerator.cpp
+++ b/xpcom/glue/nsArrayEnumerator.cpp
@@ -31,25 +31,27 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 ***** */
 
+#include "mozilla/Attributes.h"
+
 #include "nsArrayEnumerator.h"
 
 #include "nsIArray.h"
 #include "nsISimpleEnumerator.h"
 
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 
-class nsSimpleArrayEnumerator : public nsISimpleEnumerator
+class nsSimpleArrayEnumerator MOZ_FINAL : public nsISimpleEnumerator
 {
 public:
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
     // nsISimpleEnumerator interface
     NS_DECL_NSISIMPLEENUMERATOR
 
@@ -121,17 +123,17 @@ NS_NewArrayEnumerator(nsISimpleEnumerato
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // enumerator implementation for nsCOMArray
 // creates a snapshot of the array in question
 // you MUST use NS_NewArrayEnumerator to create this, so that
 // allocation is done correctly
-class nsCOMArrayEnumerator : public nsISimpleEnumerator
+class nsCOMArrayEnumerator MOZ_FINAL : public nsISimpleEnumerator
 {
 public:
     // nsISupports interface
     NS_DECL_ISUPPORTS
 
     // nsISimpleEnumerator interface
     NS_DECL_NSISIMPLEENUMERATOR
 
--- a/xpcom/glue/nsCOMPtr.h
+++ b/xpcom/glue/nsCOMPtr.h
@@ -48,16 +48,17 @@
 
 
   nsCOMPtr
     better than a raw pointer
   for owning objects
                        -- scc
 */
 
+#include "mozilla/Attributes.h"
 
   // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
 #ifndef nsDebug_h___
 #include "nsDebug.h"
   // for |NS_PRECONDITION|
 #endif
 
 #ifndef nsISupportsUtils_h__
@@ -272,18 +273,17 @@ class nsCOMPtr_helper
   avoid adding specialized machinery in |nsCOMPtr|, But |do_QueryInterface|
   is called often enough that the codesize savings are big enough to
   warrant the specialcasing.
 */
 
 class
   NS_COM_GLUE
   NS_STACK_CLASS
-  NS_FINAL_CLASS
-nsQueryInterface
+nsQueryInterface MOZ_FINAL
   {
     public:
       explicit
       nsQueryInterface( nsISupports* aRawPtr )
           : mRawPtr(aRawPtr)
         {
           // nothing else to do here
         }
@@ -508,19 +508,17 @@ nsCOMPtr_base
           if ( oldPtr )
             NSCAP_RELEASE(this, oldPtr);
         }
   };
 
 // template <class T> class nsGetterAddRefs;
 
 template <class T>
-class
-  NS_FINAL_CLASS
-nsCOMPtr
+class nsCOMPtr MOZ_FINAL
 #ifdef NSCAP_FEATURE_USE_BASE
     : private nsCOMPtr_base
 #endif
   {
 
 #ifdef NSCAP_FEATURE_USE_BASE
   #define NSCAP_CTOR_BASE(x) nsCOMPtr_base(x)
 #else
--- a/xpcom/glue/nsEnumeratorUtils.cpp
+++ b/xpcom/glue/nsEnumeratorUtils.cpp
@@ -35,16 +35,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 ***** */
 
+#include "mozilla/Attributes.h"
+
 #include "nsEnumeratorUtils.h"
 
 #include "nsISimpleEnumerator.h"
 #include "nsIStringEnumerator.h"
 
 #include "nsCOMPtr.h"
 
 class EmptyEnumeratorImpl : public nsISimpleEnumerator,
@@ -119,17 +121,17 @@ nsresult
 NS_NewEmptyEnumerator(nsISimpleEnumerator** aResult)
 {
     *aResult = EmptyEnumeratorImpl::GetInstance();
     return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class nsSingletonEnumerator : public nsISimpleEnumerator
+class nsSingletonEnumerator MOZ_FINAL : public nsISimpleEnumerator
 {
 public:
     NS_DECL_ISUPPORTS
 
     // nsISimpleEnumerator methods
     NS_IMETHOD HasMoreElements(bool* aResult);
     NS_IMETHOD GetNext(nsISupports** aResult);
 
--- a/xpcom/glue/nsWeakReference.cpp
+++ b/xpcom/glue/nsWeakReference.cpp
@@ -35,20 +35,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 ***** */
 
 // nsWeakReference.cpp
 
+#include "mozilla/Attributes.h"
+
 #include "nsWeakReference.h"
 #include "nsCOMPtr.h"
 
-class nsWeakReference : public nsIWeakReference
+class nsWeakReference MOZ_FINAL : public nsIWeakReference
   {
     public:
     // nsISupports...
       NS_DECL_ISUPPORTS
 
     // nsIWeakReference...
       NS_DECL_NSIWEAKREFERENCE