DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (71042f6bc4f6)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. *
 */

#ifndef mozilla_a11y_IUnknownImpl_h_
#define mozilla_a11y_IUnknownImpl_h_

#include <windows.h>
#undef CreateEvent  // thank you windows you're such a helper
#include "nsError.h"

// Avoid warning C4509 like "nonstandard extension used:
// 'AccessibleWrap::[acc_getName]' uses SEH and 'name' has destructor.
// At this point we're catching a crash which is of much greater
// importance than the missing dereference for the nsCOMPtr<>
#ifdef _MSC_VER
#  pragma warning(disable : 4509)
#endif

#if defined(__GNUC__) || defined(__clang__)
#  define ATTRIBUTE_UNUSED __attribute__((unused))
#else
#  define ATTRIBUTE_UNUSED
#endif

namespace mozilla {
namespace a11y {

class AutoRefCnt {
 public:
  AutoRefCnt() : mValue(0) {}

  ULONG operator++() { return ++mValue; }
  ULONG operator--() { return --mValue; }
  ULONG operator++(int) { return ++mValue; }
  ULONG operator--(int) { return --mValue; }

  operator ULONG() const { return mValue; }

 private:
  ULONG mValue;
};

}  // namespace a11y
}  // namespace mozilla

#define DECL_IUNKNOWN                                               \
 public:                                                            \
  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**); \
  ULONG STDMETHODCALLTYPE AddRef() final {                          \
    MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");            \
    ++mRefCnt;                                                      \
    return mRefCnt;                                                 \
  }                                                                 \
  ULONG STDMETHODCALLTYPE Release() final {                         \
    MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");                \
    --mRefCnt;                                                      \
    if (mRefCnt) return mRefCnt;                                    \
                                                                    \
    delete this;                                                    \
    return 0;                                                       \
  }                                                                 \
                                                                    \
 private:                                                           \
  mozilla::a11y::AutoRefCnt mRefCnt;                                \
                                                                    \
 public:

#define DECL_IUNKNOWN_INHERITED \
 public:                        \
  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**);

#define IMPL_IUNKNOWN_QUERY_HEAD(Class)                     \
  STDMETHODIMP                                              \
  Class::QueryInterface(REFIID aIID, void** aInstancePtr) { \
    if (!aInstancePtr) return E_INVALIDARG;                 \
    *aInstancePtr = nullptr;                                \
                                                            \
    HRESULT hr ATTRIBUTE_UNUSED = E_NOINTERFACE;

#define IMPL_IUNKNOWN_QUERY_TAIL \
  return hr;                     \
  }

#define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member)  \
  return Member->QueryInterface(aIID, aInstancePtr); \
  }

#define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass)   \
  return BaseClass::QueryInterface(aIID, aInstancePtr); \
  }

#define IMPL_IUNKNOWN_QUERY_IFACE(Iface)       \
  if (aIID == IID_##Iface) {                   \
    *aInstancePtr = static_cast<Iface*>(this); \
    AddRef();                                  \
    return S_OK;                               \
  }

#define IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(Iface, aResolveIface)           \
  if (aIID == IID_##Iface) {                                                \
    *aInstancePtr = static_cast<Iface*>(static_cast<aResolveIface*>(this)); \
    AddRef();                                                               \
    return S_OK;                                                            \
  }

#define IMPL_IUNKNOWN_QUERY_CLASS(Class)          \
  hr = Class::QueryInterface(aIID, aInstancePtr); \
  if (SUCCEEDED(hr)) return hr;

#define IMPL_IUNKNOWN_QUERY_CLASS_COND(Class, Cond) \
  if (Cond) {                                       \
    hr = Class::QueryInterface(aIID, aInstancePtr); \
    if (SUCCEEDED(hr)) return hr;                   \
  }

#define IMPL_IUNKNOWN_QUERY_AGGR_COND(Member, Cond)  \
  if (Cond) {                                        \
    hr = Member->QueryInterface(aIID, aInstancePtr); \
    if (SUCCEEDED(hr)) return hr;                    \
  }

#define IMPL_IUNKNOWN1(Class, I1)      \
  IMPL_IUNKNOWN_QUERY_HEAD(Class)      \
  IMPL_IUNKNOWN_QUERY_IFACE(I1);       \
  IMPL_IUNKNOWN_QUERY_IFACE(IUnknown); \
  IMPL_IUNKNOWN_QUERY_TAIL

#define IMPL_IUNKNOWN2(Class, I1, I2)                \
  IMPL_IUNKNOWN_QUERY_HEAD(Class)                    \
  IMPL_IUNKNOWN_QUERY_IFACE(I1);                     \
  IMPL_IUNKNOWN_QUERY_IFACE(I2);                     \
  IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(IUnknown, I1); \
  IMPL_IUNKNOWN_QUERY_TAIL

#define IMPL_IUNKNOWN_INHERITED1(Class, Super0, Super1) \
  IMPL_IUNKNOWN_QUERY_HEAD(Class)                       \
  IMPL_IUNKNOWN_QUERY_CLASS(Super1);                    \
  IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)

#define IMPL_IUNKNOWN_INHERITED2(Class, Super0, Super1, Super2) \
  IMPL_IUNKNOWN_QUERY_HEAD(Class)                               \
  IMPL_IUNKNOWN_QUERY_CLASS(Super1);                            \
  IMPL_IUNKNOWN_QUERY_CLASS(Super2);                            \
  IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)

namespace mozilla {
namespace a11y {

/**
 * Converts nsresult to HRESULT.
 */
HRESULT GetHRESULT(nsresult aResult);

}  // namespace a11y
}  // namespace mozilla

#endif