blob: 3a4875641d0f1cc95661fe50ced95d62c8182553 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolVendor.mm -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Symbol/SymbolVendor.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Module.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Symbol/SymbolFile.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24
25//----------------------------------------------------------------------
26// FindPlugin
27//
28// Platforms can register a callback to use when creating symbol
29// vendors to allow for complex debug information file setups, and to
30// also allow for finding separate debug information files.
31//----------------------------------------------------------------------
32SymbolVendor*
33SymbolVendor::FindPlugin (Module* module)
34{
35 std::auto_ptr<SymbolVendor> instance_ap;
36 //----------------------------------------------------------------------
37 // We currently only have one debug symbol parser...
38 //----------------------------------------------------------------------
39 SymbolVendorCreateInstance create_callback;
40 for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
41 {
42 instance_ap.reset(create_callback(module));
43
44 if (instance_ap.get())
45 {
46 // TODO: make sure this symbol vendor is what we want. We
47 // currently are just returning the first one we find, but
48 // we may want to call this function only when we have our
49 // main executable module and then give all symbol vendor
50 // plug-ins a chance to compete for who wins.
51 return instance_ap.release();
52 }
53 }
54 // The default implementation just tries to create debug information using the
55 // file representation for the module.
56 instance_ap.reset(new SymbolVendor(module));
57 if (instance_ap.get())
Greg Clayton762f7132011-09-18 18:59:15 +000058 {
59 ObjectFile *objfile = module->GetObjectFile();
60 if (objfile)
Jim Ingham7d1c1152011-12-06 01:07:22 +000061 instance_ap->AddSymbolFileRepresentation(objfile->GetSP());
Greg Clayton762f7132011-09-18 18:59:15 +000062 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063 return instance_ap.release();
64}
65
66//----------------------------------------------------------------------
67// SymbolVendor constructor
68//----------------------------------------------------------------------
69SymbolVendor::SymbolVendor(Module *module) :
70 ModuleChild(module),
71 m_mutex (Mutex::eMutexTypeRecursive),
72 m_type_list(),
73 m_compile_units(),
74 m_sym_file_ap()
75{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076}
77
78//----------------------------------------------------------------------
79// Destructor
80//----------------------------------------------------------------------
81SymbolVendor::~SymbolVendor()
82{
83}
84
85//----------------------------------------------------------------------
86// Add a represantion given an object file.
87//----------------------------------------------------------------------
88void
Jim Ingham7d1c1152011-12-06 01:07:22 +000089SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090{
91 Mutex::Locker locker(m_mutex);
Greg Clayton762f7132011-09-18 18:59:15 +000092 if (objfile_sp)
93 {
94 m_objfile_sp = objfile_sp;
95 m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get()));
96 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097}
98
99bool
Greg Clayton450e3f32010-10-12 02:24:53 +0000100SymbolVendor::SetCompileUnitAtIndex (CompUnitSP& cu, uint32_t idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101{
102 Mutex::Locker locker(m_mutex);
103 const uint32_t num_compile_units = GetNumCompileUnits();
104 if (idx < num_compile_units)
105 {
106 // Fire off an assertion if this compile unit already exists for now.
107 // The partial parsing should take care of only setting the compile
108 // unit once, so if this assertion fails, we need to make sure that
109 // we don't have a race condition, or have a second parse of the same
110 // compile unit.
111 assert(m_compile_units[idx].get() == NULL);
112 m_compile_units[idx] = cu;
113 return true;
114 }
115 return false;
116}
117
118uint32_t
119SymbolVendor::GetNumCompileUnits()
120{
121 Mutex::Locker locker(m_mutex);
122 if (m_compile_units.empty())
123 {
124 if (m_sym_file_ap.get())
125 {
126 // Resize our array of compile unit shared pointers -- which will
127 // each remain NULL until someone asks for the actual compile unit
128 // information. When this happens, the symbol file will be asked
129 // to parse this compile unit information.
130 m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits());
131 }
132 }
133 return m_compile_units.size();
134}
135
136size_t
137SymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
138{
139 Mutex::Locker locker(m_mutex);
140 if (m_sym_file_ap.get())
141 return m_sym_file_ap->ParseCompileUnitFunctions(sc);
142 return 0;
143}
144
145bool
146SymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc)
147{
148 Mutex::Locker locker(m_mutex);
149 if (m_sym_file_ap.get())
150 return m_sym_file_ap->ParseCompileUnitLineTable(sc);
151 return false;
152}
153
154bool
155SymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
156{
157 Mutex::Locker locker(m_mutex);
158 if (m_sym_file_ap.get())
159 return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
160 return false;
161}
162
163size_t
164SymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
165{
166 Mutex::Locker locker(m_mutex);
167 if (m_sym_file_ap.get())
168 return m_sym_file_ap->ParseFunctionBlocks(sc);
169 return 0;
170}
171
172size_t
173SymbolVendor::ParseTypes (const SymbolContext &sc)
174{
175 Mutex::Locker locker(m_mutex);
176 if (m_sym_file_ap.get())
177 return m_sym_file_ap->ParseTypes(sc);
178 return 0;
179}
180
181size_t
182SymbolVendor::ParseVariablesForContext (const SymbolContext& sc)
183{
184 Mutex::Locker locker(m_mutex);
185 if (m_sym_file_ap.get())
186 return m_sym_file_ap->ParseVariablesForContext(sc);
187 return 0;
188}
189
190Type*
191SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid)
192{
193 Mutex::Locker locker(m_mutex);
194 if (m_sym_file_ap.get())
195 return m_sym_file_ap->ResolveTypeUID(type_uid);
196 return NULL;
197}
198
199
200uint32_t
201SymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
202{
203 Mutex::Locker locker(m_mutex);
204 if (m_sym_file_ap.get())
205 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
206 return 0;
207}
208
209uint32_t
210SymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
211{
212 Mutex::Locker locker(m_mutex);
213 if (m_sym_file_ap.get())
214 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
215 return 0;
216}
217
218uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000219SymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220{
221 Mutex::Locker locker(m_mutex);
222 if (m_sym_file_ap.get())
Sean Callanan213fdb82011-10-13 01:49:10 +0000223 return m_sym_file_ap->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224 return 0;
225}
226
227uint32_t
228SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
229{
230 Mutex::Locker locker(m_mutex);
231 if (m_sym_file_ap.get())
232 return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables);
233 return 0;
234}
235
236uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000237SymbolVendor::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238{
239 Mutex::Locker locker(m_mutex);
240 if (m_sym_file_ap.get())
Sean Callanan213fdb82011-10-13 01:49:10 +0000241 return m_sym_file_ap->FindFunctions(name, namespace_decl, name_type_mask, append, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242 return 0;
243}
244
245uint32_t
246SymbolVendor::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
247{
248 Mutex::Locker locker(m_mutex);
249 if (m_sym_file_ap.get())
250 return m_sym_file_ap->FindFunctions(regex, append, sc_list);
251 return 0;
252}
253
254
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000255uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +0000256SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000257{
258 Mutex::Locker locker(m_mutex);
259 if (m_sym_file_ap.get())
Sean Callanan213fdb82011-10-13 01:49:10 +0000260 return m_sym_file_ap->FindTypes(sc, name, namespace_decl, append, max_matches, types);
Greg Claytonb0b9fe62010-08-03 00:35:52 +0000261 if (!append)
262 types.Clear();
263 return 0;
264}
Greg Clayton526e5af2010-11-13 03:52:47 +0000265
266ClangNamespaceDecl
Sean Callanan213fdb82011-10-13 01:49:10 +0000267SymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton526e5af2010-11-13 03:52:47 +0000268{
269 Mutex::Locker locker(m_mutex);
270 ClangNamespaceDecl namespace_decl;
271 if (m_sym_file_ap.get())
Sean Callanan213fdb82011-10-13 01:49:10 +0000272 namespace_decl = m_sym_file_ap->FindNamespace (sc, name, parent_namespace_decl);
Greg Clayton526e5af2010-11-13 03:52:47 +0000273 return namespace_decl;
274}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275
276void
277SymbolVendor::Dump(Stream *s)
278{
279 Mutex::Locker locker(m_mutex);
280 bool show_context = false;
281
Jason Molendafd54b362011-09-20 21:44:10 +0000282 s->Printf("%p: ", this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 s->Indent();
284 s->PutCString("SymbolVendor");
285 if (m_sym_file_ap.get())
286 {
287 ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
288 if (objfile)
289 {
290 const FileSpec &objfile_file_spec = objfile->GetFileSpec();
291 if (objfile_file_spec)
292 {
293 s->PutCString(" (");
294 objfile_file_spec.Dump(s);
295 s->PutChar(')');
296 }
297 }
298 }
299 s->EOL();
300 s->IndentMore();
301 m_type_list.Dump(s, show_context);
302
303 CompileUnitConstIter cu_pos, cu_end;
304 cu_end = m_compile_units.end();
305 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos)
306 {
307 // We currently only dump the compile units that have been parsed
308 if (cu_pos->get())
309 (*cu_pos)->Dump(s, show_context);
310 }
311
312 s->IndentLess();
313
314}
315
316CompUnitSP
317SymbolVendor::GetCompileUnitAtIndex(uint32_t idx)
318{
319 Mutex::Locker locker(m_mutex);
320 CompUnitSP cu_sp;
321 const uint32_t num_compile_units = GetNumCompileUnits();
322 if (idx < num_compile_units)
323 {
324 cu_sp = m_compile_units[idx];
325 if (cu_sp.get() == NULL)
326 {
327 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx);
328 cu_sp = m_compile_units[idx];
329 }
330 }
331 return cu_sp;
332}
333
334
335//------------------------------------------------------------------
336// PluginInterface protocol
337//------------------------------------------------------------------
338const char *
339SymbolVendor::GetPluginName()
340{
341 return "SymbolVendor";
342}
343
344const char *
345SymbolVendor::GetShortPluginName()
346{
347 return "vendor-default";
348}
349
350uint32_t
351SymbolVendor::GetPluginVersion()
352{
353 return 1;
354}
355