My Project
UDK 3.2.7 C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
diagnose.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org. If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 #ifndef OSL_DIAGNOSE_HXX_INCLUDED
29 #define OSL_DIAGNOSE_HXX_INCLUDED
30 
31 #include "sal/config.h"
32 
33 #include <functional>
34 #include <typeinfo>
35 
36 #include "boost/unordered_set.hpp"
37 #include "osl/diagnose.h"
38 #include "osl/interlck.h"
39 #include "osl/mutex.hxx"
40 #include "rtl/allocator.hxx"
41 #include "rtl/instance.hxx"
42 #include "sal/log.hxx"
43 #include "sal/types.h"
44 
46 
47 namespace osl {
48 namespace detail {
49 
50 struct ObjectRegistryData;
51 
52 } // namespace detail
53 } // namespace osl
54 
55 extern "C" {
56 
57 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
58  char const* pName )
60 
61 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
62  ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
64 
65 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
66  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
68 
69 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
70  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
72 
73 // These functions presumably should not be extern "C", but changing
74 // that would break binary compatibility.
75 #if SUPD < 400
76 #ifdef __clang__
77 #pragma clang diagnostic push
78 // Guard against slightly older clang versions that don't have
79 // -Wreturn-type-c-linkage...
80 #pragma clang diagnostic ignored "-Wunknown-pragmas"
81 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
82 #endif
83 #endif
84 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
86 #if SUPD < 400
87 #ifdef __clang__
88 #pragma clang diagnostic pop
89 #endif
90 #endif
91 
92 } // extern "C"
93 
94 namespace osl {
95 
96 namespace detail {
97 
98 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
99  ::std::size_t operator()( void const* p ) const {
100  ::std::size_t const d = static_cast< ::std::size_t >(
101  reinterpret_cast< ::std::ptrdiff_t >(p) );
102  return d + (d >> 3);
103  }
104 };
105 
106 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
107  ::rtl::Allocator<void const*> > VoidPointerSet;
108 
109 struct ObjectRegistryData {
110  ObjectRegistryData( ::std::type_info const& rTypeInfo )
111  : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
112  m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
113 
114  char const* const m_pName;
115  oslInterlockedCount m_nCount;
116  VoidPointerSet m_addresses;
117  bool const m_bStoreAddresses;
118 };
119 
120 template <typename T>
121 class ObjectRegistry
122 {
123 public:
124  ObjectRegistry() : m_data( typeid(T) ) {}
125  ~ObjectRegistry() { checkObjectCount(0); }
126 
127  bool checkObjectCount( ::std::size_t nExpected ) const {
128  bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
129  m_data, nExpected );
130  if (!bRet && m_data.m_bStoreAddresses) {
131  MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
132  // following loop is for debugging purposes, iterating over map:
133  VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
134  VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
135  for ( ; iPos != iEnd; ++iPos ) {
136  SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
137  }
138  }
139  return bRet;
140  }
141 
142  void registerObject( void const* pObj ) {
143  osl_detail_ObjectRegistry_registerObject(m_data, pObj);
144  }
145 
146  void revokeObject( void const* pObj ) {
147  osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
148  }
149 
150 private:
151  // not impl:
152  ObjectRegistry( ObjectRegistry const& );
153  ObjectRegistry const& operator=( ObjectRegistry const& );
154 
155  ObjectRegistryData m_data;
156 };
157 
158 } // namespace detail
159 
181 template <typename InheritingClassT>
182 class DebugBase
183 {
184 public:
185 #if OSL_DEBUG_LEVEL <= 0
186  static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
187 #else // OSL_DEBUG_LEVEL > 0
188 
191  static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
192  return StaticObjectRegistry::get().checkObjectCount(nExpected);
193  }
194 
195 protected:
196  DebugBase() {
197  StaticObjectRegistry::get().registerObject( this );
198  }
199  ~DebugBase() {
200  StaticObjectRegistry::get().revokeObject( this );
201  }
202 
203 private:
204  struct StaticObjectRegistry
205  : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
206  StaticObjectRegistry> {};
207 #endif
208 };
209 
210 } // namespace osl
211 
213 
214 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
215 
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */