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 #ifndef HAVE_CXX0X
37 #define BOOST_NO_0X_HDR_TYPEINDEX
38 #endif
39 #include "boost/unordered_set.hpp"
40 #include "osl/diagnose.h"
41 #include "osl/interlck.h"
42 #include "osl/mutex.hxx"
43 #include "rtl/allocator.hxx"
44 #include "rtl/instance.hxx"
45 #include "sal/log.hxx"
46 #include "sal/types.h"
47 
49 
50 namespace osl {
51 namespace detail {
52 
53 struct ObjectRegistryData;
54 
55 } // namespace detail
56 } // namespace osl
57 
58 extern "C" {
59 
60 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
61  char const* pName )
63 
64 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
65  ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
67 
68 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
69  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
71 
72 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
73  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
75 
76 // These functions presumably should not be extern "C", but changing
77 // that would break binary compatibility.
78 #if SUPD < 400
79 #ifdef __clang__
80 #pragma clang diagnostic push
81 // Guard against slightly older clang versions that don't have
82 // -Wreturn-type-c-linkage...
83 #pragma clang diagnostic ignored "-Wunknown-pragmas"
84 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
85 #endif
86 #endif
87 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
89 #if SUPD < 400
90 #ifdef __clang__
91 #pragma clang diagnostic pop
92 #endif
93 #endif
94 
95 } // extern "C"
96 
97 namespace osl {
98 
99 namespace detail {
100 
101 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
102  ::std::size_t operator()( void const* p ) const {
103  ::std::size_t const d = static_cast< ::std::size_t >(
104  reinterpret_cast< ::std::ptrdiff_t >(p) );
105  return d + (d >> 3);
106  }
107 };
108 
109 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
110  ::rtl::Allocator<void const*> > VoidPointerSet;
111 
112 struct ObjectRegistryData {
113  ObjectRegistryData( ::std::type_info const& rTypeInfo )
114  : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
115  m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
116 
117  char const* const m_pName;
118  oslInterlockedCount m_nCount;
119  VoidPointerSet m_addresses;
120  bool const m_bStoreAddresses;
121 };
122 
123 template <typename T>
124 class ObjectRegistry
125 {
126 public:
127  ObjectRegistry() : m_data( typeid(T) ) {}
128  ~ObjectRegistry() { checkObjectCount(0); }
129 
130  bool checkObjectCount( ::std::size_t nExpected ) const {
131  bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
132  m_data, nExpected );
133  if (!bRet && m_data.m_bStoreAddresses) {
134  MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
135  // following loop is for debugging purposes, iterating over map:
136  VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
137  VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
138  for ( ; iPos != iEnd; ++iPos ) {
139  SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
140  }
141  }
142  return bRet;
143  }
144 
145  void registerObject( void const* pObj ) {
146  osl_detail_ObjectRegistry_registerObject(m_data, pObj);
147  }
148 
149  void revokeObject( void const* pObj ) {
150  osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
151  }
152 
153 private:
154  // not impl:
155  ObjectRegistry( ObjectRegistry const& );
156  ObjectRegistry const& operator=( ObjectRegistry const& );
157 
158  ObjectRegistryData m_data;
159 };
160 
161 } // namespace detail
162 
184 template <typename InheritingClassT>
185 class DebugBase
186 {
187 public:
188 #if OSL_DEBUG_LEVEL <= 0
189  static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
190 #else // OSL_DEBUG_LEVEL > 0
191 
194  static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
195  return StaticObjectRegistry::get().checkObjectCount(nExpected);
196  }
197 
198 protected:
199  DebugBase() {
200  StaticObjectRegistry::get().registerObject( this );
201  }
202  ~DebugBase() {
203  StaticObjectRegistry::get().revokeObject( this );
204  }
205 
206 private:
207  struct StaticObjectRegistry
208  : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
209  StaticObjectRegistry> {};
210 #endif
211 };
212 
213 } // namespace osl
214 
216 
217 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
218 
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */