blob: bb0182c6855cd255f6a10c2572a2fc362f2e4127 [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 Claytonc685f8e2010-09-15 04:15:46 +0000182 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183{
184}
185
186SymbolFileDWARF::~SymbolFileDWARF()
187{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000188 if (m_is_external_ast_source)
189 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
190}
191
192static const ConstString &
193GetDWARFMachOSegmentName ()
194{
195 static ConstString g_dwarf_section_name ("__DWARF");
196 return g_dwarf_section_name;
197}
198
199ClangASTContext &
200SymbolFileDWARF::GetClangASTContext ()
201{
202 if (m_debug_map_symfile)
203 return m_debug_map_symfile->GetClangASTContext ();
204
205 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
206 if (!m_is_external_ast_source)
207 {
208 m_is_external_ast_source = true;
209 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
210 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
211 SymbolFileDWARF::CompleteObjCInterfaceDecl,
212 this));
213
214 ast.SetExternalSource (ast_source_ap);
215 }
216 return ast;
217}
218
219void
220SymbolFileDWARF::InitializeObject()
221{
222 // Install our external AST source callbacks so we can complete Clang types.
223 Module *module = m_obj_file->GetModule();
224 if (module)
225 {
226 const SectionList *section_list = m_obj_file->GetSectionList();
227
228 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
229
230 // Memory map the DWARF mach-o segment so we have everything mmap'ed
231 // to keep our heap memory usage down.
232 if (section)
233 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
234 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235}
236
237bool
238SymbolFileDWARF::SupportedVersion(uint16_t version)
239{
240 return version == 2 || version == 3;
241}
242
243uint32_t
244SymbolFileDWARF::GetAbilities ()
245{
246 uint32_t abilities = 0;
247 if (m_obj_file != NULL)
248 {
249 const Section* section = NULL;
250 const SectionList *section_list = m_obj_file->GetSectionList();
251 if (section_list == NULL)
252 return 0;
253
254 uint64_t debug_abbrev_file_size = 0;
255 uint64_t debug_aranges_file_size = 0;
256 uint64_t debug_frame_file_size = 0;
257 uint64_t debug_info_file_size = 0;
258 uint64_t debug_line_file_size = 0;
259 uint64_t debug_loc_file_size = 0;
260 uint64_t debug_macinfo_file_size = 0;
261 uint64_t debug_pubnames_file_size = 0;
262 uint64_t debug_pubtypes_file_size = 0;
263 uint64_t debug_ranges_file_size = 0;
264 uint64_t debug_str_file_size = 0;
265
Greg Clayton6beaaa62011-01-17 03:46:26 +0000266 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267
268 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000269 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270
Greg Clayton4ceb9982010-07-21 22:54:26 +0000271 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272 if (section != NULL)
273 {
274 debug_info_file_size = section->GetByteSize();
275
Greg Clayton4ceb9982010-07-21 22:54:26 +0000276 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 if (section)
278 debug_abbrev_file_size = section->GetByteSize();
279 else
280 m_flags.Set (flagsGotDebugAbbrevData);
281
Greg Clayton4ceb9982010-07-21 22:54:26 +0000282 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 if (section)
284 debug_aranges_file_size = section->GetByteSize();
285 else
286 m_flags.Set (flagsGotDebugArangesData);
287
Greg Clayton4ceb9982010-07-21 22:54:26 +0000288 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 if (section)
290 debug_frame_file_size = section->GetByteSize();
291 else
292 m_flags.Set (flagsGotDebugFrameData);
293
Greg Clayton4ceb9982010-07-21 22:54:26 +0000294 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 if (section)
296 debug_line_file_size = section->GetByteSize();
297 else
298 m_flags.Set (flagsGotDebugLineData);
299
Greg Clayton4ceb9982010-07-21 22:54:26 +0000300 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 if (section)
302 debug_loc_file_size = section->GetByteSize();
303 else
304 m_flags.Set (flagsGotDebugLocData);
305
Greg Clayton4ceb9982010-07-21 22:54:26 +0000306 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 if (section)
308 debug_macinfo_file_size = section->GetByteSize();
309 else
310 m_flags.Set (flagsGotDebugMacInfoData);
311
Greg Clayton4ceb9982010-07-21 22:54:26 +0000312 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 if (section)
314 debug_pubnames_file_size = section->GetByteSize();
315 else
316 m_flags.Set (flagsGotDebugPubNamesData);
317
Greg Clayton4ceb9982010-07-21 22:54:26 +0000318 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 if (section)
320 debug_pubtypes_file_size = section->GetByteSize();
321 else
322 m_flags.Set (flagsGotDebugPubTypesData);
323
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 if (section)
326 debug_ranges_file_size = section->GetByteSize();
327 else
328 m_flags.Set (flagsGotDebugRangesData);
329
Greg Clayton4ceb9982010-07-21 22:54:26 +0000330 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 if (section)
332 debug_str_file_size = section->GetByteSize();
333 else
334 m_flags.Set (flagsGotDebugStrData);
335 }
336
337 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
338 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
339
340 if (debug_line_file_size > 0)
341 abilities |= LineTables;
342
343 if (debug_aranges_file_size > 0)
344 abilities |= AddressAcceleratorTable;
345
346 if (debug_pubnames_file_size > 0)
347 abilities |= FunctionAcceleratorTable;
348
349 if (debug_pubtypes_file_size > 0)
350 abilities |= TypeAcceleratorTable;
351
352 if (debug_macinfo_file_size > 0)
353 abilities |= MacroInformation;
354
355 if (debug_frame_file_size > 0)
356 abilities |= CallFrameInformation;
357 }
358 return abilities;
359}
360
361const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000362SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363{
364 if (m_flags.IsClear (got_flag))
365 {
366 m_flags.Set (got_flag);
367 const SectionList *section_list = m_obj_file->GetSectionList();
368 if (section_list)
369 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000370 Section *section = section_list->FindSectionByType(sect_type, true).get();
371 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 {
373 // See if we memory mapped the DWARF segment?
374 if (m_dwarf_data.GetByteSize())
375 {
376 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
377 }
378 else
379 {
380 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
381 data.Clear();
382 }
383 }
384 }
385 }
386 return data;
387}
388
389const DataExtractor&
390SymbolFileDWARF::get_debug_abbrev_data()
391{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000392 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393}
394
395const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396SymbolFileDWARF::get_debug_frame_data()
397{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000398 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399}
400
401const DataExtractor&
402SymbolFileDWARF::get_debug_info_data()
403{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000404 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405}
406
407const DataExtractor&
408SymbolFileDWARF::get_debug_line_data()
409{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000410 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411}
412
413const DataExtractor&
414SymbolFileDWARF::get_debug_loc_data()
415{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000416 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
419const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000420SymbolFileDWARF::get_debug_ranges_data()
421{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000422 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
425const DataExtractor&
426SymbolFileDWARF::get_debug_str_data()
427{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000428 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
431
432DWARFDebugAbbrev*
433SymbolFileDWARF::DebugAbbrev()
434{
435 if (m_abbr.get() == NULL)
436 {
437 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
438 if (debug_abbrev_data.GetByteSize() > 0)
439 {
440 m_abbr.reset(new DWARFDebugAbbrev());
441 if (m_abbr.get())
442 m_abbr->Parse(debug_abbrev_data);
443 }
444 }
445 return m_abbr.get();
446}
447
448const DWARFDebugAbbrev*
449SymbolFileDWARF::DebugAbbrev() const
450{
451 return m_abbr.get();
452}
453
454DWARFDebugAranges*
455SymbolFileDWARF::DebugAranges()
456{
Greg Clayton016a95e2010-09-14 02:20:48 +0000457 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
458 // and we are already parsing all of the DWARF because the .debug_pubnames
459 // is useless (it only mentions symbols that are externally visible), so
460 // don't use the .debug_aranges section, we should be using a debug aranges
461 // we got from SymbolFileDWARF::Index().
462
463 if (!m_indexed)
464 Index();
465
466
467// if (m_aranges.get() == NULL)
468// {
469// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
470// m_aranges.reset(new DWARFDebugAranges());
471// if (m_aranges.get())
472// {
473// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
474// if (debug_aranges_data.GetByteSize() > 0)
475// m_aranges->Extract(debug_aranges_data);
476// else
477// m_aranges->Generate(this);
478// }
479// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 return m_aranges.get();
481}
482
483const DWARFDebugAranges*
484SymbolFileDWARF::DebugAranges() const
485{
486 return m_aranges.get();
487}
488
489
490DWARFDebugInfo*
491SymbolFileDWARF::DebugInfo()
492{
493 if (m_info.get() == NULL)
494 {
495 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
496 if (get_debug_info_data().GetByteSize() > 0)
497 {
498 m_info.reset(new DWARFDebugInfo());
499 if (m_info.get())
500 {
501 m_info->SetDwarfData(this);
502 }
503 }
504 }
505 return m_info.get();
506}
507
508const DWARFDebugInfo*
509SymbolFileDWARF::DebugInfo() const
510{
511 return m_info.get();
512}
513
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514DWARFCompileUnit*
515SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
516{
517 DWARFDebugInfo* info = DebugInfo();
518 if (info)
519 return info->GetCompileUnit(cu_uid).get();
520 return NULL;
521}
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523
524DWARFDebugRanges*
525SymbolFileDWARF::DebugRanges()
526{
527 if (m_ranges.get() == NULL)
528 {
529 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
530 if (get_debug_ranges_data().GetByteSize() > 0)
531 {
532 m_ranges.reset(new DWARFDebugRanges());
533 if (m_ranges.get())
534 m_ranges->Extract(this);
535 }
536 }
537 return m_ranges.get();
538}
539
540const DWARFDebugRanges*
541SymbolFileDWARF::DebugRanges() const
542{
543 return m_ranges.get();
544}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545
546bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000547SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548{
Greg Clayton96d7d742010-11-10 23:42:09 +0000549 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000551 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552 if (cu_die)
553 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000554 const char * cu_die_name = cu_die->GetName(this, curr_cu);
555 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
556 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 if (cu_die_name)
558 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000559 FileSpec cu_file_spec;
560
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
562 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000563 // If we have a full path to the compile unit, we don't need to resolve
564 // the file. This can be expensive e.g. when the source files are NFS mounted.
565 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 }
567 else
568 {
569 std::string fullpath(cu_comp_dir);
570 if (*fullpath.rbegin() != '/')
571 fullpath += '/';
572 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000573 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 }
575
Greg Clayton96d7d742010-11-10 23:42:09 +0000576 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 +0000577 if (compile_unit_sp.get())
578 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000579 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 return true;
581 }
582 }
583 }
584 }
585 return false;
586}
587
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588uint32_t
589SymbolFileDWARF::GetNumCompileUnits()
590{
591 DWARFDebugInfo* info = DebugInfo();
592 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 return 0;
595}
596
597CompUnitSP
598SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
599{
600 CompUnitSP comp_unit;
601 DWARFDebugInfo* info = DebugInfo();
602 if (info)
603 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000604 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
605 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 {
607 // Our symbol vendor shouldn't be asking us to add a compile unit that
608 // has already been added to it, which this DWARF plug-in knows as it
609 // stores the lldb compile unit (CompileUnit) pointer in each
610 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000611 assert(curr_cu->GetUserData() == NULL);
612 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613 }
614 }
615 return comp_unit;
616}
617
618static void
619AddRangesToBlock
620(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000621 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 DWARFDebugRanges::RangeList& ranges,
623 addr_t block_base_addr
624)
625{
626 ranges.SubtractOffset (block_base_addr);
627 size_t range_idx = 0;
628 const DWARFDebugRanges::Range *debug_range;
629 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
630 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000631 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 }
633}
634
635
636Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000637SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638{
639 DWARFDebugRanges::RangeList func_ranges;
640 const char *name = NULL;
641 const char *mangled = NULL;
642 int decl_file = 0;
643 int decl_line = 0;
644 int decl_column = 0;
645 int call_file = 0;
646 int call_line = 0;
647 int call_column = 0;
648 DWARFExpression frame_base;
649
Greg Claytonc93237c2010-10-01 20:48:32 +0000650 assert (die->Tag() == DW_TAG_subprogram);
651
652 if (die->Tag() != DW_TAG_subprogram)
653 return NULL;
654
655 const DWARFDebugInfoEntry *parent_die = die->GetParent();
656 switch (parent_die->Tag())
657 {
658 case DW_TAG_structure_type:
659 case DW_TAG_class_type:
660 // We have methods of a class or struct
661 {
662 Type *class_type = ResolveType (dwarf_cu, parent_die);
663 if (class_type)
664 class_type->GetClangType();
665 }
666 break;
667
668 default:
669 // Parse the function prototype as a type that can then be added to concrete function instance
670 ParseTypes (sc, dwarf_cu, die, false, false);
671 break;
672 }
673
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674 //FixupTypes();
675
676 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
677 {
678 // Union of all ranges in the function DIE (if the function is discontiguous)
679 AddressRange func_range;
680 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
681 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
682 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
683 {
684 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
685 if (func_range.GetBaseAddress().IsValid())
686 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
687 }
688
689 if (func_range.GetBaseAddress().IsValid())
690 {
691 Mangled func_name;
692 if (mangled)
693 func_name.SetValue(mangled, true);
694 else if (name)
695 func_name.SetValue(name, false);
696
697 FunctionSP func_sp;
698 std::auto_ptr<Declaration> decl_ap;
699 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000700 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
701 decl_line,
702 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703
Greg Clayton594e5ed2010-09-27 21:07:38 +0000704 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000705
706 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
707
708 func_range.GetBaseAddress().ResolveLinkedAddress();
709
710 func_sp.reset(new Function (sc.comp_unit,
711 die->GetOffset(), // UserID is the DIE offset
712 die->GetOffset(),
713 func_name,
714 func_type,
715 func_range)); // first address range
716
717 if (func_sp.get() != NULL)
718 {
719 func_sp->GetFrameBaseExpression() = frame_base;
720 sc.comp_unit->AddFunction(func_sp);
721 return func_sp.get();
722 }
723 }
724 }
725 return NULL;
726}
727
728size_t
729SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
730{
731 assert (sc.comp_unit);
732 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000733 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 if (dwarf_cu)
735 {
736 DWARFDIECollection function_dies;
737 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
738 size_t func_idx;
739 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
740 {
741 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
742 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
743 {
744 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
745 ++functions_added;
746 }
747 }
748 //FixupTypes();
749 }
750 return functions_added;
751}
752
753bool
754SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
755{
756 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000757 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
758 assert (curr_cu);
759 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760
761 if (cu_die)
762 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000763 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
764 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 +0000765
766 // All file indexes in DWARF are one based and a file of index zero is
767 // supposed to be the compile unit itself.
768 support_files.Append (*sc.comp_unit);
769
770 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
771 }
772 return false;
773}
774
775struct ParseDWARFLineTableCallbackInfo
776{
777 LineTable* line_table;
778 const SectionList *section_list;
779 lldb::addr_t prev_sect_file_base_addr;
780 lldb::addr_t curr_sect_file_base_addr;
781 bool is_oso_for_debug_map;
782 bool prev_in_final_executable;
783 DWARFDebugLine::Row prev_row;
784 SectionSP prev_section_sp;
785 SectionSP curr_section_sp;
786};
787
788//----------------------------------------------------------------------
789// ParseStatementTableCallback
790//----------------------------------------------------------------------
791static void
792ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
793{
794 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
795 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
796 {
797 // Just started parsing the line table
798 }
799 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
800 {
801 // Done parsing line table, nothing to do for the cleanup
802 }
803 else
804 {
805 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
806 // We have a new row, lets append it
807
808 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
809 {
810 info->prev_section_sp = info->curr_section_sp;
811 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
812 // If this is an end sequence entry, then we subtract one from the
813 // address to make sure we get an address that is not the end of
814 // a section.
815 if (state.end_sequence && state.address != 0)
816 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
817 else
818 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
819
820 if (info->curr_section_sp.get())
821 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
822 else
823 info->curr_sect_file_base_addr = 0;
824 }
825 if (info->curr_section_sp.get())
826 {
827 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
828 // Check for the fancy section magic to determine if we
829
830 if (info->is_oso_for_debug_map)
831 {
832 // When this is a debug map object file that contains DWARF
833 // (referenced from an N_OSO debug map nlist entry) we will have
834 // a file address in the file range for our section from the
835 // original .o file, and a load address in the executable that
836 // contains the debug map.
837 //
838 // If the sections for the file range and load range are
839 // different, we have a remapped section for the function and
840 // this address is resolved. If they are the same, then the
841 // function for this address didn't make it into the final
842 // executable.
843 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
844
845 // If we are doing DWARF with debug map, then we need to carefully
846 // add each line table entry as there may be gaps as functions
847 // get moved around or removed.
848 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
849 {
850 if (info->prev_in_final_executable)
851 {
852 bool terminate_previous_entry = false;
853 if (!curr_in_final_executable)
854 {
855 // Check for the case where the previous line entry
856 // in a function made it into the final executable,
857 // yet the current line entry falls in a function
858 // that didn't. The line table used to be contiguous
859 // through this address range but now it isn't. We
860 // need to terminate the previous line entry so
861 // that we can reconstruct the line range correctly
862 // for it and to keep the line table correct.
863 terminate_previous_entry = true;
864 }
865 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
866 {
867 // Check for cases where the line entries used to be
868 // contiguous address ranges, but now they aren't.
869 // This can happen when order files specify the
870 // ordering of the functions.
871 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
872 Section *curr_sect = info->curr_section_sp.get();
873 Section *prev_sect = info->prev_section_sp.get();
874 assert (curr_sect->GetLinkedSection());
875 assert (prev_sect->GetLinkedSection());
876 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
877 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
878 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
879 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
880 if (object_file_addr_delta != linked_file_addr_delta)
881 terminate_previous_entry = true;
882 }
883
884 if (terminate_previous_entry)
885 {
886 line_table->InsertLineEntry (info->prev_section_sp,
887 state.address - info->prev_sect_file_base_addr,
888 info->prev_row.line,
889 info->prev_row.column,
890 info->prev_row.file,
891 false, // is_stmt
892 false, // basic_block
893 false, // state.prologue_end
894 false, // state.epilogue_begin
895 true); // end_sequence);
896 }
897 }
898 }
899
900 if (curr_in_final_executable)
901 {
902 line_table->InsertLineEntry (info->curr_section_sp,
903 curr_line_section_offset,
904 state.line,
905 state.column,
906 state.file,
907 state.is_stmt,
908 state.basic_block,
909 state.prologue_end,
910 state.epilogue_begin,
911 state.end_sequence);
912 info->prev_section_sp = info->curr_section_sp;
913 }
914 else
915 {
916 // If the current address didn't make it into the final
917 // executable, the current section will be the __text
918 // segment in the .o file, so we need to clear this so
919 // we can catch the next function that did make it into
920 // the final executable.
921 info->prev_section_sp.reset();
922 info->curr_section_sp.reset();
923 }
924
925 info->prev_in_final_executable = curr_in_final_executable;
926 }
927 else
928 {
929 // We are not in an object file that contains DWARF for an
930 // N_OSO, this is just a normal DWARF file. The DWARF spec
931 // guarantees that the addresses will be in increasing order
932 // so, since we store line tables in file address order, we
933 // can always just append the line entry without needing to
934 // search for the correct insertion point (we don't need to
935 // use LineEntry::InsertLineEntry()).
936 line_table->AppendLineEntry (info->curr_section_sp,
937 curr_line_section_offset,
938 state.line,
939 state.column,
940 state.file,
941 state.is_stmt,
942 state.basic_block,
943 state.prologue_end,
944 state.epilogue_begin,
945 state.end_sequence);
946 }
947 }
948
949 info->prev_row = state;
950 }
951}
952
953bool
954SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
955{
956 assert (sc.comp_unit);
957 if (sc.comp_unit->GetLineTable() != NULL)
958 return true;
959
960 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
961 if (dwarf_cu)
962 {
963 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
964 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
965 if (cu_line_offset != DW_INVALID_OFFSET)
966 {
967 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
968 if (line_table_ap.get())
969 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000970 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 +0000971 uint32_t offset = cu_line_offset;
972 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
973 sc.comp_unit->SetLineTable(line_table_ap.release());
974 return true;
975 }
976 }
977 }
978 return false;
979}
980
981size_t
982SymbolFileDWARF::ParseFunctionBlocks
983(
984 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000985 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000986 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987 const DWARFDebugInfoEntry *die,
988 addr_t subprogram_low_pc,
989 bool parse_siblings,
990 bool parse_children
991)
992{
993 size_t blocks_added = 0;
994 while (die != NULL)
995 {
996 dw_tag_t tag = die->Tag();
997
998 switch (tag)
999 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +00001001 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001002 case DW_TAG_lexical_block:
1003 {
1004 DWARFDebugRanges::RangeList ranges;
1005 const char *name = NULL;
1006 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001007 Block *block = NULL;
1008 if (tag != DW_TAG_subprogram)
1009 {
1010 BlockSP block_sp(new Block (die->GetOffset()));
1011 parent_block->AddChild(block_sp);
1012 block = block_sp.get();
1013 }
1014 else
1015 {
1016 block = parent_block;
1017 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019 int decl_file = 0;
1020 int decl_line = 0;
1021 int decl_column = 0;
1022 int call_file = 0;
1023 int call_line = 0;
1024 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001025 if (die->GetDIENamesAndRanges (this,
1026 dwarf_cu,
1027 name,
1028 mangled_name,
1029 ranges,
1030 decl_file, decl_line, decl_column,
1031 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 {
1033 if (tag == DW_TAG_subprogram)
1034 {
1035 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1036 subprogram_low_pc = ranges.LowestAddress(0);
1037 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001038 else if (tag == DW_TAG_inlined_subroutine)
1039 {
1040 // We get called here for inlined subroutines in two ways.
1041 // The first time is when we are making the Function object
1042 // for this inlined concrete instance. Since we're creating a top level block at
1043 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1044 // adjust the containing address.
1045 // The second time is when we are parsing the blocks inside the function that contains
1046 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1047 // function the offset will be for that function.
1048 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1049 {
1050 subprogram_low_pc = ranges.LowestAddress(0);
1051 }
1052 }
1053
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001054 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055
1056 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1057 {
1058 std::auto_ptr<Declaration> decl_ap;
1059 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001060 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1061 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
1063 std::auto_ptr<Declaration> call_ap;
1064 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001065 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1066 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001068 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069 }
1070
1071 ++blocks_added;
1072
1073 if (parse_children && die->HasChildren())
1074 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001075 blocks_added += ParseFunctionBlocks (sc,
1076 block,
1077 dwarf_cu,
1078 die->GetFirstChild(),
1079 subprogram_low_pc,
1080 true,
1081 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082 }
1083 }
1084 }
1085 break;
1086 default:
1087 break;
1088 }
1089
1090 if (parse_siblings)
1091 die = die->GetSibling();
1092 else
1093 die = NULL;
1094 }
1095 return blocks_added;
1096}
1097
1098size_t
1099SymbolFileDWARF::ParseChildMembers
1100(
1101 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001102 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001103 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001104 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001105 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1107 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001108 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001109 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 bool &is_a_class
1111)
1112{
1113 if (parent_die == NULL)
1114 return 0;
1115
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 size_t count = 0;
1117 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001118 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001119 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001120
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001121 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1122 {
1123 dw_tag_t tag = die->Tag();
1124
1125 switch (tag)
1126 {
1127 case DW_TAG_member:
1128 {
1129 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001130 const size_t num_attributes = die->GetAttributes (this,
1131 dwarf_cu,
1132 fixed_form_sizes,
1133 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134 if (num_attributes > 0)
1135 {
1136 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001137 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001139 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001141 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001142 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143 size_t byte_size = 0;
1144 size_t bit_offset = 0;
1145 size_t bit_size = 0;
1146 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001147 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 {
1149 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1150 DWARFFormValue form_value;
1151 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1152 {
1153 switch (attr)
1154 {
1155 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1156 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1157 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1158 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1159 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1160 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1161 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1162 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1163 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001164// if (form_value.BlockData())
1165// {
1166// Value initialValue(0);
1167// Value memberOffset(0);
1168// const DataExtractor& debug_info_data = get_debug_info_data();
1169// uint32_t block_length = form_value.Unsigned();
1170// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1171// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1172// {
1173// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1174// }
1175// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176 break;
1177
Greg Clayton8cf05932010-07-22 18:30:50 +00001178 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001179 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 case DW_AT_declaration:
1181 case DW_AT_description:
1182 case DW_AT_mutable:
1183 case DW_AT_visibility:
1184 default:
1185 case DW_AT_sibling:
1186 break;
1187 }
1188 }
1189 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001190
1191 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1192
1193 if (class_language == eLanguageTypeObjC ||
1194 class_language == eLanguageTypeObjC_plus_plus)
1195 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001196
1197 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1198 {
1199 // Not all compilers will mark the vtable pointer
1200 // member as artificial (llvm-gcc). We can't have
1201 // the virtual members in our classes otherwise it
1202 // throws off all child offsets since we end up
1203 // having and extra pointer sized member in our
1204 // class layouts.
1205 is_artificial = true;
1206 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001207
Greg Clayton24739922010-10-13 03:15:28 +00001208 if (is_artificial == false)
1209 {
1210 Type *member_type = ResolveTypeUID(encoding_uid);
1211 assert(member_type);
1212 if (accessibility == eAccessNone)
1213 accessibility = default_accessibility;
1214 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001215
Greg Claytonba2d22d2010-11-13 22:57:37 +00001216 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1217 name,
1218 member_type->GetClangLayoutType(),
1219 accessibility,
1220 bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001221 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001222 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001223 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001224 }
1225 break;
1226
1227 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001228 // Let the type parsing code handle this one for us.
1229 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230 break;
1231
1232 case DW_TAG_inheritance:
1233 {
1234 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001235 if (default_accessibility == eAccessNone)
1236 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237 // TODO: implement DW_TAG_inheritance type parsing
1238 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001239 const size_t num_attributes = die->GetAttributes (this,
1240 dwarf_cu,
1241 fixed_form_sizes,
1242 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001243 if (num_attributes > 0)
1244 {
1245 Declaration decl;
1246 DWARFExpression location;
1247 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001248 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249 bool is_virtual = false;
1250 bool is_base_of_class = true;
1251 off_t member_offset = 0;
1252 uint32_t i;
1253 for (i=0; i<num_attributes; ++i)
1254 {
1255 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1256 DWARFFormValue form_value;
1257 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1258 {
1259 switch (attr)
1260 {
1261 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1262 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1263 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1264 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1265 case DW_AT_data_member_location:
1266 if (form_value.BlockData())
1267 {
1268 Value initialValue(0);
1269 Value memberOffset(0);
1270 const DataExtractor& debug_info_data = get_debug_info_data();
1271 uint32_t block_length = form_value.Unsigned();
1272 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001273 if (DWARFExpression::Evaluate (NULL,
1274 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001275 NULL,
1276 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001277 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001278 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001279 block_offset,
1280 block_length,
1281 eRegisterKindDWARF,
1282 &initialValue,
1283 memberOffset,
1284 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285 {
1286 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1287 }
1288 }
1289 break;
1290
1291 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001292 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001293 break;
1294
1295 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1296 default:
1297 case DW_AT_sibling:
1298 break;
1299 }
1300 }
1301 }
1302
Greg Clayton526e5af2010-11-13 03:52:47 +00001303 Type *base_class_type = ResolveTypeUID(encoding_uid);
1304 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001305
1306 if (class_language == eLanguageTypeObjC)
1307 {
Greg Clayton526e5af2010-11-13 03:52:47 +00001308 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_type->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001309 }
1310 else
1311 {
Greg Claytonba2d22d2010-11-13 22:57:37 +00001312 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_type->GetClangType(),
1313 accessibility,
1314 is_virtual,
1315 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001316 assert(base_classes.back());
1317 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318 }
1319 }
1320 break;
1321
1322 default:
1323 break;
1324 }
1325 }
1326 return count;
1327}
1328
1329
1330clang::DeclContext*
1331SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1332{
1333 DWARFDebugInfo* debug_info = DebugInfo();
1334 if (debug_info)
1335 {
1336 DWARFCompileUnitSP cu_sp;
1337 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1338 if (die)
1339 return GetClangDeclContextForDIE (cu_sp.get(), die);
1340 }
1341 return NULL;
1342}
1343
1344Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001345SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001346{
1347 DWARFDebugInfo* debug_info = DebugInfo();
1348 if (debug_info)
1349 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001350 DWARFCompileUnitSP cu_sp;
1351 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001352 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001353 {
1354 // We might be coming in in the middle of a type tree (a class
1355 // withing a class, an enum within a class), so parse any needed
1356 // parent DIEs before we get to this one...
1357 const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1358 switch (parent_die->Tag())
1359 {
1360 case DW_TAG_structure_type:
1361 case DW_TAG_union_type:
1362 case DW_TAG_class_type:
1363 ResolveType(cu_sp.get(), parent_die);
1364 break;
1365 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001366 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001367 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001368 }
1369 return NULL;
1370}
1371
Greg Clayton6beaaa62011-01-17 03:46:26 +00001372// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1373// SymbolFileDWARF objects to detect if this DWARF file is the one that
1374// can resolve a clang_type.
1375bool
1376SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1377{
1378 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1379 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1380 return die != NULL;
1381}
1382
1383
Greg Clayton1be10fc2010-09-29 01:12:09 +00001384lldb::clang_type_t
1385SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1386{
1387 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001388 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1389 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001390 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001391 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001392// if (m_debug_map_symfile)
1393// {
1394// Type *type = m_die_to_type[die];
1395// if (type && type->GetSymbolFile() != this)
1396// return type->GetClangType();
1397// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001398 // We have already resolved this type...
1399 return clang_type;
1400 }
1401 // Once we start resolving this type, remove it from the forward declaration
1402 // map in case anyone child members or other types require this type to get resolved.
1403 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1404 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001405 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001406
Greg Clayton1be10fc2010-09-29 01:12:09 +00001407
Greg Clayton450e3f32010-10-12 02:24:53 +00001408 DWARFDebugInfo* debug_info = DebugInfo();
1409
Greg Clayton96d7d742010-11-10 23:42:09 +00001410 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001411 Type *type = m_die_to_type.lookup (die);
1412
1413 const dw_tag_t tag = die->Tag();
1414
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001415 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1416 die->GetOffset(),
1417 DW_TAG_value_to_name(tag),
1418 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001419 assert (clang_type);
1420 DWARFDebugInfoEntry::Attributes attributes;
1421
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001422 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001423
1424 switch (tag)
1425 {
1426 case DW_TAG_structure_type:
1427 case DW_TAG_union_type:
1428 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001429 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001430 if (die->HasChildren())
1431 {
1432 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001433 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1434 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001435 class_language = eLanguageTypeObjC;
1436
1437 int tag_decl_kind = -1;
1438 AccessType default_accessibility = eAccessNone;
1439 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001440 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001441 tag_decl_kind = clang::TTK_Struct;
1442 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001443 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001444 else if (tag == DW_TAG_union_type)
1445 {
1446 tag_decl_kind = clang::TTK_Union;
1447 default_accessibility = eAccessPublic;
1448 }
1449 else if (tag == DW_TAG_class_type)
1450 {
1451 tag_decl_kind = clang::TTK_Class;
1452 default_accessibility = eAccessPrivate;
1453 }
1454
Greg Clayton96d7d742010-11-10 23:42:09 +00001455 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001456 std::vector<clang::CXXBaseSpecifier *> base_classes;
1457 std::vector<int> member_accessibilities;
1458 bool is_a_class = false;
1459 // Parse members and base classes first
1460 DWARFDIECollection member_function_dies;
1461
1462 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001463 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001464 die,
1465 clang_type,
1466 class_language,
1467 base_classes,
1468 member_accessibilities,
1469 member_function_dies,
1470 default_accessibility,
1471 is_a_class);
1472
1473 // Now parse any methods if there were any...
1474 size_t num_functions = member_function_dies.Size();
1475 if (num_functions > 0)
1476 {
1477 for (size_t i=0; i<num_functions; ++i)
1478 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001479 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001480 }
1481 }
1482
Greg Clayton450e3f32010-10-12 02:24:53 +00001483 if (class_language == eLanguageTypeObjC)
1484 {
1485 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1486 if (!class_str.empty())
1487 {
1488
1489 ConstString class_name (class_str.c_str());
1490 std::vector<NameToDIE::Info> method_die_infos;
1491 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1492 {
1493 DWARFCompileUnit* method_cu = NULL;
1494 DWARFCompileUnit* prev_method_cu = NULL;
1495 const size_t num_objc_methods = method_die_infos.size();
1496 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1497 {
1498 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1499
1500 if (method_cu != prev_method_cu)
1501 method_cu->ExtractDIEsIfNeeded (false);
1502
1503 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1504
1505 ResolveType (method_cu, method_die);
1506 }
1507 }
1508 }
1509 }
1510
Greg Claytonc93237c2010-10-01 20:48:32 +00001511 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1512 // need to tell the clang type it is actually a class.
1513 if (class_language != eLanguageTypeObjC)
1514 {
1515 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001516 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001517 }
1518
1519 // Since DW_TAG_structure_type gets used for both classes
1520 // and structures, we may need to set any DW_TAG_member
1521 // fields to have a "private" access if none was specified.
1522 // When we parsed the child members we tracked that actual
1523 // accessibility value for each DW_TAG_member in the
1524 // "member_accessibilities" array. If the value for the
1525 // member is zero, then it was set to the "default_accessibility"
1526 // which for structs was "public". Below we correct this
1527 // by setting any fields to "private" that weren't correctly
1528 // set.
1529 if (is_a_class && !member_accessibilities.empty())
1530 {
1531 // This is a class and all members that didn't have
1532 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001533 ast.SetDefaultAccessForRecordFields (clang_type,
1534 eAccessPrivate,
1535 &member_accessibilities.front(),
1536 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001537 }
1538
1539 if (!base_classes.empty())
1540 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001541 ast.SetBaseClassesForClassType (clang_type,
1542 &base_classes.front(),
1543 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001544
1545 // Clang will copy each CXXBaseSpecifier in "base_classes"
1546 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001547 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1548 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001549 }
1550
1551 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001552 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001553 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001554
1555 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001556 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001557 if (die->HasChildren())
1558 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001559 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1560 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001561 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001562 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001563 return clang_type;
1564
1565 default:
1566 assert(false && "not a forward clang type decl!");
1567 break;
1568 }
1569 return NULL;
1570}
1571
Greg Claytonc685f8e2010-09-15 04:15:46 +00001572Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001573SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001574{
1575 if (type_die != NULL)
1576 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001577 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001578 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001579 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001580 if (assert_not_being_parsed)
1581 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001582 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001583 }
1584 return NULL;
1585}
1586
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001587CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001588SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001589{
1590 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001591 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001592 {
1593 // The symbol vendor doesn't know about this compile unit, we
1594 // need to parse and add it to the symbol vendor object.
1595 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001596 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001597 if (dc_cu.get())
1598 {
1599 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001600 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001601 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001602
1603 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001604
1605 if (m_debug_map_symfile)
1606 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001607 }
1608 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001609 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001610}
1611
1612bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001613SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614{
1615 sc.Clear();
1616 // Check if the symbol vendor already knows about this compile unit?
1617 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001618 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001619
1620 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1621 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001622 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001623
1624 return sc.function != NULL;
1625}
1626
1627uint32_t
1628SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1629{
1630 Timer scoped_timer(__PRETTY_FUNCTION__,
1631 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1632 so_addr.GetSection(),
1633 so_addr.GetOffset(),
1634 resolve_scope);
1635 uint32_t resolved = 0;
1636 if (resolve_scope & ( eSymbolContextCompUnit |
1637 eSymbolContextFunction |
1638 eSymbolContextBlock |
1639 eSymbolContextLineEntry))
1640 {
1641 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1642
1643 DWARFDebugAranges* debug_aranges = DebugAranges();
1644 DWARFDebugInfo* debug_info = DebugInfo();
1645 if (debug_aranges)
1646 {
1647 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1648 if (cu_offset != DW_INVALID_OFFSET)
1649 {
1650 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001651 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1652 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001653 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001654 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655 assert(sc.comp_unit != NULL);
1656 resolved |= eSymbolContextCompUnit;
1657
1658 if (resolve_scope & eSymbolContextLineEntry)
1659 {
1660 LineTable *line_table = sc.comp_unit->GetLineTable();
1661 if (line_table == NULL)
1662 {
1663 if (ParseCompileUnitLineTable(sc))
1664 line_table = sc.comp_unit->GetLineTable();
1665 }
1666 if (line_table != NULL)
1667 {
1668 if (so_addr.IsLinkedAddress())
1669 {
1670 Address linked_addr (so_addr);
1671 linked_addr.ResolveLinkedAddress();
1672 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1673 {
1674 resolved |= eSymbolContextLineEntry;
1675 }
1676 }
1677 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1678 {
1679 resolved |= eSymbolContextLineEntry;
1680 }
1681 }
1682 }
1683
1684 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1685 {
1686 DWARFDebugInfoEntry *function_die = NULL;
1687 DWARFDebugInfoEntry *block_die = NULL;
1688 if (resolve_scope & eSymbolContextBlock)
1689 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001690 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001691 }
1692 else
1693 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001694 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001695 }
1696
1697 if (function_die != NULL)
1698 {
1699 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1700 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001701 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001702 }
1703
1704 if (sc.function != NULL)
1705 {
1706 resolved |= eSymbolContextFunction;
1707
1708 if (resolve_scope & eSymbolContextBlock)
1709 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001710 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001711
1712 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001713 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001714 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001715 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001716 if (sc.block)
1717 resolved |= eSymbolContextBlock;
1718 }
1719 }
1720 }
1721 }
1722 }
1723 }
1724 }
1725 return resolved;
1726}
1727
1728
1729
1730uint32_t
1731SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1732{
1733 const uint32_t prev_size = sc_list.GetSize();
1734 if (resolve_scope & eSymbolContextCompUnit)
1735 {
1736 DWARFDebugInfo* debug_info = DebugInfo();
1737 if (debug_info)
1738 {
1739 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001740 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001741
Greg Clayton96d7d742010-11-10 23:42:09 +00001742 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001743 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001744 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1746 if (check_inlines || file_spec_matches_cu_file_spec)
1747 {
1748 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001749 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001750 assert(sc.comp_unit != NULL);
1751
1752 uint32_t file_idx = UINT32_MAX;
1753
1754 // If we are looking for inline functions only and we don't
1755 // find it in the support files, we are done.
1756 if (check_inlines)
1757 {
1758 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1759 if (file_idx == UINT32_MAX)
1760 continue;
1761 }
1762
1763 if (line != 0)
1764 {
1765 LineTable *line_table = sc.comp_unit->GetLineTable();
1766
1767 if (line_table != NULL && line != 0)
1768 {
1769 // We will have already looked up the file index if
1770 // we are searching for inline entries.
1771 if (!check_inlines)
1772 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1773
1774 if (file_idx != UINT32_MAX)
1775 {
1776 uint32_t found_line;
1777 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1778 found_line = sc.line_entry.line;
1779
Greg Clayton016a95e2010-09-14 02:20:48 +00001780 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001781 {
1782 sc.function = NULL;
1783 sc.block = NULL;
1784 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1785 {
1786 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1787 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1788 {
1789 DWARFDebugInfoEntry *function_die = NULL;
1790 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001791 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001792
1793 if (function_die != NULL)
1794 {
1795 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1796 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001797 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001798 }
1799
1800 if (sc.function != NULL)
1801 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001802 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001803
1804 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001805 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001806 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001807 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001808 }
1809 }
1810 }
1811
1812 sc_list.Append(sc);
1813 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1814 }
1815 }
1816 }
1817 else if (file_spec_matches_cu_file_spec && !check_inlines)
1818 {
1819 // only append the context if we aren't looking for inline call sites
1820 // by file and line and if the file spec matches that of the compile unit
1821 sc_list.Append(sc);
1822 }
1823 }
1824 else if (file_spec_matches_cu_file_spec && !check_inlines)
1825 {
1826 // only append the context if we aren't looking for inline call sites
1827 // by file and line and if the file spec matches that of the compile unit
1828 sc_list.Append(sc);
1829 }
1830
1831 if (!check_inlines)
1832 break;
1833 }
1834 }
1835 }
1836 }
1837 return sc_list.GetSize() - prev_size;
1838}
1839
1840void
1841SymbolFileDWARF::Index ()
1842{
1843 if (m_indexed)
1844 return;
1845 m_indexed = true;
1846 Timer scoped_timer (__PRETTY_FUNCTION__,
1847 "SymbolFileDWARF::Index (%s)",
1848 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1849
1850 DWARFDebugInfo* debug_info = DebugInfo();
1851 if (debug_info)
1852 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001853 m_aranges.reset(new DWARFDebugAranges());
1854
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001855 uint32_t cu_idx = 0;
1856 const uint32_t num_compile_units = GetNumCompileUnits();
1857 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1858 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001859 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001860
Greg Clayton96d7d742010-11-10 23:42:09 +00001861 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001862
Greg Clayton96d7d742010-11-10 23:42:09 +00001863 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001864 m_function_basename_index,
1865 m_function_fullname_index,
1866 m_function_method_index,
1867 m_function_selector_index,
1868 m_objc_class_selectors_index,
1869 m_global_index,
1870 m_type_index,
1871 m_namespace_index,
1872 DebugRanges(),
1873 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001874
1875 // Keep memory down by clearing DIEs if this generate function
1876 // caused them to be parsed
1877 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001878 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879 }
1880
Greg Clayton016a95e2010-09-14 02:20:48 +00001881 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001882
Greg Clayton24739922010-10-13 03:15:28 +00001883#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001884 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001885 s.Printf ("DWARF index for (%s) '%s/%s':",
1886 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1887 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1888 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001889 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1890 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1891 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1892 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1893 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1894 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001895 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001896 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001897#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001898 }
1899}
1900
1901uint32_t
1902SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1903{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001904 DWARFDebugInfo* info = DebugInfo();
1905 if (info == NULL)
1906 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907
1908 // If we aren't appending the results to this list, then clear the list
1909 if (!append)
1910 variables.Clear();
1911
1912 // Remember how many variables are in the list before we search in case
1913 // we are appending the results to a variable list.
1914 const uint32_t original_size = variables.GetSize();
1915
1916 // Index the DWARF if we haven't already
1917 if (!m_indexed)
1918 Index ();
1919
Greg Claytonc685f8e2010-09-15 04:15:46 +00001920 SymbolContext sc;
1921 sc.module_sp = m_obj_file->GetModule()->GetSP();
1922 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001923
Greg Clayton96d7d742010-11-10 23:42:09 +00001924 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001925 DWARFCompileUnit* prev_cu = NULL;
1926 const DWARFDebugInfoEntry* die = NULL;
1927 std::vector<NameToDIE::Info> die_info_array;
1928 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001929 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001930 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001931 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001932
Greg Clayton96d7d742010-11-10 23:42:09 +00001933 if (curr_cu != prev_cu)
1934 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935
Greg Clayton96d7d742010-11-10 23:42:09 +00001936 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001937
Greg Clayton96d7d742010-11-10 23:42:09 +00001938 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001939 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001940
Greg Clayton96d7d742010-11-10 23:42:09 +00001941 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001942
1943 if (variables.GetSize() - original_size >= max_matches)
1944 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001945 }
1946
1947 // Return the number of variable that were appended to the list
1948 return variables.GetSize() - original_size;
1949}
1950
1951uint32_t
1952SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1953{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001954 DWARFDebugInfo* info = DebugInfo();
1955 if (info == NULL)
1956 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957
1958 // If we aren't appending the results to this list, then clear the list
1959 if (!append)
1960 variables.Clear();
1961
1962 // Remember how many variables are in the list before we search in case
1963 // we are appending the results to a variable list.
1964 const uint32_t original_size = variables.GetSize();
1965
1966 // Index the DWARF if we haven't already
1967 if (!m_indexed)
1968 Index ();
1969
Greg Claytonc685f8e2010-09-15 04:15:46 +00001970 SymbolContext sc;
1971 sc.module_sp = m_obj_file->GetModule()->GetSP();
1972 assert (sc.module_sp);
1973
Greg Clayton96d7d742010-11-10 23:42:09 +00001974 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001975 DWARFCompileUnit* prev_cu = NULL;
1976 const DWARFDebugInfoEntry* die = NULL;
1977 std::vector<NameToDIE::Info> die_info_array;
1978 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001979 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001980 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001981 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001982
Greg Clayton96d7d742010-11-10 23:42:09 +00001983 if (curr_cu != prev_cu)
1984 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001985
Greg Clayton96d7d742010-11-10 23:42:09 +00001986 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001987
Greg Clayton96d7d742010-11-10 23:42:09 +00001988 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001989 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001990
Greg Clayton96d7d742010-11-10 23:42:09 +00001991 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001992
Greg Claytonc685f8e2010-09-15 04:15:46 +00001993 if (variables.GetSize() - original_size >= max_matches)
1994 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001995 }
1996
1997 // Return the number of variable that were appended to the list
1998 return variables.GetSize() - original_size;
1999}
2000
2001
Greg Clayton0c5cd902010-06-28 21:30:43 +00002002void
2003SymbolFileDWARF::FindFunctions
2004(
2005 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00002006 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00002007 SymbolContextList& sc_list
2008)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002009{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002010 DWARFDebugInfo* info = DebugInfo();
2011 if (info == NULL)
2012 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002013
Greg Claytonc685f8e2010-09-15 04:15:46 +00002014 SymbolContext sc;
2015 sc.module_sp = m_obj_file->GetModule()->GetSP();
2016 assert (sc.module_sp);
2017
Greg Clayton96d7d742010-11-10 23:42:09 +00002018 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002019 DWARFCompileUnit* prev_cu = NULL;
2020 const DWARFDebugInfoEntry* die = NULL;
2021 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00002022 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002023 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002024 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002025 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002026
Greg Clayton96d7d742010-11-10 23:42:09 +00002027 if (curr_cu != prev_cu)
2028 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002029
Greg Clayton96d7d742010-11-10 23:42:09 +00002030 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00002031
2032 const DWARFDebugInfoEntry* inlined_die = NULL;
2033 if (die->Tag() == DW_TAG_inlined_subroutine)
2034 {
2035 inlined_die = die;
2036
2037 while ((die = die->GetParent()) != NULL)
2038 {
2039 if (die->Tag() == DW_TAG_subprogram)
2040 break;
2041 }
2042 }
2043 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002044 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002045 {
Greg Claytond7e05462010-11-14 00:22:48 +00002046 Address addr;
2047 // Parse all blocks if needed
2048 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002049 {
Greg Claytond7e05462010-11-14 00:22:48 +00002050 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2051 assert (sc.block != NULL);
2052 if (sc.block->GetStartAddress (addr) == false)
2053 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002054 }
Greg Claytond7e05462010-11-14 00:22:48 +00002055 else
2056 {
2057 sc.block = NULL;
2058 addr = sc.function->GetAddressRange().GetBaseAddress();
2059 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002060
Greg Claytond7e05462010-11-14 00:22:48 +00002061 if (addr.IsValid())
2062 {
2063
2064 // We found the function, so we should find the line table
2065 // and line table entry as well
2066 LineTable *line_table = sc.comp_unit->GetLineTable();
2067 if (line_table == NULL)
2068 {
2069 if (ParseCompileUnitLineTable(sc))
2070 line_table = sc.comp_unit->GetLineTable();
2071 }
2072 if (line_table != NULL)
2073 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2074
2075 sc_list.Append(sc);
2076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002077 }
2078 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002079}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080
Greg Claytonc685f8e2010-09-15 04:15:46 +00002081
2082void
2083SymbolFileDWARF::FindFunctions
2084(
2085 const RegularExpression &regex,
2086 const NameToDIE &name_to_die,
2087 SymbolContextList& sc_list
2088)
2089{
2090 DWARFDebugInfo* info = DebugInfo();
2091 if (info == NULL)
2092 return;
2093
2094 SymbolContext sc;
2095 sc.module_sp = m_obj_file->GetModule()->GetSP();
2096 assert (sc.module_sp);
2097
Greg Clayton96d7d742010-11-10 23:42:09 +00002098 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002099 DWARFCompileUnit* prev_cu = NULL;
2100 const DWARFDebugInfoEntry* die = NULL;
2101 std::vector<NameToDIE::Info> die_info_array;
2102 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002103 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002104 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002105 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002106
Greg Clayton96d7d742010-11-10 23:42:09 +00002107 if (curr_cu != prev_cu)
2108 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002109
Greg Clayton96d7d742010-11-10 23:42:09 +00002110 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonab843392010-12-03 17:49:14 +00002111
2112 const DWARFDebugInfoEntry* inlined_die = NULL;
2113 if (die->Tag() == DW_TAG_inlined_subroutine)
2114 {
2115 inlined_die = die;
2116
2117 while ((die = die->GetParent()) != NULL)
2118 {
2119 if (die->Tag() == DW_TAG_subprogram)
2120 break;
2121 }
2122 }
2123 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002124 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002125 {
Greg Claytonab843392010-12-03 17:49:14 +00002126 Address addr;
2127 // Parse all blocks if needed
2128 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002129 {
Greg Claytonab843392010-12-03 17:49:14 +00002130 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2131 assert (sc.block != NULL);
2132 if (sc.block->GetStartAddress (addr) == false)
2133 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002134 }
Greg Claytonab843392010-12-03 17:49:14 +00002135 else
2136 {
2137 sc.block = NULL;
2138 addr = sc.function->GetAddressRange().GetBaseAddress();
2139 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002140
Greg Claytonab843392010-12-03 17:49:14 +00002141 if (addr.IsValid())
2142 {
2143
2144 // We found the function, so we should find the line table
2145 // and line table entry as well
2146 LineTable *line_table = sc.comp_unit->GetLineTable();
2147 if (line_table == NULL)
2148 {
2149 if (ParseCompileUnitLineTable(sc))
2150 line_table = sc.comp_unit->GetLineTable();
2151 }
2152 if (line_table != NULL)
2153 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2154
2155 sc_list.Append(sc);
2156 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002157 }
2158 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002159}
2160
2161uint32_t
2162SymbolFileDWARF::FindFunctions
2163(
2164 const ConstString &name,
2165 uint32_t name_type_mask,
2166 bool append,
2167 SymbolContextList& sc_list
2168)
2169{
2170 Timer scoped_timer (__PRETTY_FUNCTION__,
2171 "SymbolFileDWARF::FindFunctions (name = '%s')",
2172 name.AsCString());
2173
Greg Clayton0c5cd902010-06-28 21:30:43 +00002174 // If we aren't appending the results to this list, then clear the list
2175 if (!append)
2176 sc_list.Clear();
2177
2178 // Remember how many sc_list are in the list before we search in case
2179 // we are appending the results to a variable list.
2180 uint32_t original_size = sc_list.GetSize();
2181
2182 // Index the DWARF if we haven't already
2183 if (!m_indexed)
2184 Index ();
2185
2186 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002187 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002188
2189 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002190 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002191
2192 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002193 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002194
2195 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002196 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002197
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002198 // Return the number of variable that were appended to the list
2199 return sc_list.GetSize() - original_size;
2200}
2201
2202
2203uint32_t
2204SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2205{
2206 Timer scoped_timer (__PRETTY_FUNCTION__,
2207 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2208 regex.GetText());
2209
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002210 // If we aren't appending the results to this list, then clear the list
2211 if (!append)
2212 sc_list.Clear();
2213
2214 // Remember how many sc_list are in the list before we search in case
2215 // we are appending the results to a variable list.
2216 uint32_t original_size = sc_list.GetSize();
2217
2218 // Index the DWARF if we haven't already
2219 if (!m_indexed)
2220 Index ();
2221
Greg Claytonc685f8e2010-09-15 04:15:46 +00002222 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002223
Greg Claytonc685f8e2010-09-15 04:15:46 +00002224 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002225
2226 // Return the number of variable that were appended to the list
2227 return sc_list.GetSize() - original_size;
2228}
2229
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002230uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002231SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002233 DWARFDebugInfo* info = DebugInfo();
2234 if (info == NULL)
2235 return 0;
2236
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002237 // If we aren't appending the results to this list, then clear the list
2238 if (!append)
2239 types.Clear();
2240
Greg Clayton6dbd3982010-09-15 05:51:24 +00002241 // Index if we already haven't to make sure the compile units
2242 // get indexed and make their global DIE index list
2243 if (!m_indexed)
2244 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002245
Greg Claytonc685f8e2010-09-15 04:15:46 +00002246 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002247 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002248 DWARFCompileUnit* prev_cu = NULL;
2249 const DWARFDebugInfoEntry* die = NULL;
2250 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002251 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002252 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002253 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002254 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002255
Greg Clayton96d7d742010-11-10 23:42:09 +00002256 if (curr_cu != prev_cu)
2257 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002258
Greg Clayton96d7d742010-11-10 23:42:09 +00002259 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002260
Greg Clayton96d7d742010-11-10 23:42:09 +00002261 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002262 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002264 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002265 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002266 assert (type_sp.get() != NULL);
2267 types.InsertUnique (type_sp);
2268 if (types.GetSize() >= max_matches)
2269 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002271 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002272 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002273}
2274
2275
Greg Clayton526e5af2010-11-13 03:52:47 +00002276ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002277SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2278 const ConstString &name)
2279{
Greg Clayton526e5af2010-11-13 03:52:47 +00002280 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002281 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002282 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002283 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002284 // Index if we already haven't to make sure the compile units
2285 // get indexed and make their global DIE index list
2286 if (!m_indexed)
2287 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002288
Greg Clayton526e5af2010-11-13 03:52:47 +00002289 DWARFCompileUnit* curr_cu = NULL;
2290 DWARFCompileUnit* prev_cu = NULL;
2291 const DWARFDebugInfoEntry* die = NULL;
2292 std::vector<NameToDIE::Info> die_info_array;
2293 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2294 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2295 {
2296 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2297
2298 if (curr_cu != prev_cu)
2299 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002300
Greg Clayton526e5af2010-11-13 03:52:47 +00002301 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2302
2303 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2304 if (clang_namespace_decl)
2305 {
2306 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2307 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2308 }
2309 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002310 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002311 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002312}
2313
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002314uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002315SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002316{
2317 // Remember how many sc_list are in the list before we search in case
2318 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002319 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002320
2321 const uint32_t num_die_offsets = die_offsets.size();
2322 // Parse all of the types we found from the pubtypes matches
2323 uint32_t i;
2324 uint32_t num_matches = 0;
2325 for (i = 0; i < num_die_offsets; ++i)
2326 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002327 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2328 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002329 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002330 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002331 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002332 assert (type_sp.get() != NULL);
2333 types.InsertUnique (type_sp);
2334 ++num_matches;
2335 if (num_matches >= max_matches)
2336 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002337 }
2338 }
2339
2340 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002341 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002342}
2343
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002344
2345size_t
2346SymbolFileDWARF::ParseChildParameters
2347(
2348 const SymbolContext& sc,
2349 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002350 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002352 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002353 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002354 std::vector<clang_type_t>& function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00002355 std::vector<clang::ParmVarDecl*>& function_param_decls,
2356 unsigned &type_quals
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002357)
2358{
2359 if (parent_die == NULL)
2360 return 0;
2361
Greg Claytond88d7592010-09-15 08:33:30 +00002362 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2363
Greg Clayton7fedea22010-11-16 02:10:54 +00002364 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365 const DWARFDebugInfoEntry *die;
2366 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2367 {
2368 dw_tag_t tag = die->Tag();
2369 switch (tag)
2370 {
2371 case DW_TAG_formal_parameter:
2372 {
2373 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002374 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375 if (num_attributes > 0)
2376 {
2377 const char *name = NULL;
2378 Declaration decl;
2379 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002380 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002381 // one of None, Auto, Register, Extern, Static, PrivateExtern
2382
Sean Callanane2ef6e32010-09-23 03:01:22 +00002383 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002384 uint32_t i;
2385 for (i=0; i<num_attributes; ++i)
2386 {
2387 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2388 DWARFFormValue form_value;
2389 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2390 {
2391 switch (attr)
2392 {
2393 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2394 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2395 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2396 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2397 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002398 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002399 case DW_AT_location:
2400 // if (form_value.BlockData())
2401 // {
2402 // const DataExtractor& debug_info_data = debug_info();
2403 // uint32_t block_length = form_value.Unsigned();
2404 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2405 // }
2406 // else
2407 // {
2408 // }
2409 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410 case DW_AT_const_value:
2411 case DW_AT_default_value:
2412 case DW_AT_description:
2413 case DW_AT_endianity:
2414 case DW_AT_is_optional:
2415 case DW_AT_segment:
2416 case DW_AT_variable_parameter:
2417 default:
2418 case DW_AT_abstract_origin:
2419 case DW_AT_sibling:
2420 break;
2421 }
2422 }
2423 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002424
Greg Clayton0fffff52010-09-24 05:15:53 +00002425 bool skip = false;
2426 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002427 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002428 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002429 {
2430 // In order to determine if a C++ member function is
2431 // "const" we have to look at the const-ness of "this"...
2432 // Ugly, but that
2433 if (arg_idx == 0)
2434 {
2435 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
2436 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type ||
2437 grandparent_die->Tag() == DW_TAG_class_type))
2438 {
2439 LanguageType language = sc.comp_unit->GetLanguage();
2440 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
2441 {
2442 // Often times compilers omit the "this" name for the
2443 // specification DIEs, so we can't rely upon the name
2444 // being in the formal parameter DIE...
2445 if (name == NULL || ::strcmp(name, "this")==0)
2446 {
2447 Type *this_type = ResolveTypeUID (param_type_die_offset);
2448 if (this_type)
2449 {
2450 uint32_t encoding_mask = this_type->GetEncodingMask();
2451 if (encoding_mask & Type::eEncodingIsPointerUID)
2452 {
2453 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002454 type_quals |= clang::Qualifiers::Const;
Greg Clayton7fedea22010-11-16 02:10:54 +00002455 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002456 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002457 }
2458 }
2459 }
2460 }
2461 }
2462 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002463 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002464 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002465 else
2466 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002467
Greg Clayton0fffff52010-09-24 05:15:53 +00002468 // HACK: Objective C formal parameters "self" and "_cmd"
2469 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002470 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2471 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002472 {
2473 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2474 skip = true;
2475 }
2476 }
2477 }
2478
2479 if (!skip)
2480 {
2481 Type *type = ResolveTypeUID(param_type_die_offset);
2482 if (type)
2483 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002484 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002485
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002486 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002487 assert(param_var_decl);
2488 function_param_decls.push_back(param_var_decl);
2489 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002490 }
2491 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002492 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002493 }
2494 break;
2495
2496 default:
2497 break;
2498 }
2499 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002500 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501}
2502
2503size_t
2504SymbolFileDWARF::ParseChildEnumerators
2505(
2506 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002507 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002508 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002509 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002510 const DWARFDebugInfoEntry *parent_die
2511)
2512{
2513 if (parent_die == NULL)
2514 return 0;
2515
2516 size_t enumerators_added = 0;
2517 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002518 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2519
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002520 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2521 {
2522 const dw_tag_t tag = die->Tag();
2523 if (tag == DW_TAG_enumerator)
2524 {
2525 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002526 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002527 if (num_child_attributes > 0)
2528 {
2529 const char *name = NULL;
2530 bool got_value = false;
2531 int64_t enum_value = 0;
2532 Declaration decl;
2533
2534 uint32_t i;
2535 for (i=0; i<num_child_attributes; ++i)
2536 {
2537 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2538 DWARFFormValue form_value;
2539 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2540 {
2541 switch (attr)
2542 {
2543 case DW_AT_const_value:
2544 got_value = true;
2545 enum_value = form_value.Unsigned();
2546 break;
2547
2548 case DW_AT_name:
2549 name = form_value.AsCString(&get_debug_str_data());
2550 break;
2551
2552 case DW_AT_description:
2553 default:
2554 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2555 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2556 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2557 case DW_AT_sibling:
2558 break;
2559 }
2560 }
2561 }
2562
2563 if (name && name[0] && got_value)
2564 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002565 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2566 enumerator_clang_type,
2567 decl,
2568 name,
2569 enum_value,
2570 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002571 ++enumerators_added;
2572 }
2573 }
2574 }
2575 }
2576 return enumerators_added;
2577}
2578
2579void
2580SymbolFileDWARF::ParseChildArrayInfo
2581(
2582 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002583 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002584 const DWARFDebugInfoEntry *parent_die,
2585 int64_t& first_index,
2586 std::vector<uint64_t>& element_orders,
2587 uint32_t& byte_stride,
2588 uint32_t& bit_stride
2589)
2590{
2591 if (parent_die == NULL)
2592 return;
2593
2594 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002595 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002596 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2597 {
2598 const dw_tag_t tag = die->Tag();
2599 switch (tag)
2600 {
2601 case DW_TAG_enumerator:
2602 {
2603 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002604 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002605 if (num_child_attributes > 0)
2606 {
2607 const char *name = NULL;
2608 bool got_value = false;
2609 int64_t enum_value = 0;
2610
2611 uint32_t i;
2612 for (i=0; i<num_child_attributes; ++i)
2613 {
2614 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2615 DWARFFormValue form_value;
2616 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2617 {
2618 switch (attr)
2619 {
2620 case DW_AT_const_value:
2621 got_value = true;
2622 enum_value = form_value.Unsigned();
2623 break;
2624
2625 case DW_AT_name:
2626 name = form_value.AsCString(&get_debug_str_data());
2627 break;
2628
2629 case DW_AT_description:
2630 default:
2631 case DW_AT_decl_file:
2632 case DW_AT_decl_line:
2633 case DW_AT_decl_column:
2634 case DW_AT_sibling:
2635 break;
2636 }
2637 }
2638 }
2639 }
2640 }
2641 break;
2642
2643 case DW_TAG_subrange_type:
2644 {
2645 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002646 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002647 if (num_child_attributes > 0)
2648 {
2649 const char *name = NULL;
2650 bool got_value = false;
2651 uint64_t byte_size = 0;
2652 int64_t enum_value = 0;
2653 uint64_t num_elements = 0;
2654 uint64_t lower_bound = 0;
2655 uint64_t upper_bound = 0;
2656 uint32_t i;
2657 for (i=0; i<num_child_attributes; ++i)
2658 {
2659 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2660 DWARFFormValue form_value;
2661 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2662 {
2663 switch (attr)
2664 {
2665 case DW_AT_const_value:
2666 got_value = true;
2667 enum_value = form_value.Unsigned();
2668 break;
2669
2670 case DW_AT_name:
2671 name = form_value.AsCString(&get_debug_str_data());
2672 break;
2673
2674 case DW_AT_count:
2675 num_elements = form_value.Unsigned();
2676 break;
2677
2678 case DW_AT_bit_stride:
2679 bit_stride = form_value.Unsigned();
2680 break;
2681
2682 case DW_AT_byte_stride:
2683 byte_stride = form_value.Unsigned();
2684 break;
2685
2686 case DW_AT_byte_size:
2687 byte_size = form_value.Unsigned();
2688 break;
2689
2690 case DW_AT_lower_bound:
2691 lower_bound = form_value.Unsigned();
2692 break;
2693
2694 case DW_AT_upper_bound:
2695 upper_bound = form_value.Unsigned();
2696 break;
2697
2698 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002699 case DW_AT_abstract_origin:
2700 case DW_AT_accessibility:
2701 case DW_AT_allocated:
2702 case DW_AT_associated:
2703 case DW_AT_data_location:
2704 case DW_AT_declaration:
2705 case DW_AT_description:
2706 case DW_AT_sibling:
2707 case DW_AT_threads_scaled:
2708 case DW_AT_type:
2709 case DW_AT_visibility:
2710 break;
2711 }
2712 }
2713 }
2714
2715 if (upper_bound > lower_bound)
2716 num_elements = upper_bound - lower_bound + 1;
2717
2718 if (num_elements > 0)
2719 element_orders.push_back (num_elements);
2720 }
2721 }
2722 break;
2723 }
2724 }
2725}
2726
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002727TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002728SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002729{
2730 TypeSP type_sp;
2731 if (die != NULL)
2732 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002733 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002734 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002735 if (type_ptr == NULL)
2736 {
Greg Claytonca512b32011-01-14 04:54:56 +00002737 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2738 assert (lldb_cu);
2739 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002740 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002741 }
2742 else if (type_ptr != DIE_IS_BEING_PARSED)
2743 {
2744 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002745 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002746 }
2747
2748 }
2749 return type_sp;
2750}
2751
2752clang::DeclContext *
2753SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2754{
2755 if (die_offset != DW_INVALID_OFFSET)
2756 {
2757 DWARFCompileUnitSP cu_sp;
2758 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2759 return GetClangDeclContextForDIE (cu_sp.get(), die);
2760 }
2761 return NULL;
2762}
2763
2764
Greg Clayton96d7d742010-11-10 23:42:09 +00002765clang::NamespaceDecl *
2766SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2767{
2768 if (die->Tag() == DW_TAG_namespace)
2769 {
2770 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2771 if (namespace_name)
2772 {
2773 Declaration decl; // TODO: fill in the decl object
2774 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2775 if (namespace_decl)
2776 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2777 return namespace_decl;
2778 }
2779 }
2780 return NULL;
2781}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002782
2783clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002784SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002785{
Greg Claytonca512b32011-01-14 04:54:56 +00002786 if (m_clang_tu_decl == NULL)
2787 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002788
Greg Claytonca512b32011-01-14 04:54:56 +00002789 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset());
2790 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton4cd17802011-01-25 06:17:32 +00002791 clang::DeclContext *decl_ctx = NULL;
2792
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002793 while (die != NULL)
2794 {
Greg Claytonca512b32011-01-14 04:54:56 +00002795 // If this is the original DIE that we are searching for a declaration
2796 // for, then don't look in the cache as we don't want our own decl
2797 // context to be our decl context...
2798 if (decl_die != die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002799 {
Greg Claytonca512b32011-01-14 04:54:56 +00002800 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2801 if (pos != m_die_to_decl_ctx.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002802 {
Greg Claytonca512b32011-01-14 04:54:56 +00002803 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2804 return pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002805 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002806
Greg Claytonca512b32011-01-14 04:54:56 +00002807 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2808
2809 switch (die->Tag())
2810 {
2811 case DW_TAG_namespace:
2812 {
2813 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2814 if (namespace_name)
2815 {
2816 Declaration decl; // TODO: fill in the decl object
Greg Clayton6beaaa62011-01-17 03:46:26 +00002817 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die));
Greg Claytonca512b32011-01-14 04:54:56 +00002818 if (namespace_decl)
2819 {
2820 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2821 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2822 }
2823 return namespace_decl;
2824 }
2825 }
2826 break;
2827
2828 case DW_TAG_structure_type:
2829 case DW_TAG_union_type:
2830 case DW_TAG_class_type:
2831 {
Greg Clayton4cd17802011-01-25 06:17:32 +00002832 Type* type = ResolveType (curr_cu, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002833 pos = m_die_to_decl_ctx.find(die);
Greg Claytonca512b32011-01-14 04:54:56 +00002834 if (pos != m_die_to_decl_ctx.end())
2835 {
2836 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2837 return pos->second;
2838 }
Greg Clayton4cd17802011-01-25 06:17:32 +00002839 else
2840 {
2841 if (type)
2842 {
2843 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
2844 if (decl_ctx)
2845 return decl_ctx;
2846 }
2847 }
Greg Claytonca512b32011-01-14 04:54:56 +00002848 }
2849 break;
2850
2851 default:
2852 break;
2853 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002854 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002855
Greg Clayton6beaaa62011-01-17 03:46:26 +00002856 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002857 if (die_offset != DW_INVALID_OFFSET)
2858 {
2859 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2860 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2861 if (decl_ctx != m_clang_tu_decl)
2862 return decl_ctx;
2863 }
2864
Greg Clayton6beaaa62011-01-17 03:46:26 +00002865 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002866 if (die_offset != DW_INVALID_OFFSET)
2867 {
2868 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2869 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2870 if (decl_ctx != m_clang_tu_decl)
2871 return decl_ctx;
2872 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002873
2874 die = die->GetParent();
2875 }
Greg Clayton7a345282010-11-09 23:46:37 +00002876 // Right now we have only one translation unit per module...
Greg Claytonca512b32011-01-14 04:54:56 +00002877 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Clayton7a345282010-11-09 23:46:37 +00002878 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002879}
2880
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002881// This function can be used when a DIE is found that is a forward declaration
2882// DIE and we want to try and find a type that has the complete definition.
2883TypeSP
2884SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton1a65ae12011-01-25 23:55:37 +00002885 DWARFCompileUnit* cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002886 const DWARFDebugInfoEntry *die,
2887 const ConstString &type_name
2888)
2889{
2890 TypeSP type_sp;
2891
Greg Clayton1a65ae12011-01-25 23:55:37 +00002892 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002893 return type_sp;
2894
Greg Clayton69974892010-12-03 21:42:06 +00002895 if (!m_indexed)
2896 Index ();
2897
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002898 const dw_tag_t type_tag = die->Tag();
2899 std::vector<NameToDIE::Info> die_info_array;
2900 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2901 if (num_matches > 0)
2902 {
2903 DWARFCompileUnit* type_cu = NULL;
Greg Clayton1a65ae12011-01-25 23:55:37 +00002904 DWARFCompileUnit* curr_cu = cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002905 DWARFDebugInfo *info = DebugInfo();
2906 for (size_t i=0; i<num_matches; ++i)
2907 {
2908 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2909
2910 if (type_cu != curr_cu)
2911 {
2912 type_cu->ExtractDIEsIfNeeded (false);
2913 curr_cu = type_cu;
2914 }
2915
2916 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2917
2918 if (type_die != die && type_die->Tag() == type_tag)
2919 {
2920 // Hold off on comparing parent DIE tags until
2921 // we know what happens with stuff in namespaces
2922 // for gcc and clang...
2923 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2924 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2925 //if (parent_die->Tag() == parent_type_die->Tag())
2926 {
2927 Type *resolved_type = ResolveType (type_cu, type_die, false);
2928 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2929 {
2930 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2931 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002932 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002933 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2934 type_die->GetOffset(),
2935 type_cu->GetOffset());
2936
2937 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002938 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002939 if (!type_sp)
2940 {
2941 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2942 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002943 break;
2944 }
2945 }
2946 }
2947 }
2948 }
2949 return type_sp;
2950}
2951
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002952TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002953SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002954{
2955 TypeSP type_sp;
2956
Greg Clayton1be10fc2010-09-29 01:12:09 +00002957 if (type_is_new_ptr)
2958 *type_is_new_ptr = false;
2959
Sean Callananc7fbf732010-08-06 00:32:49 +00002960 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002961 if (die != NULL)
2962 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002963 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002964 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002965 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002966 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002967 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002968 if (type_is_new_ptr)
2969 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002970
Greg Clayton594e5ed2010-09-27 21:07:38 +00002971 const dw_tag_t tag = die->Tag();
2972
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002973 bool is_forward_declaration = false;
2974 DWARFDebugInfoEntry::Attributes attributes;
2975 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002976 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00002977 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
2978 size_t byte_size = 0;
2979 Declaration decl;
2980
Greg Clayton4957bf62010-09-30 21:49:03 +00002981 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002982 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002983
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002984 dw_attr_t attr;
2985
2986 switch (tag)
2987 {
2988 case DW_TAG_base_type:
2989 case DW_TAG_pointer_type:
2990 case DW_TAG_reference_type:
2991 case DW_TAG_typedef:
2992 case DW_TAG_const_type:
2993 case DW_TAG_restrict_type:
2994 case DW_TAG_volatile_type:
2995 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002996 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002997 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002998
Greg Claytond88d7592010-09-15 08:33:30 +00002999 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003000 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3002
3003 if (num_attributes > 0)
3004 {
3005 uint32_t i;
3006 for (i=0; i<num_attributes; ++i)
3007 {
3008 attr = attributes.AttributeAtIndex(i);
3009 DWARFFormValue form_value;
3010 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3011 {
3012 switch (attr)
3013 {
3014 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3015 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3016 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3017 case DW_AT_name:
3018 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003019 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003020 break;
3021 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3022 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3023 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3024 default:
3025 case DW_AT_sibling:
3026 break;
3027 }
3028 }
3029 }
3030 }
3031
Greg Claytonc93237c2010-10-01 20:48:32 +00003032 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);
3033
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003034 switch (tag)
3035 {
3036 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003037 break;
3038
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003039 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003040 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003041 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3042 encoding,
3043 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003044 break;
3045
Greg Clayton526e5af2010-11-13 03:52:47 +00003046 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3047 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3048 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3049 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3050 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3051 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052 }
3053
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003054 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3055 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3056 {
3057 static ConstString g_objc_type_name_id("id");
3058 static ConstString g_objc_type_name_Class("Class");
3059 static ConstString g_objc_type_name_selector("SEL");
3060
Greg Clayton24739922010-10-13 03:15:28 +00003061 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003062 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003063 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003064 resolve_state = Type::eResolveStateFull;
3065
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003066 }
Greg Clayton24739922010-10-13 03:15:28 +00003067 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003068 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003069 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003070 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003071 }
Greg Clayton24739922010-10-13 03:15:28 +00003072 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003073 {
Sean Callananf6c73082010-12-06 23:53:20 +00003074 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003075 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003076 }
3077 }
3078
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003079 type_sp.reset( new Type (die->GetOffset(),
3080 this,
3081 type_name_const_str,
3082 byte_size,
3083 NULL,
3084 encoding_uid,
3085 encoding_data_type,
3086 &decl,
3087 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003088 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003089
Greg Clayton594e5ed2010-09-27 21:07:38 +00003090 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003091
3092// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3093// if (encoding_type != NULL)
3094// {
3095// if (encoding_type != DIE_IS_BEING_PARSED)
3096// type_sp->SetEncodingType(encoding_type);
3097// else
3098// m_indirect_fixups.push_back(type_sp.get());
3099// }
3100 }
3101 break;
3102
3103 case DW_TAG_structure_type:
3104 case DW_TAG_union_type:
3105 case DW_TAG_class_type:
3106 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003107 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003108 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003109
Greg Clayton9e409562010-07-28 02:04:09 +00003110 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003111 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003112 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003113 if (num_attributes > 0)
3114 {
3115 uint32_t i;
3116 for (i=0; i<num_attributes; ++i)
3117 {
3118 attr = attributes.AttributeAtIndex(i);
3119 DWARFFormValue form_value;
3120 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3121 {
3122 switch (attr)
3123 {
Greg Clayton9e409562010-07-28 02:04:09 +00003124 case DW_AT_decl_file:
3125 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3126 break;
3127
3128 case DW_AT_decl_line:
3129 decl.SetLine(form_value.Unsigned());
3130 break;
3131
3132 case DW_AT_decl_column:
3133 decl.SetColumn(form_value.Unsigned());
3134 break;
3135
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003136 case DW_AT_name:
3137 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003138 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003139 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003140
3141 case DW_AT_byte_size:
3142 byte_size = form_value.Unsigned();
3143 break;
3144
3145 case DW_AT_accessibility:
3146 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3147 break;
3148
3149 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003150 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003151 break;
3152
3153 case DW_AT_APPLE_runtime_class:
3154 class_language = (LanguageType)form_value.Signed();
3155 break;
3156
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003157 case DW_AT_allocated:
3158 case DW_AT_associated:
3159 case DW_AT_data_location:
3160 case DW_AT_description:
3161 case DW_AT_start_scope:
3162 case DW_AT_visibility:
3163 default:
3164 case DW_AT_sibling:
3165 break;
3166 }
3167 }
3168 }
3169 }
3170
Greg Claytonc93237c2010-10-01 20:48:32 +00003171 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3172
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003173 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00003174 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003175 if (tag == DW_TAG_structure_type)
3176 {
3177 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00003178 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003179 }
3180 else if (tag == DW_TAG_union_type)
3181 {
3182 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00003183 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003184 }
3185 else if (tag == DW_TAG_class_type)
3186 {
3187 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00003188 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003189 }
3190
Greg Clayton24739922010-10-13 03:15:28 +00003191
Greg Clayton4cd17802011-01-25 06:17:32 +00003192 if (is_forward_declaration)
Greg Claytonc615ce42010-11-09 04:42:43 +00003193 {
3194 // We have a forward declaration to a type and we need
3195 // to try and find a full declaration. We look in the
3196 // current type index just in case we have a forward
3197 // declaration followed by an actual declarations in the
3198 // DWARF. If this fails, we need to look elsewhere...
3199
3200 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3201
Greg Clayton4cd17802011-01-25 06:17:32 +00003202 if (!type_sp && m_debug_map_symfile)
Greg Claytonc615ce42010-11-09 04:42:43 +00003203 {
3204 // We weren't able to find a full declaration in
3205 // this DWARF, see if we have a declaration anywhere
3206 // else...
Greg Clayton4cd17802011-01-25 06:17:32 +00003207 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Claytonc615ce42010-11-09 04:42:43 +00003208 }
Greg Clayton4cd17802011-01-25 06:17:32 +00003209
Greg Claytonc615ce42010-11-09 04:42:43 +00003210 if (type_sp)
Greg Claytonfacfd062010-11-20 19:16:50 +00003211 {
3212 // We found a real definition for this type elsewhere
3213 // so lets use it and cache the fact that we found
3214 // a complete type for this die
3215 m_die_to_type[die] = type_sp.get();
Greg Claytonc615ce42010-11-09 04:42:43 +00003216 return type_sp;
Greg Claytonfacfd062010-11-20 19:16:50 +00003217 }
Greg Claytonc615ce42010-11-09 04:42:43 +00003218 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003219 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003220 bool clang_type_was_created = false;
3221 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3222 if (clang_type == NULL)
3223 {
3224 clang_type_was_created = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003225 clang_type = ast.CreateRecordType (type_name_cstr,
3226 tag_decl_kind,
3227 GetClangDeclContextForDIE (dwarf_cu, die),
3228 class_language);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003229 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230
Greg Clayton6adffa22010-09-28 01:04:25 +00003231 // Store a forward declaration to this class type in case any
3232 // parameters in any class methods need it for the clang
3233 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003234 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003235 type_sp.reset (new Type (die->GetOffset(),
3236 this,
3237 type_name_const_str,
3238 byte_size,
3239 NULL,
3240 LLDB_INVALID_UID,
3241 Type::eEncodingIsUID,
3242 &decl,
3243 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003244 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003245
Greg Clayton594e5ed2010-09-27 21:07:38 +00003246 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003247
Greg Clayton40328bf2010-11-08 02:05:08 +00003248 if (die->HasChildren() == false && is_forward_declaration == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00003249 {
Greg Clayton4957bf62010-09-30 21:49:03 +00003250 // No children for this struct/union/class, lets finish it
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003251 ast.StartTagDeclarationDefinition (clang_type);
3252 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00003253 }
3254 else if (clang_type_was_created)
3255 {
3256 // Leave this as a forward declaration until we need
3257 // to know the details of the type. lldb_private::Type
3258 // will automatically call the SymbolFile virtual function
3259 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3260 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00003261 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003262 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003263 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003264 }
Greg Clayton4957bf62010-09-30 21:49:03 +00003265
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003266 }
3267 break;
3268
3269 case DW_TAG_enumeration_type:
3270 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003271 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003272 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003273
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003274 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003275
Greg Claytond88d7592010-09-15 08:33:30 +00003276 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003277 if (num_attributes > 0)
3278 {
3279 uint32_t i;
3280
3281 for (i=0; i<num_attributes; ++i)
3282 {
3283 attr = attributes.AttributeAtIndex(i);
3284 DWARFFormValue form_value;
3285 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3286 {
3287 switch (attr)
3288 {
Greg Clayton7a345282010-11-09 23:46:37 +00003289 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3290 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3291 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003292 case DW_AT_name:
3293 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003294 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003295 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003296 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3297 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3298 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3299 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003300 case DW_AT_allocated:
3301 case DW_AT_associated:
3302 case DW_AT_bit_stride:
3303 case DW_AT_byte_stride:
3304 case DW_AT_data_location:
3305 case DW_AT_description:
3306 case DW_AT_start_scope:
3307 case DW_AT_visibility:
3308 case DW_AT_specification:
3309 case DW_AT_abstract_origin:
3310 case DW_AT_sibling:
3311 break;
3312 }
3313 }
3314 }
3315
Greg Claytonc93237c2010-10-01 20:48:32 +00003316 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3317
Greg Clayton1be10fc2010-09-29 01:12:09 +00003318 clang_type_t enumerator_clang_type = NULL;
3319 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3320 if (clang_type == NULL)
3321 {
Greg Clayton4cd17802011-01-25 06:17:32 +00003322 if (die->GetOffset() == 0x1c436)
3323 printf("REMOVE THIS!!!\n");
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003324 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3325 DW_ATE_signed,
3326 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003327 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Clayton6beaaa62011-01-17 03:46:26 +00003328 GetClangDeclContextForDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003329 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003330 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003331 }
3332 else
3333 {
3334 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3335 assert (enumerator_clang_type != NULL);
3336 }
3337
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003338 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003339 type_sp.reset( new Type (die->GetOffset(),
3340 this,
3341 type_name_const_str,
3342 byte_size,
3343 NULL,
3344 encoding_uid,
3345 Type::eEncodingIsUID,
3346 &decl,
3347 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003348 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003349
Greg Clayton594e5ed2010-09-27 21:07:38 +00003350 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003351
Greg Clayton6beaaa62011-01-17 03:46:26 +00003352#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003353 // Leave this as a forward declaration until we need
3354 // to know the details of the type. lldb_private::Type
3355 // will automatically call the SymbolFile virtual function
3356 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3357 // When the definition needs to be defined.
3358 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003359 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003360 ClangASTContext::SetHasExternalStorage (clang_type, true);
3361#else
3362 ast.StartTagDeclarationDefinition (clang_type);
3363 if (die->HasChildren())
3364 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003365 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3366 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003367 }
3368 ast.CompleteTagDeclarationDefinition (clang_type);
3369#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003370 }
3371 }
3372 break;
3373
Jim Inghamb0be4422010-08-12 01:20:14 +00003374 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003375 case DW_TAG_subprogram:
3376 case DW_TAG_subroutine_type:
3377 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003378 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003379 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003380
3381 const char *mangled = NULL;
3382 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003383 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003384 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003385 bool is_static = false;
3386 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003387 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003388
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003389 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003390 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003391
3392
Greg Claytond88d7592010-09-15 08:33:30 +00003393 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003394 if (num_attributes > 0)
3395 {
3396 uint32_t i;
3397 for (i=0; i<num_attributes; ++i)
3398 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003399 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003400 DWARFFormValue form_value;
3401 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3402 {
3403 switch (attr)
3404 {
3405 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3406 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3407 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3408 case DW_AT_name:
3409 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003410 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003411 break;
3412
3413 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3414 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003415 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003416 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003417 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3418 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003419 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3420
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421 case DW_AT_external:
3422 if (form_value.Unsigned())
3423 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003424 if (storage == clang::SC_None)
3425 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003426 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003427 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003428 }
3429 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003430
3431 case DW_AT_allocated:
3432 case DW_AT_associated:
3433 case DW_AT_address_class:
3434 case DW_AT_artificial:
3435 case DW_AT_calling_convention:
3436 case DW_AT_data_location:
3437 case DW_AT_elemental:
3438 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003439 case DW_AT_frame_base:
3440 case DW_AT_high_pc:
3441 case DW_AT_low_pc:
3442 case DW_AT_object_pointer:
3443 case DW_AT_prototyped:
3444 case DW_AT_pure:
3445 case DW_AT_ranges:
3446 case DW_AT_recursive:
3447 case DW_AT_return_addr:
3448 case DW_AT_segment:
3449 case DW_AT_specification:
3450 case DW_AT_start_scope:
3451 case DW_AT_static_link:
3452 case DW_AT_trampoline:
3453 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003454 case DW_AT_vtable_elem_location:
3455 case DW_AT_abstract_origin:
3456 case DW_AT_description:
3457 case DW_AT_sibling:
3458 break;
3459 }
3460 }
3461 }
Greg Clayton24739922010-10-13 03:15:28 +00003462 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003463
Greg Clayton24739922010-10-13 03:15:28 +00003464 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 +00003465
Greg Clayton24739922010-10-13 03:15:28 +00003466 clang_type_t return_clang_type = NULL;
3467 Type *func_type = NULL;
3468
3469 if (type_die_offset != DW_INVALID_OFFSET)
3470 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003471
Greg Clayton24739922010-10-13 03:15:28 +00003472 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003473 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003474 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003475 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003476
Greg Claytonf51de672010-10-01 02:31:07 +00003477
Greg Clayton24739922010-10-13 03:15:28 +00003478 std::vector<clang_type_t> function_param_types;
3479 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003480
Greg Clayton24739922010-10-13 03:15:28 +00003481 // Parse the function children for the parameters
3482 if (die->HasChildren())
3483 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003484 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003485 ParseChildParameters (sc,
3486 type_sp,
3487 dwarf_cu,
3488 die,
3489 skip_artificial,
3490 type_list,
3491 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003492 function_param_decls,
3493 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003494 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003495
Greg Clayton24739922010-10-13 03:15:28 +00003496 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003497 clang_type = ast.CreateFunctionType (return_clang_type,
3498 &function_param_types[0],
3499 function_param_types.size(),
3500 is_variadic,
3501 type_quals);
3502
Greg Clayton24739922010-10-13 03:15:28 +00003503 if (type_name_cstr)
3504 {
3505 bool type_handled = false;
3506 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3507 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003508 {
Greg Clayton24739922010-10-13 03:15:28 +00003509 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003510 {
Greg Clayton24739922010-10-13 03:15:28 +00003511 // We need to find the DW_TAG_class_type or
3512 // DW_TAG_struct_type by name so we can add this
3513 // as a member function of the class.
3514 const char *class_name_start = type_name_cstr + 2;
3515 const char *class_name_end = ::strchr (class_name_start, ' ');
3516 SymbolContext empty_sc;
3517 clang_type_t class_opaque_type = NULL;
3518 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003519 {
Greg Clayton24739922010-10-13 03:15:28 +00003520 ConstString class_name (class_name_start, class_name_end - class_name_start);
3521 TypeList types;
3522 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3523 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003524 {
Greg Clayton24739922010-10-13 03:15:28 +00003525 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003526 {
Greg Clayton24739922010-10-13 03:15:28 +00003527 Type *type = types.GetTypeAtIndex (i).get();
3528 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3529 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003530 {
Greg Clayton24739922010-10-13 03:15:28 +00003531 class_opaque_type = type_clang_forward_type;
3532 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003533 }
3534 }
3535 }
Greg Clayton24739922010-10-13 03:15:28 +00003536 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003537
Greg Clayton24739922010-10-13 03:15:28 +00003538 if (class_opaque_type)
3539 {
3540 // If accessibility isn't set to anything valid, assume public for
3541 // now...
3542 if (accessibility == eAccessNone)
3543 accessibility = eAccessPublic;
3544
3545 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003546 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3547 type_name_cstr,
3548 clang_type,
3549 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003550 type_handled = objc_method_decl != NULL;
3551 }
3552 }
3553 else if (parent_die->Tag() == DW_TAG_class_type ||
3554 parent_die->Tag() == DW_TAG_structure_type)
3555 {
3556 // Look at the parent of this DIE and see if is is
3557 // a class or struct and see if this is actually a
3558 // C++ method
3559 Type *class_type = ResolveType (dwarf_cu, parent_die);
3560 if (class_type)
3561 {
3562 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3563 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003564 {
Greg Clayton24739922010-10-13 03:15:28 +00003565 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3566 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003567 if (accessibility == eAccessNone)
3568 accessibility = eAccessPublic;
Greg Clayton931180e2011-01-27 06:44:37 +00003569
3570 if (!is_static && !die->HasChildren())
3571 {
3572 // We have a C++ member function with no children (this pointer!)
3573 // and clang will get mad if we try and make a function that isn't
3574 // well formed in the DWARF, so we will just skip it...
3575 type_handled = true;
3576 }
3577 else
3578 {
3579 clang::CXXMethodDecl *cxx_method_decl;
3580 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3581 type_name_cstr,
3582 clang_type,
3583 accessibility,
3584 is_virtual,
3585 is_static,
3586 is_inline,
3587 is_explicit);
3588 type_handled = cxx_method_decl != NULL;
3589 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003590 }
3591 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003592 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593 }
Greg Clayton24739922010-10-13 03:15:28 +00003594
3595 if (!type_handled)
3596 {
3597 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003598 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3599 clang_type,
3600 storage,
3601 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003602
3603 // Add the decl to our DIE to decl context map
3604 assert (function_decl);
3605 m_die_to_decl_ctx[die] = function_decl;
3606 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003607 ast.SetFunctionParameters (function_decl,
3608 &function_param_decls.front(),
3609 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003610 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003611 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003612 type_sp.reset( new Type (die->GetOffset(),
3613 this,
3614 type_name_const_str,
3615 0,
3616 NULL,
3617 LLDB_INVALID_UID,
3618 Type::eEncodingIsUID,
3619 &decl,
3620 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003621 Type::eResolveStateFull));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003622
Greg Clayton24739922010-10-13 03:15:28 +00003623 m_die_to_type[die] = type_sp.get();
3624 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003625 }
3626 break;
3627
3628 case DW_TAG_array_type:
3629 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003630 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003631 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003632
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003633 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003634 int64_t first_index = 0;
3635 uint32_t byte_stride = 0;
3636 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003637 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003638
3639 if (num_attributes > 0)
3640 {
3641 uint32_t i;
3642 for (i=0; i<num_attributes; ++i)
3643 {
3644 attr = attributes.AttributeAtIndex(i);
3645 DWARFFormValue form_value;
3646 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3647 {
3648 switch (attr)
3649 {
3650 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3651 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3652 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3653 case DW_AT_name:
3654 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003655 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003656 break;
3657
3658 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3659 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3660 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3661 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003662 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003663 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003664 case DW_AT_allocated:
3665 case DW_AT_associated:
3666 case DW_AT_data_location:
3667 case DW_AT_description:
3668 case DW_AT_ordering:
3669 case DW_AT_start_scope:
3670 case DW_AT_visibility:
3671 case DW_AT_specification:
3672 case DW_AT_abstract_origin:
3673 case DW_AT_sibling:
3674 break;
3675 }
3676 }
3677 }
3678
Greg Claytonc93237c2010-10-01 20:48:32 +00003679 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3680
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003681 Type *element_type = ResolveTypeUID(type_die_offset);
3682
3683 if (element_type)
3684 {
3685 std::vector<uint64_t> element_orders;
3686 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003687 // We have an array that claims to have no members, lets give it at least one member...
3688 if (element_orders.empty())
3689 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003690 if (byte_stride == 0 && bit_stride == 0)
3691 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003692 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003693 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3694 uint64_t num_elements = 0;
3695 std::vector<uint64_t>::const_reverse_iterator pos;
3696 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3697 for (pos = element_orders.rbegin(); pos != end; ++pos)
3698 {
3699 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003700 clang_type = ast.CreateArrayType (array_element_type,
3701 num_elements,
3702 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003703 array_element_type = clang_type;
3704 array_element_bit_stride = array_element_bit_stride * num_elements;
3705 }
3706 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003707 type_sp.reset( new Type (die->GetOffset(),
3708 this,
3709 empty_name,
3710 array_element_bit_stride / 8,
3711 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003712 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003713 Type::eEncodingIsUID,
3714 &decl,
3715 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003716 Type::eResolveStateFull));
3717 type_sp->SetEncodingType (element_type);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003718 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003719 }
3720 }
3721 }
3722 break;
3723
Greg Clayton9b81a312010-06-12 01:20:30 +00003724 case DW_TAG_ptr_to_member_type:
3725 {
3726 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3727 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3728
Greg Claytond88d7592010-09-15 08:33:30 +00003729 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003730
3731 if (num_attributes > 0) {
3732 uint32_t i;
3733 for (i=0; i<num_attributes; ++i)
3734 {
3735 attr = attributes.AttributeAtIndex(i);
3736 DWARFFormValue form_value;
3737 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3738 {
3739 switch (attr)
3740 {
3741 case DW_AT_type:
3742 type_die_offset = form_value.Reference(dwarf_cu); break;
3743 case DW_AT_containing_type:
3744 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3745 }
3746 }
3747 }
3748
3749 Type *pointee_type = ResolveTypeUID(type_die_offset);
3750 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3751
Greg Clayton526e5af2010-11-13 03:52:47 +00003752 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3753 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003754
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003755 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3756 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003757
Greg Clayton526e5af2010-11-13 03:52:47 +00003758 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3759 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003760
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003761 type_sp.reset( new Type (die->GetOffset(),
3762 this,
3763 type_name_const_str,
3764 byte_size,
3765 NULL,
3766 LLDB_INVALID_UID,
3767 Type::eEncodingIsUID,
3768 NULL,
3769 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003770 Type::eResolveStateForward));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003771 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003772 }
3773
3774 break;
3775 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003776 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003777 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003778 break;
3779 }
3780
3781 if (type_sp.get())
3782 {
3783 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3784 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3785
3786 SymbolContextScope * symbol_context_scope = NULL;
3787 if (sc_parent_tag == DW_TAG_compile_unit)
3788 {
3789 symbol_context_scope = sc.comp_unit;
3790 }
3791 else if (sc.function != NULL)
3792 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003793 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003794 if (symbol_context_scope == NULL)
3795 symbol_context_scope = sc.function;
3796 }
3797
3798 if (symbol_context_scope != NULL)
3799 {
3800 type_sp->SetSymbolContextScope(symbol_context_scope);
3801 }
3802
3803// if (udt_sp.get())
3804// {
3805// if (is_forward_declaration)
3806// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3807// type_sp->SetUserDefinedType(udt_sp);
3808// }
3809
3810 if (type_sp.unique())
3811 {
3812 // We are ready to put this type into the uniqued list up at the module level
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003813 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003814
Greg Clayton594e5ed2010-09-27 21:07:38 +00003815 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003816 }
3817 }
3818 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003819 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003820 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003821 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822 }
3823 }
3824 return type_sp;
3825}
3826
3827size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003828SymbolFileDWARF::ParseTypes
3829(
3830 const SymbolContext& sc,
3831 DWARFCompileUnit* dwarf_cu,
3832 const DWARFDebugInfoEntry *die,
3833 bool parse_siblings,
3834 bool parse_children
3835)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003836{
3837 size_t types_added = 0;
3838 while (die != NULL)
3839 {
3840 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003841 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003842 {
3843 if (type_is_new)
3844 ++types_added;
3845 }
3846
3847 if (parse_children && die->HasChildren())
3848 {
3849 if (die->Tag() == DW_TAG_subprogram)
3850 {
3851 SymbolContext child_sc(sc);
3852 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3853 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3854 }
3855 else
3856 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3857 }
3858
3859 if (parse_siblings)
3860 die = die->GetSibling();
3861 else
3862 die = NULL;
3863 }
3864 return types_added;
3865}
3866
3867
3868size_t
3869SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3870{
3871 assert(sc.comp_unit && sc.function);
3872 size_t functions_added = 0;
3873 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3874 if (dwarf_cu)
3875 {
3876 dw_offset_t function_die_offset = sc.function->GetID();
3877 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3878 if (function_die)
3879 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003880 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003881 }
3882 }
3883
3884 return functions_added;
3885}
3886
3887
3888size_t
3889SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3890{
3891 // At least a compile unit must be valid
3892 assert(sc.comp_unit);
3893 size_t types_added = 0;
3894 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3895 if (dwarf_cu)
3896 {
3897 if (sc.function)
3898 {
3899 dw_offset_t function_die_offset = sc.function->GetID();
3900 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3901 if (func_die && func_die->HasChildren())
3902 {
3903 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3904 }
3905 }
3906 else
3907 {
3908 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3909 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3910 {
3911 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3912 }
3913 }
3914 }
3915
3916 return types_added;
3917}
3918
3919size_t
3920SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3921{
3922 if (sc.comp_unit != NULL)
3923 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003924 DWARFDebugInfo* info = DebugInfo();
3925 if (info == NULL)
3926 return 0;
3927
3928 uint32_t cu_idx = UINT32_MAX;
3929 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003930
3931 if (dwarf_cu == NULL)
3932 return 0;
3933
3934 if (sc.function)
3935 {
3936 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003937
3938 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3939 assert (func_lo_pc != DW_INVALID_ADDRESS);
3940
3941 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003942 }
3943 else if (sc.comp_unit)
3944 {
3945 uint32_t vars_added = 0;
3946 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3947
3948 if (variables.get() == NULL)
3949 {
3950 variables.reset(new VariableList());
3951 sc.comp_unit->SetVariableList(variables);
3952
3953 // Index if we already haven't to make sure the compile units
3954 // get indexed and make their global DIE index list
3955 if (!m_indexed)
3956 Index ();
3957
Greg Claytonc685f8e2010-09-15 04:15:46 +00003958 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003959 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 for (size_t idx=0; idx<num_globals; ++idx)
3961 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003962 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 +00003963 if (var_sp)
3964 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00003965 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003966 ++vars_added;
3967 }
3968 }
3969 }
3970 return vars_added;
3971 }
3972 }
3973 return 0;
3974}
3975
3976
3977VariableSP
3978SymbolFileDWARF::ParseVariableDIE
3979(
3980 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003981 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003982 const DWARFDebugInfoEntry *die,
3983 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003984)
3985{
3986
Greg Clayton83c5cd92010-11-14 22:13:40 +00003987 VariableSP var_sp (m_die_to_variable_sp[die]);
3988 if (var_sp)
3989 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003990
3991 const dw_tag_t tag = die->Tag();
3992 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003993 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003994 if (num_attributes > 0)
3995 {
3996 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003997 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003998 Declaration decl;
3999 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004000 Type *var_type = NULL;
4001 DWARFExpression location;
4002 bool is_external = false;
4003 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00004004 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004005
4006 for (i=0; i<num_attributes; ++i)
4007 {
4008 dw_attr_t attr = attributes.AttributeAtIndex(i);
4009 DWARFFormValue form_value;
4010 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4011 {
4012 switch (attr)
4013 {
4014 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4015 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4016 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4017 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00004018 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00004019 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004020 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
4021 case DW_AT_location:
4022 {
4023 if (form_value.BlockData())
4024 {
4025 const DataExtractor& debug_info_data = get_debug_info_data();
4026
4027 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4028 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00004029 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004030 }
4031 else
4032 {
4033 const DataExtractor& debug_loc_data = get_debug_loc_data();
4034 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4035
4036 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4037 if (loc_list_length > 0)
4038 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004039 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4040 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4041 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004042 }
4043 }
4044 }
4045 break;
4046
4047 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004048 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004049 case DW_AT_const_value:
4050 case DW_AT_declaration:
4051 case DW_AT_description:
4052 case DW_AT_endianity:
4053 case DW_AT_segment:
4054 case DW_AT_start_scope:
4055 case DW_AT_visibility:
4056 default:
4057 case DW_AT_abstract_origin:
4058 case DW_AT_sibling:
4059 case DW_AT_specification:
4060 break;
4061 }
4062 }
4063 }
4064
4065 if (location.IsValid())
4066 {
4067 assert(var_type != DIE_IS_BEING_PARSED);
4068
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004069 ValueType scope = eValueTypeInvalid;
4070
4071 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4072 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4073
4074 if (tag == DW_TAG_formal_parameter)
4075 scope = eValueTypeVariableArgument;
4076 else if (is_external || parent_tag == DW_TAG_compile_unit)
4077 scope = eValueTypeVariableGlobal;
4078 else
4079 scope = eValueTypeVariableLocal;
4080
4081 SymbolContextScope * symbol_context_scope = NULL;
4082 if (parent_tag == DW_TAG_compile_unit)
4083 {
4084 symbol_context_scope = sc.comp_unit;
4085 }
4086 else if (sc.function != NULL)
4087 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004088 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004089 if (symbol_context_scope == NULL)
4090 symbol_context_scope = sc.function;
4091 }
4092
4093 assert(symbol_context_scope != NULL);
4094 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00004095 name,
4096 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004097 var_type,
4098 scope,
4099 symbol_context_scope,
4100 &decl,
4101 location,
4102 is_external,
4103 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00004104
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004105 }
4106 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00004107 // Cache var_sp even if NULL (the variable was just a specification or
4108 // was missing vital information to be able to be displayed in the debugger
4109 // (missing location due to optimization, etc)) so we don't re-parse
4110 // this DIE over and over later...
4111 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004112 return var_sp;
4113}
4114
4115size_t
4116SymbolFileDWARF::ParseVariables
4117(
4118 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004119 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004120 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004121 const DWARFDebugInfoEntry *orig_die,
4122 bool parse_siblings,
4123 bool parse_children,
4124 VariableList* cc_variable_list
4125)
4126{
4127 if (orig_die == NULL)
4128 return 0;
4129
4130 size_t vars_added = 0;
4131 const DWARFDebugInfoEntry *die = orig_die;
4132 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4133 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4134 VariableListSP variables;
4135 switch (parent_tag)
4136 {
4137 case DW_TAG_compile_unit:
4138 if (sc.comp_unit != NULL)
4139 {
4140 variables = sc.comp_unit->GetVariableList(false);
4141 if (variables.get() == NULL)
4142 {
4143 variables.reset(new VariableList());
4144 sc.comp_unit->SetVariableList(variables);
4145 }
4146 }
4147 else
4148 {
4149 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
4150 vars_added = 0;
4151 }
4152 break;
4153
4154 case DW_TAG_subprogram:
4155 case DW_TAG_inlined_subroutine:
4156 case DW_TAG_lexical_block:
4157 if (sc.function != NULL)
4158 {
4159 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004160
4161 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4162 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00004163 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004164 if (variables.get() == NULL)
4165 {
4166 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004167 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004168 }
4169 }
4170 else
4171 {
4172 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
4173 vars_added = 0;
4174 }
4175 break;
4176
4177 default:
4178 assert(!"Didn't find appropriate parent DIE for variable list...");
4179 break;
4180 }
4181
4182 // We need to have a variable list at this point that we can add variables to
4183 assert(variables.get());
4184
4185 while (die != NULL)
4186 {
4187 dw_tag_t tag = die->Tag();
4188
4189 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00004190 if (m_die_to_variable_sp[die])
4191 {
4192 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004193 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Greg Claytonbcf12172010-10-28 00:56:11 +00004194 }
4195 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004196 {
4197 // We haven't already parsed it, lets do that now.
4198 if ((tag == DW_TAG_variable) ||
4199 (tag == DW_TAG_constant) ||
4200 (tag == DW_TAG_formal_parameter && sc.function))
4201 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004202 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004203 if (var_sp)
4204 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004205 variables->AddVariableIfUnique (var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00004206 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004207 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004208 ++vars_added;
4209 }
4210 }
4211 }
4212
4213 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4214
4215 if (!skip_children && parse_children && die->HasChildren())
4216 {
Greg Claytonbcf12172010-10-28 00:56:11 +00004217 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218 }
4219
4220 if (parse_siblings)
4221 die = die->GetSibling();
4222 else
4223 die = NULL;
4224 }
4225
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004226 return vars_added;
4227}
4228
4229//------------------------------------------------------------------
4230// PluginInterface protocol
4231//------------------------------------------------------------------
4232const char *
4233SymbolFileDWARF::GetPluginName()
4234{
4235 return "SymbolFileDWARF";
4236}
4237
4238const char *
4239SymbolFileDWARF::GetShortPluginName()
4240{
4241 return GetPluginNameStatic();
4242}
4243
4244uint32_t
4245SymbolFileDWARF::GetPluginVersion()
4246{
4247 return 1;
4248}
4249
4250void
4251SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
4252{
4253}
4254
4255Error
4256SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
4257{
4258 Error error;
4259 error.SetErrorString("No plug-in command are currently supported.");
4260 return error;
4261}
4262
4263Log *
4264SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
4265{
4266 return NULL;
4267}
4268
Greg Clayton6beaaa62011-01-17 03:46:26 +00004269void
4270SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4271{
4272 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4273 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4274 if (clang_type)
4275 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4276}
4277
4278void
4279SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4280{
4281 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4282 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4283 if (clang_type)
4284 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4285}
4286