blob: bcbb448807e753d361015ffdb91ec122d6faf981 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- 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 "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
Sean Callanancc427fa2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000033#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
35#include "lldb/Core/Value.h"
36
37#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000038#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Symbol/CompileUnit.h"
40#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolVendor.h"
43#include "lldb/Symbol/VariableList.h"
44
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000045#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham4cda6e02011-10-07 22:23:45 +000046#include "lldb/Target/CPPLanguageRuntime.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000047
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048#include "DWARFCompileUnit.h"
49#include "DWARFDebugAbbrev.h"
50#include "DWARFDebugAranges.h"
51#include "DWARFDebugInfo.h"
52#include "DWARFDebugInfoEntry.h"
53#include "DWARFDebugLine.h"
54#include "DWARFDebugPubnames.h"
55#include "DWARFDebugRanges.h"
56#include "DWARFDIECollection.h"
57#include "DWARFFormValue.h"
58#include "DWARFLocationList.h"
59#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000060#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
62#include <map>
63
Greg Clayton62742b12010-11-11 01:09:45 +000064//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000065
66#ifdef ENABLE_DEBUG_PRINTF
67#include <stdio.h>
68#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
69#else
70#define DEBUG_PRINTF(fmt, ...)
71#endif
72
Greg Clayton594e5ed2010-09-27 21:07:38 +000073#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074
75using namespace lldb;
76using namespace lldb_private;
77
78
Sean Callananc7fbf732010-08-06 00:32:49 +000079static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000080DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081{
82 switch (dwarf_accessibility)
83 {
Sean Callananc7fbf732010-08-06 00:32:49 +000084 case DW_ACCESS_public: return eAccessPublic;
85 case DW_ACCESS_private: return eAccessPrivate;
86 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000087 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 }
Sean Callananc7fbf732010-08-06 00:32:49 +000089 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090}
91
92void
93SymbolFileDWARF::Initialize()
94{
95 LogChannelDWARF::Initialize();
96 PluginManager::RegisterPlugin (GetPluginNameStatic(),
97 GetPluginDescriptionStatic(),
98 CreateInstance);
99}
100
101void
102SymbolFileDWARF::Terminate()
103{
104 PluginManager::UnregisterPlugin (CreateInstance);
105 LogChannelDWARF::Initialize();
106}
107
108
109const char *
110SymbolFileDWARF::GetPluginNameStatic()
111{
Greg Claytond4a2b372011-09-12 23:21:58 +0000112 return "dwarf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113}
114
115const char *
116SymbolFileDWARF::GetPluginDescriptionStatic()
117{
118 return "DWARF and DWARF3 debug symbol file reader.";
119}
120
121
122SymbolFile*
123SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
124{
125 return new SymbolFileDWARF(obj_file);
126}
127
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000128TypeList *
129SymbolFileDWARF::GetTypeList ()
130{
131 if (m_debug_map_symfile)
132 return m_debug_map_symfile->GetTypeList();
133 return m_obj_file->GetModule()->GetTypeList();
134
135}
136
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137//----------------------------------------------------------------------
138// Gets the first parent that is a lexical block, function or inlined
139// subroutine, or compile unit.
140//----------------------------------------------------------------------
141static const DWARFDebugInfoEntry *
142GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
143{
144 const DWARFDebugInfoEntry *die;
145 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
146 {
147 dw_tag_t tag = die->Tag();
148
149 switch (tag)
150 {
151 case DW_TAG_compile_unit:
152 case DW_TAG_subprogram:
153 case DW_TAG_inlined_subroutine:
154 case DW_TAG_lexical_block:
155 return die;
156 }
157 }
158 return NULL;
159}
160
161
Greg Clayton450e3f32010-10-12 02:24:53 +0000162SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
163 SymbolFile (objfile),
164 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000165 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000167 m_data_debug_abbrev (),
168 m_data_debug_aranges (),
169 m_data_debug_frame (),
170 m_data_debug_info (),
171 m_data_debug_line (),
172 m_data_debug_loc (),
173 m_data_debug_ranges (),
174 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000175 m_data_apple_names (),
176 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000177 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179 m_info(),
180 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000181 m_apple_names_ap (),
182 m_apple_types_ap (),
183 m_apple_namespaces_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000184 m_function_basename_index(),
185 m_function_fullname_index(),
186 m_function_method_index(),
187 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000188 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000189 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000190 m_type_index(),
191 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000192 m_indexed (false),
193 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000194 m_ranges(),
195 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196{
197}
198
199SymbolFileDWARF::~SymbolFileDWARF()
200{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000201 if (m_is_external_ast_source)
202 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
203}
204
205static const ConstString &
206GetDWARFMachOSegmentName ()
207{
208 static ConstString g_dwarf_section_name ("__DWARF");
209 return g_dwarf_section_name;
210}
211
Greg Claytone576ab22011-02-15 00:19:15 +0000212UniqueDWARFASTTypeMap &
213SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
214{
215 if (m_debug_map_symfile)
216 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
217 return m_unique_ast_type_map;
218}
219
Greg Clayton6beaaa62011-01-17 03:46:26 +0000220ClangASTContext &
221SymbolFileDWARF::GetClangASTContext ()
222{
223 if (m_debug_map_symfile)
224 return m_debug_map_symfile->GetClangASTContext ();
225
226 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
227 if (!m_is_external_ast_source)
228 {
229 m_is_external_ast_source = true;
230 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
231 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
232 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000233 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000234 this));
235
236 ast.SetExternalSource (ast_source_ap);
237 }
238 return ast;
239}
240
241void
242SymbolFileDWARF::InitializeObject()
243{
244 // Install our external AST source callbacks so we can complete Clang types.
245 Module *module = m_obj_file->GetModule();
246 if (module)
247 {
248 const SectionList *section_list = m_obj_file->GetSectionList();
249
250 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
251
252 // Memory map the DWARF mach-o segment so we have everything mmap'ed
253 // to keep our heap memory usage down.
254 if (section)
255 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
256 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000257 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000258 if (m_data_apple_names.GetByteSize() > 0)
259 {
260 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), true));
261 if (!m_apple_names_ap->IsValid())
262 m_apple_names_ap.reset();
263 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000264 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000265 if (m_data_apple_types.GetByteSize() > 0)
266 {
267 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), false));
268 if (!m_apple_types_ap->IsValid())
269 m_apple_types_ap.reset();
270 }
271
272 get_apple_namespaces_data();
273 if (m_data_apple_namespaces.GetByteSize() > 0)
274 {
275 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), false));
276 if (!m_apple_namespaces_ap->IsValid())
277 m_apple_namespaces_ap.reset();
278 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000279
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280}
281
282bool
283SymbolFileDWARF::SupportedVersion(uint16_t version)
284{
285 return version == 2 || version == 3;
286}
287
288uint32_t
289SymbolFileDWARF::GetAbilities ()
290{
291 uint32_t abilities = 0;
292 if (m_obj_file != NULL)
293 {
294 const Section* section = NULL;
295 const SectionList *section_list = m_obj_file->GetSectionList();
296 if (section_list == NULL)
297 return 0;
298
299 uint64_t debug_abbrev_file_size = 0;
300 uint64_t debug_aranges_file_size = 0;
301 uint64_t debug_frame_file_size = 0;
302 uint64_t debug_info_file_size = 0;
303 uint64_t debug_line_file_size = 0;
304 uint64_t debug_loc_file_size = 0;
305 uint64_t debug_macinfo_file_size = 0;
306 uint64_t debug_pubnames_file_size = 0;
307 uint64_t debug_pubtypes_file_size = 0;
308 uint64_t debug_ranges_file_size = 0;
309 uint64_t debug_str_file_size = 0;
310
Greg Clayton6beaaa62011-01-17 03:46:26 +0000311 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312
313 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000314 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315
Greg Clayton4ceb9982010-07-21 22:54:26 +0000316 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 if (section != NULL)
318 {
319 debug_info_file_size = section->GetByteSize();
320
Greg Clayton4ceb9982010-07-21 22:54:26 +0000321 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 if (section)
323 debug_abbrev_file_size = section->GetByteSize();
324 else
325 m_flags.Set (flagsGotDebugAbbrevData);
326
Greg Clayton4ceb9982010-07-21 22:54:26 +0000327 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 if (section)
329 debug_aranges_file_size = section->GetByteSize();
330 else
331 m_flags.Set (flagsGotDebugArangesData);
332
Greg Clayton4ceb9982010-07-21 22:54:26 +0000333 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 if (section)
335 debug_frame_file_size = section->GetByteSize();
336 else
337 m_flags.Set (flagsGotDebugFrameData);
338
Greg Clayton4ceb9982010-07-21 22:54:26 +0000339 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 if (section)
341 debug_line_file_size = section->GetByteSize();
342 else
343 m_flags.Set (flagsGotDebugLineData);
344
Greg Clayton4ceb9982010-07-21 22:54:26 +0000345 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346 if (section)
347 debug_loc_file_size = section->GetByteSize();
348 else
349 m_flags.Set (flagsGotDebugLocData);
350
Greg Clayton4ceb9982010-07-21 22:54:26 +0000351 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352 if (section)
353 debug_macinfo_file_size = section->GetByteSize();
354 else
355 m_flags.Set (flagsGotDebugMacInfoData);
356
Greg Clayton4ceb9982010-07-21 22:54:26 +0000357 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 if (section)
359 debug_pubnames_file_size = section->GetByteSize();
360 else
361 m_flags.Set (flagsGotDebugPubNamesData);
362
Greg Clayton4ceb9982010-07-21 22:54:26 +0000363 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364 if (section)
365 debug_pubtypes_file_size = section->GetByteSize();
366 else
367 m_flags.Set (flagsGotDebugPubTypesData);
368
Greg Clayton4ceb9982010-07-21 22:54:26 +0000369 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 if (section)
371 debug_ranges_file_size = section->GetByteSize();
372 else
373 m_flags.Set (flagsGotDebugRangesData);
374
Greg Clayton4ceb9982010-07-21 22:54:26 +0000375 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 if (section)
377 debug_str_file_size = section->GetByteSize();
378 else
379 m_flags.Set (flagsGotDebugStrData);
380 }
381
382 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
383 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
384
385 if (debug_line_file_size > 0)
386 abilities |= LineTables;
387
388 if (debug_aranges_file_size > 0)
389 abilities |= AddressAcceleratorTable;
390
391 if (debug_pubnames_file_size > 0)
392 abilities |= FunctionAcceleratorTable;
393
394 if (debug_pubtypes_file_size > 0)
395 abilities |= TypeAcceleratorTable;
396
397 if (debug_macinfo_file_size > 0)
398 abilities |= MacroInformation;
399
400 if (debug_frame_file_size > 0)
401 abilities |= CallFrameInformation;
402 }
403 return abilities;
404}
405
406const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000407SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408{
409 if (m_flags.IsClear (got_flag))
410 {
411 m_flags.Set (got_flag);
412 const SectionList *section_list = m_obj_file->GetSectionList();
413 if (section_list)
414 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000415 Section *section = section_list->FindSectionByType(sect_type, true).get();
416 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417 {
418 // See if we memory mapped the DWARF segment?
419 if (m_dwarf_data.GetByteSize())
420 {
421 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
422 }
423 else
424 {
425 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
426 data.Clear();
427 }
428 }
429 }
430 }
431 return data;
432}
433
434const DataExtractor&
435SymbolFileDWARF::get_debug_abbrev_data()
436{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000437 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438}
439
440const DataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000441SymbolFileDWARF::get_debug_aranges_data()
442{
443 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
444}
445
446const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447SymbolFileDWARF::get_debug_frame_data()
448{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000449 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450}
451
452const DataExtractor&
453SymbolFileDWARF::get_debug_info_data()
454{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000455 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456}
457
458const DataExtractor&
459SymbolFileDWARF::get_debug_line_data()
460{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000461 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462}
463
464const DataExtractor&
465SymbolFileDWARF::get_debug_loc_data()
466{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000467 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468}
469
470const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471SymbolFileDWARF::get_debug_ranges_data()
472{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000473 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474}
475
476const DataExtractor&
477SymbolFileDWARF::get_debug_str_data()
478{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000479 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480}
481
Greg Claytonf9eec202011-09-01 23:16:13 +0000482const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000483SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000484{
Greg Clayton17674402011-09-28 17:06:40 +0000485 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000486}
487
488const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000489SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000490{
Greg Clayton17674402011-09-28 17:06:40 +0000491 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000492}
493
Greg Clayton7f995132011-10-04 22:41:51 +0000494const DataExtractor&
495SymbolFileDWARF::get_apple_namespaces_data()
496{
497 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
498}
499
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500
501DWARFDebugAbbrev*
502SymbolFileDWARF::DebugAbbrev()
503{
504 if (m_abbr.get() == NULL)
505 {
506 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
507 if (debug_abbrev_data.GetByteSize() > 0)
508 {
509 m_abbr.reset(new DWARFDebugAbbrev());
510 if (m_abbr.get())
511 m_abbr->Parse(debug_abbrev_data);
512 }
513 }
514 return m_abbr.get();
515}
516
517const DWARFDebugAbbrev*
518SymbolFileDWARF::DebugAbbrev() const
519{
520 return m_abbr.get();
521}
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523
524DWARFDebugInfo*
525SymbolFileDWARF::DebugInfo()
526{
527 if (m_info.get() == NULL)
528 {
529 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
530 if (get_debug_info_data().GetByteSize() > 0)
531 {
532 m_info.reset(new DWARFDebugInfo());
533 if (m_info.get())
534 {
535 m_info->SetDwarfData(this);
536 }
537 }
538 }
539 return m_info.get();
540}
541
542const DWARFDebugInfo*
543SymbolFileDWARF::DebugInfo() const
544{
545 return m_info.get();
546}
547
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548DWARFCompileUnit*
549SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
550{
551 DWARFDebugInfo* info = DebugInfo();
552 if (info)
553 return info->GetCompileUnit(cu_uid).get();
554 return NULL;
555}
556
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
558DWARFDebugRanges*
559SymbolFileDWARF::DebugRanges()
560{
561 if (m_ranges.get() == NULL)
562 {
563 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
564 if (get_debug_ranges_data().GetByteSize() > 0)
565 {
566 m_ranges.reset(new DWARFDebugRanges());
567 if (m_ranges.get())
568 m_ranges->Extract(this);
569 }
570 }
571 return m_ranges.get();
572}
573
574const DWARFDebugRanges*
575SymbolFileDWARF::DebugRanges() const
576{
577 return m_ranges.get();
578}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579
580bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000581SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582{
Greg Clayton96d7d742010-11-10 23:42:09 +0000583 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000585 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586 if (cu_die)
587 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000588 const char * cu_die_name = cu_die->GetName(this, curr_cu);
589 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham0f35ac22011-08-24 23:34:20 +0000590 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591 if (cu_die_name)
592 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000593 FileSpec cu_file_spec;
594
Greg Clayton7bd65b92011-02-09 23:39:34 +0000595 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000597 // If we have a full path to the compile unit, we don't need to resolve
598 // the file. This can be expensive e.g. when the source files are NFS mounted.
599 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600 }
601 else
602 {
603 std::string fullpath(cu_comp_dir);
604 if (*fullpath.rbegin() != '/')
605 fullpath += '/';
606 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000607 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608 }
609
Jim Ingham0f35ac22011-08-24 23:34:20 +0000610 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), cu_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611 if (compile_unit_sp.get())
612 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000613 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614 return true;
615 }
616 }
617 }
618 }
619 return false;
620}
621
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622uint32_t
623SymbolFileDWARF::GetNumCompileUnits()
624{
625 DWARFDebugInfo* info = DebugInfo();
626 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000627 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628 return 0;
629}
630
631CompUnitSP
632SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
633{
634 CompUnitSP comp_unit;
635 DWARFDebugInfo* info = DebugInfo();
636 if (info)
637 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000638 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
639 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 {
641 // Our symbol vendor shouldn't be asking us to add a compile unit that
642 // has already been added to it, which this DWARF plug-in knows as it
643 // stores the lldb compile unit (CompileUnit) pointer in each
644 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000645 assert(curr_cu->GetUserData() == NULL);
646 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 }
648 }
649 return comp_unit;
650}
651
652static void
Greg Claytonea3e7d52011-10-08 00:49:15 +0000653AddRangesToBlock (Block& block,
654 DWARFDebugRanges::RangeList& ranges,
655 addr_t block_base_addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000657 const size_t num_ranges = ranges.GetSize();
658 for (size_t i = 0; i<num_ranges; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000660 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
661 const addr_t range_base = range.GetRangeBase();
662 assert (range_base >= block_base_addr);
663 block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664 }
Greg Claytonea3e7d52011-10-08 00:49:15 +0000665 block.FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666}
667
668
669Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000670SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671{
672 DWARFDebugRanges::RangeList func_ranges;
673 const char *name = NULL;
674 const char *mangled = NULL;
675 int decl_file = 0;
676 int decl_line = 0;
677 int decl_column = 0;
678 int call_file = 0;
679 int call_line = 0;
680 int call_column = 0;
681 DWARFExpression frame_base;
682
Greg Claytonc93237c2010-10-01 20:48:32 +0000683 assert (die->Tag() == DW_TAG_subprogram);
684
685 if (die->Tag() != DW_TAG_subprogram)
686 return NULL;
687
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
689 {
690 // Union of all ranges in the function DIE (if the function is discontiguous)
691 AddressRange func_range;
Greg Claytonea3e7d52011-10-08 00:49:15 +0000692 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
693 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
695 {
696 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
697 if (func_range.GetBaseAddress().IsValid())
698 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
699 }
700
701 if (func_range.GetBaseAddress().IsValid())
702 {
703 Mangled func_name;
704 if (mangled)
705 func_name.SetValue(mangled, true);
706 else if (name)
707 func_name.SetValue(name, false);
708
709 FunctionSP func_sp;
710 std::auto_ptr<Declaration> decl_ap;
711 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000712 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
713 decl_line,
714 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000716 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +0000717 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718
719 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
720
721 func_range.GetBaseAddress().ResolveLinkedAddress();
722
723 func_sp.reset(new Function (sc.comp_unit,
724 die->GetOffset(), // UserID is the DIE offset
725 die->GetOffset(),
726 func_name,
727 func_type,
728 func_range)); // first address range
729
730 if (func_sp.get() != NULL)
731 {
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000732 if (frame_base.IsValid())
733 func_sp->GetFrameBaseExpression() = frame_base;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 sc.comp_unit->AddFunction(func_sp);
735 return func_sp.get();
736 }
737 }
738 }
739 return NULL;
740}
741
742size_t
743SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
744{
745 assert (sc.comp_unit);
746 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000747 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748 if (dwarf_cu)
749 {
750 DWARFDIECollection function_dies;
751 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
752 size_t func_idx;
753 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
754 {
755 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
756 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
757 {
758 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
759 ++functions_added;
760 }
761 }
762 //FixupTypes();
763 }
764 return functions_added;
765}
766
767bool
768SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
769{
770 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000771 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
772 assert (curr_cu);
773 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774
775 if (cu_die)
776 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000777 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
778 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779
780 // All file indexes in DWARF are one based and a file of index zero is
781 // supposed to be the compile unit itself.
782 support_files.Append (*sc.comp_unit);
783
784 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
785 }
786 return false;
787}
788
789struct ParseDWARFLineTableCallbackInfo
790{
791 LineTable* line_table;
792 const SectionList *section_list;
793 lldb::addr_t prev_sect_file_base_addr;
794 lldb::addr_t curr_sect_file_base_addr;
795 bool is_oso_for_debug_map;
796 bool prev_in_final_executable;
797 DWARFDebugLine::Row prev_row;
798 SectionSP prev_section_sp;
799 SectionSP curr_section_sp;
800};
801
802//----------------------------------------------------------------------
803// ParseStatementTableCallback
804//----------------------------------------------------------------------
805static void
806ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
807{
808 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
809 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
810 {
811 // Just started parsing the line table
812 }
813 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
814 {
815 // Done parsing line table, nothing to do for the cleanup
816 }
817 else
818 {
819 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
820 // We have a new row, lets append it
821
822 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
823 {
824 info->prev_section_sp = info->curr_section_sp;
825 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
826 // If this is an end sequence entry, then we subtract one from the
827 // address to make sure we get an address that is not the end of
828 // a section.
829 if (state.end_sequence && state.address != 0)
830 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
831 else
832 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
833
834 if (info->curr_section_sp.get())
835 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
836 else
837 info->curr_sect_file_base_addr = 0;
838 }
839 if (info->curr_section_sp.get())
840 {
841 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
842 // Check for the fancy section magic to determine if we
843
844 if (info->is_oso_for_debug_map)
845 {
846 // When this is a debug map object file that contains DWARF
847 // (referenced from an N_OSO debug map nlist entry) we will have
848 // a file address in the file range for our section from the
849 // original .o file, and a load address in the executable that
850 // contains the debug map.
851 //
852 // If the sections for the file range and load range are
853 // different, we have a remapped section for the function and
854 // this address is resolved. If they are the same, then the
855 // function for this address didn't make it into the final
856 // executable.
857 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
858
859 // If we are doing DWARF with debug map, then we need to carefully
860 // add each line table entry as there may be gaps as functions
861 // get moved around or removed.
862 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
863 {
864 if (info->prev_in_final_executable)
865 {
866 bool terminate_previous_entry = false;
867 if (!curr_in_final_executable)
868 {
869 // Check for the case where the previous line entry
870 // in a function made it into the final executable,
871 // yet the current line entry falls in a function
872 // that didn't. The line table used to be contiguous
873 // through this address range but now it isn't. We
874 // need to terminate the previous line entry so
875 // that we can reconstruct the line range correctly
876 // for it and to keep the line table correct.
877 terminate_previous_entry = true;
878 }
879 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
880 {
881 // Check for cases where the line entries used to be
882 // contiguous address ranges, but now they aren't.
883 // This can happen when order files specify the
884 // ordering of the functions.
885 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
886 Section *curr_sect = info->curr_section_sp.get();
887 Section *prev_sect = info->prev_section_sp.get();
888 assert (curr_sect->GetLinkedSection());
889 assert (prev_sect->GetLinkedSection());
890 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
891 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
892 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
893 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
894 if (object_file_addr_delta != linked_file_addr_delta)
895 terminate_previous_entry = true;
896 }
897
898 if (terminate_previous_entry)
899 {
900 line_table->InsertLineEntry (info->prev_section_sp,
901 state.address - info->prev_sect_file_base_addr,
902 info->prev_row.line,
903 info->prev_row.column,
904 info->prev_row.file,
905 false, // is_stmt
906 false, // basic_block
907 false, // state.prologue_end
908 false, // state.epilogue_begin
909 true); // end_sequence);
910 }
911 }
912 }
913
914 if (curr_in_final_executable)
915 {
916 line_table->InsertLineEntry (info->curr_section_sp,
917 curr_line_section_offset,
918 state.line,
919 state.column,
920 state.file,
921 state.is_stmt,
922 state.basic_block,
923 state.prologue_end,
924 state.epilogue_begin,
925 state.end_sequence);
926 info->prev_section_sp = info->curr_section_sp;
927 }
928 else
929 {
930 // If the current address didn't make it into the final
931 // executable, the current section will be the __text
932 // segment in the .o file, so we need to clear this so
933 // we can catch the next function that did make it into
934 // the final executable.
935 info->prev_section_sp.reset();
936 info->curr_section_sp.reset();
937 }
938
939 info->prev_in_final_executable = curr_in_final_executable;
940 }
941 else
942 {
943 // We are not in an object file that contains DWARF for an
944 // N_OSO, this is just a normal DWARF file. The DWARF spec
945 // guarantees that the addresses will be in increasing order
946 // so, since we store line tables in file address order, we
947 // can always just append the line entry without needing to
948 // search for the correct insertion point (we don't need to
949 // use LineEntry::InsertLineEntry()).
950 line_table->AppendLineEntry (info->curr_section_sp,
951 curr_line_section_offset,
952 state.line,
953 state.column,
954 state.file,
955 state.is_stmt,
956 state.basic_block,
957 state.prologue_end,
958 state.epilogue_begin,
959 state.end_sequence);
960 }
961 }
962
963 info->prev_row = state;
964 }
965}
966
967bool
968SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
969{
970 assert (sc.comp_unit);
971 if (sc.comp_unit->GetLineTable() != NULL)
972 return true;
973
974 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
975 if (dwarf_cu)
976 {
977 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
978 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
979 if (cu_line_offset != DW_INVALID_OFFSET)
980 {
981 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
982 if (line_table_ap.get())
983 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000984 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985 uint32_t offset = cu_line_offset;
986 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
987 sc.comp_unit->SetLineTable(line_table_ap.release());
988 return true;
989 }
990 }
991 }
992 return false;
993}
994
995size_t
996SymbolFileDWARF::ParseFunctionBlocks
997(
998 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000999 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001000 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 const DWARFDebugInfoEntry *die,
1002 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001003 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004)
1005{
1006 size_t blocks_added = 0;
1007 while (die != NULL)
1008 {
1009 dw_tag_t tag = die->Tag();
1010
1011 switch (tag)
1012 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001014 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 case DW_TAG_lexical_block:
1016 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001017 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001018 if (tag == DW_TAG_subprogram)
1019 {
1020 // Skip any DW_TAG_subprogram DIEs that are inside
1021 // of a normal or inlined functions. These will be
1022 // parsed on their own as separate entities.
1023
1024 if (depth > 0)
1025 break;
1026
1027 block = parent_block;
1028 }
1029 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001030 {
1031 BlockSP block_sp(new Block (die->GetOffset()));
1032 parent_block->AddChild(block_sp);
1033 block = block_sp.get();
1034 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001035 DWARFDebugRanges::RangeList ranges;
1036 const char *name = NULL;
1037 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039 int decl_file = 0;
1040 int decl_line = 0;
1041 int decl_column = 0;
1042 int call_file = 0;
1043 int call_line = 0;
1044 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001045 if (die->GetDIENamesAndRanges (this,
1046 dwarf_cu,
1047 name,
1048 mangled_name,
1049 ranges,
1050 decl_file, decl_line, decl_column,
1051 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 {
1053 if (tag == DW_TAG_subprogram)
1054 {
1055 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001056 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001057 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001058 else if (tag == DW_TAG_inlined_subroutine)
1059 {
1060 // We get called here for inlined subroutines in two ways.
1061 // The first time is when we are making the Function object
1062 // for this inlined concrete instance. Since we're creating a top level block at
1063 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1064 // adjust the containing address.
1065 // The second time is when we are parsing the blocks inside the function that contains
1066 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1067 // function the offset will be for that function.
1068 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1069 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001070 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001071 }
1072 }
1073
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001074 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075
1076 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1077 {
1078 std::auto_ptr<Declaration> decl_ap;
1079 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001080 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1081 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082
1083 std::auto_ptr<Declaration> call_ap;
1084 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001085 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1086 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001088 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 }
1090
1091 ++blocks_added;
1092
Greg Claytondd7feaf2011-08-12 17:54:33 +00001093 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001095 blocks_added += ParseFunctionBlocks (sc,
1096 block,
1097 dwarf_cu,
1098 die->GetFirstChild(),
1099 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001100 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 }
1102 }
1103 }
1104 break;
1105 default:
1106 break;
1107 }
1108
Greg Claytondd7feaf2011-08-12 17:54:33 +00001109 // Only parse siblings of the block if we are not at depth zero. A depth
1110 // of zero indicates we are currently parsing the top level
1111 // DW_TAG_subprogram DIE
1112
1113 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001114 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001115 else
1116 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 }
1118 return blocks_added;
1119}
1120
1121size_t
1122SymbolFileDWARF::ParseChildMembers
1123(
1124 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001125 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001127 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001128 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1130 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001131 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001132 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 bool &is_a_class
1134)
1135{
1136 if (parent_die == NULL)
1137 return 0;
1138
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 size_t count = 0;
1140 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001141 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001142 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001143
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1145 {
1146 dw_tag_t tag = die->Tag();
1147
1148 switch (tag)
1149 {
1150 case DW_TAG_member:
1151 {
1152 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001153 const size_t num_attributes = die->GetAttributes (this,
1154 dwarf_cu,
1155 fixed_form_sizes,
1156 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 if (num_attributes > 0)
1158 {
1159 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001160 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001162 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001164 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001165 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 size_t byte_size = 0;
1167 size_t bit_offset = 0;
1168 size_t bit_size = 0;
1169 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001170 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 {
1172 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1173 DWARFFormValue form_value;
1174 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1175 {
1176 switch (attr)
1177 {
1178 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1179 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1180 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1181 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1182 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1183 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1184 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1185 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1186 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001187// if (form_value.BlockData())
1188// {
1189// Value initialValue(0);
1190// Value memberOffset(0);
1191// const DataExtractor& debug_info_data = get_debug_info_data();
1192// uint32_t block_length = form_value.Unsigned();
1193// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1194// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1195// {
1196// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1197// }
1198// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 break;
1200
Greg Clayton8cf05932010-07-22 18:30:50 +00001201 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001202 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203 case DW_AT_declaration:
1204 case DW_AT_description:
1205 case DW_AT_mutable:
1206 case DW_AT_visibility:
1207 default:
1208 case DW_AT_sibling:
1209 break;
1210 }
1211 }
1212 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001213
1214 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1215
1216 if (class_language == eLanguageTypeObjC ||
1217 class_language == eLanguageTypeObjC_plus_plus)
1218 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001219
1220 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1221 {
1222 // Not all compilers will mark the vtable pointer
1223 // member as artificial (llvm-gcc). We can't have
1224 // the virtual members in our classes otherwise it
1225 // throws off all child offsets since we end up
1226 // having and extra pointer sized member in our
1227 // class layouts.
1228 is_artificial = true;
1229 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230
Greg Clayton24739922010-10-13 03:15:28 +00001231 if (is_artificial == false)
1232 {
1233 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001234 if (member_type)
1235 {
1236 if (accessibility == eAccessNone)
1237 accessibility = default_accessibility;
1238 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239
Greg Claytond16e1e52011-07-12 17:06:17 +00001240 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1241 name,
1242 member_type->GetClangLayoutType(),
1243 accessibility,
1244 bit_size);
1245 }
1246 else
1247 {
1248 if (name)
1249 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1250 die->GetOffset(),
1251 name,
1252 encoding_uid);
1253 else
1254 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1255 die->GetOffset(),
1256 encoding_uid);
1257 }
Greg Clayton24739922010-10-13 03:15:28 +00001258 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001260 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001261 }
1262 break;
1263
1264 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001265 // Let the type parsing code handle this one for us.
1266 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 break;
1268
1269 case DW_TAG_inheritance:
1270 {
1271 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001272 if (default_accessibility == eAccessNone)
1273 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001274 // TODO: implement DW_TAG_inheritance type parsing
1275 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001276 const size_t num_attributes = die->GetAttributes (this,
1277 dwarf_cu,
1278 fixed_form_sizes,
1279 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 if (num_attributes > 0)
1281 {
1282 Declaration decl;
1283 DWARFExpression location;
1284 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001285 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286 bool is_virtual = false;
1287 bool is_base_of_class = true;
1288 off_t member_offset = 0;
1289 uint32_t i;
1290 for (i=0; i<num_attributes; ++i)
1291 {
1292 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1293 DWARFFormValue form_value;
1294 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1295 {
1296 switch (attr)
1297 {
1298 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1299 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1300 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1301 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1302 case DW_AT_data_member_location:
1303 if (form_value.BlockData())
1304 {
1305 Value initialValue(0);
1306 Value memberOffset(0);
1307 const DataExtractor& debug_info_data = get_debug_info_data();
1308 uint32_t block_length = form_value.Unsigned();
1309 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001310 if (DWARFExpression::Evaluate (NULL,
1311 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001312 NULL,
1313 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001314 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001315 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001316 block_offset,
1317 block_length,
1318 eRegisterKindDWARF,
1319 &initialValue,
1320 memberOffset,
1321 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001322 {
1323 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1324 }
1325 }
1326 break;
1327
1328 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001329 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330 break;
1331
1332 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1333 default:
1334 case DW_AT_sibling:
1335 break;
1336 }
1337 }
1338 }
1339
Greg Clayton526e5af2010-11-13 03:52:47 +00001340 Type *base_class_type = ResolveTypeUID(encoding_uid);
1341 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001342
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001343 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1344 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001345 if (class_language == eLanguageTypeObjC)
1346 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001347 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001348 }
1349 else
1350 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001351 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001352 accessibility,
1353 is_virtual,
1354 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001355 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 }
1357 }
1358 break;
1359
1360 default:
1361 break;
1362 }
1363 }
1364 return count;
1365}
1366
1367
1368clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001369SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370{
1371 DWARFDebugInfo* debug_info = DebugInfo();
1372 if (debug_info)
1373 {
1374 DWARFCompileUnitSP cu_sp;
1375 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1376 if (die)
Sean Callanan72e49402011-08-05 23:43:37 +00001377 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
1378 }
1379 return NULL;
1380}
1381
1382clang::DeclContext*
1383SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1384{
Greg Clayton5cf58b92011-10-05 22:22:08 +00001385 return GetClangDeclContextForDIEOffset (sc, type_uid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386}
1387
1388Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001389SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390{
1391 DWARFDebugInfo* debug_info = DebugInfo();
1392 if (debug_info)
1393 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001394 DWARFCompileUnitSP cu_sp;
1395 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001397 {
1398 // We might be coming in in the middle of a type tree (a class
1399 // withing a class, an enum within a class), so parse any needed
1400 // parent DIEs before we get to this one...
Greg Clayton5cf58b92011-10-05 22:22:08 +00001401 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die);
1402 switch (decl_ctx_die->Tag())
Greg Claytonca512b32011-01-14 04:54:56 +00001403 {
1404 case DW_TAG_structure_type:
1405 case DW_TAG_union_type:
1406 case DW_TAG_class_type:
Greg Clayton5cf58b92011-10-05 22:22:08 +00001407 ResolveType(cu_sp.get(), decl_ctx_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001408 break;
1409 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001410 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001411 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412 }
1413 return NULL;
1414}
1415
Greg Clayton6beaaa62011-01-17 03:46:26 +00001416// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1417// SymbolFileDWARF objects to detect if this DWARF file is the one that
1418// can resolve a clang_type.
1419bool
1420SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1421{
1422 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1423 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1424 return die != NULL;
1425}
1426
1427
Greg Clayton1be10fc2010-09-29 01:12:09 +00001428lldb::clang_type_t
1429SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1430{
1431 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001432 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1433 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001434 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001435 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001436// if (m_debug_map_symfile)
1437// {
1438// Type *type = m_die_to_type[die];
1439// if (type && type->GetSymbolFile() != this)
1440// return type->GetClangType();
1441// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001442 // We have already resolved this type...
1443 return clang_type;
1444 }
1445 // Once we start resolving this type, remove it from the forward declaration
1446 // map in case anyone child members or other types require this type to get resolved.
1447 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1448 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001449 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001450
Greg Clayton1be10fc2010-09-29 01:12:09 +00001451
Greg Clayton450e3f32010-10-12 02:24:53 +00001452 DWARFDebugInfo* debug_info = DebugInfo();
1453
Greg Clayton96d7d742010-11-10 23:42:09 +00001454 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001455 Type *type = m_die_to_type.lookup (die);
1456
1457 const dw_tag_t tag = die->Tag();
1458
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001459 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1460 die->GetOffset(),
1461 DW_TAG_value_to_name(tag),
1462 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001463 assert (clang_type);
1464 DWARFDebugInfoEntry::Attributes attributes;
1465
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001466 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001467
1468 switch (tag)
1469 {
1470 case DW_TAG_structure_type:
1471 case DW_TAG_union_type:
1472 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001473 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001474 if (die->HasChildren())
1475 {
1476 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001477 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1478 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001479 class_language = eLanguageTypeObjC;
1480
1481 int tag_decl_kind = -1;
1482 AccessType default_accessibility = eAccessNone;
1483 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001484 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001485 tag_decl_kind = clang::TTK_Struct;
1486 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001487 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001488 else if (tag == DW_TAG_union_type)
1489 {
1490 tag_decl_kind = clang::TTK_Union;
1491 default_accessibility = eAccessPublic;
1492 }
1493 else if (tag == DW_TAG_class_type)
1494 {
1495 tag_decl_kind = clang::TTK_Class;
1496 default_accessibility = eAccessPrivate;
1497 }
1498
Greg Clayton96d7d742010-11-10 23:42:09 +00001499 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001500 std::vector<clang::CXXBaseSpecifier *> base_classes;
1501 std::vector<int> member_accessibilities;
1502 bool is_a_class = false;
1503 // Parse members and base classes first
1504 DWARFDIECollection member_function_dies;
1505
1506 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001507 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001508 die,
1509 clang_type,
1510 class_language,
1511 base_classes,
1512 member_accessibilities,
1513 member_function_dies,
1514 default_accessibility,
1515 is_a_class);
1516
1517 // Now parse any methods if there were any...
1518 size_t num_functions = member_function_dies.Size();
1519 if (num_functions > 0)
1520 {
1521 for (size_t i=0; i<num_functions; ++i)
1522 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001523 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001524 }
1525 }
1526
Greg Clayton450e3f32010-10-12 02:24:53 +00001527 if (class_language == eLanguageTypeObjC)
1528 {
Greg Claytone3055942011-06-30 02:28:26 +00001529 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001530 if (!class_str.empty())
1531 {
1532
1533 ConstString class_name (class_str.c_str());
Greg Claytond4a2b372011-09-12 23:21:58 +00001534 DIEArray method_die_offsets;
1535 if (m_objc_class_selectors_index.Find (class_name, method_die_offsets))
Greg Clayton450e3f32010-10-12 02:24:53 +00001536 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001537 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton450e3f32010-10-12 02:24:53 +00001538
Greg Claytond4a2b372011-09-12 23:21:58 +00001539 DWARFCompileUnit* method_cu = NULL;
1540 const size_t num_matches = method_die_offsets.size();
1541 for (size_t i=0; i<num_matches; ++i)
1542 {
1543 const dw_offset_t die_offset = method_die_offsets[i];
1544 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Greg Clayton450e3f32010-10-12 02:24:53 +00001545
1546 ResolveType (method_cu, method_die);
1547 }
1548 }
1549 }
1550 }
1551
Greg Claytonc93237c2010-10-01 20:48:32 +00001552 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1553 // need to tell the clang type it is actually a class.
1554 if (class_language != eLanguageTypeObjC)
1555 {
1556 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001557 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001558 }
1559
1560 // Since DW_TAG_structure_type gets used for both classes
1561 // and structures, we may need to set any DW_TAG_member
1562 // fields to have a "private" access if none was specified.
1563 // When we parsed the child members we tracked that actual
1564 // accessibility value for each DW_TAG_member in the
1565 // "member_accessibilities" array. If the value for the
1566 // member is zero, then it was set to the "default_accessibility"
1567 // which for structs was "public". Below we correct this
1568 // by setting any fields to "private" that weren't correctly
1569 // set.
1570 if (is_a_class && !member_accessibilities.empty())
1571 {
1572 // This is a class and all members that didn't have
1573 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001574 ast.SetDefaultAccessForRecordFields (clang_type,
1575 eAccessPrivate,
1576 &member_accessibilities.front(),
1577 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001578 }
1579
1580 if (!base_classes.empty())
1581 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001582 ast.SetBaseClassesForClassType (clang_type,
1583 &base_classes.front(),
1584 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001585
1586 // Clang will copy each CXXBaseSpecifier in "base_classes"
1587 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001588 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1589 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001590 }
1591
1592 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001593 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001594 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001595
1596 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001597 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001598 if (die->HasChildren())
1599 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001600 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1601 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001602 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001603 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001604 return clang_type;
1605
1606 default:
1607 assert(false && "not a forward clang type decl!");
1608 break;
1609 }
1610 return NULL;
1611}
1612
Greg Claytonc685f8e2010-09-15 04:15:46 +00001613Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001614SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001615{
1616 if (type_die != NULL)
1617 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001618 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001619 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001620 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001621 if (assert_not_being_parsed)
1622 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001623 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001624 }
1625 return NULL;
1626}
1627
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001628CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001629SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001630{
1631 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001632 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633 {
1634 // The symbol vendor doesn't know about this compile unit, we
1635 // need to parse and add it to the symbol vendor object.
1636 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001637 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638 if (dc_cu.get())
1639 {
1640 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001641 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001642 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001643
1644 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001645
1646 if (m_debug_map_symfile)
1647 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 }
1649 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001650 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651}
1652
1653bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001654SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655{
1656 sc.Clear();
1657 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001658 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001659
1660 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1661 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001662 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Jim Ingham4cda6e02011-10-07 22:23:45 +00001663
1664 if (sc.function)
1665 {
1666 sc.module_sp = sc.function->CalculateSymbolContextModule();
1667 return true;
1668 }
1669
1670 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001671}
1672
1673uint32_t
1674SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1675{
1676 Timer scoped_timer(__PRETTY_FUNCTION__,
1677 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1678 so_addr.GetSection(),
1679 so_addr.GetOffset(),
1680 resolve_scope);
1681 uint32_t resolved = 0;
1682 if (resolve_scope & ( eSymbolContextCompUnit |
1683 eSymbolContextFunction |
1684 eSymbolContextBlock |
1685 eSymbolContextLineEntry))
1686 {
1687 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1688
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001690 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001692 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001693 if (cu_offset != DW_INVALID_OFFSET)
1694 {
1695 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001696 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1697 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001698 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001699 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001700 assert(sc.comp_unit != NULL);
1701 resolved |= eSymbolContextCompUnit;
1702
1703 if (resolve_scope & eSymbolContextLineEntry)
1704 {
1705 LineTable *line_table = sc.comp_unit->GetLineTable();
1706 if (line_table == NULL)
1707 {
1708 if (ParseCompileUnitLineTable(sc))
1709 line_table = sc.comp_unit->GetLineTable();
1710 }
1711 if (line_table != NULL)
1712 {
1713 if (so_addr.IsLinkedAddress())
1714 {
1715 Address linked_addr (so_addr);
1716 linked_addr.ResolveLinkedAddress();
1717 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1718 {
1719 resolved |= eSymbolContextLineEntry;
1720 }
1721 }
1722 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1723 {
1724 resolved |= eSymbolContextLineEntry;
1725 }
1726 }
1727 }
1728
1729 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1730 {
1731 DWARFDebugInfoEntry *function_die = NULL;
1732 DWARFDebugInfoEntry *block_die = NULL;
1733 if (resolve_scope & eSymbolContextBlock)
1734 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001735 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001736 }
1737 else
1738 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001739 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001740 }
1741
1742 if (function_die != NULL)
1743 {
1744 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1745 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001746 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001747 }
1748
1749 if (sc.function != NULL)
1750 {
1751 resolved |= eSymbolContextFunction;
1752
1753 if (resolve_scope & eSymbolContextBlock)
1754 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001755 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001756
1757 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001758 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001759 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001760 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001761 if (sc.block)
1762 resolved |= eSymbolContextBlock;
1763 }
1764 }
1765 }
1766 }
1767 }
1768 }
1769 }
1770 return resolved;
1771}
1772
1773
1774
1775uint32_t
1776SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1777{
1778 const uint32_t prev_size = sc_list.GetSize();
1779 if (resolve_scope & eSymbolContextCompUnit)
1780 {
1781 DWARFDebugInfo* debug_info = DebugInfo();
1782 if (debug_info)
1783 {
1784 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001785 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001786
Greg Clayton96d7d742010-11-10 23:42:09 +00001787 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001788 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001789 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1791 if (check_inlines || file_spec_matches_cu_file_spec)
1792 {
1793 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001794 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001795 assert(sc.comp_unit != NULL);
1796
1797 uint32_t file_idx = UINT32_MAX;
1798
1799 // If we are looking for inline functions only and we don't
1800 // find it in the support files, we are done.
1801 if (check_inlines)
1802 {
Jim Ingham87df91b2011-09-23 00:54:11 +00001803 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804 if (file_idx == UINT32_MAX)
1805 continue;
1806 }
1807
1808 if (line != 0)
1809 {
1810 LineTable *line_table = sc.comp_unit->GetLineTable();
1811
1812 if (line_table != NULL && line != 0)
1813 {
1814 // We will have already looked up the file index if
1815 // we are searching for inline entries.
1816 if (!check_inlines)
Jim Ingham87df91b2011-09-23 00:54:11 +00001817 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001818
1819 if (file_idx != UINT32_MAX)
1820 {
1821 uint32_t found_line;
1822 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1823 found_line = sc.line_entry.line;
1824
Greg Clayton016a95e2010-09-14 02:20:48 +00001825 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826 {
1827 sc.function = NULL;
1828 sc.block = NULL;
1829 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1830 {
1831 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1832 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1833 {
1834 DWARFDebugInfoEntry *function_die = NULL;
1835 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001836 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001837
1838 if (function_die != NULL)
1839 {
1840 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1841 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001842 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001843 }
1844
1845 if (sc.function != NULL)
1846 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001847 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848
1849 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001850 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001852 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001853 }
1854 }
1855 }
1856
1857 sc_list.Append(sc);
1858 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1859 }
1860 }
1861 }
1862 else if (file_spec_matches_cu_file_spec && !check_inlines)
1863 {
1864 // only append the context if we aren't looking for inline call sites
1865 // by file and line and if the file spec matches that of the compile unit
1866 sc_list.Append(sc);
1867 }
1868 }
1869 else if (file_spec_matches_cu_file_spec && !check_inlines)
1870 {
1871 // only append the context if we aren't looking for inline call sites
1872 // by file and line and if the file spec matches that of the compile unit
1873 sc_list.Append(sc);
1874 }
1875
1876 if (!check_inlines)
1877 break;
1878 }
1879 }
1880 }
1881 }
1882 return sc_list.GetSize() - prev_size;
1883}
1884
1885void
1886SymbolFileDWARF::Index ()
1887{
1888 if (m_indexed)
1889 return;
1890 m_indexed = true;
1891 Timer scoped_timer (__PRETTY_FUNCTION__,
1892 "SymbolFileDWARF::Index (%s)",
1893 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1894
1895 DWARFDebugInfo* debug_info = DebugInfo();
1896 if (debug_info)
1897 {
1898 uint32_t cu_idx = 0;
1899 const uint32_t num_compile_units = GetNumCompileUnits();
1900 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1901 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001902 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903
Greg Clayton96d7d742010-11-10 23:42:09 +00001904 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905
Greg Clayton96d7d742010-11-10 23:42:09 +00001906 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001907 m_function_basename_index,
1908 m_function_fullname_index,
1909 m_function_method_index,
1910 m_function_selector_index,
1911 m_objc_class_selectors_index,
1912 m_global_index,
1913 m_type_index,
Greg Claytond4a2b372011-09-12 23:21:58 +00001914 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915
1916 // Keep memory down by clearing DIEs if this generate function
1917 // caused them to be parsed
1918 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001919 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001920 }
1921
Greg Claytond4a2b372011-09-12 23:21:58 +00001922 m_function_basename_index.Finalize();
1923 m_function_fullname_index.Finalize();
1924 m_function_method_index.Finalize();
1925 m_function_selector_index.Finalize();
1926 m_objc_class_selectors_index.Finalize();
1927 m_global_index.Finalize();
1928 m_type_index.Finalize();
1929 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001930
Greg Clayton24739922010-10-13 03:15:28 +00001931#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00001932 StreamFile s(stdout, false);
Greg Claytonf9eec202011-09-01 23:16:13 +00001933 s.Printf ("DWARF index for '%s/%s':",
Greg Clayton24739922010-10-13 03:15:28 +00001934 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1935 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001936 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1937 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1938 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1939 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1940 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1941 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001942 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001943 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001944#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001945 }
1946}
1947
1948uint32_t
1949SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1950{
Greg Clayton21f2a492011-10-06 00:09:08 +00001951 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
1952
1953 if (log)
1954 {
1955 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", name=\"%s\", append=%u, max_matches=%u, variables)",
1956 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
1957 m_obj_file->GetFileSpec().GetFilename().GetCString(),
1958 name.GetCString(), append, max_matches);
1959 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001960 DWARFDebugInfo* info = DebugInfo();
1961 if (info == NULL)
1962 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001963
1964 // If we aren't appending the results to this list, then clear the list
1965 if (!append)
1966 variables.Clear();
1967
1968 // Remember how many variables are in the list before we search in case
1969 // we are appending the results to a variable list.
1970 const uint32_t original_size = variables.GetSize();
1971
Greg Claytond4a2b372011-09-12 23:21:58 +00001972 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00001973
1974 if (m_apple_names_ap.get())
1975 {
1976 const char *name_cstr = name.GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00001977 const char *base_name_start;
1978 const char *base_name_end = NULL;
1979
1980 if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end))
1981 base_name_start = name_cstr;
1982
1983 m_apple_names_ap->FindByName (base_name_start, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00001984 }
1985 else
1986 {
1987 // Index the DWARF if we haven't already
1988 if (!m_indexed)
1989 Index ();
1990
1991 m_global_index.Find (name, die_offsets);
1992 }
1993
1994 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00001995 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001996 {
Greg Clayton7f995132011-10-04 22:41:51 +00001997 SymbolContext sc;
1998 sc.module_sp = m_obj_file->GetModule();
1999 assert (sc.module_sp);
2000
Greg Claytond4a2b372011-09-12 23:21:58 +00002001 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00002002 DWARFCompileUnit* dwarf_cu = NULL;
2003 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002004 for (size_t i=0; i<num_matches; ++i)
2005 {
2006 const dw_offset_t die_offset = die_offsets[i];
2007 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002008
Greg Claytond4a2b372011-09-12 23:21:58 +00002009 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2010 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002011
Greg Claytond4a2b372011-09-12 23:21:58 +00002012 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013
Greg Claytond4a2b372011-09-12 23:21:58 +00002014 if (variables.GetSize() - original_size >= max_matches)
2015 break;
2016 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002017 }
2018
2019 // Return the number of variable that were appended to the list
2020 return variables.GetSize() - original_size;
2021}
2022
2023uint32_t
2024SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2025{
Greg Clayton21f2a492011-10-06 00:09:08 +00002026 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2027
2028 if (log)
2029 {
2030 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", regex=\"%s\", append=%u, max_matches=%u, variables)",
2031 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2032 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2033 regex.GetText(), append, max_matches);
2034 }
2035
Greg Claytonc685f8e2010-09-15 04:15:46 +00002036 DWARFDebugInfo* info = DebugInfo();
2037 if (info == NULL)
2038 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002039
2040 // If we aren't appending the results to this list, then clear the list
2041 if (!append)
2042 variables.Clear();
2043
2044 // Remember how many variables are in the list before we search in case
2045 // we are appending the results to a variable list.
2046 const uint32_t original_size = variables.GetSize();
2047
Greg Clayton7f995132011-10-04 22:41:51 +00002048 DIEArray die_offsets;
2049
2050 if (m_apple_names_ap.get())
2051 {
2052 m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
2053 }
2054 else
2055 {
2056 // Index the DWARF if we haven't already
2057 if (!m_indexed)
2058 Index ();
2059
2060 m_global_index.Find (regex, die_offsets);
2061 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002062
Greg Claytonc685f8e2010-09-15 04:15:46 +00002063 SymbolContext sc;
Greg Claytona2eee182011-09-17 07:23:18 +00002064 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002065 assert (sc.module_sp);
2066
Greg Claytond4a2b372011-09-12 23:21:58 +00002067 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002068 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002069 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002070 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002071 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002072 DWARFDebugInfo* debug_info = DebugInfo();
2073 for (size_t i=0; i<num_matches; ++i)
2074 {
2075 const dw_offset_t die_offset = die_offsets[i];
2076 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2077 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002078
Greg Claytond4a2b372011-09-12 23:21:58 +00002079 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080
Greg Claytond4a2b372011-09-12 23:21:58 +00002081 if (variables.GetSize() - original_size >= max_matches)
2082 break;
2083 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002084 }
2085
2086 // Return the number of variable that were appended to the list
2087 return variables.GetSize() - original_size;
2088}
2089
Jim Ingham4cda6e02011-10-07 22:23:45 +00002090bool
2091SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
2092 DWARFCompileUnit *&dwarf_cu,
2093 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002094{
Greg Clayton9e315582011-09-02 04:03:59 +00002095 SymbolContext sc;
Greg Clayton9e315582011-09-02 04:03:59 +00002096
Jim Ingham4cda6e02011-10-07 22:23:45 +00002097 DWARFDebugInfo* info = DebugInfo();
2098 bool resolved_it = false;
2099
2100 if (info == NULL)
2101 return resolved_it;
2102
2103 DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2104
2105 // If we were passed a die that is not a function, just return false...
2106 if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine)
2107 return false;
2108
2109 const DWARFDebugInfoEntry* inlined_die = NULL;
2110 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002111 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002112 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002113
Jim Ingham4cda6e02011-10-07 22:23:45 +00002114 while ((die = die->GetParent()) != NULL)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002115 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002116 if (die->Tag() == DW_TAG_subprogram)
2117 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002118 }
2119 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002120 assert (die->Tag() == DW_TAG_subprogram);
2121 if (GetFunction (dwarf_cu, die, sc))
2122 {
2123 Address addr;
2124 // Parse all blocks if needed
2125 if (inlined_die)
2126 {
2127 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2128 assert (sc.block != NULL);
2129 if (sc.block->GetStartAddress (addr) == false)
2130 addr.Clear();
2131 }
2132 else
2133 {
2134 sc.block = NULL;
2135 addr = sc.function->GetAddressRange().GetBaseAddress();
2136 }
2137
2138 if (addr.IsValid())
2139 {
2140
2141 // We found the function, so we should find the line table
2142 // and line table entry as well
2143 LineTable *line_table = sc.comp_unit->GetLineTable();
2144 if (line_table == NULL)
2145 {
2146 if (ParseCompileUnitLineTable(sc))
2147 line_table = sc.comp_unit->GetLineTable();
2148 }
2149 if (line_table != NULL)
2150 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2151
2152 sc_list.Append(sc);
2153 resolved_it = true;
2154 }
2155 }
2156
2157 return resolved_it;
Greg Clayton9e315582011-09-02 04:03:59 +00002158}
2159
Greg Clayton7f995132011-10-04 22:41:51 +00002160void
2161SymbolFileDWARF::FindFunctions (const ConstString &name,
2162 const NameToDIE &name_to_die,
2163 SymbolContextList& sc_list)
2164{
Greg Claytond4a2b372011-09-12 23:21:58 +00002165 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002166 if (name_to_die.Find (name, die_offsets))
2167 {
2168 ParseFunctions (die_offsets, sc_list);
2169 }
2170}
2171
2172
2173void
2174SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2175 const NameToDIE &name_to_die,
2176 SymbolContextList& sc_list)
2177{
2178 DIEArray die_offsets;
2179 if (name_to_die.Find (regex, die_offsets))
2180 {
2181 ParseFunctions (die_offsets, sc_list);
2182 }
2183}
2184
2185
2186void
2187SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2188 const DWARFMappedHash::MemoryTable &memory_table,
2189 SymbolContextList& sc_list)
2190{
2191 DIEArray die_offsets;
2192 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
2193 {
2194 ParseFunctions (die_offsets, sc_list);
2195 }
2196}
2197
2198void
2199SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2200 SymbolContextList& sc_list)
2201{
2202 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002203 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002204 {
Greg Clayton7f995132011-10-04 22:41:51 +00002205 SymbolContext sc;
Greg Clayton7f995132011-10-04 22:41:51 +00002206
2207 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002208 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00002209 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002210 const dw_offset_t die_offset = die_offsets[i];
Jim Ingham4cda6e02011-10-07 22:23:45 +00002211 ResolveFunction (die_offset, dwarf_cu, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002212 }
2213 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002214}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002215
Jim Ingham4cda6e02011-10-07 22:23:45 +00002216bool
2217SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
2218 const DWARFCompileUnit *dwarf_cu,
2219 uint32_t name_type_mask,
2220 const char *partial_name,
2221 const char *base_name_start,
2222 const char *base_name_end)
2223{
2224 // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
2225 if (name_type_mask == eFunctionNameTypeMethod
2226 || name_type_mask == eFunctionNameTypeBase)
2227 {
2228 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
2229 if (!containing_decl_ctx)
2230 return false;
2231
2232 bool is_cxx_method = (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord);
2233
2234 if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
2235 return false;
2236 if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
2237 return false;
2238 }
2239
2240 // Now we need to check whether the name we got back for this type matches the extra specifications
2241 // that were in the name we're looking up:
2242 if (base_name_start != partial_name || *base_name_end != '\0')
2243 {
2244 // First see if the stuff to the left matches the full name. To do that let's see if
2245 // we can pull out the mips linkage name attribute:
2246
2247 Mangled best_name;
2248
2249 DWARFDebugInfoEntry::Attributes attributes;
2250 die->GetAttributes(this, dwarf_cu, NULL, attributes);
2251 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
2252 if (idx != UINT32_MAX)
2253 {
2254 DWARFFormValue form_value;
2255 if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
2256 {
2257 const char *name = form_value.AsCString(&get_debug_str_data());
2258 best_name.SetValue (name, true);
2259 }
2260 }
2261 if (best_name)
2262 {
2263 const char *demangled = best_name.GetDemangledName().GetCString();
2264 if (demangled)
2265 {
2266 std::string name_no_parens(partial_name, base_name_end - partial_name);
2267 if (strstr (demangled, name_no_parens.c_str()) == NULL)
2268 {
2269 printf ("name: \"%s\" didn't match full name: \"%s\".\n", partial_name, demangled);
2270 return false;
2271 }
2272 }
2273 }
2274 }
2275
2276 return true;
2277}
Greg Claytonc685f8e2010-09-15 04:15:46 +00002278
Greg Clayton0c5cd902010-06-28 21:30:43 +00002279uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00002280SymbolFileDWARF::FindFunctions (const ConstString &name,
2281 uint32_t name_type_mask,
2282 bool append,
2283 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002284{
2285 Timer scoped_timer (__PRETTY_FUNCTION__,
2286 "SymbolFileDWARF::FindFunctions (name = '%s')",
2287 name.AsCString());
2288
Greg Clayton21f2a492011-10-06 00:09:08 +00002289 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2290
2291 if (log)
2292 {
2293 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2294 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2295 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2296 name.GetCString(), name_type_mask, append);
2297 }
2298
Greg Clayton0c5cd902010-06-28 21:30:43 +00002299 // If we aren't appending the results to this list, then clear the list
2300 if (!append)
2301 sc_list.Clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002302
2303 // If name is empty then we won't find anything.
2304 if (name.IsEmpty())
2305 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002306
2307 // Remember how many sc_list are in the list before we search in case
2308 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002309
Greg Clayton9e315582011-09-02 04:03:59 +00002310 const uint32_t original_size = sc_list.GetSize();
Greg Clayton0c5cd902010-06-28 21:30:43 +00002311
Jim Ingham4cda6e02011-10-07 22:23:45 +00002312 const char *name_cstr = name.GetCString();
2313 uint32_t effective_name_type_mask = eFunctionNameTypeNone;
2314 const char *base_name_start = name_cstr;
2315 const char *base_name_end = name_cstr + strlen(name_cstr);
2316
2317 if (name_type_mask & eFunctionNameTypeAuto)
2318 {
2319 if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
2320 effective_name_type_mask = eFunctionNameTypeFull;
2321 else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
2322 effective_name_type_mask = eFunctionNameTypeFull;
2323 else
2324 {
2325 if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2326 effective_name_type_mask |= eFunctionNameTypeSelector;
2327
2328 if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2329 effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
2330 }
2331 }
2332 else
2333 {
2334 effective_name_type_mask = name_type_mask;
2335 if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
2336 {
2337 // If they've asked for a CPP method or function name and it can't be that, we don't
2338 // even need to search for CPP methods or names.
2339 if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2340 {
2341 effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
2342 if (effective_name_type_mask == eFunctionNameTypeNone)
2343 return 0;
2344 }
2345 }
2346
2347 if (effective_name_type_mask & eFunctionNameTypeSelector)
2348 {
2349 if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2350 {
2351 effective_name_type_mask &= ~(eFunctionNameTypeSelector);
2352 if (effective_name_type_mask == eFunctionNameTypeNone)
2353 return 0;
2354 }
2355 }
2356 }
2357
2358 DWARFDebugInfo* info = DebugInfo();
2359 if (info == NULL)
2360 return 0;
2361
Greg Clayton7f995132011-10-04 22:41:51 +00002362 if (m_apple_names_ap.get())
Greg Clayton4d01ace2011-09-29 16:58:15 +00002363 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002364 DIEArray die_offsets;
2365
2366 uint32_t num_matches = 0;
2367
2368 if (effective_name_type_mask & eFunctionNameTypeFull)
2369 {
2370 // If they asked for the full name, match what they typed. At some point we may
2371 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2372 // dies that we find by exact match.
2373 DWARFCompileUnit *dwarf_cu = NULL;
2374 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2375 for (uint32_t i = 0; i < num_matches; i++)
2376 ResolveFunction (die_offsets[i], dwarf_cu, sc_list);
2377 }
2378 else
2379 {
2380 DWARFCompileUnit* dwarf_cu = NULL;
2381
2382 if (effective_name_type_mask & eFunctionNameTypeSelector)
2383 {
2384 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2385 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2386 // and if it is an ObjC method name, we're good.
2387
2388 for (uint32_t i = 0; i < num_matches; i++)
2389 {
2390 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2391 assert (die);
2392
2393 const char *die_name = die->GetName(this, dwarf_cu);
2394 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
2395 ResolveFunction (die_offsets[i], dwarf_cu, sc_list);
2396 }
2397 die_offsets.clear();
2398 }
2399
2400 if (effective_name_type_mask & eFunctionNameTypeMethod
2401 || effective_name_type_mask & eFunctionNameTypeBase)
2402 {
2403 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2404 // extract the base name, look that up, and if there is any other information in the name we were
2405 // passed in we have to post-filter based on that.
2406
2407 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2408 std::string base_name(base_name_start, base_name_end - base_name_start);
2409 num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
2410
2411 for (uint32_t i = 0; i < num_matches; i++)
2412 {
2413 dw_offset_t offset = die_offsets[i];
2414 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu);
2415 assert (die);
2416 if (!FunctionDieMatchesPartialName(die,
2417 dwarf_cu,
2418 effective_name_type_mask,
2419 name_cstr,
2420 base_name_start,
2421 base_name_end))
2422 continue;
2423
2424 // If we get to here, the die is good, and we should add it:
2425 ResolveFunction (offset, dwarf_cu, sc_list);
2426 }
2427 die_offsets.clear();
2428 }
2429 }
Greg Clayton7f995132011-10-04 22:41:51 +00002430 }
2431 else
2432 {
2433
2434 // Index the DWARF if we haven't already
2435 if (!m_indexed)
2436 Index ();
2437
Greg Clayton7f995132011-10-04 22:41:51 +00002438 if (name_type_mask & eFunctionNameTypeFull)
2439 FindFunctions (name, m_function_fullname_index, sc_list);
2440
Jim Ingham4cda6e02011-10-07 22:23:45 +00002441 std::string base_name(base_name_start, base_name_end - base_name_start);
2442 ConstString base_name_const(base_name.c_str());
2443 DIEArray die_offsets;
2444 DWARFCompileUnit *dwarf_cu = NULL;
2445
2446 if (effective_name_type_mask & eFunctionNameTypeBase)
2447 {
2448 uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
2449 {
2450 for (uint32_t i = 0; i < num_base; i++)
2451 {
2452 dw_offset_t offset = die_offsets[i];
2453 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu);
2454 assert (die);
2455 if (!FunctionDieMatchesPartialName(die,
2456 dwarf_cu,
2457 effective_name_type_mask,
2458 name_cstr,
2459 base_name_start,
2460 base_name_end))
2461 continue;
2462
2463 // If we get to here, the die is good, and we should add it:
2464 ResolveFunction (offset, dwarf_cu, sc_list);
2465 }
2466 }
2467 die_offsets.clear();
2468 }
2469
Greg Clayton7f995132011-10-04 22:41:51 +00002470 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002471 {
2472 uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
2473 {
2474 for (uint32_t i = 0; i < num_base; i++)
2475 {
2476 dw_offset_t offset = die_offsets[i];
2477 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (offset, &dwarf_cu);
2478 assert (die);
2479 if (!FunctionDieMatchesPartialName(die,
2480 dwarf_cu,
2481 effective_name_type_mask,
2482 name_cstr,
2483 base_name_start,
2484 base_name_end))
2485 continue;
2486
2487 // If we get to here, the die is good, and we should add it:
2488 ResolveFunction (offset, dwarf_cu, sc_list);
2489 }
2490 }
2491 die_offsets.clear();
2492 }
Greg Clayton7f995132011-10-04 22:41:51 +00002493
2494 if (name_type_mask & eFunctionNameTypeSelector)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002495 {
Greg Clayton7f995132011-10-04 22:41:51 +00002496 FindFunctions (name, m_function_selector_index, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002497 }
2498
Greg Clayton4d01ace2011-09-29 16:58:15 +00002499 }
2500
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501 // Return the number of variable that were appended to the list
2502 return sc_list.GetSize() - original_size;
2503}
2504
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002505uint32_t
2506SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2507{
2508 Timer scoped_timer (__PRETTY_FUNCTION__,
2509 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2510 regex.GetText());
2511
Greg Clayton21f2a492011-10-06 00:09:08 +00002512 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2513
2514 if (log)
2515 {
2516 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", regex=\"%s\"append=%u, sc_list)",
2517 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2518 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2519 regex.GetText(), append);
2520 }
2521
2522
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002523 // If we aren't appending the results to this list, then clear the list
2524 if (!append)
2525 sc_list.Clear();
2526
2527 // Remember how many sc_list are in the list before we search in case
2528 // we are appending the results to a variable list.
2529 uint32_t original_size = sc_list.GetSize();
2530
Greg Clayton7f995132011-10-04 22:41:51 +00002531 if (m_apple_names_ap.get())
2532 {
2533 FindFunctions (regex, *m_apple_names_ap, sc_list);
2534 }
2535 else
2536 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002537 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002538 if (!m_indexed)
2539 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002540
Greg Clayton7f995132011-10-04 22:41:51 +00002541 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002542
Greg Clayton7f995132011-10-04 22:41:51 +00002543 FindFunctions (regex, m_function_fullname_index, sc_list);
2544 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002545
2546 // Return the number of variable that were appended to the list
2547 return sc_list.GetSize() - original_size;
2548}
Jim Ingham318c9f22011-08-26 19:44:13 +00002549
Greg Claytond16e1e52011-07-12 17:06:17 +00002550void
2551SymbolFileDWARF::ReportError (const char *format, ...)
2552{
2553 ::fprintf (stderr,
2554 "error: %s/%s ",
2555 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2556 m_obj_file->GetFileSpec().GetFilename().GetCString());
2557
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002558 if (m_obj_file->GetModule()->GetObjectName())
2559 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2560
Greg Claytond16e1e52011-07-12 17:06:17 +00002561 va_list args;
2562 va_start (args, format);
2563 vfprintf (stderr, format, args);
2564 va_end (args);
2565}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002566
Jim Inghamc1663042011-09-29 22:12:35 +00002567void
2568SymbolFileDWARF::ReportWarning (const char *format, ...)
2569{
2570 ::fprintf (stderr,
2571 "warning: %s/%s ",
2572 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2573 m_obj_file->GetFileSpec().GetFilename().GetCString());
2574
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002575 if (m_obj_file->GetModule()->GetObjectName())
2576 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2577
Jim Inghamc1663042011-09-29 22:12:35 +00002578 va_list args;
2579 va_start (args, format);
2580 vfprintf (stderr, format, args);
2581 va_end (args);
2582}
2583
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002584uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002585SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002586{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002587 DWARFDebugInfo* info = DebugInfo();
2588 if (info == NULL)
2589 return 0;
2590
Greg Clayton21f2a492011-10-06 00:09:08 +00002591 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2592
2593 if (log)
2594 {
2595 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", sc, name=\"%s\", append=%u, max_matches=%u, type_list)",
2596 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2597 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2598 name.GetCString(), append, max_matches);
2599 }
2600
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002601 // If we aren't appending the results to this list, then clear the list
2602 if (!append)
2603 types.Clear();
2604
Greg Claytond4a2b372011-09-12 23:21:58 +00002605 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002606
2607 if (m_apple_types_ap.get())
2608 {
2609 const char *name_cstr = name.GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002610 m_apple_types_ap->FindByName (name_cstr, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00002611 }
2612 else
2613 {
2614 if (!m_indexed)
2615 Index ();
2616
2617 m_type_index.Find (name, die_offsets);
2618 }
2619
2620
2621 const size_t num_matches = die_offsets.size();
2622
Greg Claytond4a2b372011-09-12 23:21:58 +00002623 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002624 {
Greg Clayton7f995132011-10-04 22:41:51 +00002625 const uint32_t initial_types_size = types.GetSize();
2626 DWARFCompileUnit* dwarf_cu = NULL;
2627 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002628 DWARFDebugInfo* debug_info = DebugInfo();
2629 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002630 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002631 const dw_offset_t die_offset = die_offsets[i];
2632 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2633
2634 Type *matching_type = ResolveType (dwarf_cu, die);
2635 if (matching_type)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002636 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002637 // We found a type pointer, now find the shared pointer form our type list
2638 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2639 if (type_sp)
2640 {
2641 types.InsertUnique (type_sp);
2642 if (types.GetSize() >= max_matches)
2643 break;
2644 }
2645 else
2646 {
Jim Inghamc1663042011-09-29 22:12:35 +00002647 ReportError ("error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
Greg Claytond4a2b372011-09-12 23:21:58 +00002648 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00002649 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002650 }
Greg Clayton7f995132011-10-04 22:41:51 +00002651 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002652 }
Greg Clayton7f995132011-10-04 22:41:51 +00002653 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002654}
2655
2656
Greg Clayton526e5af2010-11-13 03:52:47 +00002657ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002658SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2659 const ConstString &name)
2660{
Greg Clayton21f2a492011-10-06 00:09:08 +00002661 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2662
2663 if (log)
2664 {
2665 log->Printf ("SymbolFileDWARF::FindNamespace (file=\"%s/%s\", sc, name=\"%s\")",
2666 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2667 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2668 name.GetCString());
2669 }
2670
Greg Clayton526e5af2010-11-13 03:52:47 +00002671 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002672 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002673 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002674 {
Greg Clayton7f995132011-10-04 22:41:51 +00002675 DIEArray die_offsets;
2676
Greg Clayton526e5af2010-11-13 03:52:47 +00002677 // Index if we already haven't to make sure the compile units
2678 // get indexed and make their global DIE index list
Greg Clayton7f995132011-10-04 22:41:51 +00002679 if (m_apple_namespaces_ap.get())
2680 {
2681 const char *name_cstr = name.GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002682 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00002683 }
2684 else
2685 {
2686 if (!m_indexed)
2687 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002688
Greg Clayton7f995132011-10-04 22:41:51 +00002689 m_namespace_index.Find (name, die_offsets);
2690 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002691
2692 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00002693 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002694 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002695 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00002696 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002697 DWARFDebugInfo* debug_info = DebugInfo();
2698 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00002699 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002700 const dw_offset_t die_offset = die_offsets[i];
2701 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2702
2703 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
2704 if (clang_namespace_decl)
2705 {
2706 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2707 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2708 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002709 }
2710 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002711 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002712 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002713}
2714
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002715uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002716SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002717{
2718 // Remember how many sc_list are in the list before we search in case
2719 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002720 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002721
2722 const uint32_t num_die_offsets = die_offsets.size();
2723 // Parse all of the types we found from the pubtypes matches
2724 uint32_t i;
2725 uint32_t num_matches = 0;
2726 for (i = 0; i < num_die_offsets; ++i)
2727 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002728 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2729 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002730 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002731 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002732 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002733 assert (type_sp.get() != NULL);
2734 types.InsertUnique (type_sp);
2735 ++num_matches;
2736 if (num_matches >= max_matches)
2737 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002738 }
2739 }
2740
2741 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002742 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002743}
2744
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002745
2746size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00002747SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
2748 clang::DeclContext *containing_decl_ctx,
2749 TypeSP& type_sp,
2750 DWARFCompileUnit* dwarf_cu,
2751 const DWARFDebugInfoEntry *parent_die,
2752 bool skip_artificial,
2753 bool &is_static,
2754 TypeList* type_list,
2755 std::vector<clang_type_t>& function_param_types,
2756 std::vector<clang::ParmVarDecl*>& function_param_decls,
2757 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002758{
2759 if (parent_die == NULL)
2760 return 0;
2761
Greg Claytond88d7592010-09-15 08:33:30 +00002762 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2763
Greg Clayton7fedea22010-11-16 02:10:54 +00002764 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002765 const DWARFDebugInfoEntry *die;
2766 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2767 {
2768 dw_tag_t tag = die->Tag();
2769 switch (tag)
2770 {
2771 case DW_TAG_formal_parameter:
2772 {
2773 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002774 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002775 if (num_attributes > 0)
2776 {
2777 const char *name = NULL;
2778 Declaration decl;
2779 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002780 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002781 // one of None, Auto, Register, Extern, Static, PrivateExtern
2782
Sean Callanane2ef6e32010-09-23 03:01:22 +00002783 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002784 uint32_t i;
2785 for (i=0; i<num_attributes; ++i)
2786 {
2787 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2788 DWARFFormValue form_value;
2789 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2790 {
2791 switch (attr)
2792 {
2793 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2794 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2795 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2796 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2797 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002798 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002799 case DW_AT_location:
2800 // if (form_value.BlockData())
2801 // {
2802 // const DataExtractor& debug_info_data = debug_info();
2803 // uint32_t block_length = form_value.Unsigned();
2804 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2805 // }
2806 // else
2807 // {
2808 // }
2809 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002810 case DW_AT_const_value:
2811 case DW_AT_default_value:
2812 case DW_AT_description:
2813 case DW_AT_endianity:
2814 case DW_AT_is_optional:
2815 case DW_AT_segment:
2816 case DW_AT_variable_parameter:
2817 default:
2818 case DW_AT_abstract_origin:
2819 case DW_AT_sibling:
2820 break;
2821 }
2822 }
2823 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002824
Greg Clayton0fffff52010-09-24 05:15:53 +00002825 bool skip = false;
2826 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002827 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002828 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002829 {
2830 // In order to determine if a C++ member function is
2831 // "const" we have to look at the const-ness of "this"...
2832 // Ugly, but that
2833 if (arg_idx == 0)
2834 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002835 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord)
Sean Callanan763d72a2011-08-02 22:21:50 +00002836 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002837 // Often times compilers omit the "this" name for the
2838 // specification DIEs, so we can't rely upon the name
2839 // being in the formal parameter DIE...
2840 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00002841 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002842 Type *this_type = ResolveTypeUID (param_type_die_offset);
2843 if (this_type)
2844 {
2845 uint32_t encoding_mask = this_type->GetEncodingMask();
2846 if (encoding_mask & Type::eEncodingIsPointerUID)
2847 {
2848 is_static = false;
2849
2850 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2851 type_quals |= clang::Qualifiers::Const;
2852 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2853 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002854 }
2855 }
2856 }
2857 }
2858 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002859 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002860 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002861 else
2862 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002863
Greg Clayton0fffff52010-09-24 05:15:53 +00002864 // HACK: Objective C formal parameters "self" and "_cmd"
2865 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002866 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2867 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002868 {
2869 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2870 skip = true;
2871 }
2872 }
2873 }
2874
2875 if (!skip)
2876 {
2877 Type *type = ResolveTypeUID(param_type_die_offset);
2878 if (type)
2879 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002880 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002881
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002882 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002883 assert(param_var_decl);
2884 function_param_decls.push_back(param_var_decl);
2885 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886 }
2887 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002888 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002889 }
2890 break;
2891
2892 default:
2893 break;
2894 }
2895 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002896 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002897}
2898
2899size_t
2900SymbolFileDWARF::ParseChildEnumerators
2901(
2902 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002903 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002904 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002905 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002906 const DWARFDebugInfoEntry *parent_die
2907)
2908{
2909 if (parent_die == NULL)
2910 return 0;
2911
2912 size_t enumerators_added = 0;
2913 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002914 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2915
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002916 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2917 {
2918 const dw_tag_t tag = die->Tag();
2919 if (tag == DW_TAG_enumerator)
2920 {
2921 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002922 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002923 if (num_child_attributes > 0)
2924 {
2925 const char *name = NULL;
2926 bool got_value = false;
2927 int64_t enum_value = 0;
2928 Declaration decl;
2929
2930 uint32_t i;
2931 for (i=0; i<num_child_attributes; ++i)
2932 {
2933 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2934 DWARFFormValue form_value;
2935 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2936 {
2937 switch (attr)
2938 {
2939 case DW_AT_const_value:
2940 got_value = true;
2941 enum_value = form_value.Unsigned();
2942 break;
2943
2944 case DW_AT_name:
2945 name = form_value.AsCString(&get_debug_str_data());
2946 break;
2947
2948 case DW_AT_description:
2949 default:
2950 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2951 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2952 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2953 case DW_AT_sibling:
2954 break;
2955 }
2956 }
2957 }
2958
2959 if (name && name[0] && got_value)
2960 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002961 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2962 enumerator_clang_type,
2963 decl,
2964 name,
2965 enum_value,
2966 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002967 ++enumerators_added;
2968 }
2969 }
2970 }
2971 }
2972 return enumerators_added;
2973}
2974
2975void
2976SymbolFileDWARF::ParseChildArrayInfo
2977(
2978 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002979 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002980 const DWARFDebugInfoEntry *parent_die,
2981 int64_t& first_index,
2982 std::vector<uint64_t>& element_orders,
2983 uint32_t& byte_stride,
2984 uint32_t& bit_stride
2985)
2986{
2987 if (parent_die == NULL)
2988 return;
2989
2990 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002991 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002992 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2993 {
2994 const dw_tag_t tag = die->Tag();
2995 switch (tag)
2996 {
2997 case DW_TAG_enumerator:
2998 {
2999 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003000 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 if (num_child_attributes > 0)
3002 {
3003 const char *name = NULL;
3004 bool got_value = false;
3005 int64_t enum_value = 0;
3006
3007 uint32_t i;
3008 for (i=0; i<num_child_attributes; ++i)
3009 {
3010 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3011 DWARFFormValue form_value;
3012 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3013 {
3014 switch (attr)
3015 {
3016 case DW_AT_const_value:
3017 got_value = true;
3018 enum_value = form_value.Unsigned();
3019 break;
3020
3021 case DW_AT_name:
3022 name = form_value.AsCString(&get_debug_str_data());
3023 break;
3024
3025 case DW_AT_description:
3026 default:
3027 case DW_AT_decl_file:
3028 case DW_AT_decl_line:
3029 case DW_AT_decl_column:
3030 case DW_AT_sibling:
3031 break;
3032 }
3033 }
3034 }
3035 }
3036 }
3037 break;
3038
3039 case DW_TAG_subrange_type:
3040 {
3041 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003042 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003043 if (num_child_attributes > 0)
3044 {
3045 const char *name = NULL;
3046 bool got_value = false;
3047 uint64_t byte_size = 0;
3048 int64_t enum_value = 0;
3049 uint64_t num_elements = 0;
3050 uint64_t lower_bound = 0;
3051 uint64_t upper_bound = 0;
3052 uint32_t i;
3053 for (i=0; i<num_child_attributes; ++i)
3054 {
3055 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3056 DWARFFormValue form_value;
3057 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3058 {
3059 switch (attr)
3060 {
3061 case DW_AT_const_value:
3062 got_value = true;
3063 enum_value = form_value.Unsigned();
3064 break;
3065
3066 case DW_AT_name:
3067 name = form_value.AsCString(&get_debug_str_data());
3068 break;
3069
3070 case DW_AT_count:
3071 num_elements = form_value.Unsigned();
3072 break;
3073
3074 case DW_AT_bit_stride:
3075 bit_stride = form_value.Unsigned();
3076 break;
3077
3078 case DW_AT_byte_stride:
3079 byte_stride = form_value.Unsigned();
3080 break;
3081
3082 case DW_AT_byte_size:
3083 byte_size = form_value.Unsigned();
3084 break;
3085
3086 case DW_AT_lower_bound:
3087 lower_bound = form_value.Unsigned();
3088 break;
3089
3090 case DW_AT_upper_bound:
3091 upper_bound = form_value.Unsigned();
3092 break;
3093
3094 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003095 case DW_AT_abstract_origin:
3096 case DW_AT_accessibility:
3097 case DW_AT_allocated:
3098 case DW_AT_associated:
3099 case DW_AT_data_location:
3100 case DW_AT_declaration:
3101 case DW_AT_description:
3102 case DW_AT_sibling:
3103 case DW_AT_threads_scaled:
3104 case DW_AT_type:
3105 case DW_AT_visibility:
3106 break;
3107 }
3108 }
3109 }
3110
3111 if (upper_bound > lower_bound)
3112 num_elements = upper_bound - lower_bound + 1;
3113
3114 if (num_elements > 0)
3115 element_orders.push_back (num_elements);
3116 }
3117 }
3118 break;
3119 }
3120 }
3121}
3122
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003123TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00003124SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003125{
3126 TypeSP type_sp;
3127 if (die != NULL)
3128 {
Greg Clayton96d7d742010-11-10 23:42:09 +00003129 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003130 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003131 if (type_ptr == NULL)
3132 {
Greg Claytonca512b32011-01-14 04:54:56 +00003133 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
3134 assert (lldb_cu);
3135 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00003136 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003137 }
3138 else if (type_ptr != DIE_IS_BEING_PARSED)
3139 {
3140 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003141 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003142 }
3143
3144 }
3145 return type_sp;
3146}
3147
3148clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003149SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003150{
3151 if (die_offset != DW_INVALID_OFFSET)
3152 {
3153 DWARFCompileUnitSP cu_sp;
3154 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Sean Callanan72e49402011-08-05 23:43:37 +00003155 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003156 }
3157 return NULL;
3158}
3159
Sean Callanan72e49402011-08-05 23:43:37 +00003160clang::DeclContext *
3161SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
3162{
3163 if (die_offset != DW_INVALID_OFFSET)
3164 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003165 DWARFDebugInfo* debug_info = DebugInfo();
3166 if (debug_info)
3167 {
3168 DWARFCompileUnitSP cu_sp;
3169 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
3170 if (die)
3171 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
3172 }
Sean Callanan72e49402011-08-05 23:43:37 +00003173 }
3174 return NULL;
3175}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003176
Greg Clayton96d7d742010-11-10 23:42:09 +00003177clang::NamespaceDecl *
3178SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3179{
3180 if (die->Tag() == DW_TAG_namespace)
3181 {
3182 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3183 if (namespace_name)
3184 {
3185 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00003186 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent()));
Greg Clayton96d7d742010-11-10 23:42:09 +00003187 if (namespace_decl)
Greg Claytona2721472011-06-25 00:44:06 +00003188 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton96d7d742010-11-10 23:42:09 +00003189 return namespace_decl;
3190 }
3191 }
3192 return NULL;
3193}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194
3195clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003196SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3197{
Greg Clayton5cf58b92011-10-05 22:22:08 +00003198 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3199 if (clang_decl_ctx)
3200 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003201 // If this DIE has a specification, or an abstract origin, then trace to those.
3202
3203 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
3204 if (die_offset != DW_INVALID_OFFSET)
3205 return GetClangDeclContextForDIEOffset (sc, die_offset);
3206
3207 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3208 if (die_offset != DW_INVALID_OFFSET)
3209 return GetClangDeclContextForDIEOffset (sc, die_offset);
3210
3211 // This is the DIE we want. Parse it, then query our map.
3212
3213 ParseType(sc, curr_cu, die, NULL);
3214
Greg Clayton5cf58b92011-10-05 22:22:08 +00003215 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3216
3217 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003218}
3219
3220clang::DeclContext *
Greg Clayton2bc22f82011-09-30 03:20:47 +00003221SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003222{
Greg Claytonca512b32011-01-14 04:54:56 +00003223 if (m_clang_tu_decl == NULL)
3224 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003225
Greg Clayton2bc22f82011-09-30 03:20:47 +00003226 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
3227
3228 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003229 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003230 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
3231 if (pos != m_die_to_decl_ctx.end())
3232 return pos->second;
3233
3234 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003235 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003236 case DW_TAG_compile_unit:
3237 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003238
Greg Clayton2bc22f82011-09-30 03:20:47 +00003239 case DW_TAG_namespace:
Greg Claytonca512b32011-01-14 04:54:56 +00003240 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003241 const char *namespace_name = decl_ctx_die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
3242 if (namespace_name)
Greg Claytonca512b32011-01-14 04:54:56 +00003243 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003244 Declaration decl; // TODO: fill in the decl object
3245 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (cu, decl_ctx_die));
3246 if (namespace_decl)
3247 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, decl_ctx_die);
3248 return namespace_decl;
3249 }
3250 }
3251 break;
3252
3253 case DW_TAG_structure_type:
3254 case DW_TAG_union_type:
3255 case DW_TAG_class_type:
3256 {
3257 Type* type = ResolveType (cu, decl_ctx_die);
3258 if (type)
3259 {
3260 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
3261 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00003262 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003263 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
3264 if (decl_ctx)
3265 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00003266 }
3267 }
Greg Claytonca512b32011-01-14 04:54:56 +00003268 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00003269 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003270
Greg Clayton2bc22f82011-09-30 03:20:47 +00003271 default:
3272 break;
Greg Claytonca512b32011-01-14 04:54:56 +00003273 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003274 }
Greg Clayton7a345282010-11-09 23:46:37 +00003275 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003276}
3277
Greg Clayton2bc22f82011-09-30 03:20:47 +00003278
3279const DWARFDebugInfoEntry *
3280SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
3281{
3282 if (cu && die)
3283 {
3284 const DWARFDebugInfoEntry * const decl_die = die;
3285
3286 while (die != NULL)
3287 {
3288 // If this is the original DIE that we are searching for a declaration
3289 // for, then don't look in the cache as we don't want our own decl
3290 // context to be our decl context...
3291 if (decl_die != die)
3292 {
3293 switch (die->Tag())
3294 {
3295 case DW_TAG_compile_unit:
3296 case DW_TAG_namespace:
3297 case DW_TAG_structure_type:
3298 case DW_TAG_union_type:
3299 case DW_TAG_class_type:
3300 return die;
3301
3302 default:
3303 break;
3304 }
3305 }
3306
3307 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
3308 if (die_offset != DW_INVALID_OFFSET)
3309 {
3310 DWARFCompileUnit *spec_cu = cu;
3311 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
3312 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
3313 if (spec_die_decl_ctx_die)
3314 return spec_die_decl_ctx_die;
3315 }
3316
3317 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3318 if (die_offset != DW_INVALID_OFFSET)
3319 {
3320 DWARFCompileUnit *abs_cu = cu;
3321 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
3322 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
3323 if (abs_die_decl_ctx_die)
3324 return abs_die_decl_ctx_die;
3325 }
3326
3327 die = die->GetParent();
3328 }
3329 }
3330 return NULL;
3331}
3332
3333
3334
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003335// This function can be used when a DIE is found that is a forward declaration
3336// DIE and we want to try and find a type that has the complete definition.
3337TypeSP
Greg Clayton7f995132011-10-04 22:41:51 +00003338SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
3339 const DWARFDebugInfoEntry *die,
3340 const ConstString &type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003341{
3342 TypeSP type_sp;
3343
Greg Clayton1a65ae12011-01-25 23:55:37 +00003344 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003345 return type_sp;
3346
Greg Clayton7f995132011-10-04 22:41:51 +00003347 DIEArray die_offsets;
3348
3349 if (m_apple_types_ap.get())
3350 {
3351 const char *name_cstr = type_name.GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00003352 m_apple_types_ap->FindByName (name_cstr, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00003353 }
3354 else
3355 {
3356 if (!m_indexed)
3357 Index ();
3358
3359 m_type_index.Find (type_name, die_offsets);
3360 }
3361
3362
3363 const size_t num_matches = die_offsets.size();
Greg Clayton69974892010-12-03 21:42:06 +00003364
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003365 const dw_tag_t type_tag = die->Tag();
Greg Claytond4a2b372011-09-12 23:21:58 +00003366
3367 DWARFCompileUnit* type_cu = NULL;
3368 const DWARFDebugInfoEntry* type_die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003369 if (num_matches)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003370 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003371 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003372 for (size_t i=0; i<num_matches; ++i)
3373 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003374 const dw_offset_t die_offset = die_offsets[i];
3375 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003376
3377 if (type_die != die && type_die->Tag() == type_tag)
3378 {
3379 // Hold off on comparing parent DIE tags until
3380 // we know what happens with stuff in namespaces
3381 // for gcc and clang...
3382 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3383 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3384 //if (parent_die->Tag() == parent_type_die->Tag())
3385 {
3386 Type *resolved_type = ResolveType (type_cu, type_die, false);
3387 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3388 {
3389 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
3390 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00003391 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003392 m_obj_file->GetFileSpec().GetFilename().AsCString(),
3393 type_die->GetOffset(),
3394 type_cu->GetOffset());
3395
3396 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003397 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00003398 if (!type_sp)
3399 {
3400 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
3401 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003402 break;
3403 }
3404 }
3405 }
3406 }
3407 }
3408 return type_sp;
3409}
3410
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003411TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003412SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003413{
3414 TypeSP type_sp;
3415
Greg Clayton1be10fc2010-09-29 01:12:09 +00003416 if (type_is_new_ptr)
3417 *type_is_new_ptr = false;
3418
Sean Callananc7fbf732010-08-06 00:32:49 +00003419 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003420 if (die != NULL)
3421 {
Greg Clayton21f2a492011-10-06 00:09:08 +00003422 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Jim Ingham16746d12011-08-25 23:21:43 +00003423 if (log && dwarf_cu)
3424 {
Jim Ingham318c9f22011-08-26 19:44:13 +00003425 StreamString s;
Jim Inghamd3d25d92011-08-27 01:24:54 +00003426 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham318c9f22011-08-26 19:44:13 +00003427 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3428
Jim Ingham16746d12011-08-25 23:21:43 +00003429 }
3430
Greg Clayton594e5ed2010-09-27 21:07:38 +00003431 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003432 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003433 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003434 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003435 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003436 if (type_is_new_ptr)
3437 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003438
Greg Clayton594e5ed2010-09-27 21:07:38 +00003439 const dw_tag_t tag = die->Tag();
3440
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003441 bool is_forward_declaration = false;
3442 DWARFDebugInfoEntry::Attributes attributes;
3443 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003444 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003445 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3446 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003447 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003448 Declaration decl;
3449
Greg Clayton4957bf62010-09-30 21:49:03 +00003450 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003451 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003452
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003453 dw_attr_t attr;
3454
3455 switch (tag)
3456 {
3457 case DW_TAG_base_type:
3458 case DW_TAG_pointer_type:
3459 case DW_TAG_reference_type:
3460 case DW_TAG_typedef:
3461 case DW_TAG_const_type:
3462 case DW_TAG_restrict_type:
3463 case DW_TAG_volatile_type:
3464 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003465 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003466 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003467
Greg Claytond88d7592010-09-15 08:33:30 +00003468 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003469 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003470 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3471
3472 if (num_attributes > 0)
3473 {
3474 uint32_t i;
3475 for (i=0; i<num_attributes; ++i)
3476 {
3477 attr = attributes.AttributeAtIndex(i);
3478 DWARFFormValue form_value;
3479 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3480 {
3481 switch (attr)
3482 {
3483 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3484 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3485 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3486 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003487
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003488 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003489 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3490 // include the "&"...
3491 if (tag == DW_TAG_reference_type)
3492 {
3493 if (strchr (type_name_cstr, '&') == NULL)
3494 type_name_cstr = NULL;
3495 }
3496 if (type_name_cstr)
3497 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003498 break;
Greg Clayton36909642011-03-15 04:38:20 +00003499 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003500 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3501 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3502 default:
3503 case DW_AT_sibling:
3504 break;
3505 }
3506 }
3507 }
3508 }
3509
Greg Claytonc93237c2010-10-01 20:48:32 +00003510 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
3511
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003512 switch (tag)
3513 {
3514 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003515 break;
3516
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003518 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003519 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3520 encoding,
3521 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003522 break;
3523
Greg Clayton526e5af2010-11-13 03:52:47 +00003524 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3525 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3526 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3527 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3528 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3529 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003530 }
3531
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003532 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3533 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3534 {
3535 static ConstString g_objc_type_name_id("id");
3536 static ConstString g_objc_type_name_Class("Class");
3537 static ConstString g_objc_type_name_selector("SEL");
3538
Greg Clayton24739922010-10-13 03:15:28 +00003539 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003540 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003541 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003542 resolve_state = Type::eResolveStateFull;
3543
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003544 }
Greg Clayton24739922010-10-13 03:15:28 +00003545 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003546 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003547 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003548 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003549 }
Greg Clayton24739922010-10-13 03:15:28 +00003550 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003551 {
Sean Callananf6c73082010-12-06 23:53:20 +00003552 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003553 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003554 }
3555 }
3556
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003557 type_sp.reset( new Type (die->GetOffset(),
3558 this,
3559 type_name_const_str,
3560 byte_size,
3561 NULL,
3562 encoding_uid,
3563 encoding_data_type,
3564 &decl,
3565 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003566 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003567
Greg Clayton594e5ed2010-09-27 21:07:38 +00003568 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003569
3570// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3571// if (encoding_type != NULL)
3572// {
3573// if (encoding_type != DIE_IS_BEING_PARSED)
3574// type_sp->SetEncodingType(encoding_type);
3575// else
3576// m_indirect_fixups.push_back(type_sp.get());
3577// }
3578 }
3579 break;
3580
3581 case DW_TAG_structure_type:
3582 case DW_TAG_union_type:
3583 case DW_TAG_class_type:
3584 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003585 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003586 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003587
Greg Clayton9e409562010-07-28 02:04:09 +00003588 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003589 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003590 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003591 if (num_attributes > 0)
3592 {
3593 uint32_t i;
3594 for (i=0; i<num_attributes; ++i)
3595 {
3596 attr = attributes.AttributeAtIndex(i);
3597 DWARFFormValue form_value;
3598 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3599 {
3600 switch (attr)
3601 {
Greg Clayton9e409562010-07-28 02:04:09 +00003602 case DW_AT_decl_file:
3603 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3604 break;
3605
3606 case DW_AT_decl_line:
3607 decl.SetLine(form_value.Unsigned());
3608 break;
3609
3610 case DW_AT_decl_column:
3611 decl.SetColumn(form_value.Unsigned());
3612 break;
3613
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614 case DW_AT_name:
3615 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003616 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003617 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003618
3619 case DW_AT_byte_size:
3620 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003621 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003622 break;
3623
3624 case DW_AT_accessibility:
3625 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3626 break;
3627
3628 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003629 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003630 break;
3631
3632 case DW_AT_APPLE_runtime_class:
3633 class_language = (LanguageType)form_value.Signed();
3634 break;
3635
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003636 case DW_AT_allocated:
3637 case DW_AT_associated:
3638 case DW_AT_data_location:
3639 case DW_AT_description:
3640 case DW_AT_start_scope:
3641 case DW_AT_visibility:
3642 default:
3643 case DW_AT_sibling:
3644 break;
3645 }
3646 }
3647 }
3648 }
3649
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003650 UniqueDWARFASTType unique_ast_entry;
3651 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003652 {
Greg Claytone576ab22011-02-15 00:19:15 +00003653 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003654 this,
3655 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003656 die,
3657 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003658 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003659 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003660 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003661 // We have already parsed this type or from another
3662 // compile unit. GCC loves to use the "one definition
3663 // rule" which can result in multiple definitions
3664 // of the same class over and over in each compile
3665 // unit.
3666 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003667 if (type_sp)
3668 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003669 m_die_to_type[die] = type_sp.get();
3670 return type_sp;
3671 }
3672 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003673 }
3674
3675 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3676
3677 int tag_decl_kind = -1;
3678 AccessType default_accessibility = eAccessNone;
3679 if (tag == DW_TAG_structure_type)
3680 {
3681 tag_decl_kind = clang::TTK_Struct;
3682 default_accessibility = eAccessPublic;
3683 }
3684 else if (tag == DW_TAG_union_type)
3685 {
3686 tag_decl_kind = clang::TTK_Union;
3687 default_accessibility = eAccessPublic;
3688 }
3689 else if (tag == DW_TAG_class_type)
3690 {
3691 tag_decl_kind = clang::TTK_Class;
3692 default_accessibility = eAccessPrivate;
3693 }
3694
3695
3696 if (is_forward_declaration)
3697 {
3698 // We have a forward declaration to a type and we need
3699 // to try and find a full declaration. We look in the
3700 // current type index just in case we have a forward
3701 // declaration followed by an actual declarations in the
3702 // DWARF. If this fails, we need to look elsewhere...
3703
3704 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3705
3706 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003707 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003708 // We weren't able to find a full declaration in
3709 // this DWARF, see if we have a declaration anywhere
3710 // else...
3711 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003712 }
3713
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003714 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003715 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003716 // We found a real definition for this type elsewhere
3717 // so lets use it and cache the fact that we found
3718 // a complete type for this die
3719 m_die_to_type[die] = type_sp.get();
3720 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003721 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003722 }
3723 assert (tag_decl_kind != -1);
3724 bool clang_type_was_created = false;
3725 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3726 if (clang_type == NULL)
3727 {
3728 clang_type_was_created = true;
3729 clang_type = ast.CreateRecordType (type_name_cstr,
3730 tag_decl_kind,
Sean Callanan72e49402011-08-05 23:43:37 +00003731 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003732 class_language);
3733 }
3734
3735 // Store a forward declaration to this class type in case any
3736 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00003737 // types for function prototypes.
3738 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003739 type_sp.reset (new Type (die->GetOffset(),
3740 this,
3741 type_name_const_str,
3742 byte_size,
3743 NULL,
3744 LLDB_INVALID_UID,
3745 Type::eEncodingIsUID,
3746 &decl,
3747 clang_type,
3748 Type::eResolveStateForward));
3749
3750
3751 // Add our type to the unique type map so we don't
3752 // end up creating many copies of the same type over
3753 // and over in the ASTContext for our module
3754 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00003755 unique_ast_entry.m_symfile = this;
3756 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003757 unique_ast_entry.m_die = die;
3758 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00003759 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3760 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003761
3762 if (die->HasChildren() == false && is_forward_declaration == false)
3763 {
3764 // No children for this struct/union/class, lets finish it
3765 ast.StartTagDeclarationDefinition (clang_type);
3766 ast.CompleteTagDeclarationDefinition (clang_type);
3767 }
3768 else if (clang_type_was_created)
3769 {
3770 // Leave this as a forward declaration until we need
3771 // to know the details of the type. lldb_private::Type
3772 // will automatically call the SymbolFile virtual function
3773 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3774 // When the definition needs to be defined.
3775 m_forward_decl_die_to_clang_type[die] = clang_type;
3776 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3777 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003778 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003779 }
3780 break;
3781
3782 case DW_TAG_enumeration_type:
3783 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003784 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003785 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003786
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003787 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003788
Greg Claytond88d7592010-09-15 08:33:30 +00003789 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003790 if (num_attributes > 0)
3791 {
3792 uint32_t i;
3793
3794 for (i=0; i<num_attributes; ++i)
3795 {
3796 attr = attributes.AttributeAtIndex(i);
3797 DWARFFormValue form_value;
3798 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3799 {
3800 switch (attr)
3801 {
Greg Clayton7a345282010-11-09 23:46:37 +00003802 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3803 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3804 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003805 case DW_AT_name:
3806 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003807 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003808 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003809 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003810 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00003811 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3812 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003813 case DW_AT_allocated:
3814 case DW_AT_associated:
3815 case DW_AT_bit_stride:
3816 case DW_AT_byte_stride:
3817 case DW_AT_data_location:
3818 case DW_AT_description:
3819 case DW_AT_start_scope:
3820 case DW_AT_visibility:
3821 case DW_AT_specification:
3822 case DW_AT_abstract_origin:
3823 case DW_AT_sibling:
3824 break;
3825 }
3826 }
3827 }
3828
Greg Claytonc93237c2010-10-01 20:48:32 +00003829 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3830
Greg Clayton1be10fc2010-09-29 01:12:09 +00003831 clang_type_t enumerator_clang_type = NULL;
3832 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3833 if (clang_type == NULL)
3834 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003835 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3836 DW_ATE_signed,
3837 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003838 clang_type = ast.CreateEnumerationType (type_name_cstr,
Sean Callanan72e49402011-08-05 23:43:37 +00003839 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003840 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003841 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003842 }
3843 else
3844 {
3845 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3846 assert (enumerator_clang_type != NULL);
3847 }
3848
Greg Claytona2721472011-06-25 00:44:06 +00003849 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3850
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003851 type_sp.reset( new Type (die->GetOffset(),
3852 this,
3853 type_name_const_str,
3854 byte_size,
3855 NULL,
3856 encoding_uid,
3857 Type::eEncodingIsUID,
3858 &decl,
3859 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003860 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003861
Greg Clayton6beaaa62011-01-17 03:46:26 +00003862#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003863 // Leave this as a forward declaration until we need
3864 // to know the details of the type. lldb_private::Type
3865 // will automatically call the SymbolFile virtual function
3866 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3867 // When the definition needs to be defined.
3868 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003869 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003870 ClangASTContext::SetHasExternalStorage (clang_type, true);
3871#else
3872 ast.StartTagDeclarationDefinition (clang_type);
3873 if (die->HasChildren())
3874 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003875 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3876 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003877 }
3878 ast.CompleteTagDeclarationDefinition (clang_type);
3879#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003880 }
3881 }
3882 break;
3883
Jim Inghamb0be4422010-08-12 01:20:14 +00003884 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003885 case DW_TAG_subprogram:
3886 case DW_TAG_subroutine_type:
3887 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003888 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003889 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003890
3891 const char *mangled = NULL;
3892 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003893 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003894 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003895 bool is_static = false;
3896 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003897 bool is_explicit = false;
Greg Clayton72da3972011-08-16 18:40:23 +00003898 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
3899 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00003900
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003901 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003902 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003903
3904
Greg Claytond88d7592010-09-15 08:33:30 +00003905 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003906 if (num_attributes > 0)
3907 {
3908 uint32_t i;
3909 for (i=0; i<num_attributes; ++i)
3910 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003911 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003912 DWARFFormValue form_value;
3913 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3914 {
3915 switch (attr)
3916 {
3917 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3918 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3919 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3920 case DW_AT_name:
3921 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003922 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003923 break;
3924
3925 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3926 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003927 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003928 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003929 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3930 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003931 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3932
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003933 case DW_AT_external:
3934 if (form_value.Unsigned())
3935 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003936 if (storage == clang::SC_None)
3937 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003938 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003939 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003940 }
3941 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003942
Greg Clayton72da3972011-08-16 18:40:23 +00003943 case DW_AT_specification:
3944 specification_die_offset = form_value.Reference(dwarf_cu);
3945 break;
3946
3947 case DW_AT_abstract_origin:
3948 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
3949 break;
3950
3951
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003952 case DW_AT_allocated:
3953 case DW_AT_associated:
3954 case DW_AT_address_class:
3955 case DW_AT_artificial:
3956 case DW_AT_calling_convention:
3957 case DW_AT_data_location:
3958 case DW_AT_elemental:
3959 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 case DW_AT_frame_base:
3961 case DW_AT_high_pc:
3962 case DW_AT_low_pc:
3963 case DW_AT_object_pointer:
3964 case DW_AT_prototyped:
3965 case DW_AT_pure:
3966 case DW_AT_ranges:
3967 case DW_AT_recursive:
3968 case DW_AT_return_addr:
3969 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003970 case DW_AT_start_scope:
3971 case DW_AT_static_link:
3972 case DW_AT_trampoline:
3973 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003974 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003975 case DW_AT_description:
3976 case DW_AT_sibling:
3977 break;
3978 }
3979 }
3980 }
Greg Clayton24739922010-10-13 03:15:28 +00003981 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003982
Greg Clayton24739922010-10-13 03:15:28 +00003983 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00003984
Greg Clayton24739922010-10-13 03:15:28 +00003985 clang_type_t return_clang_type = NULL;
3986 Type *func_type = NULL;
3987
3988 if (type_die_offset != DW_INVALID_OFFSET)
3989 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003990
Greg Clayton24739922010-10-13 03:15:28 +00003991 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003992 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003993 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003994 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003995
Greg Claytonf51de672010-10-01 02:31:07 +00003996
Greg Clayton24739922010-10-13 03:15:28 +00003997 std::vector<clang_type_t> function_param_types;
3998 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003999
Greg Clayton24739922010-10-13 03:15:28 +00004000 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00004001
Greg Clayton5113dc82011-08-12 06:47:54 +00004002 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
4003 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
4004
4005 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord;
4006 // Start off static. This will be set to false in ParseChildParameters(...)
4007 // if we find a "this" paramters as the first parameter
4008 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00004009 is_static = true;
4010
Greg Clayton24739922010-10-13 03:15:28 +00004011 if (die->HasChildren())
4012 {
Greg Clayton0fffff52010-09-24 05:15:53 +00004013 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004014 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00004015 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004016 type_sp,
4017 dwarf_cu,
4018 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00004019 skip_artificial,
4020 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004021 type_list,
4022 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00004023 function_param_decls,
4024 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00004025 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004026
Greg Clayton24739922010-10-13 03:15:28 +00004027 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004028 clang_type = ast.CreateFunctionType (return_clang_type,
4029 &function_param_types[0],
4030 function_param_types.size(),
4031 is_variadic,
4032 type_quals);
4033
Greg Clayton24739922010-10-13 03:15:28 +00004034 if (type_name_cstr)
4035 {
4036 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00004037 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004038 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +00004039 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr))
Greg Clayton0fffff52010-09-24 05:15:53 +00004040 {
Greg Clayton24739922010-10-13 03:15:28 +00004041 // We need to find the DW_TAG_class_type or
4042 // DW_TAG_struct_type by name so we can add this
4043 // as a member function of the class.
4044 const char *class_name_start = type_name_cstr + 2;
4045 const char *class_name_end = ::strchr (class_name_start, ' ');
4046 SymbolContext empty_sc;
4047 clang_type_t class_opaque_type = NULL;
4048 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00004049 {
Greg Clayton24739922010-10-13 03:15:28 +00004050 ConstString class_name (class_name_start, class_name_end - class_name_start);
4051 TypeList types;
4052 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
4053 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00004054 {
Greg Clayton24739922010-10-13 03:15:28 +00004055 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00004056 {
Greg Clayton24739922010-10-13 03:15:28 +00004057 Type *type = types.GetTypeAtIndex (i).get();
4058 clang_type_t type_clang_forward_type = type->GetClangForwardType();
4059 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00004060 {
Greg Clayton24739922010-10-13 03:15:28 +00004061 class_opaque_type = type_clang_forward_type;
4062 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00004063 }
4064 }
4065 }
Greg Clayton24739922010-10-13 03:15:28 +00004066 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004067
Greg Clayton24739922010-10-13 03:15:28 +00004068 if (class_opaque_type)
4069 {
4070 // If accessibility isn't set to anything valid, assume public for
4071 // now...
4072 if (accessibility == eAccessNone)
4073 accessibility = eAccessPublic;
4074
4075 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004076 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
4077 type_name_cstr,
4078 clang_type,
4079 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004080 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00004081 type_handled = objc_method_decl != NULL;
4082 }
4083 }
Greg Clayton5113dc82011-08-12 06:47:54 +00004084 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00004085 {
4086 // Look at the parent of this DIE and see if is is
4087 // a class or struct and see if this is actually a
4088 // C++ method
Greg Clayton5113dc82011-08-12 06:47:54 +00004089 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
Greg Clayton24739922010-10-13 03:15:28 +00004090 if (class_type)
4091 {
Greg Clayton72da3972011-08-16 18:40:23 +00004092 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00004093 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004094 // We have a specification which we are going to base our function
4095 // prototype off of, so we need this type to be completed so that the
4096 // m_die_to_decl_ctx for the method in the specification has a valid
4097 // clang decl context.
4098 class_type->GetClangFullType();
Greg Clayton72da3972011-08-16 18:40:23 +00004099 // If we have a specification, then the function type should have been
4100 // made with the specification and not with this die.
4101 DWARFCompileUnitSP spec_cu_sp;
4102 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004103 clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die);
4104 if (spec_clang_decl_ctx)
4105 {
4106 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
4107 }
4108 else
Jim Inghamc1663042011-09-29 22:12:35 +00004109 {
4110 ReportWarning ("0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n",
Greg Clayton5cf58b92011-10-05 22:22:08 +00004111 die->GetOffset(),
4112 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004113 }
Greg Clayton72da3972011-08-16 18:40:23 +00004114 type_handled = true;
4115 }
4116 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
4117 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004118 // We have a specification which we are going to base our function
4119 // prototype off of, so we need this type to be completed so that the
4120 // m_die_to_decl_ctx for the method in the abstract origin has a valid
4121 // clang decl context.
4122 class_type->GetClangFullType();
4123
Greg Clayton72da3972011-08-16 18:40:23 +00004124 DWARFCompileUnitSP abs_cu_sp;
4125 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004126 clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die);
4127 if (abs_clang_decl_ctx)
4128 {
4129 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
4130 }
4131 else
Jim Inghamc1663042011-09-29 22:12:35 +00004132 {
4133 ReportWarning ("0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
Greg Clayton5cf58b92011-10-05 22:22:08 +00004134 die->GetOffset(),
4135 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004136 }
Greg Clayton72da3972011-08-16 18:40:23 +00004137 type_handled = true;
4138 }
4139 else
4140 {
4141 clang_type_t class_opaque_type = class_type->GetClangForwardType();
4142 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton931180e2011-01-27 06:44:37 +00004143 {
Greg Clayton72da3972011-08-16 18:40:23 +00004144 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
4145 // in the DWARF for C++ methods... Default to public for now...
4146 if (accessibility == eAccessNone)
4147 accessibility = eAccessPublic;
4148
4149 if (!is_static && !die->HasChildren())
4150 {
4151 // We have a C++ member function with no children (this pointer!)
4152 // and clang will get mad if we try and make a function that isn't
4153 // well formed in the DWARF, so we will just skip it...
4154 type_handled = true;
4155 }
4156 else
4157 {
4158 clang::CXXMethodDecl *cxx_method_decl;
4159 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
4160 type_name_cstr,
4161 clang_type,
4162 accessibility,
4163 is_virtual,
4164 is_static,
4165 is_inline,
4166 is_explicit);
4167 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004168
Greg Clayton72da3972011-08-16 18:40:23 +00004169 type_handled = cxx_method_decl != NULL;
4170 }
Greg Clayton931180e2011-01-27 06:44:37 +00004171 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004172 }
4173 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004174 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004175 }
Greg Clayton24739922010-10-13 03:15:28 +00004176
4177 if (!type_handled)
4178 {
4179 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004180 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
4181 clang_type,
4182 storage,
4183 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00004184
4185 // Add the decl to our DIE to decl context map
4186 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00004187 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00004188 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004189 ast.SetFunctionParameters (function_decl,
4190 &function_param_decls.front(),
4191 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00004192 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004193 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004194 type_sp.reset( new Type (die->GetOffset(),
4195 this,
4196 type_name_const_str,
4197 0,
4198 NULL,
4199 LLDB_INVALID_UID,
4200 Type::eEncodingIsUID,
4201 &decl,
4202 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004203 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00004204 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004205 }
4206 break;
4207
4208 case DW_TAG_array_type:
4209 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004210 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004211 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004212
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004213 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004214 int64_t first_index = 0;
4215 uint32_t byte_stride = 0;
4216 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00004217 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218
4219 if (num_attributes > 0)
4220 {
4221 uint32_t i;
4222 for (i=0; i<num_attributes; ++i)
4223 {
4224 attr = attributes.AttributeAtIndex(i);
4225 DWARFFormValue form_value;
4226 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4227 {
4228 switch (attr)
4229 {
4230 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4231 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4232 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4233 case DW_AT_name:
4234 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004235 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004236 break;
4237
4238 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004239 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004240 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
4241 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004242 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004243 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004244 case DW_AT_allocated:
4245 case DW_AT_associated:
4246 case DW_AT_data_location:
4247 case DW_AT_description:
4248 case DW_AT_ordering:
4249 case DW_AT_start_scope:
4250 case DW_AT_visibility:
4251 case DW_AT_specification:
4252 case DW_AT_abstract_origin:
4253 case DW_AT_sibling:
4254 break;
4255 }
4256 }
4257 }
4258
Greg Claytonc93237c2010-10-01 20:48:32 +00004259 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
4260
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004261 Type *element_type = ResolveTypeUID(type_die_offset);
4262
4263 if (element_type)
4264 {
4265 std::vector<uint64_t> element_orders;
4266 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00004267 // We have an array that claims to have no members, lets give it at least one member...
4268 if (element_orders.empty())
4269 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270 if (byte_stride == 0 && bit_stride == 0)
4271 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00004272 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004273 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
4274 uint64_t num_elements = 0;
4275 std::vector<uint64_t>::const_reverse_iterator pos;
4276 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
4277 for (pos = element_orders.rbegin(); pos != end; ++pos)
4278 {
4279 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004280 clang_type = ast.CreateArrayType (array_element_type,
4281 num_elements,
4282 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004283 array_element_type = clang_type;
4284 array_element_bit_stride = array_element_bit_stride * num_elements;
4285 }
4286 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004287 type_sp.reset( new Type (die->GetOffset(),
4288 this,
4289 empty_name,
4290 array_element_bit_stride / 8,
4291 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00004292 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004293 Type::eEncodingIsUID,
4294 &decl,
4295 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004296 Type::eResolveStateFull));
4297 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004298 }
4299 }
4300 }
4301 break;
4302
Greg Clayton9b81a312010-06-12 01:20:30 +00004303 case DW_TAG_ptr_to_member_type:
4304 {
4305 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
4306 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
4307
Greg Claytond88d7592010-09-15 08:33:30 +00004308 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00004309
4310 if (num_attributes > 0) {
4311 uint32_t i;
4312 for (i=0; i<num_attributes; ++i)
4313 {
4314 attr = attributes.AttributeAtIndex(i);
4315 DWARFFormValue form_value;
4316 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4317 {
4318 switch (attr)
4319 {
4320 case DW_AT_type:
4321 type_die_offset = form_value.Reference(dwarf_cu); break;
4322 case DW_AT_containing_type:
4323 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4324 }
4325 }
4326 }
4327
4328 Type *pointee_type = ResolveTypeUID(type_die_offset);
4329 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4330
Greg Clayton526e5af2010-11-13 03:52:47 +00004331 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4332 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00004333
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004334 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4335 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00004336
Greg Clayton526e5af2010-11-13 03:52:47 +00004337 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4338 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00004339
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004340 type_sp.reset( new Type (die->GetOffset(),
4341 this,
4342 type_name_const_str,
4343 byte_size,
4344 NULL,
4345 LLDB_INVALID_UID,
4346 Type::eEncodingIsUID,
4347 NULL,
4348 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004349 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00004350 }
4351
4352 break;
4353 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004354 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00004355 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004356 break;
4357 }
4358
4359 if (type_sp.get())
4360 {
4361 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4362 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4363
4364 SymbolContextScope * symbol_context_scope = NULL;
4365 if (sc_parent_tag == DW_TAG_compile_unit)
4366 {
4367 symbol_context_scope = sc.comp_unit;
4368 }
4369 else if (sc.function != NULL)
4370 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004371 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004372 if (symbol_context_scope == NULL)
4373 symbol_context_scope = sc.function;
4374 }
4375
4376 if (symbol_context_scope != NULL)
4377 {
4378 type_sp->SetSymbolContextScope(symbol_context_scope);
4379 }
4380
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004381 // We are ready to put this type into the uniqued list up at the module level
4382 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00004383
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004384 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004385 }
4386 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00004387 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004388 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004389 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004390 }
4391 }
4392 return type_sp;
4393}
4394
4395size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004396SymbolFileDWARF::ParseTypes
4397(
4398 const SymbolContext& sc,
4399 DWARFCompileUnit* dwarf_cu,
4400 const DWARFDebugInfoEntry *die,
4401 bool parse_siblings,
4402 bool parse_children
4403)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004404{
4405 size_t types_added = 0;
4406 while (die != NULL)
4407 {
4408 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00004409 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004410 {
4411 if (type_is_new)
4412 ++types_added;
4413 }
4414
4415 if (parse_children && die->HasChildren())
4416 {
4417 if (die->Tag() == DW_TAG_subprogram)
4418 {
4419 SymbolContext child_sc(sc);
4420 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
4421 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4422 }
4423 else
4424 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4425 }
4426
4427 if (parse_siblings)
4428 die = die->GetSibling();
4429 else
4430 die = NULL;
4431 }
4432 return types_added;
4433}
4434
4435
4436size_t
4437SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4438{
4439 assert(sc.comp_unit && sc.function);
4440 size_t functions_added = 0;
4441 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4442 if (dwarf_cu)
4443 {
4444 dw_offset_t function_die_offset = sc.function->GetID();
4445 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4446 if (function_die)
4447 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00004448 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004449 }
4450 }
4451
4452 return functions_added;
4453}
4454
4455
4456size_t
4457SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4458{
4459 // At least a compile unit must be valid
4460 assert(sc.comp_unit);
4461 size_t types_added = 0;
4462 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4463 if (dwarf_cu)
4464 {
4465 if (sc.function)
4466 {
4467 dw_offset_t function_die_offset = sc.function->GetID();
4468 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4469 if (func_die && func_die->HasChildren())
4470 {
4471 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4472 }
4473 }
4474 else
4475 {
4476 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4477 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4478 {
4479 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4480 }
4481 }
4482 }
4483
4484 return types_added;
4485}
4486
4487size_t
4488SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4489{
4490 if (sc.comp_unit != NULL)
4491 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004492 DWARFDebugInfo* info = DebugInfo();
4493 if (info == NULL)
4494 return 0;
4495
4496 uint32_t cu_idx = UINT32_MAX;
4497 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004498
4499 if (dwarf_cu == NULL)
4500 return 0;
4501
4502 if (sc.function)
4503 {
4504 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004505
4506 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4507 assert (func_lo_pc != DW_INVALID_ADDRESS);
4508
Greg Claytonc662ec82011-06-17 22:10:16 +00004509 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4510
4511 // Let all blocks know they have parse all their variables
4512 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4513
4514 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004515 }
4516 else if (sc.comp_unit)
4517 {
4518 uint32_t vars_added = 0;
4519 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4520
4521 if (variables.get() == NULL)
4522 {
4523 variables.reset(new VariableList());
4524 sc.comp_unit->SetVariableList(variables);
4525
Greg Claytond4a2b372011-09-12 23:21:58 +00004526 DWARFCompileUnit* match_dwarf_cu = NULL;
4527 const DWARFDebugInfoEntry* die = NULL;
4528 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00004529 if (m_apple_names_ap.get())
4530 {
4531 // TODO: implement finding all items in
4532 m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
4533 dwarf_cu->GetNextCompileUnitOffset(),
4534 die_offsets);
4535 }
4536 else
4537 {
4538 // Index if we already haven't to make sure the compile units
4539 // get indexed and make their global DIE index list
4540 if (!m_indexed)
4541 Index ();
4542
4543 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
4544 dwarf_cu->GetNextCompileUnitOffset(),
4545 die_offsets);
4546 }
4547
4548 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004549 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004550 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004551 DWARFDebugInfo* debug_info = DebugInfo();
4552 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004553 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004554 const dw_offset_t die_offset = die_offsets[i];
4555 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
4556 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
4557 if (var_sp)
4558 {
4559 variables->AddVariableIfUnique (var_sp);
4560 ++vars_added;
4561 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004562 }
4563 }
4564 }
4565 return vars_added;
4566 }
4567 }
4568 return 0;
4569}
4570
4571
4572VariableSP
4573SymbolFileDWARF::ParseVariableDIE
4574(
4575 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004576 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004577 const DWARFDebugInfoEntry *die,
4578 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004579)
4580{
4581
Greg Clayton83c5cd92010-11-14 22:13:40 +00004582 VariableSP var_sp (m_die_to_variable_sp[die]);
4583 if (var_sp)
4584 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004585
4586 const dw_tag_t tag = die->Tag();
Greg Clayton7f995132011-10-04 22:41:51 +00004587
4588 if ((tag == DW_TAG_variable) ||
4589 (tag == DW_TAG_constant) ||
4590 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004591 {
Greg Clayton7f995132011-10-04 22:41:51 +00004592 DWARFDebugInfoEntry::Attributes attributes;
4593 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4594 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004595 {
Greg Clayton7f995132011-10-04 22:41:51 +00004596 const char *name = NULL;
4597 const char *mangled = NULL;
4598 Declaration decl;
4599 uint32_t i;
4600 Type *var_type = NULL;
4601 DWARFExpression location;
4602 bool is_external = false;
4603 bool is_artificial = false;
4604 bool location_is_const_value_data = false;
4605 AccessType accessibility = eAccessNone;
4606
4607 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004608 {
Greg Clayton7f995132011-10-04 22:41:51 +00004609 dw_attr_t attr = attributes.AttributeAtIndex(i);
4610 DWARFFormValue form_value;
4611 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004612 {
Greg Clayton7f995132011-10-04 22:41:51 +00004613 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004614 {
Greg Clayton7f995132011-10-04 22:41:51 +00004615 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4616 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4617 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4618 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
4619 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4620 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
4621 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
4622 case DW_AT_const_value:
4623 location_is_const_value_data = true;
4624 // Fall through...
4625 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004626 {
Greg Clayton7f995132011-10-04 22:41:51 +00004627 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004628 {
Greg Clayton7f995132011-10-04 22:41:51 +00004629 const DataExtractor& debug_info_data = get_debug_info_data();
4630
4631 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4632 uint32_t block_length = form_value.Unsigned();
4633 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
4634 }
4635 else
4636 {
4637 const DataExtractor& debug_loc_data = get_debug_loc_data();
4638 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4639
4640 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4641 if (loc_list_length > 0)
4642 {
4643 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4644 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4645 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
4646 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004647 }
4648 }
Greg Clayton7f995132011-10-04 22:41:51 +00004649 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004650
Greg Clayton7f995132011-10-04 22:41:51 +00004651 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
4652 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
4653 case DW_AT_declaration:
4654 case DW_AT_description:
4655 case DW_AT_endianity:
4656 case DW_AT_segment:
4657 case DW_AT_start_scope:
4658 case DW_AT_visibility:
4659 default:
4660 case DW_AT_abstract_origin:
4661 case DW_AT_sibling:
4662 case DW_AT_specification:
4663 break;
4664 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004665 }
4666 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004667
Greg Clayton7f995132011-10-04 22:41:51 +00004668 if (location.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004669 {
Greg Clayton7f995132011-10-04 22:41:51 +00004670 assert(var_type != DIE_IS_BEING_PARSED);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004671
Greg Clayton7f995132011-10-04 22:41:51 +00004672 ValueType scope = eValueTypeInvalid;
4673
4674 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4675 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4676
4677 if (tag == DW_TAG_formal_parameter)
4678 scope = eValueTypeVariableArgument;
4679 else if (is_external || parent_tag == DW_TAG_compile_unit)
4680 scope = eValueTypeVariableGlobal;
4681 else
4682 scope = eValueTypeVariableLocal;
4683
4684 SymbolContextScope * symbol_context_scope = NULL;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004685 switch (parent_tag)
Greg Clayton7f995132011-10-04 22:41:51 +00004686 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004687 case DW_TAG_subprogram:
4688 case DW_TAG_inlined_subroutine:
4689 case DW_TAG_lexical_block:
4690 if (sc.function)
4691 {
4692 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4693 if (symbol_context_scope == NULL)
4694 symbol_context_scope = sc.function;
4695 }
4696 break;
4697
4698 default:
Greg Clayton7f995132011-10-04 22:41:51 +00004699 symbol_context_scope = sc.comp_unit;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004700 break;
Greg Clayton7f995132011-10-04 22:41:51 +00004701 }
4702
Greg Clayton5cf58b92011-10-05 22:22:08 +00004703 if (symbol_context_scope)
4704 {
4705 var_sp.reset (new Variable(die->GetOffset(),
4706 name,
4707 mangled,
4708 var_type,
4709 scope,
4710 symbol_context_scope,
4711 &decl,
4712 location,
4713 is_external,
4714 is_artificial));
4715
4716 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4717 }
4718 else
4719 {
4720 // Not ready to parse this variable yet. It might be a global
4721 // or static variable that is in a function scope and the function
4722 // in the symbol context wasn't filled in yet
4723 return var_sp;
4724 }
Greg Clayton7f995132011-10-04 22:41:51 +00004725 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004726 }
Greg Clayton7f995132011-10-04 22:41:51 +00004727 // Cache var_sp even if NULL (the variable was just a specification or
4728 // was missing vital information to be able to be displayed in the debugger
4729 // (missing location due to optimization, etc)) so we don't re-parse
4730 // this DIE over and over later...
4731 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004732 }
4733 return var_sp;
4734}
4735
Greg Claytonc662ec82011-06-17 22:10:16 +00004736
4737const DWARFDebugInfoEntry *
4738SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4739 dw_offset_t spec_block_die_offset,
4740 DWARFCompileUnit **result_die_cu_handle)
4741{
4742 // Give the concrete function die specified by "func_die_offset", find the
4743 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4744 // to "spec_block_die_offset"
4745 DWARFDebugInfo* info = DebugInfo();
4746
4747 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4748 if (die)
4749 {
4750 assert (*result_die_cu_handle);
4751 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4752 }
4753 return NULL;
4754}
4755
4756
4757const DWARFDebugInfoEntry *
4758SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4759 const DWARFDebugInfoEntry *die,
4760 dw_offset_t spec_block_die_offset,
4761 DWARFCompileUnit **result_die_cu_handle)
4762{
4763 if (die)
4764 {
4765 switch (die->Tag())
4766 {
4767 case DW_TAG_subprogram:
4768 case DW_TAG_inlined_subroutine:
4769 case DW_TAG_lexical_block:
4770 {
4771 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4772 {
4773 *result_die_cu_handle = dwarf_cu;
4774 return die;
4775 }
4776
4777 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4778 {
4779 *result_die_cu_handle = dwarf_cu;
4780 return die;
4781 }
4782 }
4783 break;
4784 }
4785
4786 // Give the concrete function die specified by "func_die_offset", find the
4787 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4788 // to "spec_block_die_offset"
4789 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4790 {
4791 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4792 child_die,
4793 spec_block_die_offset,
4794 result_die_cu_handle);
4795 if (result_die)
4796 return result_die;
4797 }
4798 }
4799
4800 *result_die_cu_handle = NULL;
4801 return NULL;
4802}
4803
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004804size_t
4805SymbolFileDWARF::ParseVariables
4806(
4807 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004808 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004809 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004810 const DWARFDebugInfoEntry *orig_die,
4811 bool parse_siblings,
4812 bool parse_children,
4813 VariableList* cc_variable_list
4814)
4815{
4816 if (orig_die == NULL)
4817 return 0;
4818
Greg Claytonc662ec82011-06-17 22:10:16 +00004819 VariableListSP variable_list_sp;
4820
4821 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004822 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004823 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004824 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004825 dw_tag_t tag = die->Tag();
4826
4827 // Check to see if we have already parsed this variable or constant?
4828 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004829 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004830 if (cc_variable_list)
4831 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004832 }
4833 else
4834 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004835 // We haven't already parsed it, lets do that now.
4836 if ((tag == DW_TAG_variable) ||
4837 (tag == DW_TAG_constant) ||
4838 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004839 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004840 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004841 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004842 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4843 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4844 switch (parent_tag)
4845 {
4846 case DW_TAG_compile_unit:
4847 if (sc.comp_unit != NULL)
4848 {
4849 variable_list_sp = sc.comp_unit->GetVariableList(false);
4850 if (variable_list_sp.get() == NULL)
4851 {
4852 variable_list_sp.reset(new VariableList());
4853 sc.comp_unit->SetVariableList(variable_list_sp);
4854 }
4855 }
4856 else
4857 {
Jim Inghamc1663042011-09-29 22:12:35 +00004858 ReportError ("parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
Greg Claytonc662ec82011-06-17 22:10:16 +00004859 sc_parent_die->GetOffset(),
4860 DW_TAG_value_to_name (parent_tag),
4861 orig_die->GetOffset(),
4862 DW_TAG_value_to_name (orig_die->Tag()));
4863 }
4864 break;
4865
4866 case DW_TAG_subprogram:
4867 case DW_TAG_inlined_subroutine:
4868 case DW_TAG_lexical_block:
4869 if (sc.function != NULL)
4870 {
4871 // Check to see if we already have parsed the variables for the given scope
4872
4873 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4874 if (block == NULL)
4875 {
4876 // This must be a specification or abstract origin with
4877 // a concrete block couterpart in the current function. We need
4878 // to find the concrete block so we can correctly add the
4879 // variable to it
4880 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4881 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4882 sc_parent_die->GetOffset(),
4883 &concrete_block_die_cu);
4884 if (concrete_block_die)
4885 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4886 }
4887
4888 if (block != NULL)
4889 {
4890 const bool can_create = false;
4891 variable_list_sp = block->GetBlockVariableList (can_create);
4892 if (variable_list_sp.get() == NULL)
4893 {
4894 variable_list_sp.reset(new VariableList());
4895 block->SetVariableList(variable_list_sp);
4896 }
4897 }
4898 }
4899 break;
4900
4901 default:
Jim Inghamc1663042011-09-29 22:12:35 +00004902 ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
Greg Claytonc662ec82011-06-17 22:10:16 +00004903 orig_die->GetOffset(),
4904 DW_TAG_value_to_name (orig_die->Tag()));
4905 break;
4906 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004907 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004908
4909 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004910 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00004911 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4912 if (var_sp)
4913 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004914 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004915 if (cc_variable_list)
4916 cc_variable_list->AddVariableIfUnique (var_sp);
4917 ++vars_added;
4918 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004919 }
4920 }
4921 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004922
4923 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4924
4925 if (!skip_children && parse_children && die->HasChildren())
4926 {
4927 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4928 }
4929
4930 if (parse_siblings)
4931 die = die->GetSibling();
4932 else
4933 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004934 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004935 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004936}
4937
4938//------------------------------------------------------------------
4939// PluginInterface protocol
4940//------------------------------------------------------------------
4941const char *
4942SymbolFileDWARF::GetPluginName()
4943{
4944 return "SymbolFileDWARF";
4945}
4946
4947const char *
4948SymbolFileDWARF::GetShortPluginName()
4949{
4950 return GetPluginNameStatic();
4951}
4952
4953uint32_t
4954SymbolFileDWARF::GetPluginVersion()
4955{
4956 return 1;
4957}
4958
4959void
Greg Clayton6beaaa62011-01-17 03:46:26 +00004960SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4961{
4962 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4963 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4964 if (clang_type)
4965 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4966}
4967
4968void
4969SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4970{
4971 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4972 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4973 if (clang_type)
4974 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4975}
4976
Greg Claytona2721472011-06-25 00:44:06 +00004977void
Sean Callanancc427fa2011-07-30 02:42:06 +00004978SymbolFileDWARF::DumpIndexes ()
4979{
4980 StreamFile s(stdout, false);
4981
4982 s.Printf ("DWARF index for (%s) '%s/%s':",
4983 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4984 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4985 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4986 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4987 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4988 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4989 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4990 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4991 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4992 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4993 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4994}
4995
4996void
4997SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4998 const char *name,
4999 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00005000{
Sean Callanancc427fa2011-07-30 02:42:06 +00005001 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00005002
5003 if (iter == m_decl_ctx_to_die.end())
5004 return;
5005
Sean Callanancc427fa2011-07-30 02:42:06 +00005006 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytona2721472011-06-25 00:44:06 +00005007
5008 if (!results)
5009 return;
5010
5011 DWARFDebugInfo* info = DebugInfo();
5012
Greg Claytond4a2b372011-09-12 23:21:58 +00005013 DIEArray die_offsets;
Greg Claytona2721472011-06-25 00:44:06 +00005014
Greg Claytond4a2b372011-09-12 23:21:58 +00005015 DWARFCompileUnit* dwarf_cu = NULL;
5016 const DWARFDebugInfoEntry* die = NULL;
5017 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets);
Greg Claytona2721472011-06-25 00:44:06 +00005018
5019 if (num_matches)
5020 {
Greg Claytond4a2b372011-09-12 23:21:58 +00005021 for (size_t i = 0; i < num_matches; ++i)
Greg Claytona2721472011-06-25 00:44:06 +00005022 {
Greg Claytond4a2b372011-09-12 23:21:58 +00005023 const dw_offset_t die_offset = die_offsets[i];
5024 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
5025
Sean Callanancc427fa2011-07-30 02:42:06 +00005026 if (die->GetParent() != context_die)
Greg Claytona2721472011-06-25 00:44:06 +00005027 continue;
5028
Greg Claytond4a2b372011-09-12 23:21:58 +00005029 Type *matching_type = ResolveType (dwarf_cu, die);
Greg Claytona2721472011-06-25 00:44:06 +00005030
5031 lldb::clang_type_t type = matching_type->GetClangFullType();
5032 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
5033
Sean Callanancc427fa2011-07-30 02:42:06 +00005034 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00005035 {
5036 clang::TagDecl *tag_decl = tag_type->getDecl();
5037 results->push_back(tag_decl);
5038 }
Sean Callanancc427fa2011-07-30 02:42:06 +00005039 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00005040 {
5041 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
5042 results->push_back(typedef_decl);
5043 }
5044 }
5045 }
5046}
5047
5048void
5049SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
5050 const clang::DeclContext *DC,
5051 clang::DeclarationName Name,
5052 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
5053{
5054 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5055
Sean Callanancc427fa2011-07-30 02:42:06 +00005056 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytona2721472011-06-25 00:44:06 +00005057}