blob: 43ccbbdfe04b5204c466d90e515dce577b6f253f [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
Sean Callanancc427fa2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000033#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
35#include "lldb/Core/Value.h"
36
37#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000038#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Symbol/CompileUnit.h"
40#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolVendor.h"
43#include "lldb/Symbol/VariableList.h"
44
45#include "DWARFCompileUnit.h"
46#include "DWARFDebugAbbrev.h"
47#include "DWARFDebugAranges.h"
48#include "DWARFDebugInfo.h"
49#include "DWARFDebugInfoEntry.h"
50#include "DWARFDebugLine.h"
51#include "DWARFDebugPubnames.h"
52#include "DWARFDebugRanges.h"
53#include "DWARFDIECollection.h"
54#include "DWARFFormValue.h"
55#include "DWARFLocationList.h"
56#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000057#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
59#include <map>
60
Greg Clayton62742b12010-11-11 01:09:45 +000061//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000062
63#ifdef ENABLE_DEBUG_PRINTF
64#include <stdio.h>
65#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
66#else
67#define DEBUG_PRINTF(fmt, ...)
68#endif
69
Greg Clayton594e5ed2010-09-27 21:07:38 +000070#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
72using namespace lldb;
73using namespace lldb_private;
74
75
Sean Callananc7fbf732010-08-06 00:32:49 +000076static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000077DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078{
79 switch (dwarf_accessibility)
80 {
Sean Callananc7fbf732010-08-06 00:32:49 +000081 case DW_ACCESS_public: return eAccessPublic;
82 case DW_ACCESS_private: return eAccessPrivate;
83 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000084 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085 }
Sean Callananc7fbf732010-08-06 00:32:49 +000086 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087}
88
89void
90SymbolFileDWARF::Initialize()
91{
92 LogChannelDWARF::Initialize();
93 PluginManager::RegisterPlugin (GetPluginNameStatic(),
94 GetPluginDescriptionStatic(),
95 CreateInstance);
96}
97
98void
99SymbolFileDWARF::Terminate()
100{
101 PluginManager::UnregisterPlugin (CreateInstance);
102 LogChannelDWARF::Initialize();
103}
104
105
106const char *
107SymbolFileDWARF::GetPluginNameStatic()
108{
109 return "symbol-file.dwarf2";
110}
111
112const char *
113SymbolFileDWARF::GetPluginDescriptionStatic()
114{
115 return "DWARF and DWARF3 debug symbol file reader.";
116}
117
118
119SymbolFile*
120SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
121{
122 return new SymbolFileDWARF(obj_file);
123}
124
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000125TypeList *
126SymbolFileDWARF::GetTypeList ()
127{
128 if (m_debug_map_symfile)
129 return m_debug_map_symfile->GetTypeList();
130 return m_obj_file->GetModule()->GetTypeList();
131
132}
133
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134//----------------------------------------------------------------------
135// Gets the first parent that is a lexical block, function or inlined
136// subroutine, or compile unit.
137//----------------------------------------------------------------------
138static const DWARFDebugInfoEntry *
139GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
140{
141 const DWARFDebugInfoEntry *die;
142 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
143 {
144 dw_tag_t tag = die->Tag();
145
146 switch (tag)
147 {
148 case DW_TAG_compile_unit:
149 case DW_TAG_subprogram:
150 case DW_TAG_inlined_subroutine:
151 case DW_TAG_lexical_block:
152 return die;
153 }
154 }
155 return NULL;
156}
157
158
Greg Clayton450e3f32010-10-12 02:24:53 +0000159SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
160 SymbolFile (objfile),
161 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000162 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 m_flags(),
164 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 m_data_debug_frame(),
166 m_data_debug_info(),
167 m_data_debug_line(),
168 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169 m_data_debug_ranges(),
170 m_data_debug_str(),
Greg Claytonf9eec202011-09-01 23:16:13 +0000171 m_data_debug_names (),
172 m_data_debug_types (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000173 m_abbr(),
174 m_aranges(),
175 m_info(),
176 m_line(),
Greg Clayton9e315582011-09-02 04:03:59 +0000177 m_debug_names (this, m_data_debug_names),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000178 m_function_basename_index(),
179 m_function_fullname_index(),
180 m_function_method_index(),
181 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000182 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000183 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000184 m_type_index(),
185 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000186 m_indexed (false),
187 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000188 m_ranges(),
189 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190{
Greg Clayton9e315582011-09-02 04:03:59 +0000191 get_debug_names_data();
192 m_debug_names.Initialize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193}
194
195SymbolFileDWARF::~SymbolFileDWARF()
196{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000197 if (m_is_external_ast_source)
198 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
199}
200
201static const ConstString &
202GetDWARFMachOSegmentName ()
203{
204 static ConstString g_dwarf_section_name ("__DWARF");
205 return g_dwarf_section_name;
206}
207
Greg Claytone576ab22011-02-15 00:19:15 +0000208UniqueDWARFASTTypeMap &
209SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
210{
211 if (m_debug_map_symfile)
212 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
213 return m_unique_ast_type_map;
214}
215
Greg Clayton6beaaa62011-01-17 03:46:26 +0000216ClangASTContext &
217SymbolFileDWARF::GetClangASTContext ()
218{
219 if (m_debug_map_symfile)
220 return m_debug_map_symfile->GetClangASTContext ();
221
222 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
223 if (!m_is_external_ast_source)
224 {
225 m_is_external_ast_source = true;
226 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
227 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
228 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000229 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000230 this));
231
232 ast.SetExternalSource (ast_source_ap);
233 }
234 return ast;
235}
236
237void
238SymbolFileDWARF::InitializeObject()
239{
240 // Install our external AST source callbacks so we can complete Clang types.
241 Module *module = m_obj_file->GetModule();
242 if (module)
243 {
244 const SectionList *section_list = m_obj_file->GetSectionList();
245
246 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
247
248 // Memory map the DWARF mach-o segment so we have everything mmap'ed
249 // to keep our heap memory usage down.
250 if (section)
251 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
252 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253}
254
255bool
256SymbolFileDWARF::SupportedVersion(uint16_t version)
257{
258 return version == 2 || version == 3;
259}
260
261uint32_t
262SymbolFileDWARF::GetAbilities ()
263{
264 uint32_t abilities = 0;
265 if (m_obj_file != NULL)
266 {
267 const Section* section = NULL;
268 const SectionList *section_list = m_obj_file->GetSectionList();
269 if (section_list == NULL)
270 return 0;
271
272 uint64_t debug_abbrev_file_size = 0;
273 uint64_t debug_aranges_file_size = 0;
274 uint64_t debug_frame_file_size = 0;
275 uint64_t debug_info_file_size = 0;
276 uint64_t debug_line_file_size = 0;
277 uint64_t debug_loc_file_size = 0;
278 uint64_t debug_macinfo_file_size = 0;
279 uint64_t debug_pubnames_file_size = 0;
280 uint64_t debug_pubtypes_file_size = 0;
281 uint64_t debug_ranges_file_size = 0;
282 uint64_t debug_str_file_size = 0;
283
Greg Clayton6beaaa62011-01-17 03:46:26 +0000284 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285
286 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000287 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288
Greg Clayton4ceb9982010-07-21 22:54:26 +0000289 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290 if (section != NULL)
291 {
292 debug_info_file_size = section->GetByteSize();
293
Greg Clayton4ceb9982010-07-21 22:54:26 +0000294 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 if (section)
296 debug_abbrev_file_size = section->GetByteSize();
297 else
298 m_flags.Set (flagsGotDebugAbbrevData);
299
Greg Clayton4ceb9982010-07-21 22:54:26 +0000300 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 if (section)
302 debug_aranges_file_size = section->GetByteSize();
303 else
304 m_flags.Set (flagsGotDebugArangesData);
305
Greg Clayton4ceb9982010-07-21 22:54:26 +0000306 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 if (section)
308 debug_frame_file_size = section->GetByteSize();
309 else
310 m_flags.Set (flagsGotDebugFrameData);
311
Greg Clayton4ceb9982010-07-21 22:54:26 +0000312 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 if (section)
314 debug_line_file_size = section->GetByteSize();
315 else
316 m_flags.Set (flagsGotDebugLineData);
317
Greg Clayton4ceb9982010-07-21 22:54:26 +0000318 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 if (section)
320 debug_loc_file_size = section->GetByteSize();
321 else
322 m_flags.Set (flagsGotDebugLocData);
323
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 if (section)
326 debug_macinfo_file_size = section->GetByteSize();
327 else
328 m_flags.Set (flagsGotDebugMacInfoData);
329
Greg Clayton4ceb9982010-07-21 22:54:26 +0000330 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 if (section)
332 debug_pubnames_file_size = section->GetByteSize();
333 else
334 m_flags.Set (flagsGotDebugPubNamesData);
335
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 if (section)
338 debug_pubtypes_file_size = section->GetByteSize();
339 else
340 m_flags.Set (flagsGotDebugPubTypesData);
341
Greg Clayton4ceb9982010-07-21 22:54:26 +0000342 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 if (section)
344 debug_ranges_file_size = section->GetByteSize();
345 else
346 m_flags.Set (flagsGotDebugRangesData);
347
Greg Clayton4ceb9982010-07-21 22:54:26 +0000348 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 if (section)
350 debug_str_file_size = section->GetByteSize();
351 else
352 m_flags.Set (flagsGotDebugStrData);
353 }
354
355 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
356 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
357
358 if (debug_line_file_size > 0)
359 abilities |= LineTables;
360
361 if (debug_aranges_file_size > 0)
362 abilities |= AddressAcceleratorTable;
363
364 if (debug_pubnames_file_size > 0)
365 abilities |= FunctionAcceleratorTable;
366
367 if (debug_pubtypes_file_size > 0)
368 abilities |= TypeAcceleratorTable;
369
370 if (debug_macinfo_file_size > 0)
371 abilities |= MacroInformation;
372
373 if (debug_frame_file_size > 0)
374 abilities |= CallFrameInformation;
375 }
376 return abilities;
377}
378
379const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000380SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381{
382 if (m_flags.IsClear (got_flag))
383 {
384 m_flags.Set (got_flag);
385 const SectionList *section_list = m_obj_file->GetSectionList();
386 if (section_list)
387 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000388 Section *section = section_list->FindSectionByType(sect_type, true).get();
389 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 {
391 // See if we memory mapped the DWARF segment?
392 if (m_dwarf_data.GetByteSize())
393 {
394 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
395 }
396 else
397 {
398 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
399 data.Clear();
400 }
401 }
402 }
403 }
404 return data;
405}
406
407const DataExtractor&
408SymbolFileDWARF::get_debug_abbrev_data()
409{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000410 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411}
412
413const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414SymbolFileDWARF::get_debug_frame_data()
415{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000416 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
419const DataExtractor&
420SymbolFileDWARF::get_debug_info_data()
421{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000422 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
425const DataExtractor&
426SymbolFileDWARF::get_debug_line_data()
427{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000428 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
431const DataExtractor&
432SymbolFileDWARF::get_debug_loc_data()
433{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000434 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435}
436
437const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438SymbolFileDWARF::get_debug_ranges_data()
439{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000440 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441}
442
443const DataExtractor&
444SymbolFileDWARF::get_debug_str_data()
445{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000446 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447}
448
Greg Claytonf9eec202011-09-01 23:16:13 +0000449const DataExtractor&
450SymbolFileDWARF::get_debug_names_data()
451{
452 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFDebugNames, m_data_debug_names);
453}
454
455const DataExtractor&
456SymbolFileDWARF::get_debug_types_data()
457{
458 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFDebugTypes, m_data_debug_types);
459}
460
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461
462DWARFDebugAbbrev*
463SymbolFileDWARF::DebugAbbrev()
464{
465 if (m_abbr.get() == NULL)
466 {
467 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
468 if (debug_abbrev_data.GetByteSize() > 0)
469 {
470 m_abbr.reset(new DWARFDebugAbbrev());
471 if (m_abbr.get())
472 m_abbr->Parse(debug_abbrev_data);
473 }
474 }
475 return m_abbr.get();
476}
477
478const DWARFDebugAbbrev*
479SymbolFileDWARF::DebugAbbrev() const
480{
481 return m_abbr.get();
482}
483
484DWARFDebugAranges*
485SymbolFileDWARF::DebugAranges()
486{
Greg Clayton016a95e2010-09-14 02:20:48 +0000487 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
488 // and we are already parsing all of the DWARF because the .debug_pubnames
489 // is useless (it only mentions symbols that are externally visible), so
490 // don't use the .debug_aranges section, we should be using a debug aranges
491 // we got from SymbolFileDWARF::Index().
492
493 if (!m_indexed)
494 Index();
495
496
497// if (m_aranges.get() == NULL)
498// {
499// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
500// m_aranges.reset(new DWARFDebugAranges());
501// if (m_aranges.get())
502// {
503// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
504// if (debug_aranges_data.GetByteSize() > 0)
505// m_aranges->Extract(debug_aranges_data);
506// else
507// m_aranges->Generate(this);
508// }
509// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 return m_aranges.get();
511}
512
513const DWARFDebugAranges*
514SymbolFileDWARF::DebugAranges() const
515{
516 return m_aranges.get();
517}
518
519
520DWARFDebugInfo*
521SymbolFileDWARF::DebugInfo()
522{
523 if (m_info.get() == NULL)
524 {
525 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
526 if (get_debug_info_data().GetByteSize() > 0)
527 {
528 m_info.reset(new DWARFDebugInfo());
529 if (m_info.get())
530 {
531 m_info->SetDwarfData(this);
532 }
533 }
534 }
535 return m_info.get();
536}
537
538const DWARFDebugInfo*
539SymbolFileDWARF::DebugInfo() const
540{
541 return m_info.get();
542}
543
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544DWARFCompileUnit*
545SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
546{
547 DWARFDebugInfo* info = DebugInfo();
548 if (info)
549 return info->GetCompileUnit(cu_uid).get();
550 return NULL;
551}
552
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553
554DWARFDebugRanges*
555SymbolFileDWARF::DebugRanges()
556{
557 if (m_ranges.get() == NULL)
558 {
559 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
560 if (get_debug_ranges_data().GetByteSize() > 0)
561 {
562 m_ranges.reset(new DWARFDebugRanges());
563 if (m_ranges.get())
564 m_ranges->Extract(this);
565 }
566 }
567 return m_ranges.get();
568}
569
570const DWARFDebugRanges*
571SymbolFileDWARF::DebugRanges() const
572{
573 return m_ranges.get();
574}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575
576bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000577SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578{
Greg Clayton96d7d742010-11-10 23:42:09 +0000579 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000581 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582 if (cu_die)
583 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000584 const char * cu_die_name = cu_die->GetName(this, curr_cu);
585 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham0f35ac22011-08-24 23:34:20 +0000586 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587 if (cu_die_name)
588 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000589 FileSpec cu_file_spec;
590
Greg Clayton7bd65b92011-02-09 23:39:34 +0000591 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000593 // If we have a full path to the compile unit, we don't need to resolve
594 // the file. This can be expensive e.g. when the source files are NFS mounted.
595 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 }
597 else
598 {
599 std::string fullpath(cu_comp_dir);
600 if (*fullpath.rbegin() != '/')
601 fullpath += '/';
602 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000603 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000604 }
605
Jim Ingham0f35ac22011-08-24 23:34:20 +0000606 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), cu_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 if (compile_unit_sp.get())
608 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000609 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 return true;
611 }
612 }
613 }
614 }
615 return false;
616}
617
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618uint32_t
619SymbolFileDWARF::GetNumCompileUnits()
620{
621 DWARFDebugInfo* info = DebugInfo();
622 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 return 0;
625}
626
627CompUnitSP
628SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
629{
630 CompUnitSP comp_unit;
631 DWARFDebugInfo* info = DebugInfo();
632 if (info)
633 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000634 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
635 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 {
637 // Our symbol vendor shouldn't be asking us to add a compile unit that
638 // has already been added to it, which this DWARF plug-in knows as it
639 // stores the lldb compile unit (CompileUnit) pointer in each
640 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000641 assert(curr_cu->GetUserData() == NULL);
642 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000643 }
644 }
645 return comp_unit;
646}
647
648static void
649AddRangesToBlock
650(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000651 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 DWARFDebugRanges::RangeList& ranges,
653 addr_t block_base_addr
654)
655{
656 ranges.SubtractOffset (block_base_addr);
657 size_t range_idx = 0;
658 const DWARFDebugRanges::Range *debug_range;
659 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
660 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000661 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000662 }
663}
664
665
666Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000667SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000668{
669 DWARFDebugRanges::RangeList func_ranges;
670 const char *name = NULL;
671 const char *mangled = NULL;
672 int decl_file = 0;
673 int decl_line = 0;
674 int decl_column = 0;
675 int call_file = 0;
676 int call_line = 0;
677 int call_column = 0;
678 DWARFExpression frame_base;
679
Greg Claytonc93237c2010-10-01 20:48:32 +0000680 assert (die->Tag() == DW_TAG_subprogram);
681
682 if (die->Tag() != DW_TAG_subprogram)
683 return NULL;
684
Greg Clayton5113dc82011-08-12 06:47:54 +0000685 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
686 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
Greg Claytonc93237c2010-10-01 20:48:32 +0000687
Greg Clayton5113dc82011-08-12 06:47:54 +0000688 switch (containing_decl_kind)
689 {
690 case clang::Decl::Record:
691 case clang::Decl::CXXRecord:
692 case clang::Decl::ObjCClass:
693 case clang::Decl::ObjCImplementation:
694 case clang::Decl::ObjCInterface:
695 // We have methods of a class or struct
696 {
697 const DWARFDebugInfoEntry *containing_decl_die = m_decl_ctx_to_die[containing_decl_ctx];
698 assert (containing_decl_die);
699 Type *class_type = ResolveType (dwarf_cu, containing_decl_die);
700 if (class_type)
701 class_type->GetClangFullType();
702 // Make sure the class definition contains the funciton DIE
703 // we wanted to parse. If it does, we are done. Else, we need
704 // to fall through and parse the function DIE stil...
705 if (containing_decl_die->Contains (die))
706 break; // DIE has been parsed, we are done
707 }
708 // Fall through...
709
710 default:
711 // Parse the function prototype as a type that can then be added to concrete function instance
712 ParseTypes (sc, dwarf_cu, die, false, false);
713 break;
Greg Claytonc93237c2010-10-01 20:48:32 +0000714 }
715
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 //FixupTypes();
717
718 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
719 {
720 // Union of all ranges in the function DIE (if the function is discontiguous)
721 AddressRange func_range;
722 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
723 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
724 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
725 {
726 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
727 if (func_range.GetBaseAddress().IsValid())
728 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
729 }
730
731 if (func_range.GetBaseAddress().IsValid())
732 {
733 Mangled func_name;
734 if (mangled)
735 func_name.SetValue(mangled, true);
736 else if (name)
737 func_name.SetValue(name, false);
738
739 FunctionSP func_sp;
740 std::auto_ptr<Declaration> decl_ap;
741 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000742 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
743 decl_line,
744 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745
Greg Clayton594e5ed2010-09-27 21:07:38 +0000746 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000747
748 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
749
750 func_range.GetBaseAddress().ResolveLinkedAddress();
751
752 func_sp.reset(new Function (sc.comp_unit,
753 die->GetOffset(), // UserID is the DIE offset
754 die->GetOffset(),
755 func_name,
756 func_type,
757 func_range)); // first address range
758
759 if (func_sp.get() != NULL)
760 {
761 func_sp->GetFrameBaseExpression() = frame_base;
762 sc.comp_unit->AddFunction(func_sp);
763 return func_sp.get();
764 }
765 }
766 }
767 return NULL;
768}
769
770size_t
771SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
772{
773 assert (sc.comp_unit);
774 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000775 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000776 if (dwarf_cu)
777 {
778 DWARFDIECollection function_dies;
779 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
780 size_t func_idx;
781 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
782 {
783 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
784 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
785 {
786 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
787 ++functions_added;
788 }
789 }
790 //FixupTypes();
791 }
792 return functions_added;
793}
794
795bool
796SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
797{
798 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000799 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
800 assert (curr_cu);
801 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000802
803 if (cu_die)
804 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000805 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
806 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 +0000807
808 // All file indexes in DWARF are one based and a file of index zero is
809 // supposed to be the compile unit itself.
810 support_files.Append (*sc.comp_unit);
811
812 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
813 }
814 return false;
815}
816
817struct ParseDWARFLineTableCallbackInfo
818{
819 LineTable* line_table;
820 const SectionList *section_list;
821 lldb::addr_t prev_sect_file_base_addr;
822 lldb::addr_t curr_sect_file_base_addr;
823 bool is_oso_for_debug_map;
824 bool prev_in_final_executable;
825 DWARFDebugLine::Row prev_row;
826 SectionSP prev_section_sp;
827 SectionSP curr_section_sp;
828};
829
830//----------------------------------------------------------------------
831// ParseStatementTableCallback
832//----------------------------------------------------------------------
833static void
834ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
835{
836 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
837 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
838 {
839 // Just started parsing the line table
840 }
841 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
842 {
843 // Done parsing line table, nothing to do for the cleanup
844 }
845 else
846 {
847 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
848 // We have a new row, lets append it
849
850 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
851 {
852 info->prev_section_sp = info->curr_section_sp;
853 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
854 // If this is an end sequence entry, then we subtract one from the
855 // address to make sure we get an address that is not the end of
856 // a section.
857 if (state.end_sequence && state.address != 0)
858 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
859 else
860 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
861
862 if (info->curr_section_sp.get())
863 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
864 else
865 info->curr_sect_file_base_addr = 0;
866 }
867 if (info->curr_section_sp.get())
868 {
869 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
870 // Check for the fancy section magic to determine if we
871
872 if (info->is_oso_for_debug_map)
873 {
874 // When this is a debug map object file that contains DWARF
875 // (referenced from an N_OSO debug map nlist entry) we will have
876 // a file address in the file range for our section from the
877 // original .o file, and a load address in the executable that
878 // contains the debug map.
879 //
880 // If the sections for the file range and load range are
881 // different, we have a remapped section for the function and
882 // this address is resolved. If they are the same, then the
883 // function for this address didn't make it into the final
884 // executable.
885 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
886
887 // If we are doing DWARF with debug map, then we need to carefully
888 // add each line table entry as there may be gaps as functions
889 // get moved around or removed.
890 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
891 {
892 if (info->prev_in_final_executable)
893 {
894 bool terminate_previous_entry = false;
895 if (!curr_in_final_executable)
896 {
897 // Check for the case where the previous line entry
898 // in a function made it into the final executable,
899 // yet the current line entry falls in a function
900 // that didn't. The line table used to be contiguous
901 // through this address range but now it isn't. We
902 // need to terminate the previous line entry so
903 // that we can reconstruct the line range correctly
904 // for it and to keep the line table correct.
905 terminate_previous_entry = true;
906 }
907 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
908 {
909 // Check for cases where the line entries used to be
910 // contiguous address ranges, but now they aren't.
911 // This can happen when order files specify the
912 // ordering of the functions.
913 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
914 Section *curr_sect = info->curr_section_sp.get();
915 Section *prev_sect = info->prev_section_sp.get();
916 assert (curr_sect->GetLinkedSection());
917 assert (prev_sect->GetLinkedSection());
918 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
919 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
920 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
921 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
922 if (object_file_addr_delta != linked_file_addr_delta)
923 terminate_previous_entry = true;
924 }
925
926 if (terminate_previous_entry)
927 {
928 line_table->InsertLineEntry (info->prev_section_sp,
929 state.address - info->prev_sect_file_base_addr,
930 info->prev_row.line,
931 info->prev_row.column,
932 info->prev_row.file,
933 false, // is_stmt
934 false, // basic_block
935 false, // state.prologue_end
936 false, // state.epilogue_begin
937 true); // end_sequence);
938 }
939 }
940 }
941
942 if (curr_in_final_executable)
943 {
944 line_table->InsertLineEntry (info->curr_section_sp,
945 curr_line_section_offset,
946 state.line,
947 state.column,
948 state.file,
949 state.is_stmt,
950 state.basic_block,
951 state.prologue_end,
952 state.epilogue_begin,
953 state.end_sequence);
954 info->prev_section_sp = info->curr_section_sp;
955 }
956 else
957 {
958 // If the current address didn't make it into the final
959 // executable, the current section will be the __text
960 // segment in the .o file, so we need to clear this so
961 // we can catch the next function that did make it into
962 // the final executable.
963 info->prev_section_sp.reset();
964 info->curr_section_sp.reset();
965 }
966
967 info->prev_in_final_executable = curr_in_final_executable;
968 }
969 else
970 {
971 // We are not in an object file that contains DWARF for an
972 // N_OSO, this is just a normal DWARF file. The DWARF spec
973 // guarantees that the addresses will be in increasing order
974 // so, since we store line tables in file address order, we
975 // can always just append the line entry without needing to
976 // search for the correct insertion point (we don't need to
977 // use LineEntry::InsertLineEntry()).
978 line_table->AppendLineEntry (info->curr_section_sp,
979 curr_line_section_offset,
980 state.line,
981 state.column,
982 state.file,
983 state.is_stmt,
984 state.basic_block,
985 state.prologue_end,
986 state.epilogue_begin,
987 state.end_sequence);
988 }
989 }
990
991 info->prev_row = state;
992 }
993}
994
995bool
996SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
997{
998 assert (sc.comp_unit);
999 if (sc.comp_unit->GetLineTable() != NULL)
1000 return true;
1001
1002 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1003 if (dwarf_cu)
1004 {
1005 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1006 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1007 if (cu_line_offset != DW_INVALID_OFFSET)
1008 {
1009 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1010 if (line_table_ap.get())
1011 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001012 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 +00001013 uint32_t offset = cu_line_offset;
1014 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1015 sc.comp_unit->SetLineTable(line_table_ap.release());
1016 return true;
1017 }
1018 }
1019 }
1020 return false;
1021}
1022
1023size_t
1024SymbolFileDWARF::ParseFunctionBlocks
1025(
1026 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001027 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001028 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 const DWARFDebugInfoEntry *die,
1030 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001031 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032)
1033{
1034 size_t blocks_added = 0;
1035 while (die != NULL)
1036 {
1037 dw_tag_t tag = die->Tag();
1038
1039 switch (tag)
1040 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001042 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 case DW_TAG_lexical_block:
1044 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001045 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001046 if (tag == DW_TAG_subprogram)
1047 {
1048 // Skip any DW_TAG_subprogram DIEs that are inside
1049 // of a normal or inlined functions. These will be
1050 // parsed on their own as separate entities.
1051
1052 if (depth > 0)
1053 break;
1054
1055 block = parent_block;
1056 }
1057 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001058 {
1059 BlockSP block_sp(new Block (die->GetOffset()));
1060 parent_block->AddChild(block_sp);
1061 block = block_sp.get();
1062 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001063 DWARFDebugRanges::RangeList ranges;
1064 const char *name = NULL;
1065 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 int decl_file = 0;
1068 int decl_line = 0;
1069 int decl_column = 0;
1070 int call_file = 0;
1071 int call_line = 0;
1072 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001073 if (die->GetDIENamesAndRanges (this,
1074 dwarf_cu,
1075 name,
1076 mangled_name,
1077 ranges,
1078 decl_file, decl_line, decl_column,
1079 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 {
1081 if (tag == DW_TAG_subprogram)
1082 {
1083 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1084 subprogram_low_pc = ranges.LowestAddress(0);
1085 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001086 else if (tag == DW_TAG_inlined_subroutine)
1087 {
1088 // We get called here for inlined subroutines in two ways.
1089 // The first time is when we are making the Function object
1090 // for this inlined concrete instance. Since we're creating a top level block at
1091 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1092 // adjust the containing address.
1093 // The second time is when we are parsing the blocks inside the function that contains
1094 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1095 // function the offset will be for that function.
1096 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1097 {
1098 subprogram_low_pc = ranges.LowestAddress(0);
1099 }
1100 }
1101
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001102 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001103
1104 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1105 {
1106 std::auto_ptr<Declaration> decl_ap;
1107 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001108 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1109 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110
1111 std::auto_ptr<Declaration> call_ap;
1112 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001113 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1114 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001115
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001116 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 }
1118
1119 ++blocks_added;
1120
Greg Claytondd7feaf2011-08-12 17:54:33 +00001121 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001123 blocks_added += ParseFunctionBlocks (sc,
1124 block,
1125 dwarf_cu,
1126 die->GetFirstChild(),
1127 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001128 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 }
1130 }
1131 }
1132 break;
1133 default:
1134 break;
1135 }
1136
Greg Claytondd7feaf2011-08-12 17:54:33 +00001137 // Only parse siblings of the block if we are not at depth zero. A depth
1138 // of zero indicates we are currently parsing the top level
1139 // DW_TAG_subprogram DIE
1140
1141 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001143 else
1144 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 }
1146 return blocks_added;
1147}
1148
1149size_t
1150SymbolFileDWARF::ParseChildMembers
1151(
1152 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001153 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001155 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001156 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1158 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001159 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001160 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161 bool &is_a_class
1162)
1163{
1164 if (parent_die == NULL)
1165 return 0;
1166
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 size_t count = 0;
1168 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001169 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001170 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001171
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1173 {
1174 dw_tag_t tag = die->Tag();
1175
1176 switch (tag)
1177 {
1178 case DW_TAG_member:
1179 {
1180 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001181 const size_t num_attributes = die->GetAttributes (this,
1182 dwarf_cu,
1183 fixed_form_sizes,
1184 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185 if (num_attributes > 0)
1186 {
1187 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001188 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001189 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001190 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001192 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001193 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001194 size_t byte_size = 0;
1195 size_t bit_offset = 0;
1196 size_t bit_size = 0;
1197 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001198 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 {
1200 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1201 DWARFFormValue form_value;
1202 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1203 {
1204 switch (attr)
1205 {
1206 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1207 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1208 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1209 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1210 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1211 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1212 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1213 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1214 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001215// if (form_value.BlockData())
1216// {
1217// Value initialValue(0);
1218// Value memberOffset(0);
1219// const DataExtractor& debug_info_data = get_debug_info_data();
1220// uint32_t block_length = form_value.Unsigned();
1221// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1222// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1223// {
1224// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1225// }
1226// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001227 break;
1228
Greg Clayton8cf05932010-07-22 18:30:50 +00001229 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001230 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 case DW_AT_declaration:
1232 case DW_AT_description:
1233 case DW_AT_mutable:
1234 case DW_AT_visibility:
1235 default:
1236 case DW_AT_sibling:
1237 break;
1238 }
1239 }
1240 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001241
1242 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1243
1244 if (class_language == eLanguageTypeObjC ||
1245 class_language == eLanguageTypeObjC_plus_plus)
1246 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001247
1248 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1249 {
1250 // Not all compilers will mark the vtable pointer
1251 // member as artificial (llvm-gcc). We can't have
1252 // the virtual members in our classes otherwise it
1253 // throws off all child offsets since we end up
1254 // having and extra pointer sized member in our
1255 // class layouts.
1256 is_artificial = true;
1257 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258
Greg Clayton24739922010-10-13 03:15:28 +00001259 if (is_artificial == false)
1260 {
1261 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001262 if (member_type)
1263 {
1264 if (accessibility == eAccessNone)
1265 accessibility = default_accessibility;
1266 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267
Greg Claytond16e1e52011-07-12 17:06:17 +00001268 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1269 name,
1270 member_type->GetClangLayoutType(),
1271 accessibility,
1272 bit_size);
1273 }
1274 else
1275 {
1276 if (name)
1277 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1278 die->GetOffset(),
1279 name,
1280 encoding_uid);
1281 else
1282 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1283 die->GetOffset(),
1284 encoding_uid);
1285 }
Greg Clayton24739922010-10-13 03:15:28 +00001286 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001288 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289 }
1290 break;
1291
1292 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001293 // Let the type parsing code handle this one for us.
1294 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295 break;
1296
1297 case DW_TAG_inheritance:
1298 {
1299 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001300 if (default_accessibility == eAccessNone)
1301 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 // TODO: implement DW_TAG_inheritance type parsing
1303 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001304 const size_t num_attributes = die->GetAttributes (this,
1305 dwarf_cu,
1306 fixed_form_sizes,
1307 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308 if (num_attributes > 0)
1309 {
1310 Declaration decl;
1311 DWARFExpression location;
1312 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001313 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001314 bool is_virtual = false;
1315 bool is_base_of_class = true;
1316 off_t member_offset = 0;
1317 uint32_t i;
1318 for (i=0; i<num_attributes; ++i)
1319 {
1320 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1321 DWARFFormValue form_value;
1322 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1323 {
1324 switch (attr)
1325 {
1326 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1327 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1328 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1329 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1330 case DW_AT_data_member_location:
1331 if (form_value.BlockData())
1332 {
1333 Value initialValue(0);
1334 Value memberOffset(0);
1335 const DataExtractor& debug_info_data = get_debug_info_data();
1336 uint32_t block_length = form_value.Unsigned();
1337 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001338 if (DWARFExpression::Evaluate (NULL,
1339 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001340 NULL,
1341 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001342 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001343 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001344 block_offset,
1345 block_length,
1346 eRegisterKindDWARF,
1347 &initialValue,
1348 memberOffset,
1349 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 {
1351 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1352 }
1353 }
1354 break;
1355
1356 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001357 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358 break;
1359
1360 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1361 default:
1362 case DW_AT_sibling:
1363 break;
1364 }
1365 }
1366 }
1367
Greg Clayton526e5af2010-11-13 03:52:47 +00001368 Type *base_class_type = ResolveTypeUID(encoding_uid);
1369 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001370
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001371 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1372 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001373 if (class_language == eLanguageTypeObjC)
1374 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001375 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001376 }
1377 else
1378 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001379 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001380 accessibility,
1381 is_virtual,
1382 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001384 }
1385 }
1386 break;
1387
1388 default:
1389 break;
1390 }
1391 }
1392 return count;
1393}
1394
1395
1396clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001397SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001398{
1399 DWARFDebugInfo* debug_info = DebugInfo();
1400 if (debug_info)
1401 {
1402 DWARFCompileUnitSP cu_sp;
1403 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1404 if (die)
Sean Callanan72e49402011-08-05 23:43:37 +00001405 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
1406 }
1407 return NULL;
1408}
1409
1410clang::DeclContext*
1411SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1412{
1413 DWARFDebugInfo* debug_info = DebugInfo();
1414 if (debug_info)
1415 {
1416 DWARFCompileUnitSP cu_sp;
1417 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1418 if (die)
1419 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420 }
1421 return NULL;
1422}
1423
1424Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001425SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426{
1427 DWARFDebugInfo* debug_info = DebugInfo();
1428 if (debug_info)
1429 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001430 DWARFCompileUnitSP cu_sp;
1431 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001432 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001433 {
1434 // We might be coming in in the middle of a type tree (a class
1435 // withing a class, an enum within a class), so parse any needed
1436 // parent DIEs before we get to this one...
1437 const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1438 switch (parent_die->Tag())
1439 {
1440 case DW_TAG_structure_type:
1441 case DW_TAG_union_type:
1442 case DW_TAG_class_type:
1443 ResolveType(cu_sp.get(), parent_die);
1444 break;
1445 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001446 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001447 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448 }
1449 return NULL;
1450}
1451
Greg Clayton6beaaa62011-01-17 03:46:26 +00001452// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1453// SymbolFileDWARF objects to detect if this DWARF file is the one that
1454// can resolve a clang_type.
1455bool
1456SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1457{
1458 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1459 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1460 return die != NULL;
1461}
1462
1463
Greg Clayton1be10fc2010-09-29 01:12:09 +00001464lldb::clang_type_t
1465SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1466{
1467 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001468 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1469 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001470 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001471 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001472// if (m_debug_map_symfile)
1473// {
1474// Type *type = m_die_to_type[die];
1475// if (type && type->GetSymbolFile() != this)
1476// return type->GetClangType();
1477// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001478 // We have already resolved this type...
1479 return clang_type;
1480 }
1481 // Once we start resolving this type, remove it from the forward declaration
1482 // map in case anyone child members or other types require this type to get resolved.
1483 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1484 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001485 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001486
Greg Clayton1be10fc2010-09-29 01:12:09 +00001487
Greg Clayton450e3f32010-10-12 02:24:53 +00001488 DWARFDebugInfo* debug_info = DebugInfo();
1489
Greg Clayton96d7d742010-11-10 23:42:09 +00001490 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001491 Type *type = m_die_to_type.lookup (die);
1492
1493 const dw_tag_t tag = die->Tag();
1494
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001495 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1496 die->GetOffset(),
1497 DW_TAG_value_to_name(tag),
1498 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001499 assert (clang_type);
1500 DWARFDebugInfoEntry::Attributes attributes;
1501
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001502 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001503
1504 switch (tag)
1505 {
1506 case DW_TAG_structure_type:
1507 case DW_TAG_union_type:
1508 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001509 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001510 if (die->HasChildren())
1511 {
1512 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001513 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1514 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001515 class_language = eLanguageTypeObjC;
1516
1517 int tag_decl_kind = -1;
1518 AccessType default_accessibility = eAccessNone;
1519 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001520 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001521 tag_decl_kind = clang::TTK_Struct;
1522 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001523 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001524 else if (tag == DW_TAG_union_type)
1525 {
1526 tag_decl_kind = clang::TTK_Union;
1527 default_accessibility = eAccessPublic;
1528 }
1529 else if (tag == DW_TAG_class_type)
1530 {
1531 tag_decl_kind = clang::TTK_Class;
1532 default_accessibility = eAccessPrivate;
1533 }
1534
Greg Clayton96d7d742010-11-10 23:42:09 +00001535 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001536 std::vector<clang::CXXBaseSpecifier *> base_classes;
1537 std::vector<int> member_accessibilities;
1538 bool is_a_class = false;
1539 // Parse members and base classes first
1540 DWARFDIECollection member_function_dies;
1541
1542 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001543 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001544 die,
1545 clang_type,
1546 class_language,
1547 base_classes,
1548 member_accessibilities,
1549 member_function_dies,
1550 default_accessibility,
1551 is_a_class);
1552
1553 // Now parse any methods if there were any...
1554 size_t num_functions = member_function_dies.Size();
1555 if (num_functions > 0)
1556 {
1557 for (size_t i=0; i<num_functions; ++i)
1558 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001559 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001560 }
1561 }
1562
Greg Clayton450e3f32010-10-12 02:24:53 +00001563 if (class_language == eLanguageTypeObjC)
1564 {
Greg Claytone3055942011-06-30 02:28:26 +00001565 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001566 if (!class_str.empty())
1567 {
1568
1569 ConstString class_name (class_str.c_str());
1570 std::vector<NameToDIE::Info> method_die_infos;
1571 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1572 {
1573 DWARFCompileUnit* method_cu = NULL;
1574 DWARFCompileUnit* prev_method_cu = NULL;
1575 const size_t num_objc_methods = method_die_infos.size();
1576 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1577 {
1578 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1579
1580 if (method_cu != prev_method_cu)
1581 method_cu->ExtractDIEsIfNeeded (false);
1582
1583 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1584
1585 ResolveType (method_cu, method_die);
1586 }
1587 }
1588 }
1589 }
1590
Greg Claytonc93237c2010-10-01 20:48:32 +00001591 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1592 // need to tell the clang type it is actually a class.
1593 if (class_language != eLanguageTypeObjC)
1594 {
1595 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001596 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001597 }
1598
1599 // Since DW_TAG_structure_type gets used for both classes
1600 // and structures, we may need to set any DW_TAG_member
1601 // fields to have a "private" access if none was specified.
1602 // When we parsed the child members we tracked that actual
1603 // accessibility value for each DW_TAG_member in the
1604 // "member_accessibilities" array. If the value for the
1605 // member is zero, then it was set to the "default_accessibility"
1606 // which for structs was "public". Below we correct this
1607 // by setting any fields to "private" that weren't correctly
1608 // set.
1609 if (is_a_class && !member_accessibilities.empty())
1610 {
1611 // This is a class and all members that didn't have
1612 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001613 ast.SetDefaultAccessForRecordFields (clang_type,
1614 eAccessPrivate,
1615 &member_accessibilities.front(),
1616 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001617 }
1618
1619 if (!base_classes.empty())
1620 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001621 ast.SetBaseClassesForClassType (clang_type,
1622 &base_classes.front(),
1623 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001624
1625 // Clang will copy each CXXBaseSpecifier in "base_classes"
1626 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001627 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1628 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001629 }
1630
1631 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001632 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001633 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001634
1635 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001636 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001637 if (die->HasChildren())
1638 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001639 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1640 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001641 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001642 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001643 return clang_type;
1644
1645 default:
1646 assert(false && "not a forward clang type decl!");
1647 break;
1648 }
1649 return NULL;
1650}
1651
Greg Claytonc685f8e2010-09-15 04:15:46 +00001652Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001653SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001654{
1655 if (type_die != NULL)
1656 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001657 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001658 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001659 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001660 if (assert_not_being_parsed)
1661 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001662 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001663 }
1664 return NULL;
1665}
1666
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001667CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001668SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001669{
1670 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001671 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001672 {
1673 // The symbol vendor doesn't know about this compile unit, we
1674 // need to parse and add it to the symbol vendor object.
1675 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001676 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001677 if (dc_cu.get())
1678 {
1679 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001680 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001681 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682
1683 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001684
1685 if (m_debug_map_symfile)
1686 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001687 }
1688 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001689 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001690}
1691
1692bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001693SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001694{
1695 sc.Clear();
1696 // Check if the symbol vendor already knows about this compile unit?
1697 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001698 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001699
1700 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1701 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001702 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001703
1704 return sc.function != NULL;
1705}
1706
1707uint32_t
1708SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1709{
1710 Timer scoped_timer(__PRETTY_FUNCTION__,
1711 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1712 so_addr.GetSection(),
1713 so_addr.GetOffset(),
1714 resolve_scope);
1715 uint32_t resolved = 0;
1716 if (resolve_scope & ( eSymbolContextCompUnit |
1717 eSymbolContextFunction |
1718 eSymbolContextBlock |
1719 eSymbolContextLineEntry))
1720 {
1721 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1722
1723 DWARFDebugAranges* debug_aranges = DebugAranges();
1724 DWARFDebugInfo* debug_info = DebugInfo();
1725 if (debug_aranges)
1726 {
1727 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1728 if (cu_offset != DW_INVALID_OFFSET)
1729 {
1730 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001731 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1732 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001733 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001734 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001735 assert(sc.comp_unit != NULL);
1736 resolved |= eSymbolContextCompUnit;
1737
1738 if (resolve_scope & eSymbolContextLineEntry)
1739 {
1740 LineTable *line_table = sc.comp_unit->GetLineTable();
1741 if (line_table == NULL)
1742 {
1743 if (ParseCompileUnitLineTable(sc))
1744 line_table = sc.comp_unit->GetLineTable();
1745 }
1746 if (line_table != NULL)
1747 {
1748 if (so_addr.IsLinkedAddress())
1749 {
1750 Address linked_addr (so_addr);
1751 linked_addr.ResolveLinkedAddress();
1752 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1753 {
1754 resolved |= eSymbolContextLineEntry;
1755 }
1756 }
1757 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1758 {
1759 resolved |= eSymbolContextLineEntry;
1760 }
1761 }
1762 }
1763
1764 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1765 {
1766 DWARFDebugInfoEntry *function_die = NULL;
1767 DWARFDebugInfoEntry *block_die = NULL;
1768 if (resolve_scope & eSymbolContextBlock)
1769 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001770 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001771 }
1772 else
1773 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001774 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001775 }
1776
1777 if (function_die != NULL)
1778 {
1779 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1780 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001781 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001782 }
1783
1784 if (sc.function != NULL)
1785 {
1786 resolved |= eSymbolContextFunction;
1787
1788 if (resolve_scope & eSymbolContextBlock)
1789 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001790 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001791
1792 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001793 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001794 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001795 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001796 if (sc.block)
1797 resolved |= eSymbolContextBlock;
1798 }
1799 }
1800 }
1801 }
1802 }
1803 }
1804 }
1805 return resolved;
1806}
1807
1808
1809
1810uint32_t
1811SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1812{
1813 const uint32_t prev_size = sc_list.GetSize();
1814 if (resolve_scope & eSymbolContextCompUnit)
1815 {
1816 DWARFDebugInfo* debug_info = DebugInfo();
1817 if (debug_info)
1818 {
1819 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001820 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001821
Greg Clayton96d7d742010-11-10 23:42:09 +00001822 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001823 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001824 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001825 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1826 if (check_inlines || file_spec_matches_cu_file_spec)
1827 {
1828 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001829 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001830 assert(sc.comp_unit != NULL);
1831
1832 uint32_t file_idx = UINT32_MAX;
1833
1834 // If we are looking for inline functions only and we don't
1835 // find it in the support files, we are done.
1836 if (check_inlines)
1837 {
1838 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1839 if (file_idx == UINT32_MAX)
1840 continue;
1841 }
1842
1843 if (line != 0)
1844 {
1845 LineTable *line_table = sc.comp_unit->GetLineTable();
1846
1847 if (line_table != NULL && line != 0)
1848 {
1849 // We will have already looked up the file index if
1850 // we are searching for inline entries.
1851 if (!check_inlines)
1852 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1853
1854 if (file_idx != UINT32_MAX)
1855 {
1856 uint32_t found_line;
1857 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1858 found_line = sc.line_entry.line;
1859
Greg Clayton016a95e2010-09-14 02:20:48 +00001860 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861 {
1862 sc.function = NULL;
1863 sc.block = NULL;
1864 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1865 {
1866 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1867 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1868 {
1869 DWARFDebugInfoEntry *function_die = NULL;
1870 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001871 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001872
1873 if (function_die != NULL)
1874 {
1875 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1876 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001877 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001878 }
1879
1880 if (sc.function != NULL)
1881 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001882 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883
1884 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001885 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001886 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001887 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888 }
1889 }
1890 }
1891
1892 sc_list.Append(sc);
1893 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1894 }
1895 }
1896 }
1897 else if (file_spec_matches_cu_file_spec && !check_inlines)
1898 {
1899 // only append the context if we aren't looking for inline call sites
1900 // by file and line and if the file spec matches that of the compile unit
1901 sc_list.Append(sc);
1902 }
1903 }
1904 else if (file_spec_matches_cu_file_spec && !check_inlines)
1905 {
1906 // only append the context if we aren't looking for inline call sites
1907 // by file and line and if the file spec matches that of the compile unit
1908 sc_list.Append(sc);
1909 }
1910
1911 if (!check_inlines)
1912 break;
1913 }
1914 }
1915 }
1916 }
1917 return sc_list.GetSize() - prev_size;
1918}
1919
1920void
1921SymbolFileDWARF::Index ()
1922{
1923 if (m_indexed)
1924 return;
1925 m_indexed = true;
1926 Timer scoped_timer (__PRETTY_FUNCTION__,
1927 "SymbolFileDWARF::Index (%s)",
1928 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1929
1930 DWARFDebugInfo* debug_info = DebugInfo();
1931 if (debug_info)
1932 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001933 m_aranges.reset(new DWARFDebugAranges());
1934
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 uint32_t cu_idx = 0;
1936 const uint32_t num_compile_units = GetNumCompileUnits();
1937 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1938 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001939 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001940
Greg Clayton96d7d742010-11-10 23:42:09 +00001941 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001942
Greg Clayton96d7d742010-11-10 23:42:09 +00001943 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001944 m_function_basename_index,
1945 m_function_fullname_index,
1946 m_function_method_index,
1947 m_function_selector_index,
1948 m_objc_class_selectors_index,
1949 m_global_index,
1950 m_type_index,
1951 m_namespace_index,
1952 DebugRanges(),
1953 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001954
1955 // Keep memory down by clearing DIEs if this generate function
1956 // caused them to be parsed
1957 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001958 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001959 }
1960
Greg Clayton016a95e2010-09-14 02:20:48 +00001961 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001962
Greg Clayton24739922010-10-13 03:15:28 +00001963#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00001964 StreamFile s(stdout, false);
Greg Claytonf9eec202011-09-01 23:16:13 +00001965 s.Printf ("DWARF index for '%s/%s':",
Greg Clayton24739922010-10-13 03:15:28 +00001966 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1967 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001968 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1969 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1970 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1971 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1972 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1973 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001974 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001975 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001976#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001977 }
1978}
1979
1980uint32_t
1981SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1982{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001983 DWARFDebugInfo* info = DebugInfo();
1984 if (info == NULL)
1985 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001986
1987 // If we aren't appending the results to this list, then clear the list
1988 if (!append)
1989 variables.Clear();
1990
1991 // Remember how many variables are in the list before we search in case
1992 // we are appending the results to a variable list.
1993 const uint32_t original_size = variables.GetSize();
1994
1995 // Index the DWARF if we haven't already
1996 if (!m_indexed)
1997 Index ();
1998
Greg Claytonc685f8e2010-09-15 04:15:46 +00001999 SymbolContext sc;
2000 sc.module_sp = m_obj_file->GetModule()->GetSP();
2001 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002002
Greg Clayton96d7d742010-11-10 23:42:09 +00002003 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002004 DWARFCompileUnit* prev_cu = NULL;
2005 const DWARFDebugInfoEntry* die = NULL;
2006 std::vector<NameToDIE::Info> die_info_array;
2007 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002008 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002009 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002010 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002011
Greg Clayton96d7d742010-11-10 23:42:09 +00002012 if (curr_cu != prev_cu)
2013 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002014
Greg Clayton96d7d742010-11-10 23:42:09 +00002015 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002016
Greg Clayton96d7d742010-11-10 23:42:09 +00002017 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002018 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002019
Greg Clayton96d7d742010-11-10 23:42:09 +00002020 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002021
2022 if (variables.GetSize() - original_size >= max_matches)
2023 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002024 }
2025
2026 // Return the number of variable that were appended to the list
2027 return variables.GetSize() - original_size;
2028}
2029
2030uint32_t
2031SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2032{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002033 DWARFDebugInfo* info = DebugInfo();
2034 if (info == NULL)
2035 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002036
2037 // If we aren't appending the results to this list, then clear the list
2038 if (!append)
2039 variables.Clear();
2040
2041 // Remember how many variables are in the list before we search in case
2042 // we are appending the results to a variable list.
2043 const uint32_t original_size = variables.GetSize();
2044
2045 // Index the DWARF if we haven't already
2046 if (!m_indexed)
2047 Index ();
2048
Greg Claytonc685f8e2010-09-15 04:15:46 +00002049 SymbolContext sc;
2050 sc.module_sp = m_obj_file->GetModule()->GetSP();
2051 assert (sc.module_sp);
2052
Greg Clayton96d7d742010-11-10 23:42:09 +00002053 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002054 DWARFCompileUnit* prev_cu = NULL;
2055 const DWARFDebugInfoEntry* die = NULL;
2056 std::vector<NameToDIE::Info> die_info_array;
2057 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002058 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002059 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002060 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002061
Greg Clayton96d7d742010-11-10 23:42:09 +00002062 if (curr_cu != prev_cu)
2063 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002064
Greg Clayton96d7d742010-11-10 23:42:09 +00002065 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002066
Greg Clayton96d7d742010-11-10 23:42:09 +00002067 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002068 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002069
Greg Clayton96d7d742010-11-10 23:42:09 +00002070 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002071
Greg Claytonc685f8e2010-09-15 04:15:46 +00002072 if (variables.GetSize() - original_size >= max_matches)
2073 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002074 }
2075
2076 // Return the number of variable that were appended to the list
2077 return variables.GetSize() - original_size;
2078}
2079
2080
Greg Clayton9e315582011-09-02 04:03:59 +00002081uint32_t
2082SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets,
2083 SymbolContextList& sc_list)
2084{
2085 DWARFDebugInfo* info = DebugInfo();
2086 if (info == NULL)
2087 return 0;
2088
2089 const uint32_t sc_list_initial_size = sc_list.GetSize();
2090 SymbolContext sc;
2091 sc.module_sp = m_obj_file->GetModule()->GetSP();
2092 assert (sc.module_sp);
2093
2094 DWARFCompileUnit* dwarf_cu = NULL;
2095 const size_t num_matches = die_offsets.size();
2096 for (size_t i=0; i<num_matches; ++i)
2097 {
2098 const dw_offset_t die_offset = die_offsets[i];
2099 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2100
2101 const DWARFDebugInfoEntry* inlined_die = NULL;
2102 if (die->Tag() == DW_TAG_inlined_subroutine)
2103 {
2104 inlined_die = die;
2105
2106 while ((die = die->GetParent()) != NULL)
2107 {
2108 if (die->Tag() == DW_TAG_subprogram)
2109 break;
2110 }
2111 }
2112 assert (die->Tag() == DW_TAG_subprogram);
2113 if (GetFunction (dwarf_cu, die, sc))
2114 {
2115 Address addr;
2116 // Parse all blocks if needed
2117 if (inlined_die)
2118 {
2119 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2120 assert (sc.block != NULL);
2121 if (sc.block->GetStartAddress (addr) == false)
2122 addr.Clear();
2123 }
2124 else
2125 {
2126 sc.block = NULL;
2127 addr = sc.function->GetAddressRange().GetBaseAddress();
2128 }
2129
2130 if (addr.IsValid())
2131 {
2132
2133 // We found the function, so we should find the line table
2134 // and line table entry as well
2135 LineTable *line_table = sc.comp_unit->GetLineTable();
2136 if (line_table == NULL)
2137 {
2138 if (ParseCompileUnitLineTable(sc))
2139 line_table = sc.comp_unit->GetLineTable();
2140 }
2141 if (line_table != NULL)
2142 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2143
2144 sc_list.Append(sc);
2145 }
2146 }
2147 }
2148 return sc_list.GetSize() - sc_list_initial_size;
2149}
2150
Greg Clayton0c5cd902010-06-28 21:30:43 +00002151void
2152SymbolFileDWARF::FindFunctions
2153(
2154 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00002155 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00002156 SymbolContextList& sc_list
2157)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002158{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002159 DWARFDebugInfo* info = DebugInfo();
2160 if (info == NULL)
2161 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002162
Greg Claytonc685f8e2010-09-15 04:15:46 +00002163 SymbolContext sc;
2164 sc.module_sp = m_obj_file->GetModule()->GetSP();
2165 assert (sc.module_sp);
2166
Greg Clayton96d7d742010-11-10 23:42:09 +00002167 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002168 DWARFCompileUnit* prev_cu = NULL;
2169 const DWARFDebugInfoEntry* die = NULL;
2170 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00002171 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002172 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002173 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002174 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002175
Greg Clayton96d7d742010-11-10 23:42:09 +00002176 if (curr_cu != prev_cu)
2177 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002178
Greg Clayton96d7d742010-11-10 23:42:09 +00002179 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00002180
2181 const DWARFDebugInfoEntry* inlined_die = NULL;
2182 if (die->Tag() == DW_TAG_inlined_subroutine)
2183 {
2184 inlined_die = die;
2185
2186 while ((die = die->GetParent()) != NULL)
2187 {
2188 if (die->Tag() == DW_TAG_subprogram)
2189 break;
2190 }
2191 }
2192 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002193 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002194 {
Greg Claytond7e05462010-11-14 00:22:48 +00002195 Address addr;
2196 // Parse all blocks if needed
2197 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002198 {
Greg Claytond7e05462010-11-14 00:22:48 +00002199 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2200 assert (sc.block != NULL);
2201 if (sc.block->GetStartAddress (addr) == false)
2202 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002203 }
Greg Claytond7e05462010-11-14 00:22:48 +00002204 else
2205 {
2206 sc.block = NULL;
2207 addr = sc.function->GetAddressRange().GetBaseAddress();
2208 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002209
Greg Claytond7e05462010-11-14 00:22:48 +00002210 if (addr.IsValid())
2211 {
2212
2213 // We found the function, so we should find the line table
2214 // and line table entry as well
2215 LineTable *line_table = sc.comp_unit->GetLineTable();
2216 if (line_table == NULL)
2217 {
2218 if (ParseCompileUnitLineTable(sc))
2219 line_table = sc.comp_unit->GetLineTable();
2220 }
2221 if (line_table != NULL)
2222 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2223
2224 sc_list.Append(sc);
2225 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002226 }
2227 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002228}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002229
Greg Claytonc685f8e2010-09-15 04:15:46 +00002230
2231void
2232SymbolFileDWARF::FindFunctions
2233(
2234 const RegularExpression &regex,
2235 const NameToDIE &name_to_die,
2236 SymbolContextList& sc_list
2237)
2238{
2239 DWARFDebugInfo* info = DebugInfo();
2240 if (info == NULL)
2241 return;
2242
2243 SymbolContext sc;
2244 sc.module_sp = m_obj_file->GetModule()->GetSP();
2245 assert (sc.module_sp);
2246
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;
2251 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002252 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +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 Claytonab843392010-12-03 17:49:14 +00002260
2261 const DWARFDebugInfoEntry* inlined_die = NULL;
2262 if (die->Tag() == DW_TAG_inlined_subroutine)
2263 {
2264 inlined_die = die;
2265
2266 while ((die = die->GetParent()) != NULL)
2267 {
2268 if (die->Tag() == DW_TAG_subprogram)
2269 break;
2270 }
2271 }
2272 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002273 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002274 {
Greg Claytonab843392010-12-03 17:49:14 +00002275 Address addr;
2276 // Parse all blocks if needed
2277 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002278 {
Greg Claytonab843392010-12-03 17:49:14 +00002279 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2280 assert (sc.block != NULL);
2281 if (sc.block->GetStartAddress (addr) == false)
2282 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002283 }
Greg Claytonab843392010-12-03 17:49:14 +00002284 else
2285 {
2286 sc.block = NULL;
2287 addr = sc.function->GetAddressRange().GetBaseAddress();
2288 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002289
Greg Claytonab843392010-12-03 17:49:14 +00002290 if (addr.IsValid())
2291 {
2292
2293 // We found the function, so we should find the line table
2294 // and line table entry as well
2295 LineTable *line_table = sc.comp_unit->GetLineTable();
2296 if (line_table == NULL)
2297 {
2298 if (ParseCompileUnitLineTable(sc))
2299 line_table = sc.comp_unit->GetLineTable();
2300 }
2301 if (line_table != NULL)
2302 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2303
2304 sc_list.Append(sc);
2305 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002306 }
2307 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002308}
2309
2310uint32_t
2311SymbolFileDWARF::FindFunctions
2312(
2313 const ConstString &name,
2314 uint32_t name_type_mask,
2315 bool append,
2316 SymbolContextList& sc_list
2317)
2318{
2319 Timer scoped_timer (__PRETTY_FUNCTION__,
2320 "SymbolFileDWARF::FindFunctions (name = '%s')",
2321 name.AsCString());
2322
Greg Clayton0c5cd902010-06-28 21:30:43 +00002323 // If we aren't appending the results to this list, then clear the list
2324 if (!append)
2325 sc_list.Clear();
2326
2327 // Remember how many sc_list are in the list before we search in case
2328 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002329
2330 if (m_debug_names.IsValid())
2331 {
2332 DIEArray die_offsets;
2333 const uint32_t num_matches = m_debug_names.Find(name, die_offsets);
2334 if (num_matches > 0)
2335 {
2336 return ResolveFunctions (die_offsets, sc_list);
2337 }
2338 return 0;
2339 }
2340
2341 const uint32_t original_size = sc_list.GetSize();
Greg Clayton0c5cd902010-06-28 21:30:43 +00002342
2343 // Index the DWARF if we haven't already
2344 if (!m_indexed)
2345 Index ();
2346
2347 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002348 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002349
2350 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002351 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002352
2353 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002354 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002355
2356 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002357 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002358
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002359 // Return the number of variable that were appended to the list
2360 return sc_list.GetSize() - original_size;
2361}
2362
2363
2364uint32_t
2365SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2366{
2367 Timer scoped_timer (__PRETTY_FUNCTION__,
2368 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2369 regex.GetText());
2370
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002371 // If we aren't appending the results to this list, then clear the list
2372 if (!append)
2373 sc_list.Clear();
2374
2375 // Remember how many sc_list are in the list before we search in case
2376 // we are appending the results to a variable list.
2377 uint32_t original_size = sc_list.GetSize();
2378
2379 // Index the DWARF if we haven't already
2380 if (!m_indexed)
2381 Index ();
2382
Greg Claytonc685f8e2010-09-15 04:15:46 +00002383 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002384
Greg Claytonc685f8e2010-09-15 04:15:46 +00002385 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002386
2387 // Return the number of variable that were appended to the list
2388 return sc_list.GetSize() - original_size;
2389}
Jim Ingham318c9f22011-08-26 19:44:13 +00002390
Greg Claytond16e1e52011-07-12 17:06:17 +00002391void
2392SymbolFileDWARF::ReportError (const char *format, ...)
2393{
2394 ::fprintf (stderr,
2395 "error: %s/%s ",
2396 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2397 m_obj_file->GetFileSpec().GetFilename().GetCString());
2398
2399 va_list args;
2400 va_start (args, format);
2401 vfprintf (stderr, format, args);
2402 va_end (args);
2403}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002405uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002406SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002407{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002408 DWARFDebugInfo* info = DebugInfo();
2409 if (info == NULL)
2410 return 0;
2411
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002412 // If we aren't appending the results to this list, then clear the list
2413 if (!append)
2414 types.Clear();
2415
Greg Clayton6dbd3982010-09-15 05:51:24 +00002416 // Index if we already haven't to make sure the compile units
2417 // get indexed and make their global DIE index list
2418 if (!m_indexed)
2419 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002420
Greg Claytonc685f8e2010-09-15 04:15:46 +00002421 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002422 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002423 DWARFCompileUnit* prev_cu = NULL;
2424 const DWARFDebugInfoEntry* die = NULL;
2425 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002426 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002427 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002428 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002429 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002430
Greg Clayton96d7d742010-11-10 23:42:09 +00002431 if (curr_cu != prev_cu)
2432 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002433
Greg Clayton96d7d742010-11-10 23:42:09 +00002434 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002435
Greg Clayton96d7d742010-11-10 23:42:09 +00002436 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002437 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002438 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002439 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002440 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Clayton73bf5db2011-06-17 01:22:15 +00002441 if (type_sp)
2442 {
2443 types.InsertUnique (type_sp);
2444 if (types.GetSize() >= max_matches)
2445 break;
2446 }
2447 else
2448 {
2449 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
2450 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002451 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002452 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002453 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002454}
2455
2456
Greg Clayton526e5af2010-11-13 03:52:47 +00002457ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002458SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2459 const ConstString &name)
2460{
Greg Clayton526e5af2010-11-13 03:52:47 +00002461 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002462 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002463 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002464 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002465 // Index if we already haven't to make sure the compile units
2466 // get indexed and make their global DIE index list
2467 if (!m_indexed)
2468 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002469
Greg Clayton526e5af2010-11-13 03:52:47 +00002470 DWARFCompileUnit* curr_cu = NULL;
2471 DWARFCompileUnit* prev_cu = NULL;
2472 const DWARFDebugInfoEntry* die = NULL;
2473 std::vector<NameToDIE::Info> die_info_array;
2474 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2475 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2476 {
2477 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2478
2479 if (curr_cu != prev_cu)
2480 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002481
Greg Clayton526e5af2010-11-13 03:52:47 +00002482 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2483
2484 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2485 if (clang_namespace_decl)
2486 {
2487 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2488 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2489 }
2490 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002491 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002492 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002493}
2494
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002495uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002496SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002497{
2498 // Remember how many sc_list are in the list before we search in case
2499 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002500 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501
2502 const uint32_t num_die_offsets = die_offsets.size();
2503 // Parse all of the types we found from the pubtypes matches
2504 uint32_t i;
2505 uint32_t num_matches = 0;
2506 for (i = 0; i < num_die_offsets; ++i)
2507 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002508 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2509 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002510 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002511 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002512 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002513 assert (type_sp.get() != NULL);
2514 types.InsertUnique (type_sp);
2515 ++num_matches;
2516 if (num_matches >= max_matches)
2517 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002518 }
2519 }
2520
2521 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002522 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002523}
2524
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002525
2526size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00002527SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
2528 clang::DeclContext *containing_decl_ctx,
2529 TypeSP& type_sp,
2530 DWARFCompileUnit* dwarf_cu,
2531 const DWARFDebugInfoEntry *parent_die,
2532 bool skip_artificial,
2533 bool &is_static,
2534 TypeList* type_list,
2535 std::vector<clang_type_t>& function_param_types,
2536 std::vector<clang::ParmVarDecl*>& function_param_decls,
2537 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002538{
2539 if (parent_die == NULL)
2540 return 0;
2541
Greg Claytond88d7592010-09-15 08:33:30 +00002542 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2543
Greg Clayton7fedea22010-11-16 02:10:54 +00002544 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002545 const DWARFDebugInfoEntry *die;
2546 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2547 {
2548 dw_tag_t tag = die->Tag();
2549 switch (tag)
2550 {
2551 case DW_TAG_formal_parameter:
2552 {
2553 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002554 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002555 if (num_attributes > 0)
2556 {
2557 const char *name = NULL;
2558 Declaration decl;
2559 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002560 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002561 // one of None, Auto, Register, Extern, Static, PrivateExtern
2562
Sean Callanane2ef6e32010-09-23 03:01:22 +00002563 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002564 uint32_t i;
2565 for (i=0; i<num_attributes; ++i)
2566 {
2567 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2568 DWARFFormValue form_value;
2569 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2570 {
2571 switch (attr)
2572 {
2573 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2574 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2575 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2576 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2577 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002578 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002579 case DW_AT_location:
2580 // if (form_value.BlockData())
2581 // {
2582 // const DataExtractor& debug_info_data = debug_info();
2583 // uint32_t block_length = form_value.Unsigned();
2584 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2585 // }
2586 // else
2587 // {
2588 // }
2589 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002590 case DW_AT_const_value:
2591 case DW_AT_default_value:
2592 case DW_AT_description:
2593 case DW_AT_endianity:
2594 case DW_AT_is_optional:
2595 case DW_AT_segment:
2596 case DW_AT_variable_parameter:
2597 default:
2598 case DW_AT_abstract_origin:
2599 case DW_AT_sibling:
2600 break;
2601 }
2602 }
2603 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002604
Greg Clayton0fffff52010-09-24 05:15:53 +00002605 bool skip = false;
2606 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002607 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002608 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002609 {
2610 // In order to determine if a C++ member function is
2611 // "const" we have to look at the const-ness of "this"...
2612 // Ugly, but that
2613 if (arg_idx == 0)
2614 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002615 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord)
Sean Callanan763d72a2011-08-02 22:21:50 +00002616 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002617 // Often times compilers omit the "this" name for the
2618 // specification DIEs, so we can't rely upon the name
2619 // being in the formal parameter DIE...
2620 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00002621 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002622 Type *this_type = ResolveTypeUID (param_type_die_offset);
2623 if (this_type)
2624 {
2625 uint32_t encoding_mask = this_type->GetEncodingMask();
2626 if (encoding_mask & Type::eEncodingIsPointerUID)
2627 {
2628 is_static = false;
2629
2630 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2631 type_quals |= clang::Qualifiers::Const;
2632 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2633 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002634 }
2635 }
2636 }
2637 }
2638 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002639 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002640 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002641 else
2642 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002643
Greg Clayton0fffff52010-09-24 05:15:53 +00002644 // HACK: Objective C formal parameters "self" and "_cmd"
2645 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002646 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2647 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002648 {
2649 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2650 skip = true;
2651 }
2652 }
2653 }
2654
2655 if (!skip)
2656 {
2657 Type *type = ResolveTypeUID(param_type_die_offset);
2658 if (type)
2659 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002660 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002661
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002662 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002663 assert(param_var_decl);
2664 function_param_decls.push_back(param_var_decl);
2665 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002666 }
2667 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002668 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002669 }
2670 break;
2671
2672 default:
2673 break;
2674 }
2675 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002676 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002677}
2678
2679size_t
2680SymbolFileDWARF::ParseChildEnumerators
2681(
2682 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002683 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002684 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002685 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002686 const DWARFDebugInfoEntry *parent_die
2687)
2688{
2689 if (parent_die == NULL)
2690 return 0;
2691
2692 size_t enumerators_added = 0;
2693 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002694 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2695
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002696 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2697 {
2698 const dw_tag_t tag = die->Tag();
2699 if (tag == DW_TAG_enumerator)
2700 {
2701 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002702 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002703 if (num_child_attributes > 0)
2704 {
2705 const char *name = NULL;
2706 bool got_value = false;
2707 int64_t enum_value = 0;
2708 Declaration decl;
2709
2710 uint32_t i;
2711 for (i=0; i<num_child_attributes; ++i)
2712 {
2713 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2714 DWARFFormValue form_value;
2715 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2716 {
2717 switch (attr)
2718 {
2719 case DW_AT_const_value:
2720 got_value = true;
2721 enum_value = form_value.Unsigned();
2722 break;
2723
2724 case DW_AT_name:
2725 name = form_value.AsCString(&get_debug_str_data());
2726 break;
2727
2728 case DW_AT_description:
2729 default:
2730 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2731 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2732 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2733 case DW_AT_sibling:
2734 break;
2735 }
2736 }
2737 }
2738
2739 if (name && name[0] && got_value)
2740 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002741 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2742 enumerator_clang_type,
2743 decl,
2744 name,
2745 enum_value,
2746 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002747 ++enumerators_added;
2748 }
2749 }
2750 }
2751 }
2752 return enumerators_added;
2753}
2754
2755void
2756SymbolFileDWARF::ParseChildArrayInfo
2757(
2758 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002759 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002760 const DWARFDebugInfoEntry *parent_die,
2761 int64_t& first_index,
2762 std::vector<uint64_t>& element_orders,
2763 uint32_t& byte_stride,
2764 uint32_t& bit_stride
2765)
2766{
2767 if (parent_die == NULL)
2768 return;
2769
2770 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002771 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002772 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2773 {
2774 const dw_tag_t tag = die->Tag();
2775 switch (tag)
2776 {
2777 case DW_TAG_enumerator:
2778 {
2779 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002780 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002781 if (num_child_attributes > 0)
2782 {
2783 const char *name = NULL;
2784 bool got_value = false;
2785 int64_t enum_value = 0;
2786
2787 uint32_t i;
2788 for (i=0; i<num_child_attributes; ++i)
2789 {
2790 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2791 DWARFFormValue form_value;
2792 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2793 {
2794 switch (attr)
2795 {
2796 case DW_AT_const_value:
2797 got_value = true;
2798 enum_value = form_value.Unsigned();
2799 break;
2800
2801 case DW_AT_name:
2802 name = form_value.AsCString(&get_debug_str_data());
2803 break;
2804
2805 case DW_AT_description:
2806 default:
2807 case DW_AT_decl_file:
2808 case DW_AT_decl_line:
2809 case DW_AT_decl_column:
2810 case DW_AT_sibling:
2811 break;
2812 }
2813 }
2814 }
2815 }
2816 }
2817 break;
2818
2819 case DW_TAG_subrange_type:
2820 {
2821 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002822 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002823 if (num_child_attributes > 0)
2824 {
2825 const char *name = NULL;
2826 bool got_value = false;
2827 uint64_t byte_size = 0;
2828 int64_t enum_value = 0;
2829 uint64_t num_elements = 0;
2830 uint64_t lower_bound = 0;
2831 uint64_t upper_bound = 0;
2832 uint32_t i;
2833 for (i=0; i<num_child_attributes; ++i)
2834 {
2835 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2836 DWARFFormValue form_value;
2837 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2838 {
2839 switch (attr)
2840 {
2841 case DW_AT_const_value:
2842 got_value = true;
2843 enum_value = form_value.Unsigned();
2844 break;
2845
2846 case DW_AT_name:
2847 name = form_value.AsCString(&get_debug_str_data());
2848 break;
2849
2850 case DW_AT_count:
2851 num_elements = form_value.Unsigned();
2852 break;
2853
2854 case DW_AT_bit_stride:
2855 bit_stride = form_value.Unsigned();
2856 break;
2857
2858 case DW_AT_byte_stride:
2859 byte_stride = form_value.Unsigned();
2860 break;
2861
2862 case DW_AT_byte_size:
2863 byte_size = form_value.Unsigned();
2864 break;
2865
2866 case DW_AT_lower_bound:
2867 lower_bound = form_value.Unsigned();
2868 break;
2869
2870 case DW_AT_upper_bound:
2871 upper_bound = form_value.Unsigned();
2872 break;
2873
2874 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002875 case DW_AT_abstract_origin:
2876 case DW_AT_accessibility:
2877 case DW_AT_allocated:
2878 case DW_AT_associated:
2879 case DW_AT_data_location:
2880 case DW_AT_declaration:
2881 case DW_AT_description:
2882 case DW_AT_sibling:
2883 case DW_AT_threads_scaled:
2884 case DW_AT_type:
2885 case DW_AT_visibility:
2886 break;
2887 }
2888 }
2889 }
2890
2891 if (upper_bound > lower_bound)
2892 num_elements = upper_bound - lower_bound + 1;
2893
2894 if (num_elements > 0)
2895 element_orders.push_back (num_elements);
2896 }
2897 }
2898 break;
2899 }
2900 }
2901}
2902
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002903TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002904SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002905{
2906 TypeSP type_sp;
2907 if (die != NULL)
2908 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002909 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002910 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002911 if (type_ptr == NULL)
2912 {
Greg Claytonca512b32011-01-14 04:54:56 +00002913 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2914 assert (lldb_cu);
2915 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002916 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002917 }
2918 else if (type_ptr != DIE_IS_BEING_PARSED)
2919 {
2920 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002921 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002922 }
2923
2924 }
2925 return type_sp;
2926}
2927
2928clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00002929SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002930{
2931 if (die_offset != DW_INVALID_OFFSET)
2932 {
2933 DWARFCompileUnitSP cu_sp;
2934 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Sean Callanan72e49402011-08-05 23:43:37 +00002935 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002936 }
2937 return NULL;
2938}
2939
Sean Callanan72e49402011-08-05 23:43:37 +00002940clang::DeclContext *
2941SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
2942{
2943 if (die_offset != DW_INVALID_OFFSET)
2944 {
2945 DWARFCompileUnitSP cu_sp;
2946 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2947 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
2948 }
2949 return NULL;
2950}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002951
Greg Clayton96d7d742010-11-10 23:42:09 +00002952clang::NamespaceDecl *
2953SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2954{
2955 if (die->Tag() == DW_TAG_namespace)
2956 {
2957 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2958 if (namespace_name)
2959 {
2960 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00002961 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent()));
Greg Clayton96d7d742010-11-10 23:42:09 +00002962 if (namespace_decl)
Greg Claytona2721472011-06-25 00:44:06 +00002963 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton96d7d742010-11-10 23:42:09 +00002964 return namespace_decl;
2965 }
2966 }
2967 return NULL;
2968}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002969
2970clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00002971SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2972{
2973 // If this DIE has a specification, or an abstract origin, then trace to those.
2974
2975 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
2976 if (die_offset != DW_INVALID_OFFSET)
2977 return GetClangDeclContextForDIEOffset (sc, die_offset);
2978
2979 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2980 if (die_offset != DW_INVALID_OFFSET)
2981 return GetClangDeclContextForDIEOffset (sc, die_offset);
2982
2983 // This is the DIE we want. Parse it, then query our map.
2984
2985 ParseType(sc, curr_cu, die, NULL);
2986
2987 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2988 if (pos != m_die_to_decl_ctx.end())
2989 return pos->second;
2990 else
2991 return NULL;
2992}
2993
2994clang::DeclContext *
2995SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002996{
Greg Claytonca512b32011-01-14 04:54:56 +00002997 if (m_clang_tu_decl == NULL)
2998 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002999
Sean Callanan72e49402011-08-05 23:43:37 +00003000 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x )\n", die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00003001 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton4cd17802011-01-25 06:17:32 +00003002 clang::DeclContext *decl_ctx = NULL;
3003
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003004 while (die != NULL)
3005 {
Greg Claytonca512b32011-01-14 04:54:56 +00003006 // If this is the original DIE that we are searching for a declaration
3007 // for, then don't look in the cache as we don't want our own decl
3008 // context to be our decl context...
3009 if (decl_die != die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003010 {
Greg Claytonca512b32011-01-14 04:54:56 +00003011 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
3012 if (pos != m_die_to_decl_ctx.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003013 {
Sean Callanan72e49402011-08-05 23:43:37 +00003014 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00003015 return pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003016 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003017
Sean Callanan72e49402011-08-05 23:43:37 +00003018 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00003019
3020 switch (die->Tag())
3021 {
3022 case DW_TAG_namespace:
3023 {
3024 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3025 if (namespace_name)
3026 {
3027 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00003028 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die));
Greg Claytonca512b32011-01-14 04:54:56 +00003029 if (namespace_decl)
3030 {
Sean Callanan72e49402011-08-05 23:43:37 +00003031 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytona2721472011-06-25 00:44:06 +00003032 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Claytonca512b32011-01-14 04:54:56 +00003033 }
3034 return namespace_decl;
3035 }
3036 }
3037 break;
3038
3039 case DW_TAG_structure_type:
3040 case DW_TAG_union_type:
3041 case DW_TAG_class_type:
3042 {
Greg Clayton4cd17802011-01-25 06:17:32 +00003043 Type* type = ResolveType (curr_cu, die);
Greg Claytonca512b32011-01-14 04:54:56 +00003044 pos = m_die_to_decl_ctx.find(die);
Greg Claytonca512b32011-01-14 04:54:56 +00003045 if (pos != m_die_to_decl_ctx.end())
3046 {
Sean Callanan72e49402011-08-05 23:43:37 +00003047 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00003048 return pos->second;
3049 }
Greg Clayton4cd17802011-01-25 06:17:32 +00003050 else
3051 {
3052 if (type)
3053 {
3054 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
Enrico Granata4a04dbc2011-08-12 18:43:16 +00003055 LinkDeclContextToDIE (decl_ctx, die);
Greg Clayton4cd17802011-01-25 06:17:32 +00003056 if (decl_ctx)
3057 return decl_ctx;
3058 }
3059 }
Greg Claytonca512b32011-01-14 04:54:56 +00003060 }
3061 break;
3062
3063 default:
3064 break;
3065 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003066 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003067
Greg Clayton6beaaa62011-01-17 03:46:26 +00003068 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00003069 if (die_offset != DW_INVALID_OFFSET)
3070 {
Sean Callanan72e49402011-08-05 23:43:37 +00003071 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
3072 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Claytonca512b32011-01-14 04:54:56 +00003073 if (decl_ctx != m_clang_tu_decl)
3074 return decl_ctx;
3075 }
3076
Greg Clayton6beaaa62011-01-17 03:46:26 +00003077 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00003078 if (die_offset != DW_INVALID_OFFSET)
3079 {
Sean Callanan72e49402011-08-05 23:43:37 +00003080 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
3081 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Claytonca512b32011-01-14 04:54:56 +00003082 if (decl_ctx != m_clang_tu_decl)
3083 return decl_ctx;
3084 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003085
3086 die = die->GetParent();
3087 }
Greg Clayton7a345282010-11-09 23:46:37 +00003088 // Right now we have only one translation unit per module...
Sean Callanan72e49402011-08-05 23:43:37 +00003089 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Clayton7a345282010-11-09 23:46:37 +00003090 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003091}
3092
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003093// This function can be used when a DIE is found that is a forward declaration
3094// DIE and we want to try and find a type that has the complete definition.
3095TypeSP
3096SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton1a65ae12011-01-25 23:55:37 +00003097 DWARFCompileUnit* cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003098 const DWARFDebugInfoEntry *die,
3099 const ConstString &type_name
3100)
3101{
3102 TypeSP type_sp;
3103
Greg Clayton1a65ae12011-01-25 23:55:37 +00003104 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003105 return type_sp;
3106
Greg Clayton69974892010-12-03 21:42:06 +00003107 if (!m_indexed)
3108 Index ();
3109
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003110 const dw_tag_t type_tag = die->Tag();
3111 std::vector<NameToDIE::Info> die_info_array;
3112 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
3113 if (num_matches > 0)
3114 {
3115 DWARFCompileUnit* type_cu = NULL;
Greg Clayton1a65ae12011-01-25 23:55:37 +00003116 DWARFCompileUnit* curr_cu = cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003117 DWARFDebugInfo *info = DebugInfo();
3118 for (size_t i=0; i<num_matches; ++i)
3119 {
3120 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
3121
3122 if (type_cu != curr_cu)
3123 {
3124 type_cu->ExtractDIEsIfNeeded (false);
3125 curr_cu = type_cu;
3126 }
3127
3128 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
3129
3130 if (type_die != die && type_die->Tag() == type_tag)
3131 {
3132 // Hold off on comparing parent DIE tags until
3133 // we know what happens with stuff in namespaces
3134 // for gcc and clang...
3135 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3136 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3137 //if (parent_die->Tag() == parent_type_die->Tag())
3138 {
3139 Type *resolved_type = ResolveType (type_cu, type_die, false);
3140 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3141 {
3142 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
3143 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00003144 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003145 m_obj_file->GetFileSpec().GetFilename().AsCString(),
3146 type_die->GetOffset(),
3147 type_cu->GetOffset());
3148
3149 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003150 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00003151 if (!type_sp)
3152 {
3153 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
3154 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003155 break;
3156 }
3157 }
3158 }
3159 }
3160 }
3161 return type_sp;
3162}
3163
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003164TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003165SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003166{
3167 TypeSP type_sp;
3168
Greg Clayton1be10fc2010-09-29 01:12:09 +00003169 if (type_is_new_ptr)
3170 *type_is_new_ptr = false;
3171
Sean Callananc7fbf732010-08-06 00:32:49 +00003172 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003173 if (die != NULL)
3174 {
Jim Ingham16746d12011-08-25 23:21:43 +00003175 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3176 if (log && dwarf_cu)
3177 {
Jim Ingham318c9f22011-08-26 19:44:13 +00003178 StreamString s;
Jim Inghamd3d25d92011-08-27 01:24:54 +00003179 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham318c9f22011-08-26 19:44:13 +00003180 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3181
Jim Ingham16746d12011-08-25 23:21:43 +00003182 }
3183
Greg Clayton594e5ed2010-09-27 21:07:38 +00003184 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003185 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003186 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003187 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003188 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003189 if (type_is_new_ptr)
3190 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003191
Greg Clayton594e5ed2010-09-27 21:07:38 +00003192 const dw_tag_t tag = die->Tag();
3193
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003194 bool is_forward_declaration = false;
3195 DWARFDebugInfoEntry::Attributes attributes;
3196 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003197 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003198 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3199 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003200 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003201 Declaration decl;
3202
Greg Clayton4957bf62010-09-30 21:49:03 +00003203 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003204 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003205
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003206 dw_attr_t attr;
3207
3208 switch (tag)
3209 {
3210 case DW_TAG_base_type:
3211 case DW_TAG_pointer_type:
3212 case DW_TAG_reference_type:
3213 case DW_TAG_typedef:
3214 case DW_TAG_const_type:
3215 case DW_TAG_restrict_type:
3216 case DW_TAG_volatile_type:
3217 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003218 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003219 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003220
Greg Claytond88d7592010-09-15 08:33:30 +00003221 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003222 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3224
3225 if (num_attributes > 0)
3226 {
3227 uint32_t i;
3228 for (i=0; i<num_attributes; ++i)
3229 {
3230 attr = attributes.AttributeAtIndex(i);
3231 DWARFFormValue form_value;
3232 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3233 {
3234 switch (attr)
3235 {
3236 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3237 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3238 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3239 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003240
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003241 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003242 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3243 // include the "&"...
3244 if (tag == DW_TAG_reference_type)
3245 {
3246 if (strchr (type_name_cstr, '&') == NULL)
3247 type_name_cstr = NULL;
3248 }
3249 if (type_name_cstr)
3250 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003251 break;
Greg Clayton36909642011-03-15 04:38:20 +00003252 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003253 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3254 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3255 default:
3256 case DW_AT_sibling:
3257 break;
3258 }
3259 }
3260 }
3261 }
3262
Greg Claytonc93237c2010-10-01 20:48:32 +00003263 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);
3264
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 switch (tag)
3266 {
3267 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003268 break;
3269
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003270 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003271 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003272 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3273 encoding,
3274 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003275 break;
3276
Greg Clayton526e5af2010-11-13 03:52:47 +00003277 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3278 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3279 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3280 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3281 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3282 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003283 }
3284
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003285 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3286 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3287 {
3288 static ConstString g_objc_type_name_id("id");
3289 static ConstString g_objc_type_name_Class("Class");
3290 static ConstString g_objc_type_name_selector("SEL");
3291
Greg Clayton24739922010-10-13 03:15:28 +00003292 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003293 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003294 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003295 resolve_state = Type::eResolveStateFull;
3296
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003297 }
Greg Clayton24739922010-10-13 03:15:28 +00003298 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003299 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003300 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003301 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003302 }
Greg Clayton24739922010-10-13 03:15:28 +00003303 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003304 {
Sean Callananf6c73082010-12-06 23:53:20 +00003305 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003306 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003307 }
3308 }
3309
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003310 type_sp.reset( new Type (die->GetOffset(),
3311 this,
3312 type_name_const_str,
3313 byte_size,
3314 NULL,
3315 encoding_uid,
3316 encoding_data_type,
3317 &decl,
3318 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003319 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003320
Greg Clayton594e5ed2010-09-27 21:07:38 +00003321 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003322
3323// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3324// if (encoding_type != NULL)
3325// {
3326// if (encoding_type != DIE_IS_BEING_PARSED)
3327// type_sp->SetEncodingType(encoding_type);
3328// else
3329// m_indirect_fixups.push_back(type_sp.get());
3330// }
3331 }
3332 break;
3333
3334 case DW_TAG_structure_type:
3335 case DW_TAG_union_type:
3336 case DW_TAG_class_type:
3337 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003338 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003339 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003340
Greg Clayton9e409562010-07-28 02:04:09 +00003341 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003342 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003343 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003344 if (num_attributes > 0)
3345 {
3346 uint32_t i;
3347 for (i=0; i<num_attributes; ++i)
3348 {
3349 attr = attributes.AttributeAtIndex(i);
3350 DWARFFormValue form_value;
3351 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3352 {
3353 switch (attr)
3354 {
Greg Clayton9e409562010-07-28 02:04:09 +00003355 case DW_AT_decl_file:
3356 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3357 break;
3358
3359 case DW_AT_decl_line:
3360 decl.SetLine(form_value.Unsigned());
3361 break;
3362
3363 case DW_AT_decl_column:
3364 decl.SetColumn(form_value.Unsigned());
3365 break;
3366
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003367 case DW_AT_name:
3368 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003369 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003370 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003371
3372 case DW_AT_byte_size:
3373 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003374 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003375 break;
3376
3377 case DW_AT_accessibility:
3378 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3379 break;
3380
3381 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003382 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003383 break;
3384
3385 case DW_AT_APPLE_runtime_class:
3386 class_language = (LanguageType)form_value.Signed();
3387 break;
3388
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003389 case DW_AT_allocated:
3390 case DW_AT_associated:
3391 case DW_AT_data_location:
3392 case DW_AT_description:
3393 case DW_AT_start_scope:
3394 case DW_AT_visibility:
3395 default:
3396 case DW_AT_sibling:
3397 break;
3398 }
3399 }
3400 }
3401 }
3402
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003403 UniqueDWARFASTType unique_ast_entry;
3404 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003405 {
Greg Claytone576ab22011-02-15 00:19:15 +00003406 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003407 this,
3408 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003409 die,
3410 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003411 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003412 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003413 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003414 // We have already parsed this type or from another
3415 // compile unit. GCC loves to use the "one definition
3416 // rule" which can result in multiple definitions
3417 // of the same class over and over in each compile
3418 // unit.
3419 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003420 if (type_sp)
3421 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003422 m_die_to_type[die] = type_sp.get();
3423 return type_sp;
3424 }
3425 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003426 }
3427
3428 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3429
3430 int tag_decl_kind = -1;
3431 AccessType default_accessibility = eAccessNone;
3432 if (tag == DW_TAG_structure_type)
3433 {
3434 tag_decl_kind = clang::TTK_Struct;
3435 default_accessibility = eAccessPublic;
3436 }
3437 else if (tag == DW_TAG_union_type)
3438 {
3439 tag_decl_kind = clang::TTK_Union;
3440 default_accessibility = eAccessPublic;
3441 }
3442 else if (tag == DW_TAG_class_type)
3443 {
3444 tag_decl_kind = clang::TTK_Class;
3445 default_accessibility = eAccessPrivate;
3446 }
3447
3448
3449 if (is_forward_declaration)
3450 {
3451 // We have a forward declaration to a type and we need
3452 // to try and find a full declaration. We look in the
3453 // current type index just in case we have a forward
3454 // declaration followed by an actual declarations in the
3455 // DWARF. If this fails, we need to look elsewhere...
3456
3457 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3458
3459 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003460 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003461 // We weren't able to find a full declaration in
3462 // this DWARF, see if we have a declaration anywhere
3463 // else...
3464 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003465 }
3466
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003467 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003468 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003469 // We found a real definition for this type elsewhere
3470 // so lets use it and cache the fact that we found
3471 // a complete type for this die
3472 m_die_to_type[die] = type_sp.get();
3473 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003474 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003475 }
3476 assert (tag_decl_kind != -1);
3477 bool clang_type_was_created = false;
3478 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3479 if (clang_type == NULL)
3480 {
3481 clang_type_was_created = true;
3482 clang_type = ast.CreateRecordType (type_name_cstr,
3483 tag_decl_kind,
Sean Callanan72e49402011-08-05 23:43:37 +00003484 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003485 class_language);
3486 }
3487
3488 // Store a forward declaration to this class type in case any
3489 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00003490 // types for function prototypes.
3491 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003492 type_sp.reset (new Type (die->GetOffset(),
3493 this,
3494 type_name_const_str,
3495 byte_size,
3496 NULL,
3497 LLDB_INVALID_UID,
3498 Type::eEncodingIsUID,
3499 &decl,
3500 clang_type,
3501 Type::eResolveStateForward));
3502
3503
3504 // Add our type to the unique type map so we don't
3505 // end up creating many copies of the same type over
3506 // and over in the ASTContext for our module
3507 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00003508 unique_ast_entry.m_symfile = this;
3509 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003510 unique_ast_entry.m_die = die;
3511 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00003512 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3513 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003514
3515 if (die->HasChildren() == false && is_forward_declaration == false)
3516 {
3517 // No children for this struct/union/class, lets finish it
3518 ast.StartTagDeclarationDefinition (clang_type);
3519 ast.CompleteTagDeclarationDefinition (clang_type);
3520 }
3521 else if (clang_type_was_created)
3522 {
3523 // Leave this as a forward declaration until we need
3524 // to know the details of the type. lldb_private::Type
3525 // will automatically call the SymbolFile virtual function
3526 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3527 // When the definition needs to be defined.
3528 m_forward_decl_die_to_clang_type[die] = clang_type;
3529 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3530 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003531 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003532 }
3533 break;
3534
3535 case DW_TAG_enumeration_type:
3536 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003537 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003538 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003539
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003540 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003541
Greg Claytond88d7592010-09-15 08:33:30 +00003542 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003543 if (num_attributes > 0)
3544 {
3545 uint32_t i;
3546
3547 for (i=0; i<num_attributes; ++i)
3548 {
3549 attr = attributes.AttributeAtIndex(i);
3550 DWARFFormValue form_value;
3551 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3552 {
3553 switch (attr)
3554 {
Greg Clayton7a345282010-11-09 23:46:37 +00003555 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3556 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3557 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003558 case DW_AT_name:
3559 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003560 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003561 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003562 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003563 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00003564 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3565 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003566 case DW_AT_allocated:
3567 case DW_AT_associated:
3568 case DW_AT_bit_stride:
3569 case DW_AT_byte_stride:
3570 case DW_AT_data_location:
3571 case DW_AT_description:
3572 case DW_AT_start_scope:
3573 case DW_AT_visibility:
3574 case DW_AT_specification:
3575 case DW_AT_abstract_origin:
3576 case DW_AT_sibling:
3577 break;
3578 }
3579 }
3580 }
3581
Greg Claytonc93237c2010-10-01 20:48:32 +00003582 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3583
Greg Clayton1be10fc2010-09-29 01:12:09 +00003584 clang_type_t enumerator_clang_type = NULL;
3585 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3586 if (clang_type == NULL)
3587 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003588 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3589 DW_ATE_signed,
3590 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003591 clang_type = ast.CreateEnumerationType (type_name_cstr,
Sean Callanan72e49402011-08-05 23:43:37 +00003592 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003593 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003594 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003595 }
3596 else
3597 {
3598 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3599 assert (enumerator_clang_type != NULL);
3600 }
3601
Greg Claytona2721472011-06-25 00:44:06 +00003602 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3603
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003604 type_sp.reset( new Type (die->GetOffset(),
3605 this,
3606 type_name_const_str,
3607 byte_size,
3608 NULL,
3609 encoding_uid,
3610 Type::eEncodingIsUID,
3611 &decl,
3612 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003613 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614
Greg Clayton6beaaa62011-01-17 03:46:26 +00003615#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003616 // Leave this as a forward declaration until we need
3617 // to know the details of the type. lldb_private::Type
3618 // will automatically call the SymbolFile virtual function
3619 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3620 // When the definition needs to be defined.
3621 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003622 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003623 ClangASTContext::SetHasExternalStorage (clang_type, true);
3624#else
3625 ast.StartTagDeclarationDefinition (clang_type);
3626 if (die->HasChildren())
3627 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003628 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3629 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003630 }
3631 ast.CompleteTagDeclarationDefinition (clang_type);
3632#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003633 }
3634 }
3635 break;
3636
Jim Inghamb0be4422010-08-12 01:20:14 +00003637 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003638 case DW_TAG_subprogram:
3639 case DW_TAG_subroutine_type:
3640 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003641 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003642 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003643
3644 const char *mangled = NULL;
3645 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003646 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003647 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003648 bool is_static = false;
3649 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003650 bool is_explicit = false;
Greg Clayton72da3972011-08-16 18:40:23 +00003651 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
3652 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00003653
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003654 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003655 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003656
3657
Greg Claytond88d7592010-09-15 08:33:30 +00003658 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003659 if (num_attributes > 0)
3660 {
3661 uint32_t i;
3662 for (i=0; i<num_attributes; ++i)
3663 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003664 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003665 DWARFFormValue form_value;
3666 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3667 {
3668 switch (attr)
3669 {
3670 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3671 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3672 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3673 case DW_AT_name:
3674 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003675 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003676 break;
3677
3678 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3679 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003680 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003681 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003682 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3683 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003684 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3685
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003686 case DW_AT_external:
3687 if (form_value.Unsigned())
3688 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003689 if (storage == clang::SC_None)
3690 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003691 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003692 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003693 }
3694 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003695
Greg Clayton72da3972011-08-16 18:40:23 +00003696 case DW_AT_specification:
3697 specification_die_offset = form_value.Reference(dwarf_cu);
3698 break;
3699
3700 case DW_AT_abstract_origin:
3701 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
3702 break;
3703
3704
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003705 case DW_AT_allocated:
3706 case DW_AT_associated:
3707 case DW_AT_address_class:
3708 case DW_AT_artificial:
3709 case DW_AT_calling_convention:
3710 case DW_AT_data_location:
3711 case DW_AT_elemental:
3712 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003713 case DW_AT_frame_base:
3714 case DW_AT_high_pc:
3715 case DW_AT_low_pc:
3716 case DW_AT_object_pointer:
3717 case DW_AT_prototyped:
3718 case DW_AT_pure:
3719 case DW_AT_ranges:
3720 case DW_AT_recursive:
3721 case DW_AT_return_addr:
3722 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003723 case DW_AT_start_scope:
3724 case DW_AT_static_link:
3725 case DW_AT_trampoline:
3726 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003727 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003728 case DW_AT_description:
3729 case DW_AT_sibling:
3730 break;
3731 }
3732 }
3733 }
Greg Clayton24739922010-10-13 03:15:28 +00003734 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003735
Greg Clayton24739922010-10-13 03:15:28 +00003736 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 +00003737
Greg Clayton24739922010-10-13 03:15:28 +00003738 clang_type_t return_clang_type = NULL;
3739 Type *func_type = NULL;
3740
3741 if (type_die_offset != DW_INVALID_OFFSET)
3742 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003743
Greg Clayton24739922010-10-13 03:15:28 +00003744 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003745 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003746 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003747 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003748
Greg Claytonf51de672010-10-01 02:31:07 +00003749
Greg Clayton24739922010-10-13 03:15:28 +00003750 std::vector<clang_type_t> function_param_types;
3751 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003752
Greg Clayton24739922010-10-13 03:15:28 +00003753 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00003754
Greg Clayton5113dc82011-08-12 06:47:54 +00003755 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
3756 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
3757
3758 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord;
3759 // Start off static. This will be set to false in ParseChildParameters(...)
3760 // if we find a "this" paramters as the first parameter
3761 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00003762 is_static = true;
3763
Greg Clayton24739922010-10-13 03:15:28 +00003764 if (die->HasChildren())
3765 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003766 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003767 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00003768 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003769 type_sp,
3770 dwarf_cu,
3771 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00003772 skip_artificial,
3773 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003774 type_list,
3775 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003776 function_param_decls,
3777 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003778 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003779
Greg Clayton24739922010-10-13 03:15:28 +00003780 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003781 clang_type = ast.CreateFunctionType (return_clang_type,
3782 &function_param_types[0],
3783 function_param_types.size(),
3784 is_variadic,
3785 type_quals);
3786
Greg Clayton24739922010-10-13 03:15:28 +00003787 if (type_name_cstr)
3788 {
3789 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00003790 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003791 {
Greg Clayton24739922010-10-13 03:15:28 +00003792 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003793 {
Greg Clayton24739922010-10-13 03:15:28 +00003794 // We need to find the DW_TAG_class_type or
3795 // DW_TAG_struct_type by name so we can add this
3796 // as a member function of the class.
3797 const char *class_name_start = type_name_cstr + 2;
3798 const char *class_name_end = ::strchr (class_name_start, ' ');
3799 SymbolContext empty_sc;
3800 clang_type_t class_opaque_type = NULL;
3801 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003802 {
Greg Clayton24739922010-10-13 03:15:28 +00003803 ConstString class_name (class_name_start, class_name_end - class_name_start);
3804 TypeList types;
3805 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3806 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003807 {
Greg Clayton24739922010-10-13 03:15:28 +00003808 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003809 {
Greg Clayton24739922010-10-13 03:15:28 +00003810 Type *type = types.GetTypeAtIndex (i).get();
3811 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3812 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003813 {
Greg Clayton24739922010-10-13 03:15:28 +00003814 class_opaque_type = type_clang_forward_type;
3815 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003816 }
3817 }
3818 }
Greg Clayton24739922010-10-13 03:15:28 +00003819 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003820
Greg Clayton24739922010-10-13 03:15:28 +00003821 if (class_opaque_type)
3822 {
3823 // If accessibility isn't set to anything valid, assume public for
3824 // now...
3825 if (accessibility == eAccessNone)
3826 accessibility = eAccessPublic;
3827
3828 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003829 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3830 type_name_cstr,
3831 clang_type,
3832 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00003833 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00003834 type_handled = objc_method_decl != NULL;
3835 }
3836 }
Greg Clayton5113dc82011-08-12 06:47:54 +00003837 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00003838 {
3839 // Look at the parent of this DIE and see if is is
3840 // a class or struct and see if this is actually a
3841 // C++ method
Greg Clayton5113dc82011-08-12 06:47:54 +00003842 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
Greg Clayton24739922010-10-13 03:15:28 +00003843 if (class_type)
3844 {
Greg Clayton72da3972011-08-16 18:40:23 +00003845 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00003846 {
Greg Clayton72da3972011-08-16 18:40:23 +00003847 // If we have a specification, then the function type should have been
3848 // made with the specification and not with this die.
3849 DWARFCompileUnitSP spec_cu_sp;
3850 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
3851 if (m_die_to_decl_ctx[spec_die] == NULL)
3852 fprintf (stderr,"warning: 0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n", die->GetOffset(), specification_die_offset);
3853 type_handled = true;
3854 }
3855 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
3856 {
3857 DWARFCompileUnitSP abs_cu_sp;
3858 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
3859 if (m_die_to_decl_ctx[abs_die] == NULL)
3860 fprintf (stderr,"warning: 0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n", die->GetOffset(), abstract_origin_die_offset);
3861 type_handled = true;
3862 }
3863 else
3864 {
3865 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3866 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton931180e2011-01-27 06:44:37 +00003867 {
Greg Clayton72da3972011-08-16 18:40:23 +00003868 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3869 // in the DWARF for C++ methods... Default to public for now...
3870 if (accessibility == eAccessNone)
3871 accessibility = eAccessPublic;
3872
3873 if (!is_static && !die->HasChildren())
3874 {
3875 // We have a C++ member function with no children (this pointer!)
3876 // and clang will get mad if we try and make a function that isn't
3877 // well formed in the DWARF, so we will just skip it...
3878 type_handled = true;
3879 }
3880 else
3881 {
3882 clang::CXXMethodDecl *cxx_method_decl;
3883 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3884 type_name_cstr,
3885 clang_type,
3886 accessibility,
3887 is_virtual,
3888 is_static,
3889 is_inline,
3890 is_explicit);
3891 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00003892
Greg Clayton72da3972011-08-16 18:40:23 +00003893 type_handled = cxx_method_decl != NULL;
3894 }
Greg Clayton931180e2011-01-27 06:44:37 +00003895 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003896 }
3897 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003898 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003899 }
Greg Clayton24739922010-10-13 03:15:28 +00003900
3901 if (!type_handled)
3902 {
3903 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003904 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3905 clang_type,
3906 storage,
3907 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003908
3909 // Add the decl to our DIE to decl context map
3910 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00003911 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00003912 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003913 ast.SetFunctionParameters (function_decl,
3914 &function_param_decls.front(),
3915 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003916 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003917 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003918 type_sp.reset( new Type (die->GetOffset(),
3919 this,
3920 type_name_const_str,
3921 0,
3922 NULL,
3923 LLDB_INVALID_UID,
3924 Type::eEncodingIsUID,
3925 &decl,
3926 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003927 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00003928 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003929 }
3930 break;
3931
3932 case DW_TAG_array_type:
3933 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003934 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003935 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003936
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003937 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003938 int64_t first_index = 0;
3939 uint32_t byte_stride = 0;
3940 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003941 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003942
3943 if (num_attributes > 0)
3944 {
3945 uint32_t i;
3946 for (i=0; i<num_attributes; ++i)
3947 {
3948 attr = attributes.AttributeAtIndex(i);
3949 DWARFFormValue form_value;
3950 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3951 {
3952 switch (attr)
3953 {
3954 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3955 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3956 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3957 case DW_AT_name:
3958 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003959 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 break;
3961
3962 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003963 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003964 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3965 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003966 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003967 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003968 case DW_AT_allocated:
3969 case DW_AT_associated:
3970 case DW_AT_data_location:
3971 case DW_AT_description:
3972 case DW_AT_ordering:
3973 case DW_AT_start_scope:
3974 case DW_AT_visibility:
3975 case DW_AT_specification:
3976 case DW_AT_abstract_origin:
3977 case DW_AT_sibling:
3978 break;
3979 }
3980 }
3981 }
3982
Greg Claytonc93237c2010-10-01 20:48:32 +00003983 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3984
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003985 Type *element_type = ResolveTypeUID(type_die_offset);
3986
3987 if (element_type)
3988 {
3989 std::vector<uint64_t> element_orders;
3990 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003991 // We have an array that claims to have no members, lets give it at least one member...
3992 if (element_orders.empty())
3993 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003994 if (byte_stride == 0 && bit_stride == 0)
3995 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00003996 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003997 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3998 uint64_t num_elements = 0;
3999 std::vector<uint64_t>::const_reverse_iterator pos;
4000 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
4001 for (pos = element_orders.rbegin(); pos != end; ++pos)
4002 {
4003 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004004 clang_type = ast.CreateArrayType (array_element_type,
4005 num_elements,
4006 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004007 array_element_type = clang_type;
4008 array_element_bit_stride = array_element_bit_stride * num_elements;
4009 }
4010 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004011 type_sp.reset( new Type (die->GetOffset(),
4012 this,
4013 empty_name,
4014 array_element_bit_stride / 8,
4015 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00004016 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004017 Type::eEncodingIsUID,
4018 &decl,
4019 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004020 Type::eResolveStateFull));
4021 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004022 }
4023 }
4024 }
4025 break;
4026
Greg Clayton9b81a312010-06-12 01:20:30 +00004027 case DW_TAG_ptr_to_member_type:
4028 {
4029 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
4030 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
4031
Greg Claytond88d7592010-09-15 08:33:30 +00004032 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00004033
4034 if (num_attributes > 0) {
4035 uint32_t i;
4036 for (i=0; i<num_attributes; ++i)
4037 {
4038 attr = attributes.AttributeAtIndex(i);
4039 DWARFFormValue form_value;
4040 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4041 {
4042 switch (attr)
4043 {
4044 case DW_AT_type:
4045 type_die_offset = form_value.Reference(dwarf_cu); break;
4046 case DW_AT_containing_type:
4047 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4048 }
4049 }
4050 }
4051
4052 Type *pointee_type = ResolveTypeUID(type_die_offset);
4053 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4054
Greg Clayton526e5af2010-11-13 03:52:47 +00004055 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4056 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00004057
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004058 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4059 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00004060
Greg Clayton526e5af2010-11-13 03:52:47 +00004061 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4062 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00004063
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004064 type_sp.reset( new Type (die->GetOffset(),
4065 this,
4066 type_name_const_str,
4067 byte_size,
4068 NULL,
4069 LLDB_INVALID_UID,
4070 Type::eEncodingIsUID,
4071 NULL,
4072 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004073 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00004074 }
4075
4076 break;
4077 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004078 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00004079 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004080 break;
4081 }
4082
4083 if (type_sp.get())
4084 {
4085 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4086 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4087
4088 SymbolContextScope * symbol_context_scope = NULL;
4089 if (sc_parent_tag == DW_TAG_compile_unit)
4090 {
4091 symbol_context_scope = sc.comp_unit;
4092 }
4093 else if (sc.function != NULL)
4094 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004095 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004096 if (symbol_context_scope == NULL)
4097 symbol_context_scope = sc.function;
4098 }
4099
4100 if (symbol_context_scope != NULL)
4101 {
4102 type_sp->SetSymbolContextScope(symbol_context_scope);
4103 }
4104
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004105 // We are ready to put this type into the uniqued list up at the module level
4106 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00004107
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004108 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004109 }
4110 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00004111 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004112 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004113 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004114 }
4115 }
4116 return type_sp;
4117}
4118
4119size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004120SymbolFileDWARF::ParseTypes
4121(
4122 const SymbolContext& sc,
4123 DWARFCompileUnit* dwarf_cu,
4124 const DWARFDebugInfoEntry *die,
4125 bool parse_siblings,
4126 bool parse_children
4127)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004128{
4129 size_t types_added = 0;
4130 while (die != NULL)
4131 {
4132 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00004133 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004134 {
4135 if (type_is_new)
4136 ++types_added;
4137 }
4138
4139 if (parse_children && die->HasChildren())
4140 {
4141 if (die->Tag() == DW_TAG_subprogram)
4142 {
4143 SymbolContext child_sc(sc);
4144 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
4145 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4146 }
4147 else
4148 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4149 }
4150
4151 if (parse_siblings)
4152 die = die->GetSibling();
4153 else
4154 die = NULL;
4155 }
4156 return types_added;
4157}
4158
4159
4160size_t
4161SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4162{
4163 assert(sc.comp_unit && sc.function);
4164 size_t functions_added = 0;
4165 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4166 if (dwarf_cu)
4167 {
4168 dw_offset_t function_die_offset = sc.function->GetID();
4169 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4170 if (function_die)
4171 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00004172 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004173 }
4174 }
4175
4176 return functions_added;
4177}
4178
4179
4180size_t
4181SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4182{
4183 // At least a compile unit must be valid
4184 assert(sc.comp_unit);
4185 size_t types_added = 0;
4186 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4187 if (dwarf_cu)
4188 {
4189 if (sc.function)
4190 {
4191 dw_offset_t function_die_offset = sc.function->GetID();
4192 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4193 if (func_die && func_die->HasChildren())
4194 {
4195 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4196 }
4197 }
4198 else
4199 {
4200 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4201 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4202 {
4203 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4204 }
4205 }
4206 }
4207
4208 return types_added;
4209}
4210
4211size_t
4212SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4213{
4214 if (sc.comp_unit != NULL)
4215 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004216 DWARFDebugInfo* info = DebugInfo();
4217 if (info == NULL)
4218 return 0;
4219
4220 uint32_t cu_idx = UINT32_MAX;
4221 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004222
4223 if (dwarf_cu == NULL)
4224 return 0;
4225
4226 if (sc.function)
4227 {
4228 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004229
4230 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4231 assert (func_lo_pc != DW_INVALID_ADDRESS);
4232
Greg Claytonc662ec82011-06-17 22:10:16 +00004233 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4234
4235 // Let all blocks know they have parse all their variables
4236 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4237
4238 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004239 }
4240 else if (sc.comp_unit)
4241 {
4242 uint32_t vars_added = 0;
4243 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4244
4245 if (variables.get() == NULL)
4246 {
4247 variables.reset(new VariableList());
4248 sc.comp_unit->SetVariableList(variables);
4249
4250 // Index if we already haven't to make sure the compile units
4251 // get indexed and make their global DIE index list
4252 if (!m_indexed)
4253 Index ();
4254
Greg Claytonc685f8e2010-09-15 04:15:46 +00004255 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00004256 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004257 for (size_t idx=0; idx<num_globals; ++idx)
4258 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00004259 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 +00004260 if (var_sp)
4261 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004262 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004263 ++vars_added;
4264 }
4265 }
4266 }
4267 return vars_added;
4268 }
4269 }
4270 return 0;
4271}
4272
4273
4274VariableSP
4275SymbolFileDWARF::ParseVariableDIE
4276(
4277 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004278 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004279 const DWARFDebugInfoEntry *die,
4280 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004281)
4282{
4283
Greg Clayton83c5cd92010-11-14 22:13:40 +00004284 VariableSP var_sp (m_die_to_variable_sp[die]);
4285 if (var_sp)
4286 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004287
4288 const dw_tag_t tag = die->Tag();
4289 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004290 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004291 if (num_attributes > 0)
4292 {
4293 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00004294 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004295 Declaration decl;
4296 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004297 Type *var_type = NULL;
4298 DWARFExpression location;
4299 bool is_external = false;
4300 bool is_artificial = false;
Greg Clayton007d5be2011-05-30 00:49:24 +00004301 bool location_is_const_value_data = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00004302 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004303
4304 for (i=0; i<num_attributes; ++i)
4305 {
4306 dw_attr_t attr = attributes.AttributeAtIndex(i);
4307 DWARFFormValue form_value;
4308 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4309 {
4310 switch (attr)
4311 {
4312 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4313 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4314 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4315 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00004316 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00004317 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004318 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
Greg Clayton007d5be2011-05-30 00:49:24 +00004319 case DW_AT_const_value:
4320 location_is_const_value_data = true;
4321 // Fall through...
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004322 case DW_AT_location:
4323 {
4324 if (form_value.BlockData())
4325 {
4326 const DataExtractor& debug_info_data = get_debug_info_data();
4327
4328 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4329 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00004330 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004331 }
4332 else
4333 {
4334 const DataExtractor& debug_loc_data = get_debug_loc_data();
4335 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4336
4337 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4338 if (loc_list_length > 0)
4339 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004340 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4341 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4342 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004343 }
4344 }
4345 }
4346 break;
4347
4348 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004349 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004350 case DW_AT_declaration:
4351 case DW_AT_description:
4352 case DW_AT_endianity:
4353 case DW_AT_segment:
4354 case DW_AT_start_scope:
4355 case DW_AT_visibility:
4356 default:
4357 case DW_AT_abstract_origin:
4358 case DW_AT_sibling:
4359 case DW_AT_specification:
4360 break;
4361 }
4362 }
4363 }
4364
4365 if (location.IsValid())
4366 {
4367 assert(var_type != DIE_IS_BEING_PARSED);
4368
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004369 ValueType scope = eValueTypeInvalid;
4370
4371 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4372 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4373
4374 if (tag == DW_TAG_formal_parameter)
4375 scope = eValueTypeVariableArgument;
4376 else if (is_external || parent_tag == DW_TAG_compile_unit)
4377 scope = eValueTypeVariableGlobal;
4378 else
4379 scope = eValueTypeVariableLocal;
4380
4381 SymbolContextScope * symbol_context_scope = NULL;
4382 if (parent_tag == DW_TAG_compile_unit)
4383 {
4384 symbol_context_scope = sc.comp_unit;
4385 }
4386 else if (sc.function != NULL)
4387 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004388 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004389 if (symbol_context_scope == NULL)
4390 symbol_context_scope = sc.function;
4391 }
4392
4393 assert(symbol_context_scope != NULL);
4394 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00004395 name,
4396 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004397 var_type,
4398 scope,
4399 symbol_context_scope,
4400 &decl,
4401 location,
4402 is_external,
4403 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00004404
Greg Clayton007d5be2011-05-30 00:49:24 +00004405 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004406 }
4407 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00004408 // Cache var_sp even if NULL (the variable was just a specification or
4409 // was missing vital information to be able to be displayed in the debugger
4410 // (missing location due to optimization, etc)) so we don't re-parse
4411 // this DIE over and over later...
4412 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004413 return var_sp;
4414}
4415
Greg Claytonc662ec82011-06-17 22:10:16 +00004416
4417const DWARFDebugInfoEntry *
4418SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4419 dw_offset_t spec_block_die_offset,
4420 DWARFCompileUnit **result_die_cu_handle)
4421{
4422 // Give the concrete function die specified by "func_die_offset", find the
4423 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4424 // to "spec_block_die_offset"
4425 DWARFDebugInfo* info = DebugInfo();
4426
4427 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4428 if (die)
4429 {
4430 assert (*result_die_cu_handle);
4431 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4432 }
4433 return NULL;
4434}
4435
4436
4437const DWARFDebugInfoEntry *
4438SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4439 const DWARFDebugInfoEntry *die,
4440 dw_offset_t spec_block_die_offset,
4441 DWARFCompileUnit **result_die_cu_handle)
4442{
4443 if (die)
4444 {
4445 switch (die->Tag())
4446 {
4447 case DW_TAG_subprogram:
4448 case DW_TAG_inlined_subroutine:
4449 case DW_TAG_lexical_block:
4450 {
4451 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4452 {
4453 *result_die_cu_handle = dwarf_cu;
4454 return die;
4455 }
4456
4457 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4458 {
4459 *result_die_cu_handle = dwarf_cu;
4460 return die;
4461 }
4462 }
4463 break;
4464 }
4465
4466 // Give the concrete function die specified by "func_die_offset", find the
4467 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4468 // to "spec_block_die_offset"
4469 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4470 {
4471 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4472 child_die,
4473 spec_block_die_offset,
4474 result_die_cu_handle);
4475 if (result_die)
4476 return result_die;
4477 }
4478 }
4479
4480 *result_die_cu_handle = NULL;
4481 return NULL;
4482}
4483
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004484size_t
4485SymbolFileDWARF::ParseVariables
4486(
4487 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004488 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004489 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004490 const DWARFDebugInfoEntry *orig_die,
4491 bool parse_siblings,
4492 bool parse_children,
4493 VariableList* cc_variable_list
4494)
4495{
4496 if (orig_die == NULL)
4497 return 0;
4498
Greg Claytonc662ec82011-06-17 22:10:16 +00004499 VariableListSP variable_list_sp;
4500
4501 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004502 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004503 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004504 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004505 dw_tag_t tag = die->Tag();
4506
4507 // Check to see if we have already parsed this variable or constant?
4508 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004509 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004510 if (cc_variable_list)
4511 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004512 }
4513 else
4514 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004515 // We haven't already parsed it, lets do that now.
4516 if ((tag == DW_TAG_variable) ||
4517 (tag == DW_TAG_constant) ||
4518 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004519 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004520 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004521 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004522 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4523 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4524 switch (parent_tag)
4525 {
4526 case DW_TAG_compile_unit:
4527 if (sc.comp_unit != NULL)
4528 {
4529 variable_list_sp = sc.comp_unit->GetVariableList(false);
4530 if (variable_list_sp.get() == NULL)
4531 {
4532 variable_list_sp.reset(new VariableList());
4533 sc.comp_unit->SetVariableList(variable_list_sp);
4534 }
4535 }
4536 else
4537 {
4538 fprintf (stderr,
4539 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
4540 sc_parent_die->GetOffset(),
4541 DW_TAG_value_to_name (parent_tag),
4542 orig_die->GetOffset(),
4543 DW_TAG_value_to_name (orig_die->Tag()));
4544 }
4545 break;
4546
4547 case DW_TAG_subprogram:
4548 case DW_TAG_inlined_subroutine:
4549 case DW_TAG_lexical_block:
4550 if (sc.function != NULL)
4551 {
4552 // Check to see if we already have parsed the variables for the given scope
4553
4554 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4555 if (block == NULL)
4556 {
4557 // This must be a specification or abstract origin with
4558 // a concrete block couterpart in the current function. We need
4559 // to find the concrete block so we can correctly add the
4560 // variable to it
4561 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4562 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4563 sc_parent_die->GetOffset(),
4564 &concrete_block_die_cu);
4565 if (concrete_block_die)
4566 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4567 }
4568
4569 if (block != NULL)
4570 {
4571 const bool can_create = false;
4572 variable_list_sp = block->GetBlockVariableList (can_create);
4573 if (variable_list_sp.get() == NULL)
4574 {
4575 variable_list_sp.reset(new VariableList());
4576 block->SetVariableList(variable_list_sp);
4577 }
4578 }
4579 }
4580 break;
4581
4582 default:
4583 fprintf (stderr,
4584 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
4585 orig_die->GetOffset(),
4586 DW_TAG_value_to_name (orig_die->Tag()));
4587 break;
4588 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004589 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004590
4591 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004592 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00004593 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4594 if (var_sp)
4595 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004596 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004597 if (cc_variable_list)
4598 cc_variable_list->AddVariableIfUnique (var_sp);
4599 ++vars_added;
4600 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004601 }
4602 }
4603 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004604
4605 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4606
4607 if (!skip_children && parse_children && die->HasChildren())
4608 {
4609 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4610 }
4611
4612 if (parse_siblings)
4613 die = die->GetSibling();
4614 else
4615 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004616 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004617 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004618}
4619
4620//------------------------------------------------------------------
4621// PluginInterface protocol
4622//------------------------------------------------------------------
4623const char *
4624SymbolFileDWARF::GetPluginName()
4625{
4626 return "SymbolFileDWARF";
4627}
4628
4629const char *
4630SymbolFileDWARF::GetShortPluginName()
4631{
4632 return GetPluginNameStatic();
4633}
4634
4635uint32_t
4636SymbolFileDWARF::GetPluginVersion()
4637{
4638 return 1;
4639}
4640
4641void
Greg Clayton6beaaa62011-01-17 03:46:26 +00004642SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4643{
4644 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4645 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4646 if (clang_type)
4647 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4648}
4649
4650void
4651SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4652{
4653 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4654 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4655 if (clang_type)
4656 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4657}
4658
Greg Claytona2721472011-06-25 00:44:06 +00004659void
Sean Callanancc427fa2011-07-30 02:42:06 +00004660SymbolFileDWARF::DumpIndexes ()
4661{
4662 StreamFile s(stdout, false);
4663
4664 s.Printf ("DWARF index for (%s) '%s/%s':",
4665 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4666 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4667 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4668 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4669 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4670 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4671 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4672 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4673 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4674 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4675 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4676}
4677
4678void
4679SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4680 const char *name,
4681 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00004682{
Sean Callanancc427fa2011-07-30 02:42:06 +00004683 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00004684
4685 if (iter == m_decl_ctx_to_die.end())
4686 return;
4687
Sean Callanancc427fa2011-07-30 02:42:06 +00004688 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytona2721472011-06-25 00:44:06 +00004689
4690 if (!results)
4691 return;
4692
4693 DWARFDebugInfo* info = DebugInfo();
4694
4695 std::vector<NameToDIE::Info> die_info_array;
4696
Greg Clayton1d4313b2011-07-07 04:49:07 +00004697 size_t num_matches = m_type_index.Find (ConstString(name), die_info_array);
Greg Claytona2721472011-06-25 00:44:06 +00004698
4699 if (num_matches)
4700 {
4701 for (int i = 0;
4702 i < num_matches;
4703 ++i)
4704 {
4705 DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
4706 compile_unit->ExtractDIEsIfNeeded (false);
4707 const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
4708
Sean Callanancc427fa2011-07-30 02:42:06 +00004709 if (die->GetParent() != context_die)
Greg Claytona2721472011-06-25 00:44:06 +00004710 continue;
4711
4712 Type *matching_type = ResolveType (compile_unit, die);
4713
4714 lldb::clang_type_t type = matching_type->GetClangFullType();
4715 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4716
Sean Callanancc427fa2011-07-30 02:42:06 +00004717 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004718 {
4719 clang::TagDecl *tag_decl = tag_type->getDecl();
4720 results->push_back(tag_decl);
4721 }
Sean Callanancc427fa2011-07-30 02:42:06 +00004722 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004723 {
4724 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4725 results->push_back(typedef_decl);
4726 }
4727 }
4728 }
4729}
4730
4731void
4732SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4733 const clang::DeclContext *DC,
4734 clang::DeclarationName Name,
4735 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4736{
4737 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4738
Sean Callanancc427fa2011-07-30 02:42:06 +00004739 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytona2721472011-06-25 00:44:06 +00004740}