00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #ifndef LIBCWD_CLASS_FUNCTION_H
00019 #define LIBCWD_CLASS_FUNCTION_H
00020
00021 #ifndef LIBCW_MAP
00022 #define LIBCW_MAP
00023 #include <map>
00024 #endif
00025
00026 namespace libcwd {
00027
00028 namespace _private_ {
00029
00030
00031
00032
00033
00034
00035
00036
00037 struct FunctionChunkKey {
00038 void const* M_start;
00039 void const* M_end;
00040 };
00041
00042
00043
00044
00045 class FunctionInstance;
00046 typedef std::pair<FunctionChunkKey const, FunctionInstance*> FunctionChunk;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 inline bool
00067 operator<(FunctionChunkKey const& chunk1, FunctionChunkKey const& chunk2)
00068 {
00069
00070 return chunk1.M_end <= chunk2.M_start;
00071 }
00072
00073
00074
00075
00076 struct FunctionRootInstanceKey {
00077 char const* M_mangled_name;
00078
00079
00080 };
00081
00082
00083
00084 inline bool
00085 operator<(FunctionRootInstanceKey key1, FunctionRootInstanceKey key2)
00086 {
00087 return std::strcmp(key1.M_mangled_name, key2.M_mangled_name);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 class FunctionRootInstanceInfo;
00100 typedef std::pair<FunctionRootInstanceKey const, FunctionRootInstanceInfo> FunctionRootInstance;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 class FunctionInstance {
00120 private:
00121 void const* M_lowpc;
00122 void const* M_highpc;
00123 FunctionRootInstance* M_root;
00124 FunctionInstance* M_inlined_by;
00125
00126 public:
00127 FunctionInstance(void const* lowpc, void const* highpc, FunctionRootInstance* root, FunctionInstance* inlined_by) :
00128 M_lowpc(lowpc), M_highpc(highpc), M_root(root), M_inlined_by(inlined_by) { }
00129
00130 void const* lowpc(void) const { return M_lowpc; }
00131 void const* highpc(void) const { return M_highpc; }
00132 inline FunctionRootInstance const* root(void) const;
00133 inline FunctionInstance const* inlined_by(void) const;
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143 #if CWDEBUG_ALLOC
00144 typedef std::map<FunctionChunkKey, FunctionInstance*, std::less<FunctionChunkKey>,
00145 _private_::internal_allocator::rebind<FunctionChunk>::other> FunctionChunkMap;
00146 #else
00147 typedef std::map<FunctionChunkKey, FunctionInstance*, std::less<FunctionChunkKey> > FunctionChunkMap;
00148 #endif
00149 extern FunctionChunkMap functionChunkMap;
00150
00151
00152
00153 class FunctionRootInstanceInfo {
00154 private:
00155 FunctionInstance M_instance;
00156 std::string M_demangled_name;
00157 std::vector<FunctionInstance> M_inlined_instances;
00158
00159 public:
00160 FunctionRootInstanceInfo(void const* lowpc, void const* highpc, std::string const& demangled_name);
00161 void const* lowpc(void) const { return M_instance.lowpc(); }
00162 void const* highpc(void) const { return M_instance.highpc(); }
00163 std::string const& demangled_name(void) const { return M_demangled_name; }
00164 std::vector<FunctionInstance> const& inlined_instances(void) const { return M_inlined_instances; }
00165 std::vector<FunctionInstance>& inlined_instances(void) { return M_inlined_instances; }
00166 };
00167
00168
00169
00170
00171 #if CWDEBUG_ALLOC
00172 typedef std::map<FunctionRootInstanceKey, FunctionRootInstanceInfo, std::less<FunctionRootInstanceKey>,
00173 _private_::internal_allocator::rebind<FunctionRootInstance>::other> FunctionRootsMap;
00174 #else
00175 typedef std::map<FunctionRootInstanceKey, FunctionRootInstanceInfo, std::less<FunctionRootInstanceKey> > FunctionRootsMap;
00176 #endif
00177
00178 FunctionRootInstance const*
00179 FunctionInstance::root(void) const
00180 {
00181 return M_root;
00182 }
00183
00184 FunctionInstance const*
00185 FunctionInstance::inlined_by(void) const
00186 {
00187 return M_inlined_by;
00188 }
00189
00190 }
00191
00192
00193
00194
00195
00196
00197 class Function {
00198 private:
00199 int volatile M_initialized;
00200 unsigned int M_flags;
00201
00202 _private_::FunctionRootInstance* M_root;
00203 char const* M_label;
00204
00205 public:
00206 char const* label(void) const { return M_label; }
00207 bool is_initialized(void) const { return M_initialized; }
00208
00209 private:
00210 void M_init(void);
00211 void M_init(Function& function);
00212 void M_init(char const* expr, unsigned int flags);
00213
00214 public:
00215 static unsigned int const nofail = 1;
00216 static unsigned int const c_linkage = 2;
00217 static unsigned int const cpp_linkage = 4;
00218 static unsigned int const mangled = 8;
00219 static unsigned int const regexp = 16;
00220 static unsigned int const exactmatch = 32;
00221
00222 Function(void) : M_initialized(false), M_flags(0) { }
00223 Function(unsigned int flags) : M_initialized(false), M_flags(flags) { }
00224
00225 void init(void) { if (!M_initialized) M_init(); }
00226 void init(Function& function) { if (!function.is_initialized()) M_init(function); }
00227 void init(char const* expr, unsigned int flags = mangled|cpp_linkage) { if (!M_initialized) M_init(expr, flags); }
00228
00229 void label(char const* lbl) { M_label = lbl; }
00230 void rmlabel(void) { M_label = NULL; }
00231 };
00232
00233 }
00234
00235 #endif // LIBCWD_CLASS_FUNCTION_H