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  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #ifndef OSL_DIAGNOSE_HXX_INCLUDED
20 #define OSL_DIAGNOSE_HXX_INCLUDED
21 
22 #include "sal/config.h"
23 
24 #include <functional>
25 #include <typeinfo>
26 
27 #ifndef HAVE_CXX0X
28 #define BOOST_NO_0X_HDR_TYPEINDEX
29 #endif
30 #include "boost/unordered_set.hpp"
31 #include "osl/diagnose.h"
32 #include "osl/interlck.h"
33 #include "osl/mutex.hxx"
34 #include "rtl/allocator.hxx"
35 #include "rtl/instance.hxx"
36 #include "sal/log.hxx"
37 #include "sal/saldllapi.h"
38 #include "sal/types.h"
39 
41 
42 namespace osl {
43 namespace detail {
44 
45 struct ObjectRegistryData;
46 
47 } // namespace detail
48 } // namespace osl
49 
50 extern "C" {
51 
52 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses(
53  char const* pName )
55 
56 SAL_DLLPUBLIC bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
57  ::osl::detail::ObjectRegistryData const& rData, ::std::size_t nExpected )
59 
60 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_registerObject(
61  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
63 
64 SAL_DLLPUBLIC void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
65  ::osl::detail::ObjectRegistryData & rData, void const* pObj )
67 
68 // These functions presumably should not be extern "C", but changing
69 // that would break binary compatibility.
70 #ifdef __clang__
71 #pragma clang diagnostic push
72 // Guard against slightly older clang versions that don't have
73 // -Wreturn-type-c-linkage...
74 #pragma clang diagnostic ignored "-Wunknown-pragmas"
75 #pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
76 #endif
77 
78 SAL_DLLPUBLIC ::osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
80 
81 #ifdef __clang__
82 #pragma clang diagnostic pop
83 #endif
84 
85 } // extern "C"
86 
87 namespace osl {
88 
89 namespace detail {
90 
91 struct VoidPtrHash : ::std::unary_function<void const*, ::std::size_t> {
92  ::std::size_t operator()( void const* p ) const {
93  ::std::size_t const d = static_cast< ::std::size_t >(
94  reinterpret_cast< ::std::ptrdiff_t >(p) );
95  return d + (d >> 3);
96  }
97 };
98 
99 typedef ::boost::unordered_set<void const*, VoidPtrHash, ::std::equal_to<void const*>,
100  ::rtl::Allocator<void const*> > VoidPointerSet;
101 
102 struct ObjectRegistryData {
103  ObjectRegistryData( ::std::type_info const& rTypeInfo )
104  : m_pName(rTypeInfo.name()), m_nCount(0), m_addresses(),
105  m_bStoreAddresses(osl_detail_ObjectRegistry_storeAddresses(m_pName)){}
106 
107  char const* const m_pName;
108  oslInterlockedCount m_nCount;
109  VoidPointerSet m_addresses;
110  bool const m_bStoreAddresses;
111 };
112 
113 template <typename T>
114 class ObjectRegistry
115 {
116 public:
117  ObjectRegistry() : m_data( typeid(T) ) {}
118  ~ObjectRegistry() { checkObjectCount(0); }
119 
120  bool checkObjectCount( ::std::size_t nExpected ) const {
121  bool const bRet = osl_detail_ObjectRegistry_checkObjectCount(
122  m_data, nExpected );
123  if (!bRet && m_data.m_bStoreAddresses) {
124  MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
125  // following loop is for debugging purposes, iterating over map:
126  VoidPointerSet::const_iterator iPos(m_data.m_addresses.begin());
127  VoidPointerSet::const_iterator const iEnd(m_data.m_addresses.end());
128  for ( ; iPos != iEnd; ++iPos ) {
129  SAL_WARN_IF( *iPos == 0, "sal.debug", "null pointer" );
130  }
131  }
132  return bRet;
133  }
134 
135  void registerObject( void const* pObj ) {
136  osl_detail_ObjectRegistry_registerObject(m_data, pObj);
137  }
138 
139  void revokeObject( void const* pObj ) {
140  osl_detail_ObjectRegistry_revokeObject(m_data, pObj);
141  }
142 
143 private:
144  // not impl:
145  ObjectRegistry( ObjectRegistry const& );
146  ObjectRegistry const& operator=( ObjectRegistry const& );
147 
148  ObjectRegistryData m_data;
149 };
150 
151 } // namespace detail
152 
174 template <typename InheritingClassT>
175 class DebugBase
176 {
177 public:
178 #if OSL_DEBUG_LEVEL <= 0
179  static bool checkObjectCount( ::std::size_t = 0 ) { return true; }
180 #else // OSL_DEBUG_LEVEL > 0
181 
184  static bool checkObjectCount( ::std::size_t nExpected = 0 ) {
185  return StaticObjectRegistry::get().checkObjectCount(nExpected);
186  }
187 
188 protected:
189  DebugBase() {
190  StaticObjectRegistry::get().registerObject( this );
191  }
192  ~DebugBase() {
193  StaticObjectRegistry::get().revokeObject( this );
194  }
195 
196 private:
197  struct StaticObjectRegistry
198  : ::rtl::Static<detail::ObjectRegistry<InheritingClassT>,
199  StaticObjectRegistry> {};
200 #endif
201 };
202 
203 } // namespace osl
204 
206 
207 #endif // ! defined(OSL_DIAGNOSE_HXX_INCLUDED)
208 
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */