blob: 6873fdc6de7d5aa6283ed4310fa5e8edb47a1a1d [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
25#include "lldb/Core/Module.h"
26#include "lldb/Core/PluginManager.h"
27#include "lldb/Core/RegularExpression.h"
28#include "lldb/Core/Scalar.h"
29#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000030#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Core/Timer.h"
32#include "lldb/Core/Value.h"
33
34#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000035#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Symbol/CompileUnit.h"
37#include "lldb/Symbol/LineTable.h"
38#include "lldb/Symbol/ObjectFile.h"
39#include "lldb/Symbol/SymbolVendor.h"
40#include "lldb/Symbol/VariableList.h"
41
42#include "DWARFCompileUnit.h"
43#include "DWARFDebugAbbrev.h"
44#include "DWARFDebugAranges.h"
45#include "DWARFDebugInfo.h"
46#include "DWARFDebugInfoEntry.h"
47#include "DWARFDebugLine.h"
48#include "DWARFDebugPubnames.h"
49#include "DWARFDebugRanges.h"
50#include "DWARFDIECollection.h"
51#include "DWARFFormValue.h"
52#include "DWARFLocationList.h"
53#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000054#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055
56#include <map>
57
Greg Clayton62742b12010-11-11 01:09:45 +000058//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000059
60#ifdef ENABLE_DEBUG_PRINTF
61#include <stdio.h>
62#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
63#else
64#define DEBUG_PRINTF(fmt, ...)
65#endif
66
Greg Clayton594e5ed2010-09-27 21:07:38 +000067#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
69using namespace lldb;
70using namespace lldb_private;
71
72
Sean Callananc7fbf732010-08-06 00:32:49 +000073static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000074DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075{
76 switch (dwarf_accessibility)
77 {
Sean Callananc7fbf732010-08-06 00:32:49 +000078 case DW_ACCESS_public: return eAccessPublic;
79 case DW_ACCESS_private: return eAccessPrivate;
80 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000081 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082 }
Sean Callananc7fbf732010-08-06 00:32:49 +000083 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084}
85
86void
87SymbolFileDWARF::Initialize()
88{
89 LogChannelDWARF::Initialize();
90 PluginManager::RegisterPlugin (GetPluginNameStatic(),
91 GetPluginDescriptionStatic(),
92 CreateInstance);
93}
94
95void
96SymbolFileDWARF::Terminate()
97{
98 PluginManager::UnregisterPlugin (CreateInstance);
99 LogChannelDWARF::Initialize();
100}
101
102
103const char *
104SymbolFileDWARF::GetPluginNameStatic()
105{
106 return "symbol-file.dwarf2";
107}
108
109const char *
110SymbolFileDWARF::GetPluginDescriptionStatic()
111{
112 return "DWARF and DWARF3 debug symbol file reader.";
113}
114
115
116SymbolFile*
117SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
118{
119 return new SymbolFileDWARF(obj_file);
120}
121
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000122TypeList *
123SymbolFileDWARF::GetTypeList ()
124{
125 if (m_debug_map_symfile)
126 return m_debug_map_symfile->GetTypeList();
127 return m_obj_file->GetModule()->GetTypeList();
128
129}
130
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131//----------------------------------------------------------------------
132// Gets the first parent that is a lexical block, function or inlined
133// subroutine, or compile unit.
134//----------------------------------------------------------------------
135static const DWARFDebugInfoEntry *
136GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
137{
138 const DWARFDebugInfoEntry *die;
139 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
140 {
141 dw_tag_t tag = die->Tag();
142
143 switch (tag)
144 {
145 case DW_TAG_compile_unit:
146 case DW_TAG_subprogram:
147 case DW_TAG_inlined_subroutine:
148 case DW_TAG_lexical_block:
149 return die;
150 }
151 }
152 return NULL;
153}
154
155
Greg Clayton450e3f32010-10-12 02:24:53 +0000156SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
157 SymbolFile (objfile),
158 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000159 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 m_flags(),
161 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 m_data_debug_frame(),
163 m_data_debug_info(),
164 m_data_debug_line(),
165 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 m_data_debug_ranges(),
167 m_data_debug_str(),
168 m_abbr(),
169 m_aranges(),
170 m_info(),
171 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000172 m_function_basename_index(),
173 m_function_fullname_index(),
174 m_function_method_index(),
175 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000176 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000177 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000178 m_type_index(),
179 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000180 m_indexed (false),
181 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000182 m_ranges(),
183 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184{
185}
186
187SymbolFileDWARF::~SymbolFileDWARF()
188{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000189 if (m_is_external_ast_source)
190 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
191}
192
193static const ConstString &
194GetDWARFMachOSegmentName ()
195{
196 static ConstString g_dwarf_section_name ("__DWARF");
197 return g_dwarf_section_name;
198}
199
200ClangASTContext &
201SymbolFileDWARF::GetClangASTContext ()
202{
203 if (m_debug_map_symfile)
204 return m_debug_map_symfile->GetClangASTContext ();
205
206 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
207 if (!m_is_external_ast_source)
208 {
209 m_is_external_ast_source = true;
210 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
211 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
212 SymbolFileDWARF::CompleteObjCInterfaceDecl,
213 this));
214
215 ast.SetExternalSource (ast_source_ap);
216 }
217 return ast;
218}
219
220void
221SymbolFileDWARF::InitializeObject()
222{
223 // Install our external AST source callbacks so we can complete Clang types.
224 Module *module = m_obj_file->GetModule();
225 if (module)
226 {
227 const SectionList *section_list = m_obj_file->GetSectionList();
228
229 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
230
231 // Memory map the DWARF mach-o segment so we have everything mmap'ed
232 // to keep our heap memory usage down.
233 if (section)
234 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
235 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236}
237
238bool
239SymbolFileDWARF::SupportedVersion(uint16_t version)
240{
241 return version == 2 || version == 3;
242}
243
244uint32_t
245SymbolFileDWARF::GetAbilities ()
246{
247 uint32_t abilities = 0;
248 if (m_obj_file != NULL)
249 {
250 const Section* section = NULL;
251 const SectionList *section_list = m_obj_file->GetSectionList();
252 if (section_list == NULL)
253 return 0;
254
255 uint64_t debug_abbrev_file_size = 0;
256 uint64_t debug_aranges_file_size = 0;
257 uint64_t debug_frame_file_size = 0;
258 uint64_t debug_info_file_size = 0;
259 uint64_t debug_line_file_size = 0;
260 uint64_t debug_loc_file_size = 0;
261 uint64_t debug_macinfo_file_size = 0;
262 uint64_t debug_pubnames_file_size = 0;
263 uint64_t debug_pubtypes_file_size = 0;
264 uint64_t debug_ranges_file_size = 0;
265 uint64_t debug_str_file_size = 0;
266
Greg Clayton6beaaa62011-01-17 03:46:26 +0000267 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268
269 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000270 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271
Greg Clayton4ceb9982010-07-21 22:54:26 +0000272 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273 if (section != NULL)
274 {
275 debug_info_file_size = section->GetByteSize();
276
Greg Clayton4ceb9982010-07-21 22:54:26 +0000277 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278 if (section)
279 debug_abbrev_file_size = section->GetByteSize();
280 else
281 m_flags.Set (flagsGotDebugAbbrevData);
282
Greg Clayton4ceb9982010-07-21 22:54:26 +0000283 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 if (section)
285 debug_aranges_file_size = section->GetByteSize();
286 else
287 m_flags.Set (flagsGotDebugArangesData);
288
Greg Clayton4ceb9982010-07-21 22:54:26 +0000289 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 if (section)
291 debug_frame_file_size = section->GetByteSize();
292 else
293 m_flags.Set (flagsGotDebugFrameData);
294
Greg Clayton4ceb9982010-07-21 22:54:26 +0000295 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296 if (section)
297 debug_line_file_size = section->GetByteSize();
298 else
299 m_flags.Set (flagsGotDebugLineData);
300
Greg Clayton4ceb9982010-07-21 22:54:26 +0000301 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 if (section)
303 debug_loc_file_size = section->GetByteSize();
304 else
305 m_flags.Set (flagsGotDebugLocData);
306
Greg Clayton4ceb9982010-07-21 22:54:26 +0000307 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 if (section)
309 debug_macinfo_file_size = section->GetByteSize();
310 else
311 m_flags.Set (flagsGotDebugMacInfoData);
312
Greg Clayton4ceb9982010-07-21 22:54:26 +0000313 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 if (section)
315 debug_pubnames_file_size = section->GetByteSize();
316 else
317 m_flags.Set (flagsGotDebugPubNamesData);
318
Greg Clayton4ceb9982010-07-21 22:54:26 +0000319 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000320 if (section)
321 debug_pubtypes_file_size = section->GetByteSize();
322 else
323 m_flags.Set (flagsGotDebugPubTypesData);
324
Greg Clayton4ceb9982010-07-21 22:54:26 +0000325 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326 if (section)
327 debug_ranges_file_size = section->GetByteSize();
328 else
329 m_flags.Set (flagsGotDebugRangesData);
330
Greg Clayton4ceb9982010-07-21 22:54:26 +0000331 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332 if (section)
333 debug_str_file_size = section->GetByteSize();
334 else
335 m_flags.Set (flagsGotDebugStrData);
336 }
337
338 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
339 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
340
341 if (debug_line_file_size > 0)
342 abilities |= LineTables;
343
344 if (debug_aranges_file_size > 0)
345 abilities |= AddressAcceleratorTable;
346
347 if (debug_pubnames_file_size > 0)
348 abilities |= FunctionAcceleratorTable;
349
350 if (debug_pubtypes_file_size > 0)
351 abilities |= TypeAcceleratorTable;
352
353 if (debug_macinfo_file_size > 0)
354 abilities |= MacroInformation;
355
356 if (debug_frame_file_size > 0)
357 abilities |= CallFrameInformation;
358 }
359 return abilities;
360}
361
362const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000363SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364{
365 if (m_flags.IsClear (got_flag))
366 {
367 m_flags.Set (got_flag);
368 const SectionList *section_list = m_obj_file->GetSectionList();
369 if (section_list)
370 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000371 Section *section = section_list->FindSectionByType(sect_type, true).get();
372 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 {
374 // See if we memory mapped the DWARF segment?
375 if (m_dwarf_data.GetByteSize())
376 {
377 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
378 }
379 else
380 {
381 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
382 data.Clear();
383 }
384 }
385 }
386 }
387 return data;
388}
389
390const DataExtractor&
391SymbolFileDWARF::get_debug_abbrev_data()
392{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000393 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394}
395
396const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397SymbolFileDWARF::get_debug_frame_data()
398{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000399 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400}
401
402const DataExtractor&
403SymbolFileDWARF::get_debug_info_data()
404{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000405 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406}
407
408const DataExtractor&
409SymbolFileDWARF::get_debug_line_data()
410{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000411 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412}
413
414const DataExtractor&
415SymbolFileDWARF::get_debug_loc_data()
416{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000417 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418}
419
420const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421SymbolFileDWARF::get_debug_ranges_data()
422{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000423 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424}
425
426const DataExtractor&
427SymbolFileDWARF::get_debug_str_data()
428{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000429 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430}
431
432
433DWARFDebugAbbrev*
434SymbolFileDWARF::DebugAbbrev()
435{
436 if (m_abbr.get() == NULL)
437 {
438 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
439 if (debug_abbrev_data.GetByteSize() > 0)
440 {
441 m_abbr.reset(new DWARFDebugAbbrev());
442 if (m_abbr.get())
443 m_abbr->Parse(debug_abbrev_data);
444 }
445 }
446 return m_abbr.get();
447}
448
449const DWARFDebugAbbrev*
450SymbolFileDWARF::DebugAbbrev() const
451{
452 return m_abbr.get();
453}
454
455DWARFDebugAranges*
456SymbolFileDWARF::DebugAranges()
457{
Greg Clayton016a95e2010-09-14 02:20:48 +0000458 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
459 // and we are already parsing all of the DWARF because the .debug_pubnames
460 // is useless (it only mentions symbols that are externally visible), so
461 // don't use the .debug_aranges section, we should be using a debug aranges
462 // we got from SymbolFileDWARF::Index().
463
464 if (!m_indexed)
465 Index();
466
467
468// if (m_aranges.get() == NULL)
469// {
470// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
471// m_aranges.reset(new DWARFDebugAranges());
472// if (m_aranges.get())
473// {
474// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
475// if (debug_aranges_data.GetByteSize() > 0)
476// m_aranges->Extract(debug_aranges_data);
477// else
478// m_aranges->Generate(this);
479// }
480// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481 return m_aranges.get();
482}
483
484const DWARFDebugAranges*
485SymbolFileDWARF::DebugAranges() const
486{
487 return m_aranges.get();
488}
489
490
491DWARFDebugInfo*
492SymbolFileDWARF::DebugInfo()
493{
494 if (m_info.get() == NULL)
495 {
496 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
497 if (get_debug_info_data().GetByteSize() > 0)
498 {
499 m_info.reset(new DWARFDebugInfo());
500 if (m_info.get())
501 {
502 m_info->SetDwarfData(this);
503 }
504 }
505 }
506 return m_info.get();
507}
508
509const DWARFDebugInfo*
510SymbolFileDWARF::DebugInfo() const
511{
512 return m_info.get();
513}
514
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515DWARFCompileUnit*
516SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
517{
518 DWARFDebugInfo* info = DebugInfo();
519 if (info)
520 return info->GetCompileUnit(cu_uid).get();
521 return NULL;
522}
523
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524
525DWARFDebugRanges*
526SymbolFileDWARF::DebugRanges()
527{
528 if (m_ranges.get() == NULL)
529 {
530 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
531 if (get_debug_ranges_data().GetByteSize() > 0)
532 {
533 m_ranges.reset(new DWARFDebugRanges());
534 if (m_ranges.get())
535 m_ranges->Extract(this);
536 }
537 }
538 return m_ranges.get();
539}
540
541const DWARFDebugRanges*
542SymbolFileDWARF::DebugRanges() const
543{
544 return m_ranges.get();
545}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546
547bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000548SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549{
Greg Clayton96d7d742010-11-10 23:42:09 +0000550 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000552 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553 if (cu_die)
554 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000555 const char * cu_die_name = cu_die->GetName(this, curr_cu);
556 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
557 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558 if (cu_die_name)
559 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000560 FileSpec cu_file_spec;
561
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
563 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000564 // If we have a full path to the compile unit, we don't need to resolve
565 // the file. This can be expensive e.g. when the source files are NFS mounted.
566 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567 }
568 else
569 {
570 std::string fullpath(cu_comp_dir);
571 if (*fullpath.rbegin() != '/')
572 fullpath += '/';
573 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000574 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 }
576
Greg Clayton96d7d742010-11-10 23:42:09 +0000577 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 if (compile_unit_sp.get())
579 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000580 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581 return true;
582 }
583 }
584 }
585 }
586 return false;
587}
588
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589uint32_t
590SymbolFileDWARF::GetNumCompileUnits()
591{
592 DWARFDebugInfo* info = DebugInfo();
593 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595 return 0;
596}
597
598CompUnitSP
599SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
600{
601 CompUnitSP comp_unit;
602 DWARFDebugInfo* info = DebugInfo();
603 if (info)
604 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000605 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
606 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 {
608 // Our symbol vendor shouldn't be asking us to add a compile unit that
609 // has already been added to it, which this DWARF plug-in knows as it
610 // stores the lldb compile unit (CompileUnit) pointer in each
611 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000612 assert(curr_cu->GetUserData() == NULL);
613 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614 }
615 }
616 return comp_unit;
617}
618
619static void
620AddRangesToBlock
621(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000622 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 DWARFDebugRanges::RangeList& ranges,
624 addr_t block_base_addr
625)
626{
627 ranges.SubtractOffset (block_base_addr);
628 size_t range_idx = 0;
629 const DWARFDebugRanges::Range *debug_range;
630 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
631 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000632 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633 }
634}
635
636
637Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000638SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639{
640 DWARFDebugRanges::RangeList func_ranges;
641 const char *name = NULL;
642 const char *mangled = NULL;
643 int decl_file = 0;
644 int decl_line = 0;
645 int decl_column = 0;
646 int call_file = 0;
647 int call_line = 0;
648 int call_column = 0;
649 DWARFExpression frame_base;
650
Greg Claytonc93237c2010-10-01 20:48:32 +0000651 assert (die->Tag() == DW_TAG_subprogram);
652
653 if (die->Tag() != DW_TAG_subprogram)
654 return NULL;
655
656 const DWARFDebugInfoEntry *parent_die = die->GetParent();
657 switch (parent_die->Tag())
658 {
659 case DW_TAG_structure_type:
660 case DW_TAG_class_type:
661 // We have methods of a class or struct
662 {
663 Type *class_type = ResolveType (dwarf_cu, parent_die);
664 if (class_type)
665 class_type->GetClangType();
666 }
667 break;
668
669 default:
670 // Parse the function prototype as a type that can then be added to concrete function instance
671 ParseTypes (sc, dwarf_cu, die, false, false);
672 break;
673 }
674
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 //FixupTypes();
676
677 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
678 {
679 // Union of all ranges in the function DIE (if the function is discontiguous)
680 AddressRange func_range;
681 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
682 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
683 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
684 {
685 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
686 if (func_range.GetBaseAddress().IsValid())
687 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
688 }
689
690 if (func_range.GetBaseAddress().IsValid())
691 {
692 Mangled func_name;
693 if (mangled)
694 func_name.SetValue(mangled, true);
695 else if (name)
696 func_name.SetValue(name, false);
697
698 FunctionSP func_sp;
699 std::auto_ptr<Declaration> decl_ap;
700 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000701 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
702 decl_line,
703 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704
Greg Clayton594e5ed2010-09-27 21:07:38 +0000705 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000706
707 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
708
709 func_range.GetBaseAddress().ResolveLinkedAddress();
710
711 func_sp.reset(new Function (sc.comp_unit,
712 die->GetOffset(), // UserID is the DIE offset
713 die->GetOffset(),
714 func_name,
715 func_type,
716 func_range)); // first address range
717
718 if (func_sp.get() != NULL)
719 {
720 func_sp->GetFrameBaseExpression() = frame_base;
721 sc.comp_unit->AddFunction(func_sp);
722 return func_sp.get();
723 }
724 }
725 }
726 return NULL;
727}
728
729size_t
730SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
731{
732 assert (sc.comp_unit);
733 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000734 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735 if (dwarf_cu)
736 {
737 DWARFDIECollection function_dies;
738 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
739 size_t func_idx;
740 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
741 {
742 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
743 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
744 {
745 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
746 ++functions_added;
747 }
748 }
749 //FixupTypes();
750 }
751 return functions_added;
752}
753
754bool
755SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
756{
757 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000758 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
759 assert (curr_cu);
760 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761
762 if (cu_die)
763 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000764 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
765 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 +0000766
767 // All file indexes in DWARF are one based and a file of index zero is
768 // supposed to be the compile unit itself.
769 support_files.Append (*sc.comp_unit);
770
771 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
772 }
773 return false;
774}
775
776struct ParseDWARFLineTableCallbackInfo
777{
778 LineTable* line_table;
779 const SectionList *section_list;
780 lldb::addr_t prev_sect_file_base_addr;
781 lldb::addr_t curr_sect_file_base_addr;
782 bool is_oso_for_debug_map;
783 bool prev_in_final_executable;
784 DWARFDebugLine::Row prev_row;
785 SectionSP prev_section_sp;
786 SectionSP curr_section_sp;
787};
788
789//----------------------------------------------------------------------
790// ParseStatementTableCallback
791//----------------------------------------------------------------------
792static void
793ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
794{
795 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
796 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
797 {
798 // Just started parsing the line table
799 }
800 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
801 {
802 // Done parsing line table, nothing to do for the cleanup
803 }
804 else
805 {
806 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
807 // We have a new row, lets append it
808
809 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
810 {
811 info->prev_section_sp = info->curr_section_sp;
812 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
813 // If this is an end sequence entry, then we subtract one from the
814 // address to make sure we get an address that is not the end of
815 // a section.
816 if (state.end_sequence && state.address != 0)
817 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
818 else
819 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
820
821 if (info->curr_section_sp.get())
822 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
823 else
824 info->curr_sect_file_base_addr = 0;
825 }
826 if (info->curr_section_sp.get())
827 {
828 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
829 // Check for the fancy section magic to determine if we
830
831 if (info->is_oso_for_debug_map)
832 {
833 // When this is a debug map object file that contains DWARF
834 // (referenced from an N_OSO debug map nlist entry) we will have
835 // a file address in the file range for our section from the
836 // original .o file, and a load address in the executable that
837 // contains the debug map.
838 //
839 // If the sections for the file range and load range are
840 // different, we have a remapped section for the function and
841 // this address is resolved. If they are the same, then the
842 // function for this address didn't make it into the final
843 // executable.
844 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
845
846 // If we are doing DWARF with debug map, then we need to carefully
847 // add each line table entry as there may be gaps as functions
848 // get moved around or removed.
849 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
850 {
851 if (info->prev_in_final_executable)
852 {
853 bool terminate_previous_entry = false;
854 if (!curr_in_final_executable)
855 {
856 // Check for the case where the previous line entry
857 // in a function made it into the final executable,
858 // yet the current line entry falls in a function
859 // that didn't. The line table used to be contiguous
860 // through this address range but now it isn't. We
861 // need to terminate the previous line entry so
862 // that we can reconstruct the line range correctly
863 // for it and to keep the line table correct.
864 terminate_previous_entry = true;
865 }
866 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
867 {
868 // Check for cases where the line entries used to be
869 // contiguous address ranges, but now they aren't.
870 // This can happen when order files specify the
871 // ordering of the functions.
872 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
873 Section *curr_sect = info->curr_section_sp.get();
874 Section *prev_sect = info->prev_section_sp.get();
875 assert (curr_sect->GetLinkedSection());
876 assert (prev_sect->GetLinkedSection());
877 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
878 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
879 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
880 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
881 if (object_file_addr_delta != linked_file_addr_delta)
882 terminate_previous_entry = true;
883 }
884
885 if (terminate_previous_entry)
886 {
887 line_table->InsertLineEntry (info->prev_section_sp,
888 state.address - info->prev_sect_file_base_addr,
889 info->prev_row.line,
890 info->prev_row.column,
891 info->prev_row.file,
892 false, // is_stmt
893 false, // basic_block
894 false, // state.prologue_end
895 false, // state.epilogue_begin
896 true); // end_sequence);
897 }
898 }
899 }
900
901 if (curr_in_final_executable)
902 {
903 line_table->InsertLineEntry (info->curr_section_sp,
904 curr_line_section_offset,
905 state.line,
906 state.column,
907 state.file,
908 state.is_stmt,
909 state.basic_block,
910 state.prologue_end,
911 state.epilogue_begin,
912 state.end_sequence);
913 info->prev_section_sp = info->curr_section_sp;
914 }
915 else
916 {
917 // If the current address didn't make it into the final
918 // executable, the current section will be the __text
919 // segment in the .o file, so we need to clear this so
920 // we can catch the next function that did make it into
921 // the final executable.
922 info->prev_section_sp.reset();
923 info->curr_section_sp.reset();
924 }
925
926 info->prev_in_final_executable = curr_in_final_executable;
927 }
928 else
929 {
930 // We are not in an object file that contains DWARF for an
931 // N_OSO, this is just a normal DWARF file. The DWARF spec
932 // guarantees that the addresses will be in increasing order
933 // so, since we store line tables in file address order, we
934 // can always just append the line entry without needing to
935 // search for the correct insertion point (we don't need to
936 // use LineEntry::InsertLineEntry()).
937 line_table->AppendLineEntry (info->curr_section_sp,
938 curr_line_section_offset,
939 state.line,
940 state.column,
941 state.file,
942 state.is_stmt,
943 state.basic_block,
944 state.prologue_end,
945 state.epilogue_begin,
946 state.end_sequence);
947 }
948 }
949
950 info->prev_row = state;
951 }
952}
953
954bool
955SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
956{
957 assert (sc.comp_unit);
958 if (sc.comp_unit->GetLineTable() != NULL)
959 return true;
960
961 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
962 if (dwarf_cu)
963 {
964 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
965 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
966 if (cu_line_offset != DW_INVALID_OFFSET)
967 {
968 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
969 if (line_table_ap.get())
970 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000971 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 +0000972 uint32_t offset = cu_line_offset;
973 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
974 sc.comp_unit->SetLineTable(line_table_ap.release());
975 return true;
976 }
977 }
978 }
979 return false;
980}
981
982size_t
983SymbolFileDWARF::ParseFunctionBlocks
984(
985 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000986 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000987 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000988 const DWARFDebugInfoEntry *die,
989 addr_t subprogram_low_pc,
990 bool parse_siblings,
991 bool parse_children
992)
993{
994 size_t blocks_added = 0;
995 while (die != NULL)
996 {
997 dw_tag_t tag = die->Tag();
998
999 switch (tag)
1000 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +00001002 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001003 case DW_TAG_lexical_block:
1004 {
1005 DWARFDebugRanges::RangeList ranges;
1006 const char *name = NULL;
1007 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001008 Block *block = NULL;
1009 if (tag != DW_TAG_subprogram)
1010 {
1011 BlockSP block_sp(new Block (die->GetOffset()));
1012 parent_block->AddChild(block_sp);
1013 block = block_sp.get();
1014 }
1015 else
1016 {
1017 block = parent_block;
1018 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001020 int decl_file = 0;
1021 int decl_line = 0;
1022 int decl_column = 0;
1023 int call_file = 0;
1024 int call_line = 0;
1025 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001026 if (die->GetDIENamesAndRanges (this,
1027 dwarf_cu,
1028 name,
1029 mangled_name,
1030 ranges,
1031 decl_file, decl_line, decl_column,
1032 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001033 {
1034 if (tag == DW_TAG_subprogram)
1035 {
1036 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1037 subprogram_low_pc = ranges.LowestAddress(0);
1038 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001039 else if (tag == DW_TAG_inlined_subroutine)
1040 {
1041 // We get called here for inlined subroutines in two ways.
1042 // The first time is when we are making the Function object
1043 // for this inlined concrete instance. Since we're creating a top level block at
1044 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1045 // adjust the containing address.
1046 // The second time is when we are parsing the blocks inside the function that contains
1047 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1048 // function the offset will be for that function.
1049 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1050 {
1051 subprogram_low_pc = ranges.LowestAddress(0);
1052 }
1053 }
1054
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001055 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056
1057 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1058 {
1059 std::auto_ptr<Declaration> decl_ap;
1060 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001061 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1062 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063
1064 std::auto_ptr<Declaration> call_ap;
1065 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001066 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1067 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001069 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 }
1071
1072 ++blocks_added;
1073
1074 if (parse_children && die->HasChildren())
1075 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001076 blocks_added += ParseFunctionBlocks (sc,
1077 block,
1078 dwarf_cu,
1079 die->GetFirstChild(),
1080 subprogram_low_pc,
1081 true,
1082 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083 }
1084 }
1085 }
1086 break;
1087 default:
1088 break;
1089 }
1090
1091 if (parse_siblings)
1092 die = die->GetSibling();
1093 else
1094 die = NULL;
1095 }
1096 return blocks_added;
1097}
1098
1099size_t
1100SymbolFileDWARF::ParseChildMembers
1101(
1102 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001103 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001105 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001106 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001107 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1108 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001109 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001110 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111 bool &is_a_class
1112)
1113{
1114 if (parent_die == NULL)
1115 return 0;
1116
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 size_t count = 0;
1118 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001119 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001120 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001121
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1123 {
1124 dw_tag_t tag = die->Tag();
1125
1126 switch (tag)
1127 {
1128 case DW_TAG_member:
1129 {
1130 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001131 const size_t num_attributes = die->GetAttributes (this,
1132 dwarf_cu,
1133 fixed_form_sizes,
1134 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 if (num_attributes > 0)
1136 {
1137 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001138 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001140 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001142 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001143 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144 size_t byte_size = 0;
1145 size_t bit_offset = 0;
1146 size_t bit_size = 0;
1147 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001148 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149 {
1150 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1151 DWARFFormValue form_value;
1152 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1153 {
1154 switch (attr)
1155 {
1156 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1157 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1158 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1159 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1160 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1161 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1162 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1163 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1164 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001165// if (form_value.BlockData())
1166// {
1167// Value initialValue(0);
1168// Value memberOffset(0);
1169// const DataExtractor& debug_info_data = get_debug_info_data();
1170// uint32_t block_length = form_value.Unsigned();
1171// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1172// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1173// {
1174// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1175// }
1176// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 break;
1178
Greg Clayton8cf05932010-07-22 18:30:50 +00001179 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001180 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001181 case DW_AT_declaration:
1182 case DW_AT_description:
1183 case DW_AT_mutable:
1184 case DW_AT_visibility:
1185 default:
1186 case DW_AT_sibling:
1187 break;
1188 }
1189 }
1190 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001191
1192 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1193
1194 if (class_language == eLanguageTypeObjC ||
1195 class_language == eLanguageTypeObjC_plus_plus)
1196 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001197
1198 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1199 {
1200 // Not all compilers will mark the vtable pointer
1201 // member as artificial (llvm-gcc). We can't have
1202 // the virtual members in our classes otherwise it
1203 // throws off all child offsets since we end up
1204 // having and extra pointer sized member in our
1205 // class layouts.
1206 is_artificial = true;
1207 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208
Greg Clayton24739922010-10-13 03:15:28 +00001209 if (is_artificial == false)
1210 {
1211 Type *member_type = ResolveTypeUID(encoding_uid);
1212 assert(member_type);
1213 if (accessibility == eAccessNone)
1214 accessibility = default_accessibility;
1215 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001216
Greg Claytonba2d22d2010-11-13 22:57:37 +00001217 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1218 name,
1219 member_type->GetClangLayoutType(),
1220 accessibility,
1221 bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001222 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001223 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001224 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225 }
1226 break;
1227
1228 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001229 // Let the type parsing code handle this one for us.
1230 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 break;
1232
1233 case DW_TAG_inheritance:
1234 {
1235 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001236 if (default_accessibility == eAccessNone)
1237 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001238 // TODO: implement DW_TAG_inheritance type parsing
1239 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001240 const size_t num_attributes = die->GetAttributes (this,
1241 dwarf_cu,
1242 fixed_form_sizes,
1243 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001244 if (num_attributes > 0)
1245 {
1246 Declaration decl;
1247 DWARFExpression location;
1248 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001249 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250 bool is_virtual = false;
1251 bool is_base_of_class = true;
1252 off_t member_offset = 0;
1253 uint32_t i;
1254 for (i=0; i<num_attributes; ++i)
1255 {
1256 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1257 DWARFFormValue form_value;
1258 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1259 {
1260 switch (attr)
1261 {
1262 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1263 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1264 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1265 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1266 case DW_AT_data_member_location:
1267 if (form_value.BlockData())
1268 {
1269 Value initialValue(0);
1270 Value memberOffset(0);
1271 const DataExtractor& debug_info_data = get_debug_info_data();
1272 uint32_t block_length = form_value.Unsigned();
1273 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001274 if (DWARFExpression::Evaluate (NULL,
1275 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001276 NULL,
1277 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001278 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001279 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001280 block_offset,
1281 block_length,
1282 eRegisterKindDWARF,
1283 &initialValue,
1284 memberOffset,
1285 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286 {
1287 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1288 }
1289 }
1290 break;
1291
1292 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001293 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 break;
1295
1296 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1297 default:
1298 case DW_AT_sibling:
1299 break;
1300 }
1301 }
1302 }
1303
Greg Clayton526e5af2010-11-13 03:52:47 +00001304 Type *base_class_type = ResolveTypeUID(encoding_uid);
1305 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001306
1307 if (class_language == eLanguageTypeObjC)
1308 {
Greg Clayton526e5af2010-11-13 03:52:47 +00001309 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_type->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001310 }
1311 else
1312 {
Greg Claytonba2d22d2010-11-13 22:57:37 +00001313 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_type->GetClangType(),
1314 accessibility,
1315 is_virtual,
1316 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001317 assert(base_classes.back());
1318 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 }
1320 }
1321 break;
1322
1323 default:
1324 break;
1325 }
1326 }
1327 return count;
1328}
1329
1330
1331clang::DeclContext*
1332SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1333{
1334 DWARFDebugInfo* debug_info = DebugInfo();
1335 if (debug_info)
1336 {
1337 DWARFCompileUnitSP cu_sp;
1338 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1339 if (die)
1340 return GetClangDeclContextForDIE (cu_sp.get(), die);
1341 }
1342 return NULL;
1343}
1344
1345Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001346SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347{
1348 DWARFDebugInfo* debug_info = DebugInfo();
1349 if (debug_info)
1350 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001351 DWARFCompileUnitSP cu_sp;
1352 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001353 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001354 {
1355 // We might be coming in in the middle of a type tree (a class
1356 // withing a class, an enum within a class), so parse any needed
1357 // parent DIEs before we get to this one...
1358 const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1359 switch (parent_die->Tag())
1360 {
1361 case DW_TAG_structure_type:
1362 case DW_TAG_union_type:
1363 case DW_TAG_class_type:
1364 ResolveType(cu_sp.get(), parent_die);
1365 break;
1366 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001367 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001368 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001369 }
1370 return NULL;
1371}
1372
Greg Clayton6beaaa62011-01-17 03:46:26 +00001373// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1374// SymbolFileDWARF objects to detect if this DWARF file is the one that
1375// can resolve a clang_type.
1376bool
1377SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1378{
1379 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1380 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1381 return die != NULL;
1382}
1383
1384
Greg Clayton1be10fc2010-09-29 01:12:09 +00001385lldb::clang_type_t
1386SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1387{
1388 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001389 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1390 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001391 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001392 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001393// if (m_debug_map_symfile)
1394// {
1395// Type *type = m_die_to_type[die];
1396// if (type && type->GetSymbolFile() != this)
1397// return type->GetClangType();
1398// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001399 // We have already resolved this type...
1400 return clang_type;
1401 }
1402 // Once we start resolving this type, remove it from the forward declaration
1403 // map in case anyone child members or other types require this type to get resolved.
1404 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1405 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001406 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001407
Greg Clayton1be10fc2010-09-29 01:12:09 +00001408
Greg Clayton450e3f32010-10-12 02:24:53 +00001409 DWARFDebugInfo* debug_info = DebugInfo();
1410
Greg Clayton96d7d742010-11-10 23:42:09 +00001411 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001412 Type *type = m_die_to_type.lookup (die);
1413
1414 const dw_tag_t tag = die->Tag();
1415
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001416 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1417 die->GetOffset(),
1418 DW_TAG_value_to_name(tag),
1419 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001420 assert (clang_type);
1421 DWARFDebugInfoEntry::Attributes attributes;
1422
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001423 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001424
1425 switch (tag)
1426 {
1427 case DW_TAG_structure_type:
1428 case DW_TAG_union_type:
1429 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001430 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001431 if (die->HasChildren())
1432 {
1433 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001434 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1435 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001436 class_language = eLanguageTypeObjC;
1437
1438 int tag_decl_kind = -1;
1439 AccessType default_accessibility = eAccessNone;
1440 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001441 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001442 tag_decl_kind = clang::TTK_Struct;
1443 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001444 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001445 else if (tag == DW_TAG_union_type)
1446 {
1447 tag_decl_kind = clang::TTK_Union;
1448 default_accessibility = eAccessPublic;
1449 }
1450 else if (tag == DW_TAG_class_type)
1451 {
1452 tag_decl_kind = clang::TTK_Class;
1453 default_accessibility = eAccessPrivate;
1454 }
1455
Greg Clayton96d7d742010-11-10 23:42:09 +00001456 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001457 std::vector<clang::CXXBaseSpecifier *> base_classes;
1458 std::vector<int> member_accessibilities;
1459 bool is_a_class = false;
1460 // Parse members and base classes first
1461 DWARFDIECollection member_function_dies;
1462
1463 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001464 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001465 die,
1466 clang_type,
1467 class_language,
1468 base_classes,
1469 member_accessibilities,
1470 member_function_dies,
1471 default_accessibility,
1472 is_a_class);
1473
1474 // Now parse any methods if there were any...
1475 size_t num_functions = member_function_dies.Size();
1476 if (num_functions > 0)
1477 {
1478 for (size_t i=0; i<num_functions; ++i)
1479 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001480 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001481 }
1482 }
1483
Greg Clayton450e3f32010-10-12 02:24:53 +00001484 if (class_language == eLanguageTypeObjC)
1485 {
1486 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1487 if (!class_str.empty())
1488 {
1489
1490 ConstString class_name (class_str.c_str());
1491 std::vector<NameToDIE::Info> method_die_infos;
1492 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1493 {
1494 DWARFCompileUnit* method_cu = NULL;
1495 DWARFCompileUnit* prev_method_cu = NULL;
1496 const size_t num_objc_methods = method_die_infos.size();
1497 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1498 {
1499 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1500
1501 if (method_cu != prev_method_cu)
1502 method_cu->ExtractDIEsIfNeeded (false);
1503
1504 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1505
1506 ResolveType (method_cu, method_die);
1507 }
1508 }
1509 }
1510 }
1511
Greg Claytonc93237c2010-10-01 20:48:32 +00001512 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1513 // need to tell the clang type it is actually a class.
1514 if (class_language != eLanguageTypeObjC)
1515 {
1516 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001517 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001518 }
1519
1520 // Since DW_TAG_structure_type gets used for both classes
1521 // and structures, we may need to set any DW_TAG_member
1522 // fields to have a "private" access if none was specified.
1523 // When we parsed the child members we tracked that actual
1524 // accessibility value for each DW_TAG_member in the
1525 // "member_accessibilities" array. If the value for the
1526 // member is zero, then it was set to the "default_accessibility"
1527 // which for structs was "public". Below we correct this
1528 // by setting any fields to "private" that weren't correctly
1529 // set.
1530 if (is_a_class && !member_accessibilities.empty())
1531 {
1532 // This is a class and all members that didn't have
1533 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001534 ast.SetDefaultAccessForRecordFields (clang_type,
1535 eAccessPrivate,
1536 &member_accessibilities.front(),
1537 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001538 }
1539
1540 if (!base_classes.empty())
1541 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001542 ast.SetBaseClassesForClassType (clang_type,
1543 &base_classes.front(),
1544 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001545
1546 // Clang will copy each CXXBaseSpecifier in "base_classes"
1547 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001548 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1549 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001550 }
1551
1552 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001553 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001554 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001555
1556 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001557 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001558 if (die->HasChildren())
1559 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001560 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1561 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001562 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001563 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001564 return clang_type;
1565
1566 default:
1567 assert(false && "not a forward clang type decl!");
1568 break;
1569 }
1570 return NULL;
1571}
1572
Greg Claytonc685f8e2010-09-15 04:15:46 +00001573Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001574SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001575{
1576 if (type_die != NULL)
1577 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001578 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001579 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001580 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001581 if (assert_not_being_parsed)
1582 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001583 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001584 }
1585 return NULL;
1586}
1587
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001588CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001589SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001590{
1591 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001592 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001593 {
1594 // The symbol vendor doesn't know about this compile unit, we
1595 // need to parse and add it to the symbol vendor object.
1596 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001597 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001598 if (dc_cu.get())
1599 {
1600 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001601 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001602 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603
1604 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001605
1606 if (m_debug_map_symfile)
1607 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 }
1609 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001610 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001611}
1612
1613bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001614SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001615{
1616 sc.Clear();
1617 // Check if the symbol vendor already knows about this compile unit?
1618 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001619 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001620
1621 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1622 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001623 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001624
1625 return sc.function != NULL;
1626}
1627
1628uint32_t
1629SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1630{
1631 Timer scoped_timer(__PRETTY_FUNCTION__,
1632 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1633 so_addr.GetSection(),
1634 so_addr.GetOffset(),
1635 resolve_scope);
1636 uint32_t resolved = 0;
1637 if (resolve_scope & ( eSymbolContextCompUnit |
1638 eSymbolContextFunction |
1639 eSymbolContextBlock |
1640 eSymbolContextLineEntry))
1641 {
1642 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1643
1644 DWARFDebugAranges* debug_aranges = DebugAranges();
1645 DWARFDebugInfo* debug_info = DebugInfo();
1646 if (debug_aranges)
1647 {
1648 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1649 if (cu_offset != DW_INVALID_OFFSET)
1650 {
1651 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001652 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1653 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001655 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656 assert(sc.comp_unit != NULL);
1657 resolved |= eSymbolContextCompUnit;
1658
1659 if (resolve_scope & eSymbolContextLineEntry)
1660 {
1661 LineTable *line_table = sc.comp_unit->GetLineTable();
1662 if (line_table == NULL)
1663 {
1664 if (ParseCompileUnitLineTable(sc))
1665 line_table = sc.comp_unit->GetLineTable();
1666 }
1667 if (line_table != NULL)
1668 {
1669 if (so_addr.IsLinkedAddress())
1670 {
1671 Address linked_addr (so_addr);
1672 linked_addr.ResolveLinkedAddress();
1673 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1674 {
1675 resolved |= eSymbolContextLineEntry;
1676 }
1677 }
1678 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1679 {
1680 resolved |= eSymbolContextLineEntry;
1681 }
1682 }
1683 }
1684
1685 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1686 {
1687 DWARFDebugInfoEntry *function_die = NULL;
1688 DWARFDebugInfoEntry *block_die = NULL;
1689 if (resolve_scope & eSymbolContextBlock)
1690 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001691 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001692 }
1693 else
1694 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001695 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696 }
1697
1698 if (function_die != NULL)
1699 {
1700 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1701 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001702 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001703 }
1704
1705 if (sc.function != NULL)
1706 {
1707 resolved |= eSymbolContextFunction;
1708
1709 if (resolve_scope & eSymbolContextBlock)
1710 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001711 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001712
1713 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001714 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001715 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001716 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001717 if (sc.block)
1718 resolved |= eSymbolContextBlock;
1719 }
1720 }
1721 }
1722 }
1723 }
1724 }
1725 }
1726 return resolved;
1727}
1728
1729
1730
1731uint32_t
1732SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1733{
1734 const uint32_t prev_size = sc_list.GetSize();
1735 if (resolve_scope & eSymbolContextCompUnit)
1736 {
1737 DWARFDebugInfo* debug_info = DebugInfo();
1738 if (debug_info)
1739 {
1740 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001741 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001742
Greg Clayton96d7d742010-11-10 23:42:09 +00001743 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001744 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001745 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001746 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1747 if (check_inlines || file_spec_matches_cu_file_spec)
1748 {
1749 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001750 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001751 assert(sc.comp_unit != NULL);
1752
1753 uint32_t file_idx = UINT32_MAX;
1754
1755 // If we are looking for inline functions only and we don't
1756 // find it in the support files, we are done.
1757 if (check_inlines)
1758 {
1759 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1760 if (file_idx == UINT32_MAX)
1761 continue;
1762 }
1763
1764 if (line != 0)
1765 {
1766 LineTable *line_table = sc.comp_unit->GetLineTable();
1767
1768 if (line_table != NULL && line != 0)
1769 {
1770 // We will have already looked up the file index if
1771 // we are searching for inline entries.
1772 if (!check_inlines)
1773 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1774
1775 if (file_idx != UINT32_MAX)
1776 {
1777 uint32_t found_line;
1778 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1779 found_line = sc.line_entry.line;
1780
Greg Clayton016a95e2010-09-14 02:20:48 +00001781 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001782 {
1783 sc.function = NULL;
1784 sc.block = NULL;
1785 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1786 {
1787 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1788 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1789 {
1790 DWARFDebugInfoEntry *function_die = NULL;
1791 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001792 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001793
1794 if (function_die != NULL)
1795 {
1796 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1797 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001798 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001799 }
1800
1801 if (sc.function != NULL)
1802 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001803 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001804
1805 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001806 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001807 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001808 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001809 }
1810 }
1811 }
1812
1813 sc_list.Append(sc);
1814 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1815 }
1816 }
1817 }
1818 else if (file_spec_matches_cu_file_spec && !check_inlines)
1819 {
1820 // only append the context if we aren't looking for inline call sites
1821 // by file and line and if the file spec matches that of the compile unit
1822 sc_list.Append(sc);
1823 }
1824 }
1825 else if (file_spec_matches_cu_file_spec && !check_inlines)
1826 {
1827 // only append the context if we aren't looking for inline call sites
1828 // by file and line and if the file spec matches that of the compile unit
1829 sc_list.Append(sc);
1830 }
1831
1832 if (!check_inlines)
1833 break;
1834 }
1835 }
1836 }
1837 }
1838 return sc_list.GetSize() - prev_size;
1839}
1840
1841void
1842SymbolFileDWARF::Index ()
1843{
1844 if (m_indexed)
1845 return;
1846 m_indexed = true;
1847 Timer scoped_timer (__PRETTY_FUNCTION__,
1848 "SymbolFileDWARF::Index (%s)",
1849 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1850
1851 DWARFDebugInfo* debug_info = DebugInfo();
1852 if (debug_info)
1853 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001854 m_aranges.reset(new DWARFDebugAranges());
1855
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001856 uint32_t cu_idx = 0;
1857 const uint32_t num_compile_units = GetNumCompileUnits();
1858 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1859 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001860 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861
Greg Clayton96d7d742010-11-10 23:42:09 +00001862 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001863
Greg Clayton96d7d742010-11-10 23:42:09 +00001864 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001865 m_function_basename_index,
1866 m_function_fullname_index,
1867 m_function_method_index,
1868 m_function_selector_index,
1869 m_objc_class_selectors_index,
1870 m_global_index,
1871 m_type_index,
1872 m_namespace_index,
1873 DebugRanges(),
1874 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001875
1876 // Keep memory down by clearing DIEs if this generate function
1877 // caused them to be parsed
1878 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001879 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001880 }
1881
Greg Clayton016a95e2010-09-14 02:20:48 +00001882 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001883
Greg Clayton24739922010-10-13 03:15:28 +00001884#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001885 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001886 s.Printf ("DWARF index for (%s) '%s/%s':",
1887 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1888 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1889 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001890 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1891 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1892 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1893 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1894 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1895 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001896 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001897 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001898#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 }
1900}
1901
1902uint32_t
1903SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1904{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001905 DWARFDebugInfo* info = DebugInfo();
1906 if (info == NULL)
1907 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001908
1909 // If we aren't appending the results to this list, then clear the list
1910 if (!append)
1911 variables.Clear();
1912
1913 // Remember how many variables are in the list before we search in case
1914 // we are appending the results to a variable list.
1915 const uint32_t original_size = variables.GetSize();
1916
1917 // Index the DWARF if we haven't already
1918 if (!m_indexed)
1919 Index ();
1920
Greg Claytonc685f8e2010-09-15 04:15:46 +00001921 SymbolContext sc;
1922 sc.module_sp = m_obj_file->GetModule()->GetSP();
1923 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001924
Greg Clayton96d7d742010-11-10 23:42:09 +00001925 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001926 DWARFCompileUnit* prev_cu = NULL;
1927 const DWARFDebugInfoEntry* die = NULL;
1928 std::vector<NameToDIE::Info> die_info_array;
1929 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001930 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001931 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001932 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001933
Greg Clayton96d7d742010-11-10 23:42:09 +00001934 if (curr_cu != prev_cu)
1935 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001936
Greg Clayton96d7d742010-11-10 23:42:09 +00001937 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001938
Greg Clayton96d7d742010-11-10 23:42:09 +00001939 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001940 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001941
Greg Clayton96d7d742010-11-10 23:42:09 +00001942 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001943
1944 if (variables.GetSize() - original_size >= max_matches)
1945 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001946 }
1947
1948 // Return the number of variable that were appended to the list
1949 return variables.GetSize() - original_size;
1950}
1951
1952uint32_t
1953SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1954{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001955 DWARFDebugInfo* info = DebugInfo();
1956 if (info == NULL)
1957 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958
1959 // If we aren't appending the results to this list, then clear the list
1960 if (!append)
1961 variables.Clear();
1962
1963 // Remember how many variables are in the list before we search in case
1964 // we are appending the results to a variable list.
1965 const uint32_t original_size = variables.GetSize();
1966
1967 // Index the DWARF if we haven't already
1968 if (!m_indexed)
1969 Index ();
1970
Greg Claytonc685f8e2010-09-15 04:15:46 +00001971 SymbolContext sc;
1972 sc.module_sp = m_obj_file->GetModule()->GetSP();
1973 assert (sc.module_sp);
1974
Greg Clayton96d7d742010-11-10 23:42:09 +00001975 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001976 DWARFCompileUnit* prev_cu = NULL;
1977 const DWARFDebugInfoEntry* die = NULL;
1978 std::vector<NameToDIE::Info> die_info_array;
1979 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001980 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001981 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001982 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001983
Greg Clayton96d7d742010-11-10 23:42:09 +00001984 if (curr_cu != prev_cu)
1985 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986
Greg Clayton96d7d742010-11-10 23:42:09 +00001987 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001988
Greg Clayton96d7d742010-11-10 23:42:09 +00001989 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001990 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001991
Greg Clayton96d7d742010-11-10 23:42:09 +00001992 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001993
Greg Claytonc685f8e2010-09-15 04:15:46 +00001994 if (variables.GetSize() - original_size >= max_matches)
1995 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001996 }
1997
1998 // Return the number of variable that were appended to the list
1999 return variables.GetSize() - original_size;
2000}
2001
2002
Greg Clayton0c5cd902010-06-28 21:30:43 +00002003void
2004SymbolFileDWARF::FindFunctions
2005(
2006 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00002007 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00002008 SymbolContextList& sc_list
2009)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002010{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002011 DWARFDebugInfo* info = DebugInfo();
2012 if (info == NULL)
2013 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002014
Greg Claytonc685f8e2010-09-15 04:15:46 +00002015 SymbolContext sc;
2016 sc.module_sp = m_obj_file->GetModule()->GetSP();
2017 assert (sc.module_sp);
2018
Greg Clayton96d7d742010-11-10 23:42:09 +00002019 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002020 DWARFCompileUnit* prev_cu = NULL;
2021 const DWARFDebugInfoEntry* die = NULL;
2022 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00002023 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002024 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002025 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002026 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002027
Greg Clayton96d7d742010-11-10 23:42:09 +00002028 if (curr_cu != prev_cu)
2029 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002030
Greg Clayton96d7d742010-11-10 23:42:09 +00002031 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00002032
2033 const DWARFDebugInfoEntry* inlined_die = NULL;
2034 if (die->Tag() == DW_TAG_inlined_subroutine)
2035 {
2036 inlined_die = die;
2037
2038 while ((die = die->GetParent()) != NULL)
2039 {
2040 if (die->Tag() == DW_TAG_subprogram)
2041 break;
2042 }
2043 }
2044 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002045 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002046 {
Greg Claytond7e05462010-11-14 00:22:48 +00002047 Address addr;
2048 // Parse all blocks if needed
2049 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002050 {
Greg Claytond7e05462010-11-14 00:22:48 +00002051 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2052 assert (sc.block != NULL);
2053 if (sc.block->GetStartAddress (addr) == false)
2054 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002055 }
Greg Claytond7e05462010-11-14 00:22:48 +00002056 else
2057 {
2058 sc.block = NULL;
2059 addr = sc.function->GetAddressRange().GetBaseAddress();
2060 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002061
Greg Claytond7e05462010-11-14 00:22:48 +00002062 if (addr.IsValid())
2063 {
2064
2065 // We found the function, so we should find the line table
2066 // and line table entry as well
2067 LineTable *line_table = sc.comp_unit->GetLineTable();
2068 if (line_table == NULL)
2069 {
2070 if (ParseCompileUnitLineTable(sc))
2071 line_table = sc.comp_unit->GetLineTable();
2072 }
2073 if (line_table != NULL)
2074 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2075
2076 sc_list.Append(sc);
2077 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002078 }
2079 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002080}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002081
Greg Claytonc685f8e2010-09-15 04:15:46 +00002082
2083void
2084SymbolFileDWARF::FindFunctions
2085(
2086 const RegularExpression &regex,
2087 const NameToDIE &name_to_die,
2088 SymbolContextList& sc_list
2089)
2090{
2091 DWARFDebugInfo* info = DebugInfo();
2092 if (info == NULL)
2093 return;
2094
2095 SymbolContext sc;
2096 sc.module_sp = m_obj_file->GetModule()->GetSP();
2097 assert (sc.module_sp);
2098
Greg Clayton96d7d742010-11-10 23:42:09 +00002099 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002100 DWARFCompileUnit* prev_cu = NULL;
2101 const DWARFDebugInfoEntry* die = NULL;
2102 std::vector<NameToDIE::Info> die_info_array;
2103 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002104 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002105 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002106 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002107
Greg Clayton96d7d742010-11-10 23:42:09 +00002108 if (curr_cu != prev_cu)
2109 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002110
Greg Clayton96d7d742010-11-10 23:42:09 +00002111 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonab843392010-12-03 17:49:14 +00002112
2113 const DWARFDebugInfoEntry* inlined_die = NULL;
2114 if (die->Tag() == DW_TAG_inlined_subroutine)
2115 {
2116 inlined_die = die;
2117
2118 while ((die = die->GetParent()) != NULL)
2119 {
2120 if (die->Tag() == DW_TAG_subprogram)
2121 break;
2122 }
2123 }
2124 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002125 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002126 {
Greg Claytonab843392010-12-03 17:49:14 +00002127 Address addr;
2128 // Parse all blocks if needed
2129 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002130 {
Greg Claytonab843392010-12-03 17:49:14 +00002131 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2132 assert (sc.block != NULL);
2133 if (sc.block->GetStartAddress (addr) == false)
2134 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002135 }
Greg Claytonab843392010-12-03 17:49:14 +00002136 else
2137 {
2138 sc.block = NULL;
2139 addr = sc.function->GetAddressRange().GetBaseAddress();
2140 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002141
Greg Claytonab843392010-12-03 17:49:14 +00002142 if (addr.IsValid())
2143 {
2144
2145 // We found the function, so we should find the line table
2146 // and line table entry as well
2147 LineTable *line_table = sc.comp_unit->GetLineTable();
2148 if (line_table == NULL)
2149 {
2150 if (ParseCompileUnitLineTable(sc))
2151 line_table = sc.comp_unit->GetLineTable();
2152 }
2153 if (line_table != NULL)
2154 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2155
2156 sc_list.Append(sc);
2157 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002158 }
2159 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002160}
2161
2162uint32_t
2163SymbolFileDWARF::FindFunctions
2164(
2165 const ConstString &name,
2166 uint32_t name_type_mask,
2167 bool append,
2168 SymbolContextList& sc_list
2169)
2170{
2171 Timer scoped_timer (__PRETTY_FUNCTION__,
2172 "SymbolFileDWARF::FindFunctions (name = '%s')",
2173 name.AsCString());
2174
Greg Clayton0c5cd902010-06-28 21:30:43 +00002175 // If we aren't appending the results to this list, then clear the list
2176 if (!append)
2177 sc_list.Clear();
2178
2179 // Remember how many sc_list are in the list before we search in case
2180 // we are appending the results to a variable list.
2181 uint32_t original_size = sc_list.GetSize();
2182
2183 // Index the DWARF if we haven't already
2184 if (!m_indexed)
2185 Index ();
2186
2187 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002188 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002189
2190 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002191 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002192
2193 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002194 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002195
2196 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002197 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002198
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002199 // Return the number of variable that were appended to the list
2200 return sc_list.GetSize() - original_size;
2201}
2202
2203
2204uint32_t
2205SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2206{
2207 Timer scoped_timer (__PRETTY_FUNCTION__,
2208 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2209 regex.GetText());
2210
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002211 // If we aren't appending the results to this list, then clear the list
2212 if (!append)
2213 sc_list.Clear();
2214
2215 // Remember how many sc_list are in the list before we search in case
2216 // we are appending the results to a variable list.
2217 uint32_t original_size = sc_list.GetSize();
2218
2219 // Index the DWARF if we haven't already
2220 if (!m_indexed)
2221 Index ();
2222
Greg Claytonc685f8e2010-09-15 04:15:46 +00002223 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002224
Greg Claytonc685f8e2010-09-15 04:15:46 +00002225 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002226
2227 // Return the number of variable that were appended to the list
2228 return sc_list.GetSize() - original_size;
2229}
2230
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002231uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002232SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002233{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002234 DWARFDebugInfo* info = DebugInfo();
2235 if (info == NULL)
2236 return 0;
2237
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002238 // If we aren't appending the results to this list, then clear the list
2239 if (!append)
2240 types.Clear();
2241
Greg Clayton6dbd3982010-09-15 05:51:24 +00002242 // Index if we already haven't to make sure the compile units
2243 // get indexed and make their global DIE index list
2244 if (!m_indexed)
2245 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002246
Greg Claytonc685f8e2010-09-15 04:15:46 +00002247 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002248 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002249 DWARFCompileUnit* prev_cu = NULL;
2250 const DWARFDebugInfoEntry* die = NULL;
2251 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002252 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002253 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002254 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002255 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002256
Greg Clayton96d7d742010-11-10 23:42:09 +00002257 if (curr_cu != prev_cu)
2258 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002259
Greg Clayton96d7d742010-11-10 23:42:09 +00002260 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002261
Greg Clayton96d7d742010-11-10 23:42:09 +00002262 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002263 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002264 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002265 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002266 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002267 assert (type_sp.get() != NULL);
2268 types.InsertUnique (type_sp);
2269 if (types.GetSize() >= max_matches)
2270 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002271 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002272 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002273 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002274}
2275
2276
Greg Clayton526e5af2010-11-13 03:52:47 +00002277ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002278SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2279 const ConstString &name)
2280{
Greg Clayton526e5af2010-11-13 03:52:47 +00002281 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002282 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002283 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002284 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002285 // Index if we already haven't to make sure the compile units
2286 // get indexed and make their global DIE index list
2287 if (!m_indexed)
2288 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002289
Greg Clayton526e5af2010-11-13 03:52:47 +00002290 DWARFCompileUnit* curr_cu = NULL;
2291 DWARFCompileUnit* prev_cu = NULL;
2292 const DWARFDebugInfoEntry* die = NULL;
2293 std::vector<NameToDIE::Info> die_info_array;
2294 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2295 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2296 {
2297 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2298
2299 if (curr_cu != prev_cu)
2300 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002301
Greg Clayton526e5af2010-11-13 03:52:47 +00002302 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2303
2304 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2305 if (clang_namespace_decl)
2306 {
2307 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2308 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2309 }
2310 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002311 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002312 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002313}
2314
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002315uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002316SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002317{
2318 // Remember how many sc_list are in the list before we search in case
2319 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002320 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002321
2322 const uint32_t num_die_offsets = die_offsets.size();
2323 // Parse all of the types we found from the pubtypes matches
2324 uint32_t i;
2325 uint32_t num_matches = 0;
2326 for (i = 0; i < num_die_offsets; ++i)
2327 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002328 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2329 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002330 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002331 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002332 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002333 assert (type_sp.get() != NULL);
2334 types.InsertUnique (type_sp);
2335 ++num_matches;
2336 if (num_matches >= max_matches)
2337 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002338 }
2339 }
2340
2341 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002342 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002343}
2344
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345
2346size_t
2347SymbolFileDWARF::ParseChildParameters
2348(
2349 const SymbolContext& sc,
2350 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002351 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002352 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002353 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002355 std::vector<clang_type_t>& function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00002356 std::vector<clang::ParmVarDecl*>& function_param_decls,
2357 unsigned &type_quals
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002358)
2359{
2360 if (parent_die == NULL)
2361 return 0;
2362
Greg Claytond88d7592010-09-15 08:33:30 +00002363 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2364
Greg Clayton7fedea22010-11-16 02:10:54 +00002365 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002366 const DWARFDebugInfoEntry *die;
2367 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2368 {
2369 dw_tag_t tag = die->Tag();
2370 switch (tag)
2371 {
2372 case DW_TAG_formal_parameter:
2373 {
2374 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002375 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002376 if (num_attributes > 0)
2377 {
2378 const char *name = NULL;
2379 Declaration decl;
2380 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002381 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002382 // one of None, Auto, Register, Extern, Static, PrivateExtern
2383
Sean Callanane2ef6e32010-09-23 03:01:22 +00002384 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002385 uint32_t i;
2386 for (i=0; i<num_attributes; ++i)
2387 {
2388 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2389 DWARFFormValue form_value;
2390 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2391 {
2392 switch (attr)
2393 {
2394 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2395 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2396 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2397 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2398 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002399 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002400 case DW_AT_location:
2401 // if (form_value.BlockData())
2402 // {
2403 // const DataExtractor& debug_info_data = debug_info();
2404 // uint32_t block_length = form_value.Unsigned();
2405 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2406 // }
2407 // else
2408 // {
2409 // }
2410 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002411 case DW_AT_const_value:
2412 case DW_AT_default_value:
2413 case DW_AT_description:
2414 case DW_AT_endianity:
2415 case DW_AT_is_optional:
2416 case DW_AT_segment:
2417 case DW_AT_variable_parameter:
2418 default:
2419 case DW_AT_abstract_origin:
2420 case DW_AT_sibling:
2421 break;
2422 }
2423 }
2424 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002425
Greg Clayton0fffff52010-09-24 05:15:53 +00002426 bool skip = false;
2427 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002428 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002429 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002430 {
2431 // In order to determine if a C++ member function is
2432 // "const" we have to look at the const-ness of "this"...
2433 // Ugly, but that
2434 if (arg_idx == 0)
2435 {
2436 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
2437 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type ||
2438 grandparent_die->Tag() == DW_TAG_class_type))
2439 {
2440 LanguageType language = sc.comp_unit->GetLanguage();
2441 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
2442 {
2443 // Often times compilers omit the "this" name for the
2444 // specification DIEs, so we can't rely upon the name
2445 // being in the formal parameter DIE...
2446 if (name == NULL || ::strcmp(name, "this")==0)
2447 {
2448 Type *this_type = ResolveTypeUID (param_type_die_offset);
2449 if (this_type)
2450 {
2451 uint32_t encoding_mask = this_type->GetEncodingMask();
2452 if (encoding_mask & Type::eEncodingIsPointerUID)
2453 {
2454 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002455 type_quals |= clang::Qualifiers::Const;
Greg Clayton7fedea22010-11-16 02:10:54 +00002456 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002457 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002458 }
2459 }
2460 }
2461 }
2462 }
2463 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002464 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002465 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002466 else
2467 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002468
Greg Clayton0fffff52010-09-24 05:15:53 +00002469 // HACK: Objective C formal parameters "self" and "_cmd"
2470 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002471 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2472 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002473 {
2474 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2475 skip = true;
2476 }
2477 }
2478 }
2479
2480 if (!skip)
2481 {
2482 Type *type = ResolveTypeUID(param_type_die_offset);
2483 if (type)
2484 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002485 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002486
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002487 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002488 assert(param_var_decl);
2489 function_param_decls.push_back(param_var_decl);
2490 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002491 }
2492 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002493 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002494 }
2495 break;
2496
2497 default:
2498 break;
2499 }
2500 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002501 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002502}
2503
2504size_t
2505SymbolFileDWARF::ParseChildEnumerators
2506(
2507 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002508 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002509 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002510 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002511 const DWARFDebugInfoEntry *parent_die
2512)
2513{
2514 if (parent_die == NULL)
2515 return 0;
2516
2517 size_t enumerators_added = 0;
2518 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002519 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2520
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002521 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2522 {
2523 const dw_tag_t tag = die->Tag();
2524 if (tag == DW_TAG_enumerator)
2525 {
2526 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002527 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002528 if (num_child_attributes > 0)
2529 {
2530 const char *name = NULL;
2531 bool got_value = false;
2532 int64_t enum_value = 0;
2533 Declaration decl;
2534
2535 uint32_t i;
2536 for (i=0; i<num_child_attributes; ++i)
2537 {
2538 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2539 DWARFFormValue form_value;
2540 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2541 {
2542 switch (attr)
2543 {
2544 case DW_AT_const_value:
2545 got_value = true;
2546 enum_value = form_value.Unsigned();
2547 break;
2548
2549 case DW_AT_name:
2550 name = form_value.AsCString(&get_debug_str_data());
2551 break;
2552
2553 case DW_AT_description:
2554 default:
2555 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2556 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2557 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2558 case DW_AT_sibling:
2559 break;
2560 }
2561 }
2562 }
2563
2564 if (name && name[0] && got_value)
2565 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002566 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2567 enumerator_clang_type,
2568 decl,
2569 name,
2570 enum_value,
2571 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002572 ++enumerators_added;
2573 }
2574 }
2575 }
2576 }
2577 return enumerators_added;
2578}
2579
2580void
2581SymbolFileDWARF::ParseChildArrayInfo
2582(
2583 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002584 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002585 const DWARFDebugInfoEntry *parent_die,
2586 int64_t& first_index,
2587 std::vector<uint64_t>& element_orders,
2588 uint32_t& byte_stride,
2589 uint32_t& bit_stride
2590)
2591{
2592 if (parent_die == NULL)
2593 return;
2594
2595 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002596 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002597 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2598 {
2599 const dw_tag_t tag = die->Tag();
2600 switch (tag)
2601 {
2602 case DW_TAG_enumerator:
2603 {
2604 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002605 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002606 if (num_child_attributes > 0)
2607 {
2608 const char *name = NULL;
2609 bool got_value = false;
2610 int64_t enum_value = 0;
2611
2612 uint32_t i;
2613 for (i=0; i<num_child_attributes; ++i)
2614 {
2615 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2616 DWARFFormValue form_value;
2617 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2618 {
2619 switch (attr)
2620 {
2621 case DW_AT_const_value:
2622 got_value = true;
2623 enum_value = form_value.Unsigned();
2624 break;
2625
2626 case DW_AT_name:
2627 name = form_value.AsCString(&get_debug_str_data());
2628 break;
2629
2630 case DW_AT_description:
2631 default:
2632 case DW_AT_decl_file:
2633 case DW_AT_decl_line:
2634 case DW_AT_decl_column:
2635 case DW_AT_sibling:
2636 break;
2637 }
2638 }
2639 }
2640 }
2641 }
2642 break;
2643
2644 case DW_TAG_subrange_type:
2645 {
2646 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002647 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002648 if (num_child_attributes > 0)
2649 {
2650 const char *name = NULL;
2651 bool got_value = false;
2652 uint64_t byte_size = 0;
2653 int64_t enum_value = 0;
2654 uint64_t num_elements = 0;
2655 uint64_t lower_bound = 0;
2656 uint64_t upper_bound = 0;
2657 uint32_t i;
2658 for (i=0; i<num_child_attributes; ++i)
2659 {
2660 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2661 DWARFFormValue form_value;
2662 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2663 {
2664 switch (attr)
2665 {
2666 case DW_AT_const_value:
2667 got_value = true;
2668 enum_value = form_value.Unsigned();
2669 break;
2670
2671 case DW_AT_name:
2672 name = form_value.AsCString(&get_debug_str_data());
2673 break;
2674
2675 case DW_AT_count:
2676 num_elements = form_value.Unsigned();
2677 break;
2678
2679 case DW_AT_bit_stride:
2680 bit_stride = form_value.Unsigned();
2681 break;
2682
2683 case DW_AT_byte_stride:
2684 byte_stride = form_value.Unsigned();
2685 break;
2686
2687 case DW_AT_byte_size:
2688 byte_size = form_value.Unsigned();
2689 break;
2690
2691 case DW_AT_lower_bound:
2692 lower_bound = form_value.Unsigned();
2693 break;
2694
2695 case DW_AT_upper_bound:
2696 upper_bound = form_value.Unsigned();
2697 break;
2698
2699 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002700 case DW_AT_abstract_origin:
2701 case DW_AT_accessibility:
2702 case DW_AT_allocated:
2703 case DW_AT_associated:
2704 case DW_AT_data_location:
2705 case DW_AT_declaration:
2706 case DW_AT_description:
2707 case DW_AT_sibling:
2708 case DW_AT_threads_scaled:
2709 case DW_AT_type:
2710 case DW_AT_visibility:
2711 break;
2712 }
2713 }
2714 }
2715
2716 if (upper_bound > lower_bound)
2717 num_elements = upper_bound - lower_bound + 1;
2718
2719 if (num_elements > 0)
2720 element_orders.push_back (num_elements);
2721 }
2722 }
2723 break;
2724 }
2725 }
2726}
2727
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002728TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002729SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002730{
2731 TypeSP type_sp;
2732 if (die != NULL)
2733 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002734 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002735 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002736 if (type_ptr == NULL)
2737 {
Greg Claytonca512b32011-01-14 04:54:56 +00002738 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2739 assert (lldb_cu);
2740 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002741 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002742 }
2743 else if (type_ptr != DIE_IS_BEING_PARSED)
2744 {
2745 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002746 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002747 }
2748
2749 }
2750 return type_sp;
2751}
2752
2753clang::DeclContext *
2754SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2755{
2756 if (die_offset != DW_INVALID_OFFSET)
2757 {
2758 DWARFCompileUnitSP cu_sp;
2759 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2760 return GetClangDeclContextForDIE (cu_sp.get(), die);
2761 }
2762 return NULL;
2763}
2764
2765
Greg Clayton96d7d742010-11-10 23:42:09 +00002766clang::NamespaceDecl *
2767SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2768{
2769 if (die->Tag() == DW_TAG_namespace)
2770 {
2771 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2772 if (namespace_name)
2773 {
2774 Declaration decl; // TODO: fill in the decl object
2775 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2776 if (namespace_decl)
2777 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2778 return namespace_decl;
2779 }
2780 }
2781 return NULL;
2782}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002783
2784clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002785SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002786{
Greg Claytonca512b32011-01-14 04:54:56 +00002787 if (m_clang_tu_decl == NULL)
2788 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002789
Greg Claytonca512b32011-01-14 04:54:56 +00002790 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset());
2791 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton4cd17802011-01-25 06:17:32 +00002792 clang::DeclContext *decl_ctx = NULL;
2793
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002794 while (die != NULL)
2795 {
Greg Claytonca512b32011-01-14 04:54:56 +00002796 // If this is the original DIE that we are searching for a declaration
2797 // for, then don't look in the cache as we don't want our own decl
2798 // context to be our decl context...
2799 if (decl_die != die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002800 {
Greg Claytonca512b32011-01-14 04:54:56 +00002801 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2802 if (pos != m_die_to_decl_ctx.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002803 {
Greg Claytonca512b32011-01-14 04:54:56 +00002804 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2805 return pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002806 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002807
Greg Claytonca512b32011-01-14 04:54:56 +00002808 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2809
2810 switch (die->Tag())
2811 {
2812 case DW_TAG_namespace:
2813 {
2814 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2815 if (namespace_name)
2816 {
2817 Declaration decl; // TODO: fill in the decl object
Greg Clayton6beaaa62011-01-17 03:46:26 +00002818 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die));
Greg Claytonca512b32011-01-14 04:54:56 +00002819 if (namespace_decl)
2820 {
2821 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2822 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2823 }
2824 return namespace_decl;
2825 }
2826 }
2827 break;
2828
2829 case DW_TAG_structure_type:
2830 case DW_TAG_union_type:
2831 case DW_TAG_class_type:
2832 {
Greg Clayton4cd17802011-01-25 06:17:32 +00002833 Type* type = ResolveType (curr_cu, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002834 pos = m_die_to_decl_ctx.find(die);
Greg Claytonca512b32011-01-14 04:54:56 +00002835 if (pos != m_die_to_decl_ctx.end())
2836 {
2837 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2838 return pos->second;
2839 }
Greg Clayton4cd17802011-01-25 06:17:32 +00002840 else
2841 {
2842 if (type)
2843 {
2844 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
2845 if (decl_ctx)
2846 return decl_ctx;
2847 }
2848 }
Greg Claytonca512b32011-01-14 04:54:56 +00002849 }
2850 break;
2851
2852 default:
2853 break;
2854 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002855 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002856
Greg Clayton6beaaa62011-01-17 03:46:26 +00002857 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002858 if (die_offset != DW_INVALID_OFFSET)
2859 {
2860 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2861 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2862 if (decl_ctx != m_clang_tu_decl)
2863 return decl_ctx;
2864 }
2865
Greg Clayton6beaaa62011-01-17 03:46:26 +00002866 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002867 if (die_offset != DW_INVALID_OFFSET)
2868 {
2869 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2870 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2871 if (decl_ctx != m_clang_tu_decl)
2872 return decl_ctx;
2873 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002874
2875 die = die->GetParent();
2876 }
Greg Clayton7a345282010-11-09 23:46:37 +00002877 // Right now we have only one translation unit per module...
Greg Claytonca512b32011-01-14 04:54:56 +00002878 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Clayton7a345282010-11-09 23:46:37 +00002879 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002880}
2881
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002882// This function can be used when a DIE is found that is a forward declaration
2883// DIE and we want to try and find a type that has the complete definition.
2884TypeSP
2885SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton1a65ae12011-01-25 23:55:37 +00002886 DWARFCompileUnit* cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002887 const DWARFDebugInfoEntry *die,
2888 const ConstString &type_name
2889)
2890{
2891 TypeSP type_sp;
2892
Greg Clayton1a65ae12011-01-25 23:55:37 +00002893 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002894 return type_sp;
2895
Greg Clayton69974892010-12-03 21:42:06 +00002896 if (!m_indexed)
2897 Index ();
2898
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002899 const dw_tag_t type_tag = die->Tag();
2900 std::vector<NameToDIE::Info> die_info_array;
2901 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2902 if (num_matches > 0)
2903 {
2904 DWARFCompileUnit* type_cu = NULL;
Greg Clayton1a65ae12011-01-25 23:55:37 +00002905 DWARFCompileUnit* curr_cu = cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002906 DWARFDebugInfo *info = DebugInfo();
2907 for (size_t i=0; i<num_matches; ++i)
2908 {
2909 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2910
2911 if (type_cu != curr_cu)
2912 {
2913 type_cu->ExtractDIEsIfNeeded (false);
2914 curr_cu = type_cu;
2915 }
2916
2917 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2918
2919 if (type_die != die && type_die->Tag() == type_tag)
2920 {
2921 // Hold off on comparing parent DIE tags until
2922 // we know what happens with stuff in namespaces
2923 // for gcc and clang...
2924 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2925 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2926 //if (parent_die->Tag() == parent_type_die->Tag())
2927 {
2928 Type *resolved_type = ResolveType (type_cu, type_die, false);
2929 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2930 {
2931 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2932 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002933 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002934 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2935 type_die->GetOffset(),
2936 type_cu->GetOffset());
2937
2938 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002939 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002940 if (!type_sp)
2941 {
2942 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2943 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002944 break;
2945 }
2946 }
2947 }
2948 }
2949 }
2950 return type_sp;
2951}
2952
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002953TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002954SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002955{
2956 TypeSP type_sp;
2957
Greg Clayton1be10fc2010-09-29 01:12:09 +00002958 if (type_is_new_ptr)
2959 *type_is_new_ptr = false;
2960
Sean Callananc7fbf732010-08-06 00:32:49 +00002961 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002962 if (die != NULL)
2963 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002964 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002965 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002966 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002967 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002968 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002969 if (type_is_new_ptr)
2970 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002971
Greg Clayton594e5ed2010-09-27 21:07:38 +00002972 const dw_tag_t tag = die->Tag();
2973
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002974 bool is_forward_declaration = false;
2975 DWARFDebugInfoEntry::Attributes attributes;
2976 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002977 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00002978 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
2979 size_t byte_size = 0;
2980 Declaration decl;
2981
Greg Clayton4957bf62010-09-30 21:49:03 +00002982 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002983 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002984
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002985 dw_attr_t attr;
2986
2987 switch (tag)
2988 {
2989 case DW_TAG_base_type:
2990 case DW_TAG_pointer_type:
2991 case DW_TAG_reference_type:
2992 case DW_TAG_typedef:
2993 case DW_TAG_const_type:
2994 case DW_TAG_restrict_type:
2995 case DW_TAG_volatile_type:
2996 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002997 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002998 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002999
Greg Claytond88d7592010-09-15 08:33:30 +00003000 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003002 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3003
3004 if (num_attributes > 0)
3005 {
3006 uint32_t i;
3007 for (i=0; i<num_attributes; ++i)
3008 {
3009 attr = attributes.AttributeAtIndex(i);
3010 DWARFFormValue form_value;
3011 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3012 {
3013 switch (attr)
3014 {
3015 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3016 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3017 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3018 case DW_AT_name:
3019 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003020 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021 break;
3022 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3023 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3024 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3025 default:
3026 case DW_AT_sibling:
3027 break;
3028 }
3029 }
3030 }
3031 }
3032
Greg Claytonc93237c2010-10-01 20:48:32 +00003033 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);
3034
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003035 switch (tag)
3036 {
3037 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003038 break;
3039
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003040 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003041 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003042 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3043 encoding,
3044 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003045 break;
3046
Greg Clayton526e5af2010-11-13 03:52:47 +00003047 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3048 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3049 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3050 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3051 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3052 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003053 }
3054
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003055 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3056 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3057 {
3058 static ConstString g_objc_type_name_id("id");
3059 static ConstString g_objc_type_name_Class("Class");
3060 static ConstString g_objc_type_name_selector("SEL");
3061
Greg Clayton24739922010-10-13 03:15:28 +00003062 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003063 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003064 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003065 resolve_state = Type::eResolveStateFull;
3066
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003067 }
Greg Clayton24739922010-10-13 03:15:28 +00003068 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003069 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003070 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003071 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003072 }
Greg Clayton24739922010-10-13 03:15:28 +00003073 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003074 {
Sean Callananf6c73082010-12-06 23:53:20 +00003075 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003076 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003077 }
3078 }
3079
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003080 type_sp.reset( new Type (die->GetOffset(),
3081 this,
3082 type_name_const_str,
3083 byte_size,
3084 NULL,
3085 encoding_uid,
3086 encoding_data_type,
3087 &decl,
3088 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003089 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003090
Greg Clayton594e5ed2010-09-27 21:07:38 +00003091 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003092
3093// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3094// if (encoding_type != NULL)
3095// {
3096// if (encoding_type != DIE_IS_BEING_PARSED)
3097// type_sp->SetEncodingType(encoding_type);
3098// else
3099// m_indirect_fixups.push_back(type_sp.get());
3100// }
3101 }
3102 break;
3103
3104 case DW_TAG_structure_type:
3105 case DW_TAG_union_type:
3106 case DW_TAG_class_type:
3107 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003108 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003109 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003110
Greg Clayton9e409562010-07-28 02:04:09 +00003111 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003112 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003113 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003114 if (num_attributes > 0)
3115 {
3116 uint32_t i;
3117 for (i=0; i<num_attributes; ++i)
3118 {
3119 attr = attributes.AttributeAtIndex(i);
3120 DWARFFormValue form_value;
3121 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3122 {
3123 switch (attr)
3124 {
Greg Clayton9e409562010-07-28 02:04:09 +00003125 case DW_AT_decl_file:
3126 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3127 break;
3128
3129 case DW_AT_decl_line:
3130 decl.SetLine(form_value.Unsigned());
3131 break;
3132
3133 case DW_AT_decl_column:
3134 decl.SetColumn(form_value.Unsigned());
3135 break;
3136
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003137 case DW_AT_name:
3138 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003139 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003140 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003141
3142 case DW_AT_byte_size:
3143 byte_size = form_value.Unsigned();
3144 break;
3145
3146 case DW_AT_accessibility:
3147 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3148 break;
3149
3150 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003151 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003152 break;
3153
3154 case DW_AT_APPLE_runtime_class:
3155 class_language = (LanguageType)form_value.Signed();
3156 break;
3157
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003158 case DW_AT_allocated:
3159 case DW_AT_associated:
3160 case DW_AT_data_location:
3161 case DW_AT_description:
3162 case DW_AT_start_scope:
3163 case DW_AT_visibility:
3164 default:
3165 case DW_AT_sibling:
3166 break;
3167 }
3168 }
3169 }
3170 }
3171
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003172 UniqueDWARFASTType unique_ast_entry;
3173 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003174 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003175 if (m_unique_ast_type_map.Find (type_name_const_str,
3176 die,
3177 decl,
3178 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003179 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003180 // We have already parsed this type or from another
3181 // compile unit. GCC loves to use the "one definition
3182 // rule" which can result in multiple definitions
3183 // of the same class over and over in each compile
3184 // unit.
3185 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003186 if (type_sp)
3187 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003188 m_die_to_type[die] = type_sp.get();
3189 return type_sp;
3190 }
3191 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003192 }
3193
3194 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3195
3196 int tag_decl_kind = -1;
3197 AccessType default_accessibility = eAccessNone;
3198 if (tag == DW_TAG_structure_type)
3199 {
3200 tag_decl_kind = clang::TTK_Struct;
3201 default_accessibility = eAccessPublic;
3202 }
3203 else if (tag == DW_TAG_union_type)
3204 {
3205 tag_decl_kind = clang::TTK_Union;
3206 default_accessibility = eAccessPublic;
3207 }
3208 else if (tag == DW_TAG_class_type)
3209 {
3210 tag_decl_kind = clang::TTK_Class;
3211 default_accessibility = eAccessPrivate;
3212 }
3213
3214
3215 if (is_forward_declaration)
3216 {
3217 // We have a forward declaration to a type and we need
3218 // to try and find a full declaration. We look in the
3219 // current type index just in case we have a forward
3220 // declaration followed by an actual declarations in the
3221 // DWARF. If this fails, we need to look elsewhere...
3222
3223 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3224
3225 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003226 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003227 // We weren't able to find a full declaration in
3228 // this DWARF, see if we have a declaration anywhere
3229 // else...
3230 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003231 }
3232
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003233 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003234 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003235 // We found a real definition for this type elsewhere
3236 // so lets use it and cache the fact that we found
3237 // a complete type for this die
3238 m_die_to_type[die] = type_sp.get();
3239 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003240 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003241 }
3242 assert (tag_decl_kind != -1);
3243 bool clang_type_was_created = false;
3244 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3245 if (clang_type == NULL)
3246 {
3247 clang_type_was_created = true;
3248 clang_type = ast.CreateRecordType (type_name_cstr,
3249 tag_decl_kind,
3250 GetClangDeclContextForDIE (dwarf_cu, die),
3251 class_language);
3252 }
3253
3254 // Store a forward declaration to this class type in case any
3255 // parameters in any class methods need it for the clang
3256 // types for function prototypes.
3257 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
3258 type_sp.reset (new Type (die->GetOffset(),
3259 this,
3260 type_name_const_str,
3261 byte_size,
3262 NULL,
3263 LLDB_INVALID_UID,
3264 Type::eEncodingIsUID,
3265 &decl,
3266 clang_type,
3267 Type::eResolveStateForward));
3268
3269
3270 // Add our type to the unique type map so we don't
3271 // end up creating many copies of the same type over
3272 // and over in the ASTContext for our module
3273 unique_ast_entry.m_type_sp = type_sp;
3274 unique_ast_entry.m_die = die;
3275 unique_ast_entry.m_declaration = decl;
3276 m_unique_ast_type_map.Insert (type_name_const_str,
3277 unique_ast_entry);
3278
3279 if (die->HasChildren() == false && is_forward_declaration == false)
3280 {
3281 // No children for this struct/union/class, lets finish it
3282 ast.StartTagDeclarationDefinition (clang_type);
3283 ast.CompleteTagDeclarationDefinition (clang_type);
3284 }
3285 else if (clang_type_was_created)
3286 {
3287 // Leave this as a forward declaration until we need
3288 // to know the details of the type. lldb_private::Type
3289 // will automatically call the SymbolFile virtual function
3290 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3291 // When the definition needs to be defined.
3292 m_forward_decl_die_to_clang_type[die] = clang_type;
3293 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3294 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003295 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003296 }
3297 break;
3298
3299 case DW_TAG_enumeration_type:
3300 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003301 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003302 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003303
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003304 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003305
Greg Claytond88d7592010-09-15 08:33:30 +00003306 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003307 if (num_attributes > 0)
3308 {
3309 uint32_t i;
3310
3311 for (i=0; i<num_attributes; ++i)
3312 {
3313 attr = attributes.AttributeAtIndex(i);
3314 DWARFFormValue form_value;
3315 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3316 {
3317 switch (attr)
3318 {
Greg Clayton7a345282010-11-09 23:46:37 +00003319 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3320 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3321 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003322 case DW_AT_name:
3323 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003324 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003325 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003326 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3327 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3328 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3329 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003330 case DW_AT_allocated:
3331 case DW_AT_associated:
3332 case DW_AT_bit_stride:
3333 case DW_AT_byte_stride:
3334 case DW_AT_data_location:
3335 case DW_AT_description:
3336 case DW_AT_start_scope:
3337 case DW_AT_visibility:
3338 case DW_AT_specification:
3339 case DW_AT_abstract_origin:
3340 case DW_AT_sibling:
3341 break;
3342 }
3343 }
3344 }
3345
Greg Claytonc93237c2010-10-01 20:48:32 +00003346 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3347
Greg Clayton1be10fc2010-09-29 01:12:09 +00003348 clang_type_t enumerator_clang_type = NULL;
3349 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3350 if (clang_type == NULL)
3351 {
Greg Clayton4cd17802011-01-25 06:17:32 +00003352 if (die->GetOffset() == 0x1c436)
3353 printf("REMOVE THIS!!!\n");
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003354 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3355 DW_ATE_signed,
3356 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003357 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Clayton6beaaa62011-01-17 03:46:26 +00003358 GetClangDeclContextForDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003359 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003360 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003361 }
3362 else
3363 {
3364 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3365 assert (enumerator_clang_type != NULL);
3366 }
3367
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003368 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003369 type_sp.reset( new Type (die->GetOffset(),
3370 this,
3371 type_name_const_str,
3372 byte_size,
3373 NULL,
3374 encoding_uid,
3375 Type::eEncodingIsUID,
3376 &decl,
3377 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003378 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003379
Greg Clayton6beaaa62011-01-17 03:46:26 +00003380#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003381 // Leave this as a forward declaration until we need
3382 // to know the details of the type. lldb_private::Type
3383 // will automatically call the SymbolFile virtual function
3384 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3385 // When the definition needs to be defined.
3386 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003387 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003388 ClangASTContext::SetHasExternalStorage (clang_type, true);
3389#else
3390 ast.StartTagDeclarationDefinition (clang_type);
3391 if (die->HasChildren())
3392 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003393 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3394 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003395 }
3396 ast.CompleteTagDeclarationDefinition (clang_type);
3397#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003398 }
3399 }
3400 break;
3401
Jim Inghamb0be4422010-08-12 01:20:14 +00003402 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003403 case DW_TAG_subprogram:
3404 case DW_TAG_subroutine_type:
3405 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003406 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003407 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003408
3409 const char *mangled = NULL;
3410 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003411 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003412 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003413 bool is_static = false;
3414 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003415 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003416
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003417 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003418 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003419
3420
Greg Claytond88d7592010-09-15 08:33:30 +00003421 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003422 if (num_attributes > 0)
3423 {
3424 uint32_t i;
3425 for (i=0; i<num_attributes; ++i)
3426 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003427 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003428 DWARFFormValue form_value;
3429 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3430 {
3431 switch (attr)
3432 {
3433 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3434 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3435 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3436 case DW_AT_name:
3437 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003438 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003439 break;
3440
3441 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3442 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003443 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003444 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003445 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3446 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003447 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3448
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003449 case DW_AT_external:
3450 if (form_value.Unsigned())
3451 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003452 if (storage == clang::SC_None)
3453 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003454 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003455 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003456 }
3457 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003458
3459 case DW_AT_allocated:
3460 case DW_AT_associated:
3461 case DW_AT_address_class:
3462 case DW_AT_artificial:
3463 case DW_AT_calling_convention:
3464 case DW_AT_data_location:
3465 case DW_AT_elemental:
3466 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003467 case DW_AT_frame_base:
3468 case DW_AT_high_pc:
3469 case DW_AT_low_pc:
3470 case DW_AT_object_pointer:
3471 case DW_AT_prototyped:
3472 case DW_AT_pure:
3473 case DW_AT_ranges:
3474 case DW_AT_recursive:
3475 case DW_AT_return_addr:
3476 case DW_AT_segment:
3477 case DW_AT_specification:
3478 case DW_AT_start_scope:
3479 case DW_AT_static_link:
3480 case DW_AT_trampoline:
3481 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003482 case DW_AT_vtable_elem_location:
3483 case DW_AT_abstract_origin:
3484 case DW_AT_description:
3485 case DW_AT_sibling:
3486 break;
3487 }
3488 }
3489 }
Greg Clayton24739922010-10-13 03:15:28 +00003490 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003491
Greg Clayton24739922010-10-13 03:15:28 +00003492 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 +00003493
Greg Clayton24739922010-10-13 03:15:28 +00003494 clang_type_t return_clang_type = NULL;
3495 Type *func_type = NULL;
3496
3497 if (type_die_offset != DW_INVALID_OFFSET)
3498 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003499
Greg Clayton24739922010-10-13 03:15:28 +00003500 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003501 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003502 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003503 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003504
Greg Claytonf51de672010-10-01 02:31:07 +00003505
Greg Clayton24739922010-10-13 03:15:28 +00003506 std::vector<clang_type_t> function_param_types;
3507 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003508
Greg Clayton24739922010-10-13 03:15:28 +00003509 // Parse the function children for the parameters
3510 if (die->HasChildren())
3511 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003512 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003513 ParseChildParameters (sc,
3514 type_sp,
3515 dwarf_cu,
3516 die,
3517 skip_artificial,
3518 type_list,
3519 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003520 function_param_decls,
3521 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003522 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003523
Greg Clayton24739922010-10-13 03:15:28 +00003524 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003525 clang_type = ast.CreateFunctionType (return_clang_type,
3526 &function_param_types[0],
3527 function_param_types.size(),
3528 is_variadic,
3529 type_quals);
3530
Greg Clayton24739922010-10-13 03:15:28 +00003531 if (type_name_cstr)
3532 {
3533 bool type_handled = false;
3534 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3535 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003536 {
Greg Clayton24739922010-10-13 03:15:28 +00003537 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003538 {
Greg Clayton24739922010-10-13 03:15:28 +00003539 // We need to find the DW_TAG_class_type or
3540 // DW_TAG_struct_type by name so we can add this
3541 // as a member function of the class.
3542 const char *class_name_start = type_name_cstr + 2;
3543 const char *class_name_end = ::strchr (class_name_start, ' ');
3544 SymbolContext empty_sc;
3545 clang_type_t class_opaque_type = NULL;
3546 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003547 {
Greg Clayton24739922010-10-13 03:15:28 +00003548 ConstString class_name (class_name_start, class_name_end - class_name_start);
3549 TypeList types;
3550 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3551 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003552 {
Greg Clayton24739922010-10-13 03:15:28 +00003553 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003554 {
Greg Clayton24739922010-10-13 03:15:28 +00003555 Type *type = types.GetTypeAtIndex (i).get();
3556 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3557 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003558 {
Greg Clayton24739922010-10-13 03:15:28 +00003559 class_opaque_type = type_clang_forward_type;
3560 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003561 }
3562 }
3563 }
Greg Clayton24739922010-10-13 03:15:28 +00003564 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003565
Greg Clayton24739922010-10-13 03:15:28 +00003566 if (class_opaque_type)
3567 {
3568 // If accessibility isn't set to anything valid, assume public for
3569 // now...
3570 if (accessibility == eAccessNone)
3571 accessibility = eAccessPublic;
3572
3573 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003574 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3575 type_name_cstr,
3576 clang_type,
3577 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003578 type_handled = objc_method_decl != NULL;
3579 }
3580 }
3581 else if (parent_die->Tag() == DW_TAG_class_type ||
3582 parent_die->Tag() == DW_TAG_structure_type)
3583 {
3584 // Look at the parent of this DIE and see if is is
3585 // a class or struct and see if this is actually a
3586 // C++ method
3587 Type *class_type = ResolveType (dwarf_cu, parent_die);
3588 if (class_type)
3589 {
3590 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3591 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003592 {
Greg Clayton24739922010-10-13 03:15:28 +00003593 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3594 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003595 if (accessibility == eAccessNone)
3596 accessibility = eAccessPublic;
Greg Clayton931180e2011-01-27 06:44:37 +00003597
3598 if (!is_static && !die->HasChildren())
3599 {
3600 // We have a C++ member function with no children (this pointer!)
3601 // and clang will get mad if we try and make a function that isn't
3602 // well formed in the DWARF, so we will just skip it...
3603 type_handled = true;
3604 }
3605 else
3606 {
3607 clang::CXXMethodDecl *cxx_method_decl;
3608 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3609 type_name_cstr,
3610 clang_type,
3611 accessibility,
3612 is_virtual,
3613 is_static,
3614 is_inline,
3615 is_explicit);
3616 type_handled = cxx_method_decl != NULL;
3617 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003618 }
3619 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003620 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003621 }
Greg Clayton24739922010-10-13 03:15:28 +00003622
3623 if (!type_handled)
3624 {
3625 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003626 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3627 clang_type,
3628 storage,
3629 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003630
3631 // Add the decl to our DIE to decl context map
3632 assert (function_decl);
3633 m_die_to_decl_ctx[die] = function_decl;
3634 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003635 ast.SetFunctionParameters (function_decl,
3636 &function_param_decls.front(),
3637 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003638 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003639 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003640 type_sp.reset( new Type (die->GetOffset(),
3641 this,
3642 type_name_const_str,
3643 0,
3644 NULL,
3645 LLDB_INVALID_UID,
3646 Type::eEncodingIsUID,
3647 &decl,
3648 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003649 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00003650 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003651 }
3652 break;
3653
3654 case DW_TAG_array_type:
3655 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003656 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003657 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003658
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003659 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003660 int64_t first_index = 0;
3661 uint32_t byte_stride = 0;
3662 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003663 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003664
3665 if (num_attributes > 0)
3666 {
3667 uint32_t i;
3668 for (i=0; i<num_attributes; ++i)
3669 {
3670 attr = attributes.AttributeAtIndex(i);
3671 DWARFFormValue form_value;
3672 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3673 {
3674 switch (attr)
3675 {
3676 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3677 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3678 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3679 case DW_AT_name:
3680 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003681 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003682 break;
3683
3684 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3685 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3686 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3687 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003688 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003689 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003690 case DW_AT_allocated:
3691 case DW_AT_associated:
3692 case DW_AT_data_location:
3693 case DW_AT_description:
3694 case DW_AT_ordering:
3695 case DW_AT_start_scope:
3696 case DW_AT_visibility:
3697 case DW_AT_specification:
3698 case DW_AT_abstract_origin:
3699 case DW_AT_sibling:
3700 break;
3701 }
3702 }
3703 }
3704
Greg Claytonc93237c2010-10-01 20:48:32 +00003705 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3706
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003707 Type *element_type = ResolveTypeUID(type_die_offset);
3708
3709 if (element_type)
3710 {
3711 std::vector<uint64_t> element_orders;
3712 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003713 // We have an array that claims to have no members, lets give it at least one member...
3714 if (element_orders.empty())
3715 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003716 if (byte_stride == 0 && bit_stride == 0)
3717 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003718 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003719 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3720 uint64_t num_elements = 0;
3721 std::vector<uint64_t>::const_reverse_iterator pos;
3722 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3723 for (pos = element_orders.rbegin(); pos != end; ++pos)
3724 {
3725 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003726 clang_type = ast.CreateArrayType (array_element_type,
3727 num_elements,
3728 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003729 array_element_type = clang_type;
3730 array_element_bit_stride = array_element_bit_stride * num_elements;
3731 }
3732 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003733 type_sp.reset( new Type (die->GetOffset(),
3734 this,
3735 empty_name,
3736 array_element_bit_stride / 8,
3737 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003738 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003739 Type::eEncodingIsUID,
3740 &decl,
3741 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003742 Type::eResolveStateFull));
3743 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003744 }
3745 }
3746 }
3747 break;
3748
Greg Clayton9b81a312010-06-12 01:20:30 +00003749 case DW_TAG_ptr_to_member_type:
3750 {
3751 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3752 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3753
Greg Claytond88d7592010-09-15 08:33:30 +00003754 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003755
3756 if (num_attributes > 0) {
3757 uint32_t i;
3758 for (i=0; i<num_attributes; ++i)
3759 {
3760 attr = attributes.AttributeAtIndex(i);
3761 DWARFFormValue form_value;
3762 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3763 {
3764 switch (attr)
3765 {
3766 case DW_AT_type:
3767 type_die_offset = form_value.Reference(dwarf_cu); break;
3768 case DW_AT_containing_type:
3769 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3770 }
3771 }
3772 }
3773
3774 Type *pointee_type = ResolveTypeUID(type_die_offset);
3775 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3776
Greg Clayton526e5af2010-11-13 03:52:47 +00003777 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3778 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003779
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003780 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3781 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003782
Greg Clayton526e5af2010-11-13 03:52:47 +00003783 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3784 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003785
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003786 type_sp.reset( new Type (die->GetOffset(),
3787 this,
3788 type_name_const_str,
3789 byte_size,
3790 NULL,
3791 LLDB_INVALID_UID,
3792 Type::eEncodingIsUID,
3793 NULL,
3794 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003795 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00003796 }
3797
3798 break;
3799 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003800 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003801 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003802 break;
3803 }
3804
3805 if (type_sp.get())
3806 {
3807 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3808 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3809
3810 SymbolContextScope * symbol_context_scope = NULL;
3811 if (sc_parent_tag == DW_TAG_compile_unit)
3812 {
3813 symbol_context_scope = sc.comp_unit;
3814 }
3815 else if (sc.function != NULL)
3816 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003817 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003818 if (symbol_context_scope == NULL)
3819 symbol_context_scope = sc.function;
3820 }
3821
3822 if (symbol_context_scope != NULL)
3823 {
3824 type_sp->SetSymbolContextScope(symbol_context_scope);
3825 }
3826
3827// if (udt_sp.get())
3828// {
3829// if (is_forward_declaration)
3830// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3831// type_sp->SetUserDefinedType(udt_sp);
3832// }
3833
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003834 //printf ("Adding type to map: 0x%8.8x for %s\n", die->GetOffset(), type_sp->GetName().GetCString());
3835 // We are ready to put this type into the uniqued list up at the module level
3836 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003837
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003838 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003839 }
3840 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003841 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003842 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003843 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003844 }
3845 }
3846 return type_sp;
3847}
3848
3849size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003850SymbolFileDWARF::ParseTypes
3851(
3852 const SymbolContext& sc,
3853 DWARFCompileUnit* dwarf_cu,
3854 const DWARFDebugInfoEntry *die,
3855 bool parse_siblings,
3856 bool parse_children
3857)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003858{
3859 size_t types_added = 0;
3860 while (die != NULL)
3861 {
3862 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003863 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003864 {
3865 if (type_is_new)
3866 ++types_added;
3867 }
3868
3869 if (parse_children && die->HasChildren())
3870 {
3871 if (die->Tag() == DW_TAG_subprogram)
3872 {
3873 SymbolContext child_sc(sc);
3874 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3875 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3876 }
3877 else
3878 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3879 }
3880
3881 if (parse_siblings)
3882 die = die->GetSibling();
3883 else
3884 die = NULL;
3885 }
3886 return types_added;
3887}
3888
3889
3890size_t
3891SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3892{
3893 assert(sc.comp_unit && sc.function);
3894 size_t functions_added = 0;
3895 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3896 if (dwarf_cu)
3897 {
3898 dw_offset_t function_die_offset = sc.function->GetID();
3899 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3900 if (function_die)
3901 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003902 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003903 }
3904 }
3905
3906 return functions_added;
3907}
3908
3909
3910size_t
3911SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3912{
3913 // At least a compile unit must be valid
3914 assert(sc.comp_unit);
3915 size_t types_added = 0;
3916 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3917 if (dwarf_cu)
3918 {
3919 if (sc.function)
3920 {
3921 dw_offset_t function_die_offset = sc.function->GetID();
3922 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3923 if (func_die && func_die->HasChildren())
3924 {
3925 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3926 }
3927 }
3928 else
3929 {
3930 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3931 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3932 {
3933 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3934 }
3935 }
3936 }
3937
3938 return types_added;
3939}
3940
3941size_t
3942SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3943{
3944 if (sc.comp_unit != NULL)
3945 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003946 DWARFDebugInfo* info = DebugInfo();
3947 if (info == NULL)
3948 return 0;
3949
3950 uint32_t cu_idx = UINT32_MAX;
3951 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003952
3953 if (dwarf_cu == NULL)
3954 return 0;
3955
3956 if (sc.function)
3957 {
3958 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003959
3960 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3961 assert (func_lo_pc != DW_INVALID_ADDRESS);
3962
3963 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003964 }
3965 else if (sc.comp_unit)
3966 {
3967 uint32_t vars_added = 0;
3968 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3969
3970 if (variables.get() == NULL)
3971 {
3972 variables.reset(new VariableList());
3973 sc.comp_unit->SetVariableList(variables);
3974
3975 // Index if we already haven't to make sure the compile units
3976 // get indexed and make their global DIE index list
3977 if (!m_indexed)
3978 Index ();
3979
Greg Claytonc685f8e2010-09-15 04:15:46 +00003980 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003981 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003982 for (size_t idx=0; idx<num_globals; ++idx)
3983 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003984 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003985 if (var_sp)
3986 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00003987 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003988 ++vars_added;
3989 }
3990 }
3991 }
3992 return vars_added;
3993 }
3994 }
3995 return 0;
3996}
3997
3998
3999VariableSP
4000SymbolFileDWARF::ParseVariableDIE
4001(
4002 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004003 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004004 const DWARFDebugInfoEntry *die,
4005 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004006)
4007{
4008
Greg Clayton83c5cd92010-11-14 22:13:40 +00004009 VariableSP var_sp (m_die_to_variable_sp[die]);
4010 if (var_sp)
4011 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004012
4013 const dw_tag_t tag = die->Tag();
4014 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004015 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004016 if (num_attributes > 0)
4017 {
4018 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00004019 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004020 Declaration decl;
4021 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004022 Type *var_type = NULL;
4023 DWARFExpression location;
4024 bool is_external = false;
4025 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00004026 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004027
4028 for (i=0; i<num_attributes; ++i)
4029 {
4030 dw_attr_t attr = attributes.AttributeAtIndex(i);
4031 DWARFFormValue form_value;
4032 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4033 {
4034 switch (attr)
4035 {
4036 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4037 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4038 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4039 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00004040 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00004041 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004042 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
4043 case DW_AT_location:
4044 {
4045 if (form_value.BlockData())
4046 {
4047 const DataExtractor& debug_info_data = get_debug_info_data();
4048
4049 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4050 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00004051 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004052 }
4053 else
4054 {
4055 const DataExtractor& debug_loc_data = get_debug_loc_data();
4056 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4057
4058 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4059 if (loc_list_length > 0)
4060 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004061 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4062 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4063 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004064 }
4065 }
4066 }
4067 break;
4068
4069 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004070 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004071 case DW_AT_const_value:
4072 case DW_AT_declaration:
4073 case DW_AT_description:
4074 case DW_AT_endianity:
4075 case DW_AT_segment:
4076 case DW_AT_start_scope:
4077 case DW_AT_visibility:
4078 default:
4079 case DW_AT_abstract_origin:
4080 case DW_AT_sibling:
4081 case DW_AT_specification:
4082 break;
4083 }
4084 }
4085 }
4086
4087 if (location.IsValid())
4088 {
4089 assert(var_type != DIE_IS_BEING_PARSED);
4090
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004091 ValueType scope = eValueTypeInvalid;
4092
4093 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4094 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4095
4096 if (tag == DW_TAG_formal_parameter)
4097 scope = eValueTypeVariableArgument;
4098 else if (is_external || parent_tag == DW_TAG_compile_unit)
4099 scope = eValueTypeVariableGlobal;
4100 else
4101 scope = eValueTypeVariableLocal;
4102
4103 SymbolContextScope * symbol_context_scope = NULL;
4104 if (parent_tag == DW_TAG_compile_unit)
4105 {
4106 symbol_context_scope = sc.comp_unit;
4107 }
4108 else if (sc.function != NULL)
4109 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004110 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004111 if (symbol_context_scope == NULL)
4112 symbol_context_scope = sc.function;
4113 }
4114
4115 assert(symbol_context_scope != NULL);
4116 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00004117 name,
4118 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004119 var_type,
4120 scope,
4121 symbol_context_scope,
4122 &decl,
4123 location,
4124 is_external,
4125 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00004126
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004127 }
4128 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00004129 // Cache var_sp even if NULL (the variable was just a specification or
4130 // was missing vital information to be able to be displayed in the debugger
4131 // (missing location due to optimization, etc)) so we don't re-parse
4132 // this DIE over and over later...
4133 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004134 return var_sp;
4135}
4136
4137size_t
4138SymbolFileDWARF::ParseVariables
4139(
4140 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004141 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004142 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004143 const DWARFDebugInfoEntry *orig_die,
4144 bool parse_siblings,
4145 bool parse_children,
4146 VariableList* cc_variable_list
4147)
4148{
4149 if (orig_die == NULL)
4150 return 0;
4151
4152 size_t vars_added = 0;
4153 const DWARFDebugInfoEntry *die = orig_die;
4154 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4155 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4156 VariableListSP variables;
4157 switch (parent_tag)
4158 {
4159 case DW_TAG_compile_unit:
4160 if (sc.comp_unit != NULL)
4161 {
4162 variables = sc.comp_unit->GetVariableList(false);
4163 if (variables.get() == NULL)
4164 {
4165 variables.reset(new VariableList());
4166 sc.comp_unit->SetVariableList(variables);
4167 }
4168 }
4169 else
4170 {
4171 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
4172 vars_added = 0;
4173 }
4174 break;
4175
4176 case DW_TAG_subprogram:
4177 case DW_TAG_inlined_subroutine:
4178 case DW_TAG_lexical_block:
4179 if (sc.function != NULL)
4180 {
4181 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004182
4183 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4184 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00004185 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004186 if (variables.get() == NULL)
4187 {
4188 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004189 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004190 }
4191 }
4192 else
4193 {
4194 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
4195 vars_added = 0;
4196 }
4197 break;
4198
4199 default:
4200 assert(!"Didn't find appropriate parent DIE for variable list...");
4201 break;
4202 }
4203
4204 // We need to have a variable list at this point that we can add variables to
4205 assert(variables.get());
4206
4207 while (die != NULL)
4208 {
4209 dw_tag_t tag = die->Tag();
4210
4211 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00004212 if (m_die_to_variable_sp[die])
4213 {
4214 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004215 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Greg Claytonbcf12172010-10-28 00:56:11 +00004216 }
4217 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218 {
4219 // We haven't already parsed it, lets do that now.
4220 if ((tag == DW_TAG_variable) ||
4221 (tag == DW_TAG_constant) ||
4222 (tag == DW_TAG_formal_parameter && sc.function))
4223 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004224 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004225 if (var_sp)
4226 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004227 variables->AddVariableIfUnique (var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00004228 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004229 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004230 ++vars_added;
4231 }
4232 }
4233 }
4234
4235 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4236
4237 if (!skip_children && parse_children && die->HasChildren())
4238 {
Greg Claytonbcf12172010-10-28 00:56:11 +00004239 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004240 }
4241
4242 if (parse_siblings)
4243 die = die->GetSibling();
4244 else
4245 die = NULL;
4246 }
4247
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004248 return vars_added;
4249}
4250
4251//------------------------------------------------------------------
4252// PluginInterface protocol
4253//------------------------------------------------------------------
4254const char *
4255SymbolFileDWARF::GetPluginName()
4256{
4257 return "SymbolFileDWARF";
4258}
4259
4260const char *
4261SymbolFileDWARF::GetShortPluginName()
4262{
4263 return GetPluginNameStatic();
4264}
4265
4266uint32_t
4267SymbolFileDWARF::GetPluginVersion()
4268{
4269 return 1;
4270}
4271
4272void
4273SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
4274{
4275}
4276
4277Error
4278SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
4279{
4280 Error error;
4281 error.SetErrorString("No plug-in command are currently supported.");
4282 return error;
4283}
4284
4285Log *
4286SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
4287{
4288 return NULL;
4289}
4290
Greg Clayton6beaaa62011-01-17 03:46:26 +00004291void
4292SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4293{
4294 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4295 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4296 if (clang_type)
4297 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4298}
4299
4300void
4301SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4302{
4303 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4304 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4305 if (clang_type)
4306 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4307}
4308