Bug 1463287: Add QueryInterface helper macro for concrete class types. r=bz
authorKris Maglione <maglione.k@gmail.com>
Mon, 21 May 2018 16:33:18 -0700
changeset 419333 a1bf5dfd3c00c5e59a59272fb03d0d6684539b82
parent 419332 4f8b341fea03c37954f49dff6f6c1d91e8efafec
child 419334 bfdfd3388e9a17d65a81ddbdc4fc669ab2887b3a
push id34037
push userdluca@mozilla.com
push dateWed, 23 May 2018 09:51:55 +0000
treeherdermozilla-central@d36cd8bdbc5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1463287
milestone62.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 1463287: Add QueryInterface helper macro for concrete class types. r=bz Using concrete class types with static IIDs in QueryInterface methods is a pretty common pattern which isn't supported by any existing helper macros. That's lead to separate ad-hoc implementations, with varying degrees of dodginess, being scattered around the tree. This patch adds a helper macro with a canonical (and safe) implementation, and updates existing ad-hoc users to use it. MozReview-Commit-ID: HaTGF7MN5Cv
accessible/generic/Accessible.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/file/Blob.cpp
dom/svg/nsSVGFilters.cpp
editor/libeditor/CompositionTransaction.cpp
editor/libeditor/InsertTextTransaction.cpp
layout/xul/tree/nsTreeColumns.cpp
modules/libjar/nsJARURI.cpp
netwerk/base/nsProtocolProxyService.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParentListener.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
uriloader/base/nsDocLoader.cpp
xpcom/base/nsISupportsImpl.h
xpfe/appshell/nsXULWindow.cpp
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -93,19 +93,17 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(Accessibl
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Accessible)
   tmp->Shutdown();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Accessible)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent, mDoc)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Accessible)
-  if (aIID.Equals(NS_GET_IID(Accessible)))
-    foundInterface = this;
-  else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(Accessible)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, Accessible)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Accessible)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(Accessible, LastRelease())
 
 Accessible::Accessible(nsIContent* aContent, DocAccessible* aDoc) :
   mContent(aContent), mDoc(aDoc),
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -149,21 +149,17 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ns
                                       mChildMessageManager,
                                       mOpener,
                                       mParentSHistory)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFrameLoader)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFrameLoader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFrameLoader)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  if (aIID.Equals(NS_GET_IID(nsFrameLoader))) {
-      // We want to end up with a pointer that can then be reinterpret_cast
-      // from nsISupports* to nsFrameLoader* and end up with |this|.
-      foundInterface = reinterpret_cast<nsISupports*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsFrameLoader)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 nsFrameLoader::nsFrameLoader(Element* aOwner, nsPIDOMWindowOuter* aOpener,
                              bool aNetworkCreated, int32_t aJSPluginID)
   : mOwnerContent(aOwner)
   , mDetachedSubdocFrame(nullptr)
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -1329,25 +1329,19 @@ nsGlobalWindowInner::FreeInnerObjects()
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowInner)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
-  if (aIID.Equals(NS_GET_IID(nsPIDOMWindowInner))) {
-    foundInterface = static_cast<nsPIDOMWindowInner*>(this);
-  } else
-  if (aIID.Equals(NS_GET_IID(mozIDOMWindow))) {
-    foundInterface = static_cast<mozIDOMWindow*>(this);
-  } else
-  if (aIID.Equals(NS_GET_IID(nsIDOMChromeWindow)) && IsChromeWindow()) {
-    foundInterface = static_cast<nsIDOMChromeWindow*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowInner)
+  NS_INTERFACE_MAP_ENTRY(mozIDOMWindow)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMChromeWindow, IsChromeWindow())
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindowInner)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindowInner)
 
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1083,25 +1083,19 @@ nsGlobalWindowOuter::ClearControllers()
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindowOuter)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
-  if (aIID.Equals(NS_GET_IID(nsPIDOMWindowOuter))) {
-    foundInterface = static_cast<nsPIDOMWindowOuter*>(this);
-  } else
-  if (aIID.Equals(NS_GET_IID(mozIDOMWindowProxy))) {
-    foundInterface = static_cast<mozIDOMWindowProxy*>(this);
-  } else
-  if (aIID.Equals(NS_GET_IID(nsIDOMChromeWindow)) && IsChromeWindow()) {
-    foundInterface = static_cast<nsIDOMChromeWindow*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY(nsPIDOMWindowOuter)
+  NS_INTERFACE_MAP_ENTRY(mozIDOMWindowProxy)
+  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMChromeWindow, IsChromeWindow())
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGlobalWindowOuter)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGlobalWindowOuter)
 
--- a/dom/file/Blob.cpp
+++ b/dom/file/Blob.cpp
@@ -30,21 +30,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Blob)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Blob)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMutable)
-  // Alas, there is no helper macro for this.
-  if (aIID.Equals(NS_GET_IID(Blob))) {
-    *aInstancePtr = do_AddRef(this).take();
-    return NS_OK;
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(Blob)
   NS_INTERFACE_MAP_ENTRY(nsIMutable)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(Blob)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(Blob)
 
 void
--- a/dom/svg/nsSVGFilters.cpp
+++ b/dom/svg/nsSVGFilters.cpp
@@ -61,21 +61,17 @@ nsSVGElement::LengthInfo nsSVGFE::sLengt
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(nsSVGFE,nsSVGFEBase)
 NS_IMPL_RELEASE_INHERITED(nsSVGFE,nsSVGFEBase)
 
 NS_INTERFACE_MAP_BEGIN(nsSVGFE)
-   // nsISupports is an ambiguous base of nsSVGFE so we have to work
-   // around that
-   if ( aIID.Equals(NS_GET_IID(nsSVGFE)) )
-     foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-   else
+   NS_INTERFACE_MAP_ENTRY_CONCRETE(nsSVGFE)
 NS_INTERFACE_MAP_END_INHERITING(nsSVGFEBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
 void
 nsSVGFE::GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources)
 {
@@ -240,21 +236,17 @@ nsSVGElement::EnumInfo SVGComponentTrans
 
 //----------------------------------------------------------------------
 // nsISupports methods
 
 NS_IMPL_ADDREF_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
 NS_IMPL_RELEASE_INHERITED(SVGComponentTransferFunctionElement,SVGComponentTransferFunctionElementBase)
 
 NS_INTERFACE_MAP_BEGIN(SVGComponentTransferFunctionElement)
-   // nsISupports is an ambiguous base of nsSVGFE so we have to work
-   // around that
-   if ( aIID.Equals(NS_GET_IID(SVGComponentTransferFunctionElement)) )
-     foundInterface = static_cast<nsISupports*>(static_cast<void*>(this));
-   else
+   NS_INTERFACE_MAP_ENTRY_CONCRETE(SVGComponentTransferFunctionElement)
 NS_INTERFACE_MAP_END_INHERITING(SVGComponentTransferFunctionElementBase)
 
 
 //----------------------------------------------------------------------
 // nsFEUnstyledElement methods
 
 bool
 SVGComponentTransferFunctionElement::AttributeAffectsRendering(int32_t aNameSpaceID,
--- a/editor/libeditor/CompositionTransaction.cpp
+++ b/editor/libeditor/CompositionTransaction.cpp
@@ -77,19 +77,17 @@ CompositionTransaction::~CompositionTran
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(CompositionTransaction, EditTransactionBase,
                                    mEditorBase,
                                    mTextNode)
 // mRangeList can't lead to cycles
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositionTransaction)
-  if (aIID.Equals(NS_GET_IID(CompositionTransaction))) {
-    foundInterface = static_cast<nsITransaction*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(CompositionTransaction)
 NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
 
 NS_IMPL_ADDREF_INHERITED(CompositionTransaction, EditTransactionBase)
 NS_IMPL_RELEASE_INHERITED(CompositionTransaction, EditTransactionBase)
 
 NS_IMETHODIMP
 CompositionTransaction::DoTransaction()
 {
--- a/editor/libeditor/InsertTextTransaction.cpp
+++ b/editor/libeditor/InsertTextTransaction.cpp
@@ -47,19 +47,17 @@ InsertTextTransaction::~InsertTextTransa
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertTextTransaction, EditTransactionBase,
                                    mEditorBase,
                                    mTextNode)
 
 NS_IMPL_ADDREF_INHERITED(InsertTextTransaction, EditTransactionBase)
 NS_IMPL_RELEASE_INHERITED(InsertTextTransaction, EditTransactionBase)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertTextTransaction)
-  if (aIID.Equals(NS_GET_IID(InsertTextTransaction))) {
-    foundInterface = static_cast<nsITransaction*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(InsertTextTransaction)
 NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
 
 
 NS_IMETHODIMP
 InsertTextTransaction::DoTransaction()
 {
   if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
     return NS_ERROR_NOT_AVAILABLE;
--- a/layout/xul/tree/nsTreeColumns.cpp
+++ b/layout/xul/tree/nsTreeColumns.cpp
@@ -59,22 +59,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCA
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeColumn)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeColumn)
 
 // QueryInterface implementation for nsTreeColumn
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeColumn)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsITreeColumn)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
-  if (aIID.Equals(NS_GET_IID(nsTreeColumn))) {
-    AddRef();
-    *aInstancePtr = this;
-    return NS_OK;
-  }
-  else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsTreeColumn)
 NS_INTERFACE_MAP_END
 
 nsIFrame*
 nsTreeColumn::GetFrame()
 {
   NS_ENSURE_TRUE(mContent, nullptr);
 
   return mContent->GetPrimaryFrame();
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -14,16 +14,17 @@
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsIZipReader.h"
 #include "nsReadableUtils.h"
 #include "nsAutoPtr.h"
 #include "nsNetCID.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
+#include "nsQueryObject.h"
 #include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla::ipc;
 
 static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -42,20 +43,17 @@ NS_INTERFACE_MAP_BEGIN(nsJARURI)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI)
   NS_INTERFACE_MAP_ENTRY(nsIURI)
   NS_INTERFACE_MAP_ENTRY(nsIURL)
   NS_INTERFACE_MAP_ENTRY(nsIJARURI)
   NS_INTERFACE_MAP_ENTRY(nsISerializable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY(nsINestedURI)
   NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
-  // see nsJARURI::Equals
-  if (aIID.Equals(NS_GET_IID(nsJARURI)))
-      foundInterface = reinterpret_cast<nsISupports*>(this);
-  else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsJARURI)
 NS_INTERFACE_MAP_END
 
 nsresult
 nsJARURI::Init(const char *charsetHint)
 {
     mCharsetHint = charsetHint;
     return NS_OK;
 }
@@ -332,18 +330,17 @@ nsJARURI::SetSpecWithBase(const nsACStri
 
     nsAutoCString scheme;
     rv = ioServ->ExtractScheme(aSpec, scheme);
     if (NS_FAILED(rv)) {
         // not an absolute URI
         if (!aBaseURL)
             return NS_ERROR_MALFORMED_URI;
 
-        RefPtr<nsJARURI> otherJAR;
-        aBaseURL->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
+        RefPtr<nsJARURI> otherJAR = do_QueryObject(aBaseURL);
         NS_ENSURE_TRUE(otherJAR, NS_NOINTERFACE);
 
         mJARFile = otherJAR->mJARFile;
 
         nsCOMPtr<nsIURI> entry;
 
         rv = NS_MutateURI(NS_STANDARDURLMUTATOR_CONTRACTID)
                .Apply(NS_MutatorMethod(&nsIStandardURLMutator::Init,
@@ -559,18 +556,17 @@ nsJARURI::EqualsInternal(nsIURI *other,
                          nsJARURI::RefHandlingEnum refHandlingMode,
                          bool *result)
 {
     *result = false;
 
     if (!other)
         return NS_OK;	// not equal
 
-    RefPtr<nsJARURI> otherJAR;
-    other->QueryInterface(NS_GET_IID(nsJARURI), getter_AddRefs(otherJAR));
+    RefPtr<nsJARURI> otherJAR = do_QueryObject(other);
     if (!otherJAR)
         return NS_OK;   // not equal
 
     bool equal;
     nsresult rv = mJARFile->Equals(otherJAR->mJARFile, &equal);
     if (NS_FAILED(rv) || !equal) {
         return rv;   // not equal
     }
--- a/netwerk/base/nsProtocolProxyService.cpp
+++ b/netwerk/base/nsProtocolProxyService.cpp
@@ -797,17 +797,17 @@ NS_IMPL_RELEASE(nsProtocolProxyService)
 NS_IMPL_CLASSINFO(nsProtocolProxyService, nullptr, nsIClassInfo::SINGLETON,
                   NS_PROTOCOLPROXYSERVICE_CID)
 
 // NS_IMPL_QUERY_INTERFACE_CI with the nsProtocolProxyService QI change
 NS_INTERFACE_MAP_BEGIN(nsProtocolProxyService)
 NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyService)
 NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyService2)
 NS_INTERFACE_MAP_ENTRY(nsIObserver)
-if ( aIID.Equals(NS_GET_IID(nsProtocolProxyService)) )  foundInterface = static_cast<nsIProtocolProxyService2*>(this); else
+NS_INTERFACE_MAP_ENTRY_CONCRETE(nsProtocolProxyService)
 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIProtocolProxyService)
 NS_IMPL_QUERY_CLASSINFO(nsProtocolProxyService)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CI_INTERFACE_GETTER(nsProtocolProxyService,
                             nsIProtocolProxyService,
                             nsIProtocolProxyService2)
 
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -400,19 +400,17 @@ NS_INTERFACE_MAP_BEGIN(HttpBaseChannel)
   NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)
   NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
   NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
   NS_INTERFACE_MAP_ENTRY(nsIPrivateBrowsingChannel)
   NS_INTERFACE_MAP_ENTRY(nsITimedChannel)
   NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector)
   NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel)
   NS_INTERFACE_MAP_ENTRY(nsIClassifiedChannel)
-  if (aIID.Equals(NS_GET_IID(HttpBaseChannel))) {
-    foundInterface = static_cast<nsIWritablePropertyBag*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpBaseChannel)
 NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpBaseChannel::GetName(nsACString& aName)
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -288,19 +288,17 @@ NS_INTERFACE_MAP_BEGIN(HttpChannelParent
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
   NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
   NS_INTERFACE_MAP_ENTRY(nsIParentRedirectingChannel)
   NS_INTERFACE_MAP_ENTRY(nsIDeprecationWarner)
   NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectReadyCallback)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParentRedirectingChannel)
-  if (aIID.Equals(NS_GET_IID(HttpChannelParent))) {
-    foundInterface = static_cast<nsIInterfaceRequestor*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelParent)
 NS_INTERFACE_MAP_END
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelParent::GetInterface(const nsIID& aIID, void **result)
--- a/netwerk/protocol/http/HttpChannelParentListener.cpp
+++ b/netwerk/protocol/http/HttpChannelParentListener.cpp
@@ -52,19 +52,17 @@ NS_IMPL_RELEASE(HttpChannelParentListene
 NS_INTERFACE_MAP_BEGIN(HttpChannelParentListener)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
   NS_INTERFACE_MAP_ENTRY(nsIRedirectResultListener)
   NS_INTERFACE_MAP_ENTRY(nsINetworkInterceptController)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInterfaceRequestor)
-  if (aIID.Equals(NS_GET_IID(HttpChannelParentListener))) {
-    foundInterface = static_cast<nsIInterfaceRequestor*>(this);
-  } else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpChannelParentListener)
 NS_INTERFACE_MAP_END
 
 //-----------------------------------------------------------------------------
 // HttpChannelParentListener::nsIRequestObserver
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpChannelParentListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -5847,22 +5847,17 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
     NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
     NS_INTERFACE_MAP_ENTRY(nsIDNSListener)
     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback)
     NS_INTERFACE_MAP_ENTRY(nsIRaceCacheWithNetwork)
     NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
     NS_INTERFACE_MAP_ENTRY(nsIChannelWithDivertableParentListener)
     NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)
-    // we have no macro that covers this case.
-    if (aIID.Equals(NS_GET_IID(nsHttpChannel)) ) {
-        AddRef();
-        *aInstancePtr = this;
-        return NS_OK;
-    } else
+    NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)
 NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::Cancel(nsresult status)
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -2299,22 +2299,17 @@ NS_IMPL_ADDREF(nsHttpConnection)
 NS_IMPL_RELEASE(nsHttpConnection)
 
 NS_INTERFACE_MAP_BEGIN(nsHttpConnection)
     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
     NS_INTERFACE_MAP_ENTRY(nsIOutputStreamCallback)
     NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
-    // we have no macro that covers this case.
-    if (aIID.Equals(NS_GET_IID(nsHttpConnection)) ) {
-        AddRef();
-        *aInstancePtr = this;
-        return NS_OK;
-    } else
+    NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpConnection)
 NS_INTERFACE_MAP_END
 
 //-----------------------------------------------------------------------------
 // nsHttpConnection::nsIInputStreamCallback
 //-----------------------------------------------------------------------------
 
 // called on the socket transport thread
 NS_IMETHODIMP
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -33,18 +33,16 @@
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 
 using mozilla::DebugOnly;
 using mozilla::LogLevel;
 
-static NS_DEFINE_CID(kThisImplCID, NS_THIS_DOCLOADER_IMPL_CID);
-
 //
 // Log module for nsIDocumentLoader logging...
 //
 // To enable logging (see mozilla/Logging.h for full details):
 //
 //    set MOZ_LOG=DocLoader:5
 //    set MOZ_LOG_FILE=debug.log
 //
@@ -175,19 +173,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
    NS_INTERFACE_MAP_ENTRY(nsIDocumentLoader)
    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    NS_INTERFACE_MAP_ENTRY(nsIWebProgress)
    NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
    NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
    NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
    NS_INTERFACE_MAP_ENTRY(nsISecurityEventSink)
    NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
-   if (aIID.Equals(kThisImplCID))
-     foundInterface = static_cast<nsIDocumentLoader *>(this);
-   else
+   NS_INTERFACE_MAP_ENTRY_CONCRETE(nsDocLoader)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION(nsDocLoader, mChildrenInOnload)
 
 
 /*
  * Implementation of nsIInterfaceRequestor methods...
  */
--- a/xpcom/base/nsISupportsImpl.h
+++ b/xpcom/base/nsISupportsImpl.h
@@ -996,16 +996,24 @@ NS_IMETHODIMP _class::QueryInterface(REF
   else
 
 #define NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass)                  \
   if ( aIID.Equals(NS_GET_IID(_interface)) )                                  \
     foundInterface = static_cast<_interface*>(                                \
                                     static_cast<_implClass*>(this));          \
   else
 
+// Use this for querying to concrete class types which cannot be unambiguously
+// cast to nsISupports. See also nsQueryObject.h.
+#define NS_IMPL_QUERY_BODY_CONCRETE(_class)                                   \
+  if (aIID.Equals(NS_GET_IID(_class))) {                                      \
+    *aInstancePtr = do_AddRef(static_cast<_class*>(this)).take();             \
+    return NS_OK;                                                             \
+  } else
+
 #define NS_IMPL_QUERY_BODY_AGGREGATED(_interface, _aggregate)                 \
   if ( aIID.Equals(NS_GET_IID(_interface)) )                                  \
     foundInterface = static_cast<_interface*>(_aggregate);                    \
   else
 
 #define NS_IMPL_QUERY_TAIL_GUTS                                               \
     foundInterface = 0;                                                       \
   nsresult status;                                                            \
@@ -1069,16 +1077,18 @@ NS_IMETHODIMP _class::QueryInterface(REF
 #define NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface, condition)             \
   NS_IMPL_QUERY_BODY_CONDITIONAL(_interface, condition)
 #define NS_INTERFACE_MAP_ENTRY_AGGREGATED(_interface,_aggregate)              \
   NS_IMPL_QUERY_BODY_AGGREGATED(_interface,_aggregate)
 
 #define NS_INTERFACE_MAP_END                    NS_IMPL_QUERY_TAIL_GUTS
 #define NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(_interface, _implClass)              \
   NS_IMPL_QUERY_BODY_AMBIGUOUS(_interface, _implClass)
+#define NS_INTERFACE_MAP_ENTRY_CONCRETE(_class)                               \
+  NS_IMPL_QUERY_BODY_CONCRETE(_class)
 #define NS_INTERFACE_MAP_END_INHERITING(_baseClass)                           \
   NS_IMPL_QUERY_TAIL_INHERITING(_baseClass)
 #define NS_INTERFACE_MAP_END_AGGREGATED(_aggregator)                          \
   NS_IMPL_QUERY_TAIL_USING_AGGREGATOR(_aggregator)
 
 #define NS_INTERFACE_TABLE0(_class)                                           \
   NS_INTERFACE_TABLE_BEGIN                                                    \
     NS_INTERFACE_TABLE_ENTRY(_class, nsISupports)                             \
--- a/xpfe/appshell/nsXULWindow.cpp
+++ b/xpfe/appshell/nsXULWindow.cpp
@@ -124,19 +124,17 @@ NS_IMPL_ADDREF(nsXULWindow)
 NS_IMPL_RELEASE(nsXULWindow)
 
 NS_INTERFACE_MAP_BEGIN(nsXULWindow)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULWindow)
   NS_INTERFACE_MAP_ENTRY(nsIXULWindow)
   NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
-  if (aIID.Equals(NS_GET_IID(nsXULWindow)))
-    foundInterface = reinterpret_cast<nsISupports*>(this);
-  else
+  NS_INTERFACE_MAP_ENTRY_CONCRETE(nsXULWindow)
 NS_INTERFACE_MAP_END
 
 //*****************************************************************************
 // nsXULWindow::nsIIntefaceRequestor
 //*****************************************************************************
 
 NS_IMETHODIMP nsXULWindow::GetInterface(const nsIID& aIID, void** aSink)
 {