blob: f33b6446def95f03c43397610b3659ab308555dc [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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Core/Timer.h"
34#include "lldb/Core/Value.h"
35
36#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000037#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Symbol/CompileUnit.h"
39#include "lldb/Symbol/LineTable.h"
40#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Symbol/SymbolVendor.h"
42#include "lldb/Symbol/VariableList.h"
43
44#include "DWARFCompileUnit.h"
45#include "DWARFDebugAbbrev.h"
46#include "DWARFDebugAranges.h"
47#include "DWARFDebugInfo.h"
48#include "DWARFDebugInfoEntry.h"
49#include "DWARFDebugLine.h"
50#include "DWARFDebugPubnames.h"
51#include "DWARFDebugRanges.h"
52#include "DWARFDIECollection.h"
53#include "DWARFFormValue.h"
54#include "DWARFLocationList.h"
55#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000056#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
58#include <map>
59
Greg Clayton62742b12010-11-11 01:09:45 +000060//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000061
62#ifdef ENABLE_DEBUG_PRINTF
63#include <stdio.h>
64#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
65#else
66#define DEBUG_PRINTF(fmt, ...)
67#endif
68
Greg Clayton594e5ed2010-09-27 21:07:38 +000069#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070
71using namespace lldb;
72using namespace lldb_private;
73
74
Sean Callananc7fbf732010-08-06 00:32:49 +000075static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000076DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077{
78 switch (dwarf_accessibility)
79 {
Sean Callananc7fbf732010-08-06 00:32:49 +000080 case DW_ACCESS_public: return eAccessPublic;
81 case DW_ACCESS_private: return eAccessPrivate;
82 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000083 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 }
Sean Callananc7fbf732010-08-06 00:32:49 +000085 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086}
87
88void
89SymbolFileDWARF::Initialize()
90{
91 LogChannelDWARF::Initialize();
92 PluginManager::RegisterPlugin (GetPluginNameStatic(),
93 GetPluginDescriptionStatic(),
94 CreateInstance);
95}
96
97void
98SymbolFileDWARF::Terminate()
99{
100 PluginManager::UnregisterPlugin (CreateInstance);
101 LogChannelDWARF::Initialize();
102}
103
104
105const char *
106SymbolFileDWARF::GetPluginNameStatic()
107{
108 return "symbol-file.dwarf2";
109}
110
111const char *
112SymbolFileDWARF::GetPluginDescriptionStatic()
113{
114 return "DWARF and DWARF3 debug symbol file reader.";
115}
116
117
118SymbolFile*
119SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
120{
121 return new SymbolFileDWARF(obj_file);
122}
123
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000124TypeList *
125SymbolFileDWARF::GetTypeList ()
126{
127 if (m_debug_map_symfile)
128 return m_debug_map_symfile->GetTypeList();
129 return m_obj_file->GetModule()->GetTypeList();
130
131}
132
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133//----------------------------------------------------------------------
134// Gets the first parent that is a lexical block, function or inlined
135// subroutine, or compile unit.
136//----------------------------------------------------------------------
137static const DWARFDebugInfoEntry *
138GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
139{
140 const DWARFDebugInfoEntry *die;
141 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
142 {
143 dw_tag_t tag = die->Tag();
144
145 switch (tag)
146 {
147 case DW_TAG_compile_unit:
148 case DW_TAG_subprogram:
149 case DW_TAG_inlined_subroutine:
150 case DW_TAG_lexical_block:
151 return die;
152 }
153 }
154 return NULL;
155}
156
157
Greg Clayton450e3f32010-10-12 02:24:53 +0000158SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
159 SymbolFile (objfile),
160 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000161 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 m_flags(),
163 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 m_data_debug_frame(),
165 m_data_debug_info(),
166 m_data_debug_line(),
167 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 m_data_debug_ranges(),
169 m_data_debug_str(),
170 m_abbr(),
171 m_aranges(),
172 m_info(),
173 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000174 m_function_basename_index(),
175 m_function_fullname_index(),
176 m_function_method_index(),
177 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000178 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000179 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000180 m_type_index(),
181 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000182 m_indexed (false),
183 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000184 m_ranges(),
185 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186{
187}
188
189SymbolFileDWARF::~SymbolFileDWARF()
190{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000191 if (m_is_external_ast_source)
192 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
193}
194
195static const ConstString &
196GetDWARFMachOSegmentName ()
197{
198 static ConstString g_dwarf_section_name ("__DWARF");
199 return g_dwarf_section_name;
200}
201
Greg Claytone576ab22011-02-15 00:19:15 +0000202UniqueDWARFASTTypeMap &
203SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
204{
205 if (m_debug_map_symfile)
206 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
207 return m_unique_ast_type_map;
208}
209
Greg Clayton6beaaa62011-01-17 03:46:26 +0000210ClangASTContext &
211SymbolFileDWARF::GetClangASTContext ()
212{
213 if (m_debug_map_symfile)
214 return m_debug_map_symfile->GetClangASTContext ();
215
216 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
217 if (!m_is_external_ast_source)
218 {
219 m_is_external_ast_source = true;
220 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
221 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
222 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000223 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000224 this));
225
226 ast.SetExternalSource (ast_source_ap);
227 }
228 return ast;
229}
230
231void
232SymbolFileDWARF::InitializeObject()
233{
234 // Install our external AST source callbacks so we can complete Clang types.
235 Module *module = m_obj_file->GetModule();
236 if (module)
237 {
238 const SectionList *section_list = m_obj_file->GetSectionList();
239
240 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
241
242 // Memory map the DWARF mach-o segment so we have everything mmap'ed
243 // to keep our heap memory usage down.
244 if (section)
245 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
246 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247}
248
249bool
250SymbolFileDWARF::SupportedVersion(uint16_t version)
251{
252 return version == 2 || version == 3;
253}
254
255uint32_t
256SymbolFileDWARF::GetAbilities ()
257{
258 uint32_t abilities = 0;
259 if (m_obj_file != NULL)
260 {
261 const Section* section = NULL;
262 const SectionList *section_list = m_obj_file->GetSectionList();
263 if (section_list == NULL)
264 return 0;
265
266 uint64_t debug_abbrev_file_size = 0;
267 uint64_t debug_aranges_file_size = 0;
268 uint64_t debug_frame_file_size = 0;
269 uint64_t debug_info_file_size = 0;
270 uint64_t debug_line_file_size = 0;
271 uint64_t debug_loc_file_size = 0;
272 uint64_t debug_macinfo_file_size = 0;
273 uint64_t debug_pubnames_file_size = 0;
274 uint64_t debug_pubtypes_file_size = 0;
275 uint64_t debug_ranges_file_size = 0;
276 uint64_t debug_str_file_size = 0;
277
Greg Clayton6beaaa62011-01-17 03:46:26 +0000278 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279
280 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000281 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
Greg Clayton4ceb9982010-07-21 22:54:26 +0000283 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 if (section != NULL)
285 {
286 debug_info_file_size = section->GetByteSize();
287
Greg Clayton4ceb9982010-07-21 22:54:26 +0000288 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 if (section)
290 debug_abbrev_file_size = section->GetByteSize();
291 else
292 m_flags.Set (flagsGotDebugAbbrevData);
293
Greg Clayton4ceb9982010-07-21 22:54:26 +0000294 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 if (section)
296 debug_aranges_file_size = section->GetByteSize();
297 else
298 m_flags.Set (flagsGotDebugArangesData);
299
Greg Clayton4ceb9982010-07-21 22:54:26 +0000300 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 if (section)
302 debug_frame_file_size = section->GetByteSize();
303 else
304 m_flags.Set (flagsGotDebugFrameData);
305
Greg Clayton4ceb9982010-07-21 22:54:26 +0000306 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 if (section)
308 debug_line_file_size = section->GetByteSize();
309 else
310 m_flags.Set (flagsGotDebugLineData);
311
Greg Clayton4ceb9982010-07-21 22:54:26 +0000312 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 if (section)
314 debug_loc_file_size = section->GetByteSize();
315 else
316 m_flags.Set (flagsGotDebugLocData);
317
Greg Clayton4ceb9982010-07-21 22:54:26 +0000318 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 if (section)
320 debug_macinfo_file_size = section->GetByteSize();
321 else
322 m_flags.Set (flagsGotDebugMacInfoData);
323
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 if (section)
326 debug_pubnames_file_size = section->GetByteSize();
327 else
328 m_flags.Set (flagsGotDebugPubNamesData);
329
Greg Clayton4ceb9982010-07-21 22:54:26 +0000330 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 if (section)
332 debug_pubtypes_file_size = section->GetByteSize();
333 else
334 m_flags.Set (flagsGotDebugPubTypesData);
335
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 if (section)
338 debug_ranges_file_size = section->GetByteSize();
339 else
340 m_flags.Set (flagsGotDebugRangesData);
341
Greg Clayton4ceb9982010-07-21 22:54:26 +0000342 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 if (section)
344 debug_str_file_size = section->GetByteSize();
345 else
346 m_flags.Set (flagsGotDebugStrData);
347 }
348
349 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
350 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
351
352 if (debug_line_file_size > 0)
353 abilities |= LineTables;
354
355 if (debug_aranges_file_size > 0)
356 abilities |= AddressAcceleratorTable;
357
358 if (debug_pubnames_file_size > 0)
359 abilities |= FunctionAcceleratorTable;
360
361 if (debug_pubtypes_file_size > 0)
362 abilities |= TypeAcceleratorTable;
363
364 if (debug_macinfo_file_size > 0)
365 abilities |= MacroInformation;
366
367 if (debug_frame_file_size > 0)
368 abilities |= CallFrameInformation;
369 }
370 return abilities;
371}
372
373const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000374SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375{
376 if (m_flags.IsClear (got_flag))
377 {
378 m_flags.Set (got_flag);
379 const SectionList *section_list = m_obj_file->GetSectionList();
380 if (section_list)
381 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000382 Section *section = section_list->FindSectionByType(sect_type, true).get();
383 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 {
385 // See if we memory mapped the DWARF segment?
386 if (m_dwarf_data.GetByteSize())
387 {
388 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
389 }
390 else
391 {
392 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
393 data.Clear();
394 }
395 }
396 }
397 }
398 return data;
399}
400
401const DataExtractor&
402SymbolFileDWARF::get_debug_abbrev_data()
403{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000404 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405}
406
407const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408SymbolFileDWARF::get_debug_frame_data()
409{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000410 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411}
412
413const DataExtractor&
414SymbolFileDWARF::get_debug_info_data()
415{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000416 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
419const DataExtractor&
420SymbolFileDWARF::get_debug_line_data()
421{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000422 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
425const DataExtractor&
426SymbolFileDWARF::get_debug_loc_data()
427{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000428 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
431const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432SymbolFileDWARF::get_debug_ranges_data()
433{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000434 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435}
436
437const DataExtractor&
438SymbolFileDWARF::get_debug_str_data()
439{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000440 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441}
442
443
444DWARFDebugAbbrev*
445SymbolFileDWARF::DebugAbbrev()
446{
447 if (m_abbr.get() == NULL)
448 {
449 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
450 if (debug_abbrev_data.GetByteSize() > 0)
451 {
452 m_abbr.reset(new DWARFDebugAbbrev());
453 if (m_abbr.get())
454 m_abbr->Parse(debug_abbrev_data);
455 }
456 }
457 return m_abbr.get();
458}
459
460const DWARFDebugAbbrev*
461SymbolFileDWARF::DebugAbbrev() const
462{
463 return m_abbr.get();
464}
465
466DWARFDebugAranges*
467SymbolFileDWARF::DebugAranges()
468{
Greg Clayton016a95e2010-09-14 02:20:48 +0000469 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
470 // and we are already parsing all of the DWARF because the .debug_pubnames
471 // is useless (it only mentions symbols that are externally visible), so
472 // don't use the .debug_aranges section, we should be using a debug aranges
473 // we got from SymbolFileDWARF::Index().
474
475 if (!m_indexed)
476 Index();
477
478
479// if (m_aranges.get() == NULL)
480// {
481// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
482// m_aranges.reset(new DWARFDebugAranges());
483// if (m_aranges.get())
484// {
485// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
486// if (debug_aranges_data.GetByteSize() > 0)
487// m_aranges->Extract(debug_aranges_data);
488// else
489// m_aranges->Generate(this);
490// }
491// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 return m_aranges.get();
493}
494
495const DWARFDebugAranges*
496SymbolFileDWARF::DebugAranges() const
497{
498 return m_aranges.get();
499}
500
501
502DWARFDebugInfo*
503SymbolFileDWARF::DebugInfo()
504{
505 if (m_info.get() == NULL)
506 {
507 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
508 if (get_debug_info_data().GetByteSize() > 0)
509 {
510 m_info.reset(new DWARFDebugInfo());
511 if (m_info.get())
512 {
513 m_info->SetDwarfData(this);
514 }
515 }
516 }
517 return m_info.get();
518}
519
520const DWARFDebugInfo*
521SymbolFileDWARF::DebugInfo() const
522{
523 return m_info.get();
524}
525
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526DWARFCompileUnit*
527SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
528{
529 DWARFDebugInfo* info = DebugInfo();
530 if (info)
531 return info->GetCompileUnit(cu_uid).get();
532 return NULL;
533}
534
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535
536DWARFDebugRanges*
537SymbolFileDWARF::DebugRanges()
538{
539 if (m_ranges.get() == NULL)
540 {
541 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
542 if (get_debug_ranges_data().GetByteSize() > 0)
543 {
544 m_ranges.reset(new DWARFDebugRanges());
545 if (m_ranges.get())
546 m_ranges->Extract(this);
547 }
548 }
549 return m_ranges.get();
550}
551
552const DWARFDebugRanges*
553SymbolFileDWARF::DebugRanges() const
554{
555 return m_ranges.get();
556}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
558bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000559SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560{
Greg Clayton96d7d742010-11-10 23:42:09 +0000561 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000563 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 if (cu_die)
565 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000566 const char * cu_die_name = cu_die->GetName(this, curr_cu);
567 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
568 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569 if (cu_die_name)
570 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000571 FileSpec cu_file_spec;
572
Greg Clayton7bd65b92011-02-09 23:39:34 +0000573 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000575 // If we have a full path to the compile unit, we don't need to resolve
576 // the file. This can be expensive e.g. when the source files are NFS mounted.
577 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 }
579 else
580 {
581 std::string fullpath(cu_comp_dir);
582 if (*fullpath.rbegin() != '/')
583 fullpath += '/';
584 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000585 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586 }
587
Greg Clayton96d7d742010-11-10 23:42:09 +0000588 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589 if (compile_unit_sp.get())
590 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000591 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592 return true;
593 }
594 }
595 }
596 }
597 return false;
598}
599
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600uint32_t
601SymbolFileDWARF::GetNumCompileUnits()
602{
603 DWARFDebugInfo* info = DebugInfo();
604 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 return 0;
607}
608
609CompUnitSP
610SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
611{
612 CompUnitSP comp_unit;
613 DWARFDebugInfo* info = DebugInfo();
614 if (info)
615 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000616 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
617 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 {
619 // Our symbol vendor shouldn't be asking us to add a compile unit that
620 // has already been added to it, which this DWARF plug-in knows as it
621 // stores the lldb compile unit (CompileUnit) pointer in each
622 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000623 assert(curr_cu->GetUserData() == NULL);
624 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 }
626 }
627 return comp_unit;
628}
629
630static void
631AddRangesToBlock
632(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000633 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 DWARFDebugRanges::RangeList& ranges,
635 addr_t block_base_addr
636)
637{
638 ranges.SubtractOffset (block_base_addr);
639 size_t range_idx = 0;
640 const DWARFDebugRanges::Range *debug_range;
641 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
642 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000643 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 }
645}
646
647
648Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000649SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000650{
651 DWARFDebugRanges::RangeList func_ranges;
652 const char *name = NULL;
653 const char *mangled = NULL;
654 int decl_file = 0;
655 int decl_line = 0;
656 int decl_column = 0;
657 int call_file = 0;
658 int call_line = 0;
659 int call_column = 0;
660 DWARFExpression frame_base;
661
Greg Claytonc93237c2010-10-01 20:48:32 +0000662 assert (die->Tag() == DW_TAG_subprogram);
663
664 if (die->Tag() != DW_TAG_subprogram)
665 return NULL;
666
667 const DWARFDebugInfoEntry *parent_die = die->GetParent();
668 switch (parent_die->Tag())
669 {
670 case DW_TAG_structure_type:
671 case DW_TAG_class_type:
672 // We have methods of a class or struct
673 {
674 Type *class_type = ResolveType (dwarf_cu, parent_die);
675 if (class_type)
Greg Claytonf4ecaa52011-02-16 23:00:21 +0000676 class_type->GetClangFullType();
Greg Claytonc93237c2010-10-01 20:48:32 +0000677 }
678 break;
679
680 default:
681 // Parse the function prototype as a type that can then be added to concrete function instance
682 ParseTypes (sc, dwarf_cu, die, false, false);
683 break;
684 }
685
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686 //FixupTypes();
687
688 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
689 {
690 // Union of all ranges in the function DIE (if the function is discontiguous)
691 AddressRange func_range;
692 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
693 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
694 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
695 {
696 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
697 if (func_range.GetBaseAddress().IsValid())
698 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
699 }
700
701 if (func_range.GetBaseAddress().IsValid())
702 {
703 Mangled func_name;
704 if (mangled)
705 func_name.SetValue(mangled, true);
706 else if (name)
707 func_name.SetValue(name, false);
708
709 FunctionSP func_sp;
710 std::auto_ptr<Declaration> decl_ap;
711 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000712 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
713 decl_line,
714 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715
Greg Clayton594e5ed2010-09-27 21:07:38 +0000716 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000717
718 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
719
720 func_range.GetBaseAddress().ResolveLinkedAddress();
721
722 func_sp.reset(new Function (sc.comp_unit,
723 die->GetOffset(), // UserID is the DIE offset
724 die->GetOffset(),
725 func_name,
726 func_type,
727 func_range)); // first address range
728
729 if (func_sp.get() != NULL)
730 {
731 func_sp->GetFrameBaseExpression() = frame_base;
732 sc.comp_unit->AddFunction(func_sp);
733 return func_sp.get();
734 }
735 }
736 }
737 return NULL;
738}
739
740size_t
741SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
742{
743 assert (sc.comp_unit);
744 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000745 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000746 if (dwarf_cu)
747 {
748 DWARFDIECollection function_dies;
749 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
750 size_t func_idx;
751 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
752 {
753 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
754 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
755 {
756 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
757 ++functions_added;
758 }
759 }
760 //FixupTypes();
761 }
762 return functions_added;
763}
764
765bool
766SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
767{
768 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000769 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
770 assert (curr_cu);
771 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772
773 if (cu_die)
774 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000775 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
776 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 +0000777
778 // All file indexes in DWARF are one based and a file of index zero is
779 // supposed to be the compile unit itself.
780 support_files.Append (*sc.comp_unit);
781
782 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
783 }
784 return false;
785}
786
787struct ParseDWARFLineTableCallbackInfo
788{
789 LineTable* line_table;
790 const SectionList *section_list;
791 lldb::addr_t prev_sect_file_base_addr;
792 lldb::addr_t curr_sect_file_base_addr;
793 bool is_oso_for_debug_map;
794 bool prev_in_final_executable;
795 DWARFDebugLine::Row prev_row;
796 SectionSP prev_section_sp;
797 SectionSP curr_section_sp;
798};
799
800//----------------------------------------------------------------------
801// ParseStatementTableCallback
802//----------------------------------------------------------------------
803static void
804ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
805{
806 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
807 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
808 {
809 // Just started parsing the line table
810 }
811 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
812 {
813 // Done parsing line table, nothing to do for the cleanup
814 }
815 else
816 {
817 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
818 // We have a new row, lets append it
819
820 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
821 {
822 info->prev_section_sp = info->curr_section_sp;
823 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
824 // If this is an end sequence entry, then we subtract one from the
825 // address to make sure we get an address that is not the end of
826 // a section.
827 if (state.end_sequence && state.address != 0)
828 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
829 else
830 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
831
832 if (info->curr_section_sp.get())
833 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
834 else
835 info->curr_sect_file_base_addr = 0;
836 }
837 if (info->curr_section_sp.get())
838 {
839 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
840 // Check for the fancy section magic to determine if we
841
842 if (info->is_oso_for_debug_map)
843 {
844 // When this is a debug map object file that contains DWARF
845 // (referenced from an N_OSO debug map nlist entry) we will have
846 // a file address in the file range for our section from the
847 // original .o file, and a load address in the executable that
848 // contains the debug map.
849 //
850 // If the sections for the file range and load range are
851 // different, we have a remapped section for the function and
852 // this address is resolved. If they are the same, then the
853 // function for this address didn't make it into the final
854 // executable.
855 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
856
857 // If we are doing DWARF with debug map, then we need to carefully
858 // add each line table entry as there may be gaps as functions
859 // get moved around or removed.
860 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
861 {
862 if (info->prev_in_final_executable)
863 {
864 bool terminate_previous_entry = false;
865 if (!curr_in_final_executable)
866 {
867 // Check for the case where the previous line entry
868 // in a function made it into the final executable,
869 // yet the current line entry falls in a function
870 // that didn't. The line table used to be contiguous
871 // through this address range but now it isn't. We
872 // need to terminate the previous line entry so
873 // that we can reconstruct the line range correctly
874 // for it and to keep the line table correct.
875 terminate_previous_entry = true;
876 }
877 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
878 {
879 // Check for cases where the line entries used to be
880 // contiguous address ranges, but now they aren't.
881 // This can happen when order files specify the
882 // ordering of the functions.
883 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
884 Section *curr_sect = info->curr_section_sp.get();
885 Section *prev_sect = info->prev_section_sp.get();
886 assert (curr_sect->GetLinkedSection());
887 assert (prev_sect->GetLinkedSection());
888 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
889 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
890 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
891 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
892 if (object_file_addr_delta != linked_file_addr_delta)
893 terminate_previous_entry = true;
894 }
895
896 if (terminate_previous_entry)
897 {
898 line_table->InsertLineEntry (info->prev_section_sp,
899 state.address - info->prev_sect_file_base_addr,
900 info->prev_row.line,
901 info->prev_row.column,
902 info->prev_row.file,
903 false, // is_stmt
904 false, // basic_block
905 false, // state.prologue_end
906 false, // state.epilogue_begin
907 true); // end_sequence);
908 }
909 }
910 }
911
912 if (curr_in_final_executable)
913 {
914 line_table->InsertLineEntry (info->curr_section_sp,
915 curr_line_section_offset,
916 state.line,
917 state.column,
918 state.file,
919 state.is_stmt,
920 state.basic_block,
921 state.prologue_end,
922 state.epilogue_begin,
923 state.end_sequence);
924 info->prev_section_sp = info->curr_section_sp;
925 }
926 else
927 {
928 // If the current address didn't make it into the final
929 // executable, the current section will be the __text
930 // segment in the .o file, so we need to clear this so
931 // we can catch the next function that did make it into
932 // the final executable.
933 info->prev_section_sp.reset();
934 info->curr_section_sp.reset();
935 }
936
937 info->prev_in_final_executable = curr_in_final_executable;
938 }
939 else
940 {
941 // We are not in an object file that contains DWARF for an
942 // N_OSO, this is just a normal DWARF file. The DWARF spec
943 // guarantees that the addresses will be in increasing order
944 // so, since we store line tables in file address order, we
945 // can always just append the line entry without needing to
946 // search for the correct insertion point (we don't need to
947 // use LineEntry::InsertLineEntry()).
948 line_table->AppendLineEntry (info->curr_section_sp,
949 curr_line_section_offset,
950 state.line,
951 state.column,
952 state.file,
953 state.is_stmt,
954 state.basic_block,
955 state.prologue_end,
956 state.epilogue_begin,
957 state.end_sequence);
958 }
959 }
960
961 info->prev_row = state;
962 }
963}
964
965bool
966SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
967{
968 assert (sc.comp_unit);
969 if (sc.comp_unit->GetLineTable() != NULL)
970 return true;
971
972 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
973 if (dwarf_cu)
974 {
975 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
976 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
977 if (cu_line_offset != DW_INVALID_OFFSET)
978 {
979 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
980 if (line_table_ap.get())
981 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000982 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 +0000983 uint32_t offset = cu_line_offset;
984 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
985 sc.comp_unit->SetLineTable(line_table_ap.release());
986 return true;
987 }
988 }
989 }
990 return false;
991}
992
993size_t
994SymbolFileDWARF::ParseFunctionBlocks
995(
996 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000997 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000998 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999 const DWARFDebugInfoEntry *die,
1000 addr_t subprogram_low_pc,
1001 bool parse_siblings,
1002 bool parse_children
1003)
1004{
1005 size_t blocks_added = 0;
1006 while (die != NULL)
1007 {
1008 dw_tag_t tag = die->Tag();
1009
1010 switch (tag)
1011 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001012 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +00001013 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001014 case DW_TAG_lexical_block:
1015 {
1016 DWARFDebugRanges::RangeList ranges;
1017 const char *name = NULL;
1018 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001019 Block *block = NULL;
1020 if (tag != DW_TAG_subprogram)
1021 {
1022 BlockSP block_sp(new Block (die->GetOffset()));
1023 parent_block->AddChild(block_sp);
1024 block = block_sp.get();
1025 }
1026 else
1027 {
1028 block = parent_block;
1029 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001031 int decl_file = 0;
1032 int decl_line = 0;
1033 int decl_column = 0;
1034 int call_file = 0;
1035 int call_line = 0;
1036 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001037 if (die->GetDIENamesAndRanges (this,
1038 dwarf_cu,
1039 name,
1040 mangled_name,
1041 ranges,
1042 decl_file, decl_line, decl_column,
1043 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 {
1045 if (tag == DW_TAG_subprogram)
1046 {
1047 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1048 subprogram_low_pc = ranges.LowestAddress(0);
1049 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001050 else if (tag == DW_TAG_inlined_subroutine)
1051 {
1052 // We get called here for inlined subroutines in two ways.
1053 // The first time is when we are making the Function object
1054 // for this inlined concrete instance. Since we're creating a top level block at
1055 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1056 // adjust the containing address.
1057 // The second time is when we are parsing the blocks inside the function that contains
1058 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1059 // function the offset will be for that function.
1060 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1061 {
1062 subprogram_low_pc = ranges.LowestAddress(0);
1063 }
1064 }
1065
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001066 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067
1068 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1069 {
1070 std::auto_ptr<Declaration> decl_ap;
1071 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001072 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1073 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074
1075 std::auto_ptr<Declaration> call_ap;
1076 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001077 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1078 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001080 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 }
1082
1083 ++blocks_added;
1084
1085 if (parse_children && die->HasChildren())
1086 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001087 blocks_added += ParseFunctionBlocks (sc,
1088 block,
1089 dwarf_cu,
1090 die->GetFirstChild(),
1091 subprogram_low_pc,
1092 true,
1093 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 }
1095 }
1096 }
1097 break;
1098 default:
1099 break;
1100 }
1101
1102 if (parse_siblings)
1103 die = die->GetSibling();
1104 else
1105 die = NULL;
1106 }
1107 return blocks_added;
1108}
1109
1110size_t
1111SymbolFileDWARF::ParseChildMembers
1112(
1113 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001114 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001115 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001116 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001117 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1119 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001120 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001121 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122 bool &is_a_class
1123)
1124{
1125 if (parent_die == NULL)
1126 return 0;
1127
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128 size_t count = 0;
1129 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001130 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001131 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001132
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1134 {
1135 dw_tag_t tag = die->Tag();
1136
1137 switch (tag)
1138 {
1139 case DW_TAG_member:
1140 {
1141 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001142 const size_t num_attributes = die->GetAttributes (this,
1143 dwarf_cu,
1144 fixed_form_sizes,
1145 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001146 if (num_attributes > 0)
1147 {
1148 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001149 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001150 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001151 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001153 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001154 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155 size_t byte_size = 0;
1156 size_t bit_offset = 0;
1157 size_t bit_size = 0;
1158 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001159 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160 {
1161 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1162 DWARFFormValue form_value;
1163 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1164 {
1165 switch (attr)
1166 {
1167 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1168 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1169 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1170 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1171 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1172 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1173 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1174 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1175 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001176// if (form_value.BlockData())
1177// {
1178// Value initialValue(0);
1179// Value memberOffset(0);
1180// const DataExtractor& debug_info_data = get_debug_info_data();
1181// uint32_t block_length = form_value.Unsigned();
1182// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1183// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1184// {
1185// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1186// }
1187// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001188 break;
1189
Greg Clayton8cf05932010-07-22 18:30:50 +00001190 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001191 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192 case DW_AT_declaration:
1193 case DW_AT_description:
1194 case DW_AT_mutable:
1195 case DW_AT_visibility:
1196 default:
1197 case DW_AT_sibling:
1198 break;
1199 }
1200 }
1201 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001202
1203 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1204
1205 if (class_language == eLanguageTypeObjC ||
1206 class_language == eLanguageTypeObjC_plus_plus)
1207 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001208
1209 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1210 {
1211 // Not all compilers will mark the vtable pointer
1212 // member as artificial (llvm-gcc). We can't have
1213 // the virtual members in our classes otherwise it
1214 // throws off all child offsets since we end up
1215 // having and extra pointer sized member in our
1216 // class layouts.
1217 is_artificial = true;
1218 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219
Greg Clayton24739922010-10-13 03:15:28 +00001220 if (is_artificial == false)
1221 {
1222 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001223 if (member_type)
1224 {
1225 if (accessibility == eAccessNone)
1226 accessibility = default_accessibility;
1227 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001228
Greg Claytond16e1e52011-07-12 17:06:17 +00001229 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1230 name,
1231 member_type->GetClangLayoutType(),
1232 accessibility,
1233 bit_size);
1234 }
1235 else
1236 {
1237 if (name)
1238 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1239 die->GetOffset(),
1240 name,
1241 encoding_uid);
1242 else
1243 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1244 die->GetOffset(),
1245 encoding_uid);
1246 }
Greg Clayton24739922010-10-13 03:15:28 +00001247 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001248 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001249 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250 }
1251 break;
1252
1253 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001254 // Let the type parsing code handle this one for us.
1255 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256 break;
1257
1258 case DW_TAG_inheritance:
1259 {
1260 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001261 if (default_accessibility == eAccessNone)
1262 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 // TODO: implement DW_TAG_inheritance type parsing
1264 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001265 const size_t num_attributes = die->GetAttributes (this,
1266 dwarf_cu,
1267 fixed_form_sizes,
1268 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269 if (num_attributes > 0)
1270 {
1271 Declaration decl;
1272 DWARFExpression location;
1273 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001274 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 bool is_virtual = false;
1276 bool is_base_of_class = true;
1277 off_t member_offset = 0;
1278 uint32_t i;
1279 for (i=0; i<num_attributes; ++i)
1280 {
1281 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1282 DWARFFormValue form_value;
1283 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1284 {
1285 switch (attr)
1286 {
1287 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1288 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1289 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1290 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1291 case DW_AT_data_member_location:
1292 if (form_value.BlockData())
1293 {
1294 Value initialValue(0);
1295 Value memberOffset(0);
1296 const DataExtractor& debug_info_data = get_debug_info_data();
1297 uint32_t block_length = form_value.Unsigned();
1298 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001299 if (DWARFExpression::Evaluate (NULL,
1300 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001301 NULL,
1302 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001303 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001304 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001305 block_offset,
1306 block_length,
1307 eRegisterKindDWARF,
1308 &initialValue,
1309 memberOffset,
1310 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001311 {
1312 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1313 }
1314 }
1315 break;
1316
1317 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001318 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 break;
1320
1321 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1322 default:
1323 case DW_AT_sibling:
1324 break;
1325 }
1326 }
1327 }
1328
Greg Clayton526e5af2010-11-13 03:52:47 +00001329 Type *base_class_type = ResolveTypeUID(encoding_uid);
1330 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001331
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001332 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1333 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001334 if (class_language == eLanguageTypeObjC)
1335 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001336 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001337 }
1338 else
1339 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001340 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001341 accessibility,
1342 is_virtual,
1343 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001344 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001345 }
1346 }
1347 break;
1348
1349 default:
1350 break;
1351 }
1352 }
1353 return count;
1354}
1355
1356
1357clang::DeclContext*
1358SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1359{
1360 DWARFDebugInfo* debug_info = DebugInfo();
1361 if (debug_info)
1362 {
1363 DWARFCompileUnitSP cu_sp;
1364 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1365 if (die)
1366 return GetClangDeclContextForDIE (cu_sp.get(), die);
1367 }
1368 return NULL;
1369}
1370
1371Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001372SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001373{
1374 DWARFDebugInfo* debug_info = DebugInfo();
1375 if (debug_info)
1376 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001377 DWARFCompileUnitSP cu_sp;
1378 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001379 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001380 {
1381 // We might be coming in in the middle of a type tree (a class
1382 // withing a class, an enum within a class), so parse any needed
1383 // parent DIEs before we get to this one...
1384 const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1385 switch (parent_die->Tag())
1386 {
1387 case DW_TAG_structure_type:
1388 case DW_TAG_union_type:
1389 case DW_TAG_class_type:
1390 ResolveType(cu_sp.get(), parent_die);
1391 break;
1392 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001393 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001394 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395 }
1396 return NULL;
1397}
1398
Greg Clayton6beaaa62011-01-17 03:46:26 +00001399// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1400// SymbolFileDWARF objects to detect if this DWARF file is the one that
1401// can resolve a clang_type.
1402bool
1403SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1404{
1405 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1406 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1407 return die != NULL;
1408}
1409
1410
Greg Clayton1be10fc2010-09-29 01:12:09 +00001411lldb::clang_type_t
1412SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1413{
1414 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001415 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1416 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001417 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001418 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001419// if (m_debug_map_symfile)
1420// {
1421// Type *type = m_die_to_type[die];
1422// if (type && type->GetSymbolFile() != this)
1423// return type->GetClangType();
1424// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001425 // We have already resolved this type...
1426 return clang_type;
1427 }
1428 // Once we start resolving this type, remove it from the forward declaration
1429 // map in case anyone child members or other types require this type to get resolved.
1430 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1431 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001432 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001433
Greg Clayton1be10fc2010-09-29 01:12:09 +00001434
Greg Clayton450e3f32010-10-12 02:24:53 +00001435 DWARFDebugInfo* debug_info = DebugInfo();
1436
Greg Clayton96d7d742010-11-10 23:42:09 +00001437 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001438 Type *type = m_die_to_type.lookup (die);
1439
1440 const dw_tag_t tag = die->Tag();
1441
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001442 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1443 die->GetOffset(),
1444 DW_TAG_value_to_name(tag),
1445 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001446 assert (clang_type);
1447 DWARFDebugInfoEntry::Attributes attributes;
1448
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001449 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001450
1451 switch (tag)
1452 {
1453 case DW_TAG_structure_type:
1454 case DW_TAG_union_type:
1455 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001456 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001457 if (die->HasChildren())
1458 {
1459 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001460 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1461 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001462 class_language = eLanguageTypeObjC;
1463
1464 int tag_decl_kind = -1;
1465 AccessType default_accessibility = eAccessNone;
1466 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001467 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001468 tag_decl_kind = clang::TTK_Struct;
1469 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001470 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001471 else if (tag == DW_TAG_union_type)
1472 {
1473 tag_decl_kind = clang::TTK_Union;
1474 default_accessibility = eAccessPublic;
1475 }
1476 else if (tag == DW_TAG_class_type)
1477 {
1478 tag_decl_kind = clang::TTK_Class;
1479 default_accessibility = eAccessPrivate;
1480 }
1481
Greg Clayton96d7d742010-11-10 23:42:09 +00001482 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001483 std::vector<clang::CXXBaseSpecifier *> base_classes;
1484 std::vector<int> member_accessibilities;
1485 bool is_a_class = false;
1486 // Parse members and base classes first
1487 DWARFDIECollection member_function_dies;
1488
1489 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001490 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001491 die,
1492 clang_type,
1493 class_language,
1494 base_classes,
1495 member_accessibilities,
1496 member_function_dies,
1497 default_accessibility,
1498 is_a_class);
1499
1500 // Now parse any methods if there were any...
1501 size_t num_functions = member_function_dies.Size();
1502 if (num_functions > 0)
1503 {
1504 for (size_t i=0; i<num_functions; ++i)
1505 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001506 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001507 }
1508 }
1509
Greg Clayton450e3f32010-10-12 02:24:53 +00001510 if (class_language == eLanguageTypeObjC)
1511 {
Greg Claytone3055942011-06-30 02:28:26 +00001512 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001513 if (!class_str.empty())
1514 {
1515
1516 ConstString class_name (class_str.c_str());
1517 std::vector<NameToDIE::Info> method_die_infos;
1518 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1519 {
1520 DWARFCompileUnit* method_cu = NULL;
1521 DWARFCompileUnit* prev_method_cu = NULL;
1522 const size_t num_objc_methods = method_die_infos.size();
1523 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1524 {
1525 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1526
1527 if (method_cu != prev_method_cu)
1528 method_cu->ExtractDIEsIfNeeded (false);
1529
1530 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1531
1532 ResolveType (method_cu, method_die);
1533 }
1534 }
1535 }
1536 }
1537
Greg Claytonc93237c2010-10-01 20:48:32 +00001538 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1539 // need to tell the clang type it is actually a class.
1540 if (class_language != eLanguageTypeObjC)
1541 {
1542 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001543 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001544 }
1545
1546 // Since DW_TAG_structure_type gets used for both classes
1547 // and structures, we may need to set any DW_TAG_member
1548 // fields to have a "private" access if none was specified.
1549 // When we parsed the child members we tracked that actual
1550 // accessibility value for each DW_TAG_member in the
1551 // "member_accessibilities" array. If the value for the
1552 // member is zero, then it was set to the "default_accessibility"
1553 // which for structs was "public". Below we correct this
1554 // by setting any fields to "private" that weren't correctly
1555 // set.
1556 if (is_a_class && !member_accessibilities.empty())
1557 {
1558 // This is a class and all members that didn't have
1559 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001560 ast.SetDefaultAccessForRecordFields (clang_type,
1561 eAccessPrivate,
1562 &member_accessibilities.front(),
1563 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001564 }
1565
1566 if (!base_classes.empty())
1567 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001568 ast.SetBaseClassesForClassType (clang_type,
1569 &base_classes.front(),
1570 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001571
1572 // Clang will copy each CXXBaseSpecifier in "base_classes"
1573 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001574 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1575 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001576 }
1577
1578 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001579 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001580 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001581
1582 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001583 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001584 if (die->HasChildren())
1585 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001586 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1587 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001588 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001589 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001590 return clang_type;
1591
1592 default:
1593 assert(false && "not a forward clang type decl!");
1594 break;
1595 }
1596 return NULL;
1597}
1598
Greg Claytonc685f8e2010-09-15 04:15:46 +00001599Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001600SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001601{
1602 if (type_die != NULL)
1603 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001604 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001605 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001606 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001607 if (assert_not_being_parsed)
1608 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001609 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001610 }
1611 return NULL;
1612}
1613
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001615SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001616{
1617 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001618 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001619 {
1620 // The symbol vendor doesn't know about this compile unit, we
1621 // need to parse and add it to the symbol vendor object.
1622 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001623 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001624 if (dc_cu.get())
1625 {
1626 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001627 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001628 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001629
1630 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001631
1632 if (m_debug_map_symfile)
1633 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001634 }
1635 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001636 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001637}
1638
1639bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001640SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001641{
1642 sc.Clear();
1643 // Check if the symbol vendor already knows about this compile unit?
1644 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001645 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001646
1647 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1648 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001649 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001650
1651 return sc.function != NULL;
1652}
1653
1654uint32_t
1655SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1656{
1657 Timer scoped_timer(__PRETTY_FUNCTION__,
1658 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1659 so_addr.GetSection(),
1660 so_addr.GetOffset(),
1661 resolve_scope);
1662 uint32_t resolved = 0;
1663 if (resolve_scope & ( eSymbolContextCompUnit |
1664 eSymbolContextFunction |
1665 eSymbolContextBlock |
1666 eSymbolContextLineEntry))
1667 {
1668 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1669
1670 DWARFDebugAranges* debug_aranges = DebugAranges();
1671 DWARFDebugInfo* debug_info = DebugInfo();
1672 if (debug_aranges)
1673 {
1674 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1675 if (cu_offset != DW_INVALID_OFFSET)
1676 {
1677 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001678 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1679 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001680 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001681 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001682 assert(sc.comp_unit != NULL);
1683 resolved |= eSymbolContextCompUnit;
1684
1685 if (resolve_scope & eSymbolContextLineEntry)
1686 {
1687 LineTable *line_table = sc.comp_unit->GetLineTable();
1688 if (line_table == NULL)
1689 {
1690 if (ParseCompileUnitLineTable(sc))
1691 line_table = sc.comp_unit->GetLineTable();
1692 }
1693 if (line_table != NULL)
1694 {
1695 if (so_addr.IsLinkedAddress())
1696 {
1697 Address linked_addr (so_addr);
1698 linked_addr.ResolveLinkedAddress();
1699 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1700 {
1701 resolved |= eSymbolContextLineEntry;
1702 }
1703 }
1704 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1705 {
1706 resolved |= eSymbolContextLineEntry;
1707 }
1708 }
1709 }
1710
1711 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1712 {
1713 DWARFDebugInfoEntry *function_die = NULL;
1714 DWARFDebugInfoEntry *block_die = NULL;
1715 if (resolve_scope & eSymbolContextBlock)
1716 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001717 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001718 }
1719 else
1720 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001721 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001722 }
1723
1724 if (function_die != NULL)
1725 {
1726 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1727 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001728 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001729 }
1730
1731 if (sc.function != NULL)
1732 {
1733 resolved |= eSymbolContextFunction;
1734
1735 if (resolve_scope & eSymbolContextBlock)
1736 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001737 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001738
1739 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001740 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001741 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001742 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001743 if (sc.block)
1744 resolved |= eSymbolContextBlock;
1745 }
1746 }
1747 }
1748 }
1749 }
1750 }
1751 }
1752 return resolved;
1753}
1754
1755
1756
1757uint32_t
1758SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1759{
1760 const uint32_t prev_size = sc_list.GetSize();
1761 if (resolve_scope & eSymbolContextCompUnit)
1762 {
1763 DWARFDebugInfo* debug_info = DebugInfo();
1764 if (debug_info)
1765 {
1766 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001767 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001768
Greg Clayton96d7d742010-11-10 23:42:09 +00001769 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001770 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001771 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001772 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1773 if (check_inlines || file_spec_matches_cu_file_spec)
1774 {
1775 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001776 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001777 assert(sc.comp_unit != NULL);
1778
1779 uint32_t file_idx = UINT32_MAX;
1780
1781 // If we are looking for inline functions only and we don't
1782 // find it in the support files, we are done.
1783 if (check_inlines)
1784 {
1785 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1786 if (file_idx == UINT32_MAX)
1787 continue;
1788 }
1789
1790 if (line != 0)
1791 {
1792 LineTable *line_table = sc.comp_unit->GetLineTable();
1793
1794 if (line_table != NULL && line != 0)
1795 {
1796 // We will have already looked up the file index if
1797 // we are searching for inline entries.
1798 if (!check_inlines)
1799 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1800
1801 if (file_idx != UINT32_MAX)
1802 {
1803 uint32_t found_line;
1804 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1805 found_line = sc.line_entry.line;
1806
Greg Clayton016a95e2010-09-14 02:20:48 +00001807 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001808 {
1809 sc.function = NULL;
1810 sc.block = NULL;
1811 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1812 {
1813 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1814 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1815 {
1816 DWARFDebugInfoEntry *function_die = NULL;
1817 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001818 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001819
1820 if (function_die != NULL)
1821 {
1822 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1823 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001824 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001825 }
1826
1827 if (sc.function != NULL)
1828 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001829 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001830
1831 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001832 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001833 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001834 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835 }
1836 }
1837 }
1838
1839 sc_list.Append(sc);
1840 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1841 }
1842 }
1843 }
1844 else if (file_spec_matches_cu_file_spec && !check_inlines)
1845 {
1846 // only append the context if we aren't looking for inline call sites
1847 // by file and line and if the file spec matches that of the compile unit
1848 sc_list.Append(sc);
1849 }
1850 }
1851 else if (file_spec_matches_cu_file_spec && !check_inlines)
1852 {
1853 // only append the context if we aren't looking for inline call sites
1854 // by file and line and if the file spec matches that of the compile unit
1855 sc_list.Append(sc);
1856 }
1857
1858 if (!check_inlines)
1859 break;
1860 }
1861 }
1862 }
1863 }
1864 return sc_list.GetSize() - prev_size;
1865}
1866
1867void
1868SymbolFileDWARF::Index ()
1869{
1870 if (m_indexed)
1871 return;
1872 m_indexed = true;
1873 Timer scoped_timer (__PRETTY_FUNCTION__,
1874 "SymbolFileDWARF::Index (%s)",
1875 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1876
1877 DWARFDebugInfo* debug_info = DebugInfo();
1878 if (debug_info)
1879 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001880 m_aranges.reset(new DWARFDebugAranges());
1881
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001882 uint32_t cu_idx = 0;
1883 const uint32_t num_compile_units = GetNumCompileUnits();
1884 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1885 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001886 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001887
Greg Clayton96d7d742010-11-10 23:42:09 +00001888 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001889
Greg Clayton96d7d742010-11-10 23:42:09 +00001890 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001891 m_function_basename_index,
1892 m_function_fullname_index,
1893 m_function_method_index,
1894 m_function_selector_index,
1895 m_objc_class_selectors_index,
1896 m_global_index,
1897 m_type_index,
1898 m_namespace_index,
1899 DebugRanges(),
1900 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901
1902 // Keep memory down by clearing DIEs if this generate function
1903 // caused them to be parsed
1904 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001905 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 }
1907
Greg Clayton016a95e2010-09-14 02:20:48 +00001908 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001909
Greg Clayton24739922010-10-13 03:15:28 +00001910#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00001911 StreamFile s(stdout, false);
Greg Clayton24739922010-10-13 03:15:28 +00001912 s.Printf ("DWARF index for (%s) '%s/%s':",
1913 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1914 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1915 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001916 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1917 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1918 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1919 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1920 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1921 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001922 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001923 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001924#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001925 }
1926}
1927
1928uint32_t
1929SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1930{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001931 DWARFDebugInfo* info = DebugInfo();
1932 if (info == NULL)
1933 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001934
1935 // If we aren't appending the results to this list, then clear the list
1936 if (!append)
1937 variables.Clear();
1938
1939 // Remember how many variables are in the list before we search in case
1940 // we are appending the results to a variable list.
1941 const uint32_t original_size = variables.GetSize();
1942
1943 // Index the DWARF if we haven't already
1944 if (!m_indexed)
1945 Index ();
1946
Greg Claytonc685f8e2010-09-15 04:15:46 +00001947 SymbolContext sc;
1948 sc.module_sp = m_obj_file->GetModule()->GetSP();
1949 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001950
Greg Clayton96d7d742010-11-10 23:42:09 +00001951 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001952 DWARFCompileUnit* prev_cu = NULL;
1953 const DWARFDebugInfoEntry* die = NULL;
1954 std::vector<NameToDIE::Info> die_info_array;
1955 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001956 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001957 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001958 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001959
Greg Clayton96d7d742010-11-10 23:42:09 +00001960 if (curr_cu != prev_cu)
1961 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001962
Greg Clayton96d7d742010-11-10 23:42:09 +00001963 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001964
Greg Clayton96d7d742010-11-10 23:42:09 +00001965 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001966 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001967
Greg Clayton96d7d742010-11-10 23:42:09 +00001968 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001969
1970 if (variables.GetSize() - original_size >= max_matches)
1971 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001972 }
1973
1974 // Return the number of variable that were appended to the list
1975 return variables.GetSize() - original_size;
1976}
1977
1978uint32_t
1979SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1980{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001981 DWARFDebugInfo* info = DebugInfo();
1982 if (info == NULL)
1983 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001984
1985 // If we aren't appending the results to this list, then clear the list
1986 if (!append)
1987 variables.Clear();
1988
1989 // Remember how many variables are in the list before we search in case
1990 // we are appending the results to a variable list.
1991 const uint32_t original_size = variables.GetSize();
1992
1993 // Index the DWARF if we haven't already
1994 if (!m_indexed)
1995 Index ();
1996
Greg Claytonc685f8e2010-09-15 04:15:46 +00001997 SymbolContext sc;
1998 sc.module_sp = m_obj_file->GetModule()->GetSP();
1999 assert (sc.module_sp);
2000
Greg Clayton96d7d742010-11-10 23:42:09 +00002001 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002002 DWARFCompileUnit* prev_cu = NULL;
2003 const DWARFDebugInfoEntry* die = NULL;
2004 std::vector<NameToDIE::Info> die_info_array;
2005 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002006 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002008 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002009
Greg Clayton96d7d742010-11-10 23:42:09 +00002010 if (curr_cu != prev_cu)
2011 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002012
Greg Clayton96d7d742010-11-10 23:42:09 +00002013 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002014
Greg Clayton96d7d742010-11-10 23:42:09 +00002015 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002016 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002017
Greg Clayton96d7d742010-11-10 23:42:09 +00002018 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002019
Greg Claytonc685f8e2010-09-15 04:15:46 +00002020 if (variables.GetSize() - original_size >= max_matches)
2021 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002022 }
2023
2024 // Return the number of variable that were appended to the list
2025 return variables.GetSize() - original_size;
2026}
2027
2028
Greg Clayton0c5cd902010-06-28 21:30:43 +00002029void
2030SymbolFileDWARF::FindFunctions
2031(
2032 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00002033 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00002034 SymbolContextList& sc_list
2035)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002036{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002037 DWARFDebugInfo* info = DebugInfo();
2038 if (info == NULL)
2039 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002040
Greg Claytonc685f8e2010-09-15 04:15:46 +00002041 SymbolContext sc;
2042 sc.module_sp = m_obj_file->GetModule()->GetSP();
2043 assert (sc.module_sp);
2044
Greg Clayton96d7d742010-11-10 23:42:09 +00002045 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002046 DWARFCompileUnit* prev_cu = NULL;
2047 const DWARFDebugInfoEntry* die = NULL;
2048 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00002049 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002050 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002051 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002052 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002053
Greg Clayton96d7d742010-11-10 23:42:09 +00002054 if (curr_cu != prev_cu)
2055 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002056
Greg Clayton96d7d742010-11-10 23:42:09 +00002057 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00002058
2059 const DWARFDebugInfoEntry* inlined_die = NULL;
2060 if (die->Tag() == DW_TAG_inlined_subroutine)
2061 {
2062 inlined_die = die;
2063
2064 while ((die = die->GetParent()) != NULL)
2065 {
2066 if (die->Tag() == DW_TAG_subprogram)
2067 break;
2068 }
2069 }
2070 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002071 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002072 {
Greg Claytond7e05462010-11-14 00:22:48 +00002073 Address addr;
2074 // Parse all blocks if needed
2075 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002076 {
Greg Claytond7e05462010-11-14 00:22:48 +00002077 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2078 assert (sc.block != NULL);
2079 if (sc.block->GetStartAddress (addr) == false)
2080 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002081 }
Greg Claytond7e05462010-11-14 00:22:48 +00002082 else
2083 {
2084 sc.block = NULL;
2085 addr = sc.function->GetAddressRange().GetBaseAddress();
2086 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002087
Greg Claytond7e05462010-11-14 00:22:48 +00002088 if (addr.IsValid())
2089 {
2090
2091 // We found the function, so we should find the line table
2092 // and line table entry as well
2093 LineTable *line_table = sc.comp_unit->GetLineTable();
2094 if (line_table == NULL)
2095 {
2096 if (ParseCompileUnitLineTable(sc))
2097 line_table = sc.comp_unit->GetLineTable();
2098 }
2099 if (line_table != NULL)
2100 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2101
2102 sc_list.Append(sc);
2103 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002104 }
2105 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002106}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002107
Greg Claytonc685f8e2010-09-15 04:15:46 +00002108
2109void
2110SymbolFileDWARF::FindFunctions
2111(
2112 const RegularExpression &regex,
2113 const NameToDIE &name_to_die,
2114 SymbolContextList& sc_list
2115)
2116{
2117 DWARFDebugInfo* info = DebugInfo();
2118 if (info == NULL)
2119 return;
2120
2121 SymbolContext sc;
2122 sc.module_sp = m_obj_file->GetModule()->GetSP();
2123 assert (sc.module_sp);
2124
Greg Clayton96d7d742010-11-10 23:42:09 +00002125 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002126 DWARFCompileUnit* prev_cu = NULL;
2127 const DWARFDebugInfoEntry* die = NULL;
2128 std::vector<NameToDIE::Info> die_info_array;
2129 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002130 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002131 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002132 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002133
Greg Clayton96d7d742010-11-10 23:42:09 +00002134 if (curr_cu != prev_cu)
2135 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002136
Greg Clayton96d7d742010-11-10 23:42:09 +00002137 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonab843392010-12-03 17:49:14 +00002138
2139 const DWARFDebugInfoEntry* inlined_die = NULL;
2140 if (die->Tag() == DW_TAG_inlined_subroutine)
2141 {
2142 inlined_die = die;
2143
2144 while ((die = die->GetParent()) != NULL)
2145 {
2146 if (die->Tag() == DW_TAG_subprogram)
2147 break;
2148 }
2149 }
2150 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002151 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002152 {
Greg Claytonab843392010-12-03 17:49:14 +00002153 Address addr;
2154 // Parse all blocks if needed
2155 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002156 {
Greg Claytonab843392010-12-03 17:49:14 +00002157 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2158 assert (sc.block != NULL);
2159 if (sc.block->GetStartAddress (addr) == false)
2160 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002161 }
Greg Claytonab843392010-12-03 17:49:14 +00002162 else
2163 {
2164 sc.block = NULL;
2165 addr = sc.function->GetAddressRange().GetBaseAddress();
2166 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002167
Greg Claytonab843392010-12-03 17:49:14 +00002168 if (addr.IsValid())
2169 {
2170
2171 // We found the function, so we should find the line table
2172 // and line table entry as well
2173 LineTable *line_table = sc.comp_unit->GetLineTable();
2174 if (line_table == NULL)
2175 {
2176 if (ParseCompileUnitLineTable(sc))
2177 line_table = sc.comp_unit->GetLineTable();
2178 }
2179 if (line_table != NULL)
2180 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2181
2182 sc_list.Append(sc);
2183 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002184 }
2185 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002186}
2187
2188uint32_t
2189SymbolFileDWARF::FindFunctions
2190(
2191 const ConstString &name,
2192 uint32_t name_type_mask,
2193 bool append,
2194 SymbolContextList& sc_list
2195)
2196{
2197 Timer scoped_timer (__PRETTY_FUNCTION__,
2198 "SymbolFileDWARF::FindFunctions (name = '%s')",
2199 name.AsCString());
2200
Greg Clayton0c5cd902010-06-28 21:30:43 +00002201 // If we aren't appending the results to this list, then clear the list
2202 if (!append)
2203 sc_list.Clear();
2204
2205 // Remember how many sc_list are in the list before we search in case
2206 // we are appending the results to a variable list.
2207 uint32_t original_size = sc_list.GetSize();
2208
2209 // Index the DWARF if we haven't already
2210 if (!m_indexed)
2211 Index ();
2212
2213 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002214 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002215
2216 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002217 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002218
2219 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002220 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002221
2222 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002223 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002224
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002225 // Return the number of variable that were appended to the list
2226 return sc_list.GetSize() - original_size;
2227}
2228
2229
2230uint32_t
2231SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2232{
2233 Timer scoped_timer (__PRETTY_FUNCTION__,
2234 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2235 regex.GetText());
2236
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002237 // If we aren't appending the results to this list, then clear the list
2238 if (!append)
2239 sc_list.Clear();
2240
2241 // Remember how many sc_list are in the list before we search in case
2242 // we are appending the results to a variable list.
2243 uint32_t original_size = sc_list.GetSize();
2244
2245 // Index the DWARF if we haven't already
2246 if (!m_indexed)
2247 Index ();
2248
Greg Claytonc685f8e2010-09-15 04:15:46 +00002249 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002250
Greg Claytonc685f8e2010-09-15 04:15:46 +00002251 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002252
2253 // Return the number of variable that were appended to the list
2254 return sc_list.GetSize() - original_size;
2255}
Greg Claytond16e1e52011-07-12 17:06:17 +00002256void
2257SymbolFileDWARF::ReportError (const char *format, ...)
2258{
2259 ::fprintf (stderr,
2260 "error: %s/%s ",
2261 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2262 m_obj_file->GetFileSpec().GetFilename().GetCString());
2263
2264 va_list args;
2265 va_start (args, format);
2266 vfprintf (stderr, format, args);
2267 va_end (args);
2268}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002269
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002271SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002272{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002273 DWARFDebugInfo* info = DebugInfo();
2274 if (info == NULL)
2275 return 0;
2276
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002277 // If we aren't appending the results to this list, then clear the list
2278 if (!append)
2279 types.Clear();
2280
Greg Clayton6dbd3982010-09-15 05:51:24 +00002281 // Index if we already haven't to make sure the compile units
2282 // get indexed and make their global DIE index list
2283 if (!m_indexed)
2284 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002285
Greg Claytonc685f8e2010-09-15 04:15:46 +00002286 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002287 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002288 DWARFCompileUnit* prev_cu = NULL;
2289 const DWARFDebugInfoEntry* die = NULL;
2290 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002291 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002292 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002293 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002294 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002295
Greg Clayton96d7d742010-11-10 23:42:09 +00002296 if (curr_cu != prev_cu)
2297 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002298
Greg Clayton96d7d742010-11-10 23:42:09 +00002299 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002300
Greg Clayton96d7d742010-11-10 23:42:09 +00002301 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002302 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002303 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002304 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002305 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Clayton73bf5db2011-06-17 01:22:15 +00002306 if (type_sp)
2307 {
2308 types.InsertUnique (type_sp);
2309 if (types.GetSize() >= max_matches)
2310 break;
2311 }
2312 else
2313 {
2314 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
2315 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002316 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002317 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002318 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002319}
2320
2321
Greg Clayton526e5af2010-11-13 03:52:47 +00002322ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002323SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2324 const ConstString &name)
2325{
Greg Clayton526e5af2010-11-13 03:52:47 +00002326 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002327 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002328 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002329 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002330 // Index if we already haven't to make sure the compile units
2331 // get indexed and make their global DIE index list
2332 if (!m_indexed)
2333 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002334
Greg Clayton526e5af2010-11-13 03:52:47 +00002335 DWARFCompileUnit* curr_cu = NULL;
2336 DWARFCompileUnit* prev_cu = NULL;
2337 const DWARFDebugInfoEntry* die = NULL;
2338 std::vector<NameToDIE::Info> die_info_array;
2339 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2340 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2341 {
2342 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2343
2344 if (curr_cu != prev_cu)
2345 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002346
Greg Clayton526e5af2010-11-13 03:52:47 +00002347 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2348
2349 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2350 if (clang_namespace_decl)
2351 {
2352 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2353 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2354 }
2355 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002356 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002357 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002358}
2359
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002360uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002361SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002362{
2363 // Remember how many sc_list are in the list before we search in case
2364 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002365 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002366
2367 const uint32_t num_die_offsets = die_offsets.size();
2368 // Parse all of the types we found from the pubtypes matches
2369 uint32_t i;
2370 uint32_t num_matches = 0;
2371 for (i = 0; i < num_die_offsets; ++i)
2372 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002373 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2374 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002376 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002377 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002378 assert (type_sp.get() != NULL);
2379 types.InsertUnique (type_sp);
2380 ++num_matches;
2381 if (num_matches >= max_matches)
2382 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002383 }
2384 }
2385
2386 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002387 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002388}
2389
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002390
2391size_t
2392SymbolFileDWARF::ParseChildParameters
2393(
2394 const SymbolContext& sc,
2395 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002396 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002397 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002398 bool skip_artificial,
Sean Callanan763d72a2011-08-02 22:21:50 +00002399 bool &is_static,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002400 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002401 std::vector<clang_type_t>& function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00002402 std::vector<clang::ParmVarDecl*>& function_param_decls,
2403 unsigned &type_quals
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002404)
2405{
2406 if (parent_die == NULL)
2407 return 0;
2408
Greg Claytond88d7592010-09-15 08:33:30 +00002409 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2410
Greg Clayton7fedea22010-11-16 02:10:54 +00002411 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002412 const DWARFDebugInfoEntry *die;
2413 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2414 {
2415 dw_tag_t tag = die->Tag();
2416 switch (tag)
2417 {
2418 case DW_TAG_formal_parameter:
2419 {
2420 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002421 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002422 if (num_attributes > 0)
2423 {
2424 const char *name = NULL;
2425 Declaration decl;
2426 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002427 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002428 // one of None, Auto, Register, Extern, Static, PrivateExtern
2429
Sean Callanane2ef6e32010-09-23 03:01:22 +00002430 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002431 uint32_t i;
2432 for (i=0; i<num_attributes; ++i)
2433 {
2434 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2435 DWARFFormValue form_value;
2436 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2437 {
2438 switch (attr)
2439 {
2440 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2441 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2442 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2443 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2444 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002445 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002446 case DW_AT_location:
2447 // if (form_value.BlockData())
2448 // {
2449 // const DataExtractor& debug_info_data = debug_info();
2450 // uint32_t block_length = form_value.Unsigned();
2451 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2452 // }
2453 // else
2454 // {
2455 // }
2456 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002457 case DW_AT_const_value:
2458 case DW_AT_default_value:
2459 case DW_AT_description:
2460 case DW_AT_endianity:
2461 case DW_AT_is_optional:
2462 case DW_AT_segment:
2463 case DW_AT_variable_parameter:
2464 default:
2465 case DW_AT_abstract_origin:
2466 case DW_AT_sibling:
2467 break;
2468 }
2469 }
2470 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002471
Greg Clayton0fffff52010-09-24 05:15:53 +00002472 bool skip = false;
2473 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002474 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002475 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002476 {
2477 // In order to determine if a C++ member function is
2478 // "const" we have to look at the const-ness of "this"...
2479 // Ugly, but that
2480 if (arg_idx == 0)
2481 {
2482 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
2483 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type ||
2484 grandparent_die->Tag() == DW_TAG_class_type))
Sean Callanan763d72a2011-08-02 22:21:50 +00002485 {
Greg Clayton7fedea22010-11-16 02:10:54 +00002486 LanguageType language = sc.comp_unit->GetLanguage();
2487 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
2488 {
2489 // Often times compilers omit the "this" name for the
2490 // specification DIEs, so we can't rely upon the name
2491 // being in the formal parameter DIE...
2492 if (name == NULL || ::strcmp(name, "this")==0)
2493 {
2494 Type *this_type = ResolveTypeUID (param_type_die_offset);
2495 if (this_type)
Sean Callanan763d72a2011-08-02 22:21:50 +00002496 {
Greg Clayton7fedea22010-11-16 02:10:54 +00002497 uint32_t encoding_mask = this_type->GetEncodingMask();
2498 if (encoding_mask & Type::eEncodingIsPointerUID)
2499 {
Sean Callanan763d72a2011-08-02 22:21:50 +00002500 is_static = false;
2501
Greg Clayton7fedea22010-11-16 02:10:54 +00002502 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002503 type_quals |= clang::Qualifiers::Const;
Greg Clayton7fedea22010-11-16 02:10:54 +00002504 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002505 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002506 }
2507 }
2508 }
2509 }
2510 }
2511 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002512 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002513 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002514 else
2515 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002516
Greg Clayton0fffff52010-09-24 05:15:53 +00002517 // HACK: Objective C formal parameters "self" and "_cmd"
2518 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002519 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2520 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002521 {
2522 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2523 skip = true;
2524 }
2525 }
2526 }
2527
2528 if (!skip)
2529 {
2530 Type *type = ResolveTypeUID(param_type_die_offset);
2531 if (type)
2532 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002533 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002534
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002535 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002536 assert(param_var_decl);
2537 function_param_decls.push_back(param_var_decl);
2538 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002539 }
2540 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002541 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002542 }
2543 break;
2544
2545 default:
2546 break;
2547 }
2548 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002549 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002550}
2551
2552size_t
2553SymbolFileDWARF::ParseChildEnumerators
2554(
2555 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002556 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002557 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002558 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002559 const DWARFDebugInfoEntry *parent_die
2560)
2561{
2562 if (parent_die == NULL)
2563 return 0;
2564
2565 size_t enumerators_added = 0;
2566 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002567 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2568
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002569 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2570 {
2571 const dw_tag_t tag = die->Tag();
2572 if (tag == DW_TAG_enumerator)
2573 {
2574 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002575 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002576 if (num_child_attributes > 0)
2577 {
2578 const char *name = NULL;
2579 bool got_value = false;
2580 int64_t enum_value = 0;
2581 Declaration decl;
2582
2583 uint32_t i;
2584 for (i=0; i<num_child_attributes; ++i)
2585 {
2586 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2587 DWARFFormValue form_value;
2588 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2589 {
2590 switch (attr)
2591 {
2592 case DW_AT_const_value:
2593 got_value = true;
2594 enum_value = form_value.Unsigned();
2595 break;
2596
2597 case DW_AT_name:
2598 name = form_value.AsCString(&get_debug_str_data());
2599 break;
2600
2601 case DW_AT_description:
2602 default:
2603 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2604 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2605 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2606 case DW_AT_sibling:
2607 break;
2608 }
2609 }
2610 }
2611
2612 if (name && name[0] && got_value)
2613 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002614 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2615 enumerator_clang_type,
2616 decl,
2617 name,
2618 enum_value,
2619 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002620 ++enumerators_added;
2621 }
2622 }
2623 }
2624 }
2625 return enumerators_added;
2626}
2627
2628void
2629SymbolFileDWARF::ParseChildArrayInfo
2630(
2631 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002632 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002633 const DWARFDebugInfoEntry *parent_die,
2634 int64_t& first_index,
2635 std::vector<uint64_t>& element_orders,
2636 uint32_t& byte_stride,
2637 uint32_t& bit_stride
2638)
2639{
2640 if (parent_die == NULL)
2641 return;
2642
2643 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002644 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002645 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2646 {
2647 const dw_tag_t tag = die->Tag();
2648 switch (tag)
2649 {
2650 case DW_TAG_enumerator:
2651 {
2652 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002653 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002654 if (num_child_attributes > 0)
2655 {
2656 const char *name = NULL;
2657 bool got_value = false;
2658 int64_t enum_value = 0;
2659
2660 uint32_t i;
2661 for (i=0; i<num_child_attributes; ++i)
2662 {
2663 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2664 DWARFFormValue form_value;
2665 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2666 {
2667 switch (attr)
2668 {
2669 case DW_AT_const_value:
2670 got_value = true;
2671 enum_value = form_value.Unsigned();
2672 break;
2673
2674 case DW_AT_name:
2675 name = form_value.AsCString(&get_debug_str_data());
2676 break;
2677
2678 case DW_AT_description:
2679 default:
2680 case DW_AT_decl_file:
2681 case DW_AT_decl_line:
2682 case DW_AT_decl_column:
2683 case DW_AT_sibling:
2684 break;
2685 }
2686 }
2687 }
2688 }
2689 }
2690 break;
2691
2692 case DW_TAG_subrange_type:
2693 {
2694 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002695 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002696 if (num_child_attributes > 0)
2697 {
2698 const char *name = NULL;
2699 bool got_value = false;
2700 uint64_t byte_size = 0;
2701 int64_t enum_value = 0;
2702 uint64_t num_elements = 0;
2703 uint64_t lower_bound = 0;
2704 uint64_t upper_bound = 0;
2705 uint32_t i;
2706 for (i=0; i<num_child_attributes; ++i)
2707 {
2708 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2709 DWARFFormValue form_value;
2710 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2711 {
2712 switch (attr)
2713 {
2714 case DW_AT_const_value:
2715 got_value = true;
2716 enum_value = form_value.Unsigned();
2717 break;
2718
2719 case DW_AT_name:
2720 name = form_value.AsCString(&get_debug_str_data());
2721 break;
2722
2723 case DW_AT_count:
2724 num_elements = form_value.Unsigned();
2725 break;
2726
2727 case DW_AT_bit_stride:
2728 bit_stride = form_value.Unsigned();
2729 break;
2730
2731 case DW_AT_byte_stride:
2732 byte_stride = form_value.Unsigned();
2733 break;
2734
2735 case DW_AT_byte_size:
2736 byte_size = form_value.Unsigned();
2737 break;
2738
2739 case DW_AT_lower_bound:
2740 lower_bound = form_value.Unsigned();
2741 break;
2742
2743 case DW_AT_upper_bound:
2744 upper_bound = form_value.Unsigned();
2745 break;
2746
2747 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002748 case DW_AT_abstract_origin:
2749 case DW_AT_accessibility:
2750 case DW_AT_allocated:
2751 case DW_AT_associated:
2752 case DW_AT_data_location:
2753 case DW_AT_declaration:
2754 case DW_AT_description:
2755 case DW_AT_sibling:
2756 case DW_AT_threads_scaled:
2757 case DW_AT_type:
2758 case DW_AT_visibility:
2759 break;
2760 }
2761 }
2762 }
2763
2764 if (upper_bound > lower_bound)
2765 num_elements = upper_bound - lower_bound + 1;
2766
2767 if (num_elements > 0)
2768 element_orders.push_back (num_elements);
2769 }
2770 }
2771 break;
2772 }
2773 }
2774}
2775
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002776TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002777SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002778{
2779 TypeSP type_sp;
2780 if (die != NULL)
2781 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002782 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002783 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002784 if (type_ptr == NULL)
2785 {
Greg Claytonca512b32011-01-14 04:54:56 +00002786 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2787 assert (lldb_cu);
2788 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002789 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002790 }
2791 else if (type_ptr != DIE_IS_BEING_PARSED)
2792 {
2793 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002794 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002795 }
2796
2797 }
2798 return type_sp;
2799}
2800
2801clang::DeclContext *
2802SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2803{
2804 if (die_offset != DW_INVALID_OFFSET)
2805 {
2806 DWARFCompileUnitSP cu_sp;
2807 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2808 return GetClangDeclContextForDIE (cu_sp.get(), die);
2809 }
2810 return NULL;
2811}
2812
2813
Greg Clayton96d7d742010-11-10 23:42:09 +00002814clang::NamespaceDecl *
2815SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2816{
2817 if (die->Tag() == DW_TAG_namespace)
2818 {
2819 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2820 if (namespace_name)
2821 {
2822 Declaration decl; // TODO: fill in the decl object
2823 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2824 if (namespace_decl)
Greg Claytona2721472011-06-25 00:44:06 +00002825 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton96d7d742010-11-10 23:42:09 +00002826 return namespace_decl;
2827 }
2828 }
2829 return NULL;
2830}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002831
2832clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002833SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002834{
Greg Claytonca512b32011-01-14 04:54:56 +00002835 if (m_clang_tu_decl == NULL)
2836 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002837
Greg Claytonca512b32011-01-14 04:54:56 +00002838 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset());
2839 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton4cd17802011-01-25 06:17:32 +00002840 clang::DeclContext *decl_ctx = NULL;
2841
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002842 while (die != NULL)
2843 {
Greg Claytonca512b32011-01-14 04:54:56 +00002844 // If this is the original DIE that we are searching for a declaration
2845 // for, then don't look in the cache as we don't want our own decl
2846 // context to be our decl context...
2847 if (decl_die != die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002848 {
Greg Claytonca512b32011-01-14 04:54:56 +00002849 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2850 if (pos != m_die_to_decl_ctx.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002851 {
Greg Claytonca512b32011-01-14 04:54:56 +00002852 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2853 return pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002854 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002855
Greg Claytonca512b32011-01-14 04:54:56 +00002856 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2857
2858 switch (die->Tag())
2859 {
2860 case DW_TAG_namespace:
2861 {
2862 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2863 if (namespace_name)
2864 {
2865 Declaration decl; // TODO: fill in the decl object
Greg Clayton6beaaa62011-01-17 03:46:26 +00002866 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die));
Greg Claytonca512b32011-01-14 04:54:56 +00002867 if (namespace_decl)
2868 {
2869 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytona2721472011-06-25 00:44:06 +00002870 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002871 }
2872 return namespace_decl;
2873 }
2874 }
2875 break;
2876
2877 case DW_TAG_structure_type:
2878 case DW_TAG_union_type:
2879 case DW_TAG_class_type:
2880 {
Greg Clayton4cd17802011-01-25 06:17:32 +00002881 Type* type = ResolveType (curr_cu, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002882 pos = m_die_to_decl_ctx.find(die);
Greg Claytonca512b32011-01-14 04:54:56 +00002883 if (pos != m_die_to_decl_ctx.end())
2884 {
2885 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2886 return pos->second;
2887 }
Greg Clayton4cd17802011-01-25 06:17:32 +00002888 else
2889 {
2890 if (type)
2891 {
2892 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
2893 if (decl_ctx)
2894 return decl_ctx;
2895 }
2896 }
Greg Claytonca512b32011-01-14 04:54:56 +00002897 }
2898 break;
2899
2900 default:
2901 break;
2902 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002903 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002904
Greg Clayton6beaaa62011-01-17 03:46:26 +00002905 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002906 if (die_offset != DW_INVALID_OFFSET)
2907 {
2908 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2909 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2910 if (decl_ctx != m_clang_tu_decl)
2911 return decl_ctx;
2912 }
2913
Greg Clayton6beaaa62011-01-17 03:46:26 +00002914 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002915 if (die_offset != DW_INVALID_OFFSET)
2916 {
2917 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2918 decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2919 if (decl_ctx != m_clang_tu_decl)
2920 return decl_ctx;
2921 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002922
2923 die = die->GetParent();
2924 }
Greg Clayton7a345282010-11-09 23:46:37 +00002925 // Right now we have only one translation unit per module...
Greg Claytonca512b32011-01-14 04:54:56 +00002926 //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Clayton7a345282010-11-09 23:46:37 +00002927 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002928}
2929
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002930// This function can be used when a DIE is found that is a forward declaration
2931// DIE and we want to try and find a type that has the complete definition.
2932TypeSP
2933SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton1a65ae12011-01-25 23:55:37 +00002934 DWARFCompileUnit* cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002935 const DWARFDebugInfoEntry *die,
2936 const ConstString &type_name
2937)
2938{
2939 TypeSP type_sp;
2940
Greg Clayton1a65ae12011-01-25 23:55:37 +00002941 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002942 return type_sp;
2943
Greg Clayton69974892010-12-03 21:42:06 +00002944 if (!m_indexed)
2945 Index ();
2946
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002947 const dw_tag_t type_tag = die->Tag();
2948 std::vector<NameToDIE::Info> die_info_array;
2949 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2950 if (num_matches > 0)
2951 {
2952 DWARFCompileUnit* type_cu = NULL;
Greg Clayton1a65ae12011-01-25 23:55:37 +00002953 DWARFCompileUnit* curr_cu = cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002954 DWARFDebugInfo *info = DebugInfo();
2955 for (size_t i=0; i<num_matches; ++i)
2956 {
2957 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2958
2959 if (type_cu != curr_cu)
2960 {
2961 type_cu->ExtractDIEsIfNeeded (false);
2962 curr_cu = type_cu;
2963 }
2964
2965 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2966
2967 if (type_die != die && type_die->Tag() == type_tag)
2968 {
2969 // Hold off on comparing parent DIE tags until
2970 // we know what happens with stuff in namespaces
2971 // for gcc and clang...
2972 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2973 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2974 //if (parent_die->Tag() == parent_type_die->Tag())
2975 {
2976 Type *resolved_type = ResolveType (type_cu, type_die, false);
2977 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2978 {
2979 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2980 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002981 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002982 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2983 type_die->GetOffset(),
2984 type_cu->GetOffset());
2985
2986 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002987 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002988 if (!type_sp)
2989 {
2990 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2991 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002992 break;
2993 }
2994 }
2995 }
2996 }
2997 }
2998 return type_sp;
2999}
3000
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003002SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003003{
3004 TypeSP type_sp;
3005
Greg Clayton1be10fc2010-09-29 01:12:09 +00003006 if (type_is_new_ptr)
3007 *type_is_new_ptr = false;
3008
Sean Callananc7fbf732010-08-06 00:32:49 +00003009 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003010 if (die != NULL)
3011 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00003012 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003013 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003014 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003015 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003016 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003017 if (type_is_new_ptr)
3018 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003019
Greg Clayton594e5ed2010-09-27 21:07:38 +00003020 const dw_tag_t tag = die->Tag();
3021
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003022 bool is_forward_declaration = false;
3023 DWARFDebugInfoEntry::Attributes attributes;
3024 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003025 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003026 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3027 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003028 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003029 Declaration decl;
3030
Greg Clayton4957bf62010-09-30 21:49:03 +00003031 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003032 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003033
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003034 dw_attr_t attr;
3035
3036 switch (tag)
3037 {
3038 case DW_TAG_base_type:
3039 case DW_TAG_pointer_type:
3040 case DW_TAG_reference_type:
3041 case DW_TAG_typedef:
3042 case DW_TAG_const_type:
3043 case DW_TAG_restrict_type:
3044 case DW_TAG_volatile_type:
3045 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003046 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003047 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003048
Greg Claytond88d7592010-09-15 08:33:30 +00003049 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003050 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003051 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3052
3053 if (num_attributes > 0)
3054 {
3055 uint32_t i;
3056 for (i=0; i<num_attributes; ++i)
3057 {
3058 attr = attributes.AttributeAtIndex(i);
3059 DWARFFormValue form_value;
3060 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3061 {
3062 switch (attr)
3063 {
3064 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3065 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3066 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3067 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003068
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003069 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003070 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3071 // include the "&"...
3072 if (tag == DW_TAG_reference_type)
3073 {
3074 if (strchr (type_name_cstr, '&') == NULL)
3075 type_name_cstr = NULL;
3076 }
3077 if (type_name_cstr)
3078 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003079 break;
Greg Clayton36909642011-03-15 04:38:20 +00003080 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003081 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3082 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3083 default:
3084 case DW_AT_sibling:
3085 break;
3086 }
3087 }
3088 }
3089 }
3090
Greg Claytonc93237c2010-10-01 20:48:32 +00003091 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);
3092
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003093 switch (tag)
3094 {
3095 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003096 break;
3097
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003098 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003099 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003100 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3101 encoding,
3102 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003103 break;
3104
Greg Clayton526e5af2010-11-13 03:52:47 +00003105 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3106 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3107 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3108 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3109 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3110 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003111 }
3112
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003113 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3114 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3115 {
3116 static ConstString g_objc_type_name_id("id");
3117 static ConstString g_objc_type_name_Class("Class");
3118 static ConstString g_objc_type_name_selector("SEL");
3119
Greg Clayton24739922010-10-13 03:15:28 +00003120 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003121 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003122 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003123 resolve_state = Type::eResolveStateFull;
3124
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003125 }
Greg Clayton24739922010-10-13 03:15:28 +00003126 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003127 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003128 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003129 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003130 }
Greg Clayton24739922010-10-13 03:15:28 +00003131 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003132 {
Sean Callananf6c73082010-12-06 23:53:20 +00003133 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003134 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003135 }
3136 }
3137
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003138 type_sp.reset( new Type (die->GetOffset(),
3139 this,
3140 type_name_const_str,
3141 byte_size,
3142 NULL,
3143 encoding_uid,
3144 encoding_data_type,
3145 &decl,
3146 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003147 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003148
Greg Clayton594e5ed2010-09-27 21:07:38 +00003149 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003150
3151// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3152// if (encoding_type != NULL)
3153// {
3154// if (encoding_type != DIE_IS_BEING_PARSED)
3155// type_sp->SetEncodingType(encoding_type);
3156// else
3157// m_indirect_fixups.push_back(type_sp.get());
3158// }
3159 }
3160 break;
3161
3162 case DW_TAG_structure_type:
3163 case DW_TAG_union_type:
3164 case DW_TAG_class_type:
3165 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003166 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003167 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003168
Greg Clayton9e409562010-07-28 02:04:09 +00003169 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003170 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003171 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003172 if (num_attributes > 0)
3173 {
3174 uint32_t i;
3175 for (i=0; i<num_attributes; ++i)
3176 {
3177 attr = attributes.AttributeAtIndex(i);
3178 DWARFFormValue form_value;
3179 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3180 {
3181 switch (attr)
3182 {
Greg Clayton9e409562010-07-28 02:04:09 +00003183 case DW_AT_decl_file:
3184 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3185 break;
3186
3187 case DW_AT_decl_line:
3188 decl.SetLine(form_value.Unsigned());
3189 break;
3190
3191 case DW_AT_decl_column:
3192 decl.SetColumn(form_value.Unsigned());
3193 break;
3194
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003195 case DW_AT_name:
3196 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003197 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003198 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003199
3200 case DW_AT_byte_size:
3201 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003202 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003203 break;
3204
3205 case DW_AT_accessibility:
3206 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3207 break;
3208
3209 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003210 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003211 break;
3212
3213 case DW_AT_APPLE_runtime_class:
3214 class_language = (LanguageType)form_value.Signed();
3215 break;
3216
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003217 case DW_AT_allocated:
3218 case DW_AT_associated:
3219 case DW_AT_data_location:
3220 case DW_AT_description:
3221 case DW_AT_start_scope:
3222 case DW_AT_visibility:
3223 default:
3224 case DW_AT_sibling:
3225 break;
3226 }
3227 }
3228 }
3229 }
3230
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003231 UniqueDWARFASTType unique_ast_entry;
3232 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003233 {
Greg Claytone576ab22011-02-15 00:19:15 +00003234 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003235 this,
3236 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003237 die,
3238 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003239 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003240 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003241 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003242 // We have already parsed this type or from another
3243 // compile unit. GCC loves to use the "one definition
3244 // rule" which can result in multiple definitions
3245 // of the same class over and over in each compile
3246 // unit.
3247 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003248 if (type_sp)
3249 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003250 m_die_to_type[die] = type_sp.get();
3251 return type_sp;
3252 }
3253 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003254 }
3255
3256 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3257
3258 int tag_decl_kind = -1;
3259 AccessType default_accessibility = eAccessNone;
3260 if (tag == DW_TAG_structure_type)
3261 {
3262 tag_decl_kind = clang::TTK_Struct;
3263 default_accessibility = eAccessPublic;
3264 }
3265 else if (tag == DW_TAG_union_type)
3266 {
3267 tag_decl_kind = clang::TTK_Union;
3268 default_accessibility = eAccessPublic;
3269 }
3270 else if (tag == DW_TAG_class_type)
3271 {
3272 tag_decl_kind = clang::TTK_Class;
3273 default_accessibility = eAccessPrivate;
3274 }
3275
3276
3277 if (is_forward_declaration)
3278 {
3279 // We have a forward declaration to a type and we need
3280 // to try and find a full declaration. We look in the
3281 // current type index just in case we have a forward
3282 // declaration followed by an actual declarations in the
3283 // DWARF. If this fails, we need to look elsewhere...
3284
3285 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3286
3287 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003288 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003289 // We weren't able to find a full declaration in
3290 // this DWARF, see if we have a declaration anywhere
3291 // else...
3292 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003293 }
3294
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003295 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003296 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003297 // We found a real definition for this type elsewhere
3298 // so lets use it and cache the fact that we found
3299 // a complete type for this die
3300 m_die_to_type[die] = type_sp.get();
3301 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003302 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003303 }
3304 assert (tag_decl_kind != -1);
3305 bool clang_type_was_created = false;
3306 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3307 if (clang_type == NULL)
3308 {
3309 clang_type_was_created = true;
3310 clang_type = ast.CreateRecordType (type_name_cstr,
3311 tag_decl_kind,
3312 GetClangDeclContextForDIE (dwarf_cu, die),
3313 class_language);
3314 }
3315
3316 // Store a forward declaration to this class type in case any
3317 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00003318 // types for function prototypes.
3319 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003320 type_sp.reset (new Type (die->GetOffset(),
3321 this,
3322 type_name_const_str,
3323 byte_size,
3324 NULL,
3325 LLDB_INVALID_UID,
3326 Type::eEncodingIsUID,
3327 &decl,
3328 clang_type,
3329 Type::eResolveStateForward));
3330
3331
3332 // Add our type to the unique type map so we don't
3333 // end up creating many copies of the same type over
3334 // and over in the ASTContext for our module
3335 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00003336 unique_ast_entry.m_symfile = this;
3337 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003338 unique_ast_entry.m_die = die;
3339 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00003340 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3341 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003342
3343 if (die->HasChildren() == false && is_forward_declaration == false)
3344 {
3345 // No children for this struct/union/class, lets finish it
3346 ast.StartTagDeclarationDefinition (clang_type);
3347 ast.CompleteTagDeclarationDefinition (clang_type);
3348 }
3349 else if (clang_type_was_created)
3350 {
3351 // Leave this as a forward declaration until we need
3352 // to know the details of the type. lldb_private::Type
3353 // will automatically call the SymbolFile virtual function
3354 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3355 // When the definition needs to be defined.
3356 m_forward_decl_die_to_clang_type[die] = clang_type;
3357 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3358 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003359 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003360 }
3361 break;
3362
3363 case DW_TAG_enumeration_type:
3364 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003365 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003366 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003367
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003368 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003369
Greg Claytond88d7592010-09-15 08:33:30 +00003370 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003371 if (num_attributes > 0)
3372 {
3373 uint32_t i;
3374
3375 for (i=0; i<num_attributes; ++i)
3376 {
3377 attr = attributes.AttributeAtIndex(i);
3378 DWARFFormValue form_value;
3379 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3380 {
3381 switch (attr)
3382 {
Greg Clayton7a345282010-11-09 23:46:37 +00003383 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3384 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3385 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003386 case DW_AT_name:
3387 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003388 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003389 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003390 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003391 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00003392 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3393 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003394 case DW_AT_allocated:
3395 case DW_AT_associated:
3396 case DW_AT_bit_stride:
3397 case DW_AT_byte_stride:
3398 case DW_AT_data_location:
3399 case DW_AT_description:
3400 case DW_AT_start_scope:
3401 case DW_AT_visibility:
3402 case DW_AT_specification:
3403 case DW_AT_abstract_origin:
3404 case DW_AT_sibling:
3405 break;
3406 }
3407 }
3408 }
3409
Greg Claytonc93237c2010-10-01 20:48:32 +00003410 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3411
Greg Clayton1be10fc2010-09-29 01:12:09 +00003412 clang_type_t enumerator_clang_type = NULL;
3413 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3414 if (clang_type == NULL)
3415 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003416 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3417 DW_ATE_signed,
3418 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003419 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Clayton6beaaa62011-01-17 03:46:26 +00003420 GetClangDeclContextForDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003421 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003422 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003423 }
3424 else
3425 {
3426 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3427 assert (enumerator_clang_type != NULL);
3428 }
3429
Greg Claytona2721472011-06-25 00:44:06 +00003430 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3431
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003432 type_sp.reset( new Type (die->GetOffset(),
3433 this,
3434 type_name_const_str,
3435 byte_size,
3436 NULL,
3437 encoding_uid,
3438 Type::eEncodingIsUID,
3439 &decl,
3440 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003441 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003442
Greg Clayton6beaaa62011-01-17 03:46:26 +00003443#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003444 // Leave this as a forward declaration until we need
3445 // to know the details of the type. lldb_private::Type
3446 // will automatically call the SymbolFile virtual function
3447 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3448 // When the definition needs to be defined.
3449 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003450 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003451 ClangASTContext::SetHasExternalStorage (clang_type, true);
3452#else
3453 ast.StartTagDeclarationDefinition (clang_type);
3454 if (die->HasChildren())
3455 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003456 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3457 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003458 }
3459 ast.CompleteTagDeclarationDefinition (clang_type);
3460#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003461 }
3462 }
3463 break;
3464
Jim Inghamb0be4422010-08-12 01:20:14 +00003465 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003466 case DW_TAG_subprogram:
3467 case DW_TAG_subroutine_type:
3468 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003469 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003470 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003471
3472 const char *mangled = NULL;
3473 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003474 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003475 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003476 bool is_static = false;
3477 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003478 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003479
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003480 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003481 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003482
3483
Greg Claytond88d7592010-09-15 08:33:30 +00003484 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003485 if (num_attributes > 0)
3486 {
3487 uint32_t i;
3488 for (i=0; i<num_attributes; ++i)
3489 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003490 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003491 DWARFFormValue form_value;
3492 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3493 {
3494 switch (attr)
3495 {
3496 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3497 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3498 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3499 case DW_AT_name:
3500 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003501 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003502 break;
3503
3504 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3505 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003506 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003507 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003508 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3509 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003510 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3511
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003512 case DW_AT_external:
3513 if (form_value.Unsigned())
3514 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003515 if (storage == clang::SC_None)
3516 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003518 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003519 }
3520 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003521
3522 case DW_AT_allocated:
3523 case DW_AT_associated:
3524 case DW_AT_address_class:
3525 case DW_AT_artificial:
3526 case DW_AT_calling_convention:
3527 case DW_AT_data_location:
3528 case DW_AT_elemental:
3529 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003530 case DW_AT_frame_base:
3531 case DW_AT_high_pc:
3532 case DW_AT_low_pc:
3533 case DW_AT_object_pointer:
3534 case DW_AT_prototyped:
3535 case DW_AT_pure:
3536 case DW_AT_ranges:
3537 case DW_AT_recursive:
3538 case DW_AT_return_addr:
3539 case DW_AT_segment:
3540 case DW_AT_specification:
3541 case DW_AT_start_scope:
3542 case DW_AT_static_link:
3543 case DW_AT_trampoline:
3544 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545 case DW_AT_vtable_elem_location:
3546 case DW_AT_abstract_origin:
3547 case DW_AT_description:
3548 case DW_AT_sibling:
3549 break;
3550 }
3551 }
3552 }
Greg Clayton24739922010-10-13 03:15:28 +00003553 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003554
Greg Clayton24739922010-10-13 03:15:28 +00003555 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 +00003556
Greg Clayton24739922010-10-13 03:15:28 +00003557 clang_type_t return_clang_type = NULL;
3558 Type *func_type = NULL;
3559
3560 if (type_die_offset != DW_INVALID_OFFSET)
3561 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003562
Greg Clayton24739922010-10-13 03:15:28 +00003563 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003564 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003565 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003566 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003567
Greg Claytonf51de672010-10-01 02:31:07 +00003568
Greg Clayton24739922010-10-13 03:15:28 +00003569 std::vector<clang_type_t> function_param_types;
3570 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003571
Greg Clayton24739922010-10-13 03:15:28 +00003572 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00003573
3574 const DWARFDebugInfoEntry *class_die = die->GetParent();
3575 if (class_die && (class_die->Tag() == DW_TAG_structure_type ||
3576 class_die->Tag() == DW_TAG_class_type))
3577 is_static = true;
3578
Greg Clayton24739922010-10-13 03:15:28 +00003579 if (die->HasChildren())
3580 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003581 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003582 ParseChildParameters (sc,
3583 type_sp,
3584 dwarf_cu,
3585 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00003586 skip_artificial,
3587 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003588 type_list,
3589 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003590 function_param_decls,
3591 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003592 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593
Greg Clayton24739922010-10-13 03:15:28 +00003594 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003595 clang_type = ast.CreateFunctionType (return_clang_type,
3596 &function_param_types[0],
3597 function_param_types.size(),
3598 is_variadic,
3599 type_quals);
3600
Greg Clayton24739922010-10-13 03:15:28 +00003601 if (type_name_cstr)
3602 {
3603 bool type_handled = false;
3604 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3605 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003606 {
Greg Clayton24739922010-10-13 03:15:28 +00003607 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003608 {
Greg Clayton24739922010-10-13 03:15:28 +00003609 // We need to find the DW_TAG_class_type or
3610 // DW_TAG_struct_type by name so we can add this
3611 // as a member function of the class.
3612 const char *class_name_start = type_name_cstr + 2;
3613 const char *class_name_end = ::strchr (class_name_start, ' ');
3614 SymbolContext empty_sc;
3615 clang_type_t class_opaque_type = NULL;
3616 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003617 {
Greg Clayton24739922010-10-13 03:15:28 +00003618 ConstString class_name (class_name_start, class_name_end - class_name_start);
3619 TypeList types;
3620 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3621 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003622 {
Greg Clayton24739922010-10-13 03:15:28 +00003623 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003624 {
Greg Clayton24739922010-10-13 03:15:28 +00003625 Type *type = types.GetTypeAtIndex (i).get();
3626 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3627 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003628 {
Greg Clayton24739922010-10-13 03:15:28 +00003629 class_opaque_type = type_clang_forward_type;
3630 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003631 }
3632 }
3633 }
Greg Clayton24739922010-10-13 03:15:28 +00003634 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003635
Greg Clayton24739922010-10-13 03:15:28 +00003636 if (class_opaque_type)
3637 {
3638 // If accessibility isn't set to anything valid, assume public for
3639 // now...
3640 if (accessibility == eAccessNone)
3641 accessibility = eAccessPublic;
3642
3643 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003644 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3645 type_name_cstr,
3646 clang_type,
3647 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003648 type_handled = objc_method_decl != NULL;
3649 }
3650 }
3651 else if (parent_die->Tag() == DW_TAG_class_type ||
3652 parent_die->Tag() == DW_TAG_structure_type)
3653 {
3654 // Look at the parent of this DIE and see if is is
3655 // a class or struct and see if this is actually a
3656 // C++ method
3657 Type *class_type = ResolveType (dwarf_cu, parent_die);
3658 if (class_type)
3659 {
3660 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3661 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003662 {
Greg Clayton24739922010-10-13 03:15:28 +00003663 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3664 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003665 if (accessibility == eAccessNone)
3666 accessibility = eAccessPublic;
Greg Clayton931180e2011-01-27 06:44:37 +00003667
3668 if (!is_static && !die->HasChildren())
3669 {
3670 // We have a C++ member function with no children (this pointer!)
3671 // and clang will get mad if we try and make a function that isn't
3672 // well formed in the DWARF, so we will just skip it...
3673 type_handled = true;
3674 }
3675 else
3676 {
3677 clang::CXXMethodDecl *cxx_method_decl;
3678 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3679 type_name_cstr,
3680 clang_type,
3681 accessibility,
3682 is_virtual,
3683 is_static,
3684 is_inline,
3685 is_explicit);
3686 type_handled = cxx_method_decl != NULL;
3687 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003688 }
3689 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003690 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003691 }
Greg Clayton24739922010-10-13 03:15:28 +00003692
3693 if (!type_handled)
3694 {
3695 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003696 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3697 clang_type,
3698 storage,
3699 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003700
3701 // Add the decl to our DIE to decl context map
3702 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00003703 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00003704 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003705 ast.SetFunctionParameters (function_decl,
3706 &function_param_decls.front(),
3707 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003708 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003709 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003710 type_sp.reset( new Type (die->GetOffset(),
3711 this,
3712 type_name_const_str,
3713 0,
3714 NULL,
3715 LLDB_INVALID_UID,
3716 Type::eEncodingIsUID,
3717 &decl,
3718 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003719 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00003720 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003721 }
3722 break;
3723
3724 case DW_TAG_array_type:
3725 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003726 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003727 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003728
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003729 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003730 int64_t first_index = 0;
3731 uint32_t byte_stride = 0;
3732 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003733 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003734
3735 if (num_attributes > 0)
3736 {
3737 uint32_t i;
3738 for (i=0; i<num_attributes; ++i)
3739 {
3740 attr = attributes.AttributeAtIndex(i);
3741 DWARFFormValue form_value;
3742 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3743 {
3744 switch (attr)
3745 {
3746 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3747 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3748 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3749 case DW_AT_name:
3750 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003751 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003752 break;
3753
3754 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003755 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003756 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3757 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003758 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003759 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003760 case DW_AT_allocated:
3761 case DW_AT_associated:
3762 case DW_AT_data_location:
3763 case DW_AT_description:
3764 case DW_AT_ordering:
3765 case DW_AT_start_scope:
3766 case DW_AT_visibility:
3767 case DW_AT_specification:
3768 case DW_AT_abstract_origin:
3769 case DW_AT_sibling:
3770 break;
3771 }
3772 }
3773 }
3774
Greg Claytonc93237c2010-10-01 20:48:32 +00003775 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3776
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003777 Type *element_type = ResolveTypeUID(type_die_offset);
3778
3779 if (element_type)
3780 {
3781 std::vector<uint64_t> element_orders;
3782 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003783 // We have an array that claims to have no members, lets give it at least one member...
3784 if (element_orders.empty())
3785 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003786 if (byte_stride == 0 && bit_stride == 0)
3787 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00003788 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003789 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3790 uint64_t num_elements = 0;
3791 std::vector<uint64_t>::const_reverse_iterator pos;
3792 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3793 for (pos = element_orders.rbegin(); pos != end; ++pos)
3794 {
3795 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003796 clang_type = ast.CreateArrayType (array_element_type,
3797 num_elements,
3798 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003799 array_element_type = clang_type;
3800 array_element_bit_stride = array_element_bit_stride * num_elements;
3801 }
3802 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003803 type_sp.reset( new Type (die->GetOffset(),
3804 this,
3805 empty_name,
3806 array_element_bit_stride / 8,
3807 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003808 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003809 Type::eEncodingIsUID,
3810 &decl,
3811 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003812 Type::eResolveStateFull));
3813 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003814 }
3815 }
3816 }
3817 break;
3818
Greg Clayton9b81a312010-06-12 01:20:30 +00003819 case DW_TAG_ptr_to_member_type:
3820 {
3821 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3822 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3823
Greg Claytond88d7592010-09-15 08:33:30 +00003824 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003825
3826 if (num_attributes > 0) {
3827 uint32_t i;
3828 for (i=0; i<num_attributes; ++i)
3829 {
3830 attr = attributes.AttributeAtIndex(i);
3831 DWARFFormValue form_value;
3832 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3833 {
3834 switch (attr)
3835 {
3836 case DW_AT_type:
3837 type_die_offset = form_value.Reference(dwarf_cu); break;
3838 case DW_AT_containing_type:
3839 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3840 }
3841 }
3842 }
3843
3844 Type *pointee_type = ResolveTypeUID(type_die_offset);
3845 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3846
Greg Clayton526e5af2010-11-13 03:52:47 +00003847 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3848 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003849
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003850 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3851 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003852
Greg Clayton526e5af2010-11-13 03:52:47 +00003853 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3854 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003855
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003856 type_sp.reset( new Type (die->GetOffset(),
3857 this,
3858 type_name_const_str,
3859 byte_size,
3860 NULL,
3861 LLDB_INVALID_UID,
3862 Type::eEncodingIsUID,
3863 NULL,
3864 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003865 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00003866 }
3867
3868 break;
3869 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003870 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003871 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003872 break;
3873 }
3874
3875 if (type_sp.get())
3876 {
3877 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3878 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3879
3880 SymbolContextScope * symbol_context_scope = NULL;
3881 if (sc_parent_tag == DW_TAG_compile_unit)
3882 {
3883 symbol_context_scope = sc.comp_unit;
3884 }
3885 else if (sc.function != NULL)
3886 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003887 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003888 if (symbol_context_scope == NULL)
3889 symbol_context_scope = sc.function;
3890 }
3891
3892 if (symbol_context_scope != NULL)
3893 {
3894 type_sp->SetSymbolContextScope(symbol_context_scope);
3895 }
3896
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003897 // We are ready to put this type into the uniqued list up at the module level
3898 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003899
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003900 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003901 }
3902 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003903 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003904 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003905 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003906 }
3907 }
3908 return type_sp;
3909}
3910
3911size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003912SymbolFileDWARF::ParseTypes
3913(
3914 const SymbolContext& sc,
3915 DWARFCompileUnit* dwarf_cu,
3916 const DWARFDebugInfoEntry *die,
3917 bool parse_siblings,
3918 bool parse_children
3919)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003920{
3921 size_t types_added = 0;
3922 while (die != NULL)
3923 {
3924 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003925 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003926 {
3927 if (type_is_new)
3928 ++types_added;
3929 }
3930
3931 if (parse_children && die->HasChildren())
3932 {
3933 if (die->Tag() == DW_TAG_subprogram)
3934 {
3935 SymbolContext child_sc(sc);
3936 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3937 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3938 }
3939 else
3940 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3941 }
3942
3943 if (parse_siblings)
3944 die = die->GetSibling();
3945 else
3946 die = NULL;
3947 }
3948 return types_added;
3949}
3950
3951
3952size_t
3953SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3954{
3955 assert(sc.comp_unit && sc.function);
3956 size_t functions_added = 0;
3957 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3958 if (dwarf_cu)
3959 {
3960 dw_offset_t function_die_offset = sc.function->GetID();
3961 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3962 if (function_die)
3963 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003964 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965 }
3966 }
3967
3968 return functions_added;
3969}
3970
3971
3972size_t
3973SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3974{
3975 // At least a compile unit must be valid
3976 assert(sc.comp_unit);
3977 size_t types_added = 0;
3978 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3979 if (dwarf_cu)
3980 {
3981 if (sc.function)
3982 {
3983 dw_offset_t function_die_offset = sc.function->GetID();
3984 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3985 if (func_die && func_die->HasChildren())
3986 {
3987 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3988 }
3989 }
3990 else
3991 {
3992 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3993 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3994 {
3995 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3996 }
3997 }
3998 }
3999
4000 return types_added;
4001}
4002
4003size_t
4004SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4005{
4006 if (sc.comp_unit != NULL)
4007 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004008 DWARFDebugInfo* info = DebugInfo();
4009 if (info == NULL)
4010 return 0;
4011
4012 uint32_t cu_idx = UINT32_MAX;
4013 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004014
4015 if (dwarf_cu == NULL)
4016 return 0;
4017
4018 if (sc.function)
4019 {
4020 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004021
4022 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4023 assert (func_lo_pc != DW_INVALID_ADDRESS);
4024
Greg Claytonc662ec82011-06-17 22:10:16 +00004025 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4026
4027 // Let all blocks know they have parse all their variables
4028 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4029
4030 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004031 }
4032 else if (sc.comp_unit)
4033 {
4034 uint32_t vars_added = 0;
4035 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4036
4037 if (variables.get() == NULL)
4038 {
4039 variables.reset(new VariableList());
4040 sc.comp_unit->SetVariableList(variables);
4041
4042 // Index if we already haven't to make sure the compile units
4043 // get indexed and make their global DIE index list
4044 if (!m_indexed)
4045 Index ();
4046
Greg Claytonc685f8e2010-09-15 04:15:46 +00004047 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00004048 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004049 for (size_t idx=0; idx<num_globals; ++idx)
4050 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00004051 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 +00004052 if (var_sp)
4053 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004054 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004055 ++vars_added;
4056 }
4057 }
4058 }
4059 return vars_added;
4060 }
4061 }
4062 return 0;
4063}
4064
4065
4066VariableSP
4067SymbolFileDWARF::ParseVariableDIE
4068(
4069 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004070 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004071 const DWARFDebugInfoEntry *die,
4072 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004073)
4074{
4075
Greg Clayton83c5cd92010-11-14 22:13:40 +00004076 VariableSP var_sp (m_die_to_variable_sp[die]);
4077 if (var_sp)
4078 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004079
4080 const dw_tag_t tag = die->Tag();
4081 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004082 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004083 if (num_attributes > 0)
4084 {
4085 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00004086 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004087 Declaration decl;
4088 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004089 Type *var_type = NULL;
4090 DWARFExpression location;
4091 bool is_external = false;
4092 bool is_artificial = false;
Greg Clayton007d5be2011-05-30 00:49:24 +00004093 bool location_is_const_value_data = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00004094 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004095
4096 for (i=0; i<num_attributes; ++i)
4097 {
4098 dw_attr_t attr = attributes.AttributeAtIndex(i);
4099 DWARFFormValue form_value;
4100 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4101 {
4102 switch (attr)
4103 {
4104 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4105 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4106 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4107 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00004108 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00004109 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004110 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
Greg Clayton007d5be2011-05-30 00:49:24 +00004111 case DW_AT_const_value:
4112 location_is_const_value_data = true;
4113 // Fall through...
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004114 case DW_AT_location:
4115 {
4116 if (form_value.BlockData())
4117 {
4118 const DataExtractor& debug_info_data = get_debug_info_data();
4119
4120 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4121 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00004122 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004123 }
4124 else
4125 {
4126 const DataExtractor& debug_loc_data = get_debug_loc_data();
4127 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4128
4129 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4130 if (loc_list_length > 0)
4131 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004132 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4133 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4134 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004135 }
4136 }
4137 }
4138 break;
4139
4140 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004141 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004142 case DW_AT_declaration:
4143 case DW_AT_description:
4144 case DW_AT_endianity:
4145 case DW_AT_segment:
4146 case DW_AT_start_scope:
4147 case DW_AT_visibility:
4148 default:
4149 case DW_AT_abstract_origin:
4150 case DW_AT_sibling:
4151 case DW_AT_specification:
4152 break;
4153 }
4154 }
4155 }
4156
4157 if (location.IsValid())
4158 {
4159 assert(var_type != DIE_IS_BEING_PARSED);
4160
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004161 ValueType scope = eValueTypeInvalid;
4162
4163 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4164 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4165
4166 if (tag == DW_TAG_formal_parameter)
4167 scope = eValueTypeVariableArgument;
4168 else if (is_external || parent_tag == DW_TAG_compile_unit)
4169 scope = eValueTypeVariableGlobal;
4170 else
4171 scope = eValueTypeVariableLocal;
4172
4173 SymbolContextScope * symbol_context_scope = NULL;
4174 if (parent_tag == DW_TAG_compile_unit)
4175 {
4176 symbol_context_scope = sc.comp_unit;
4177 }
4178 else if (sc.function != NULL)
4179 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004180 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004181 if (symbol_context_scope == NULL)
4182 symbol_context_scope = sc.function;
4183 }
4184
4185 assert(symbol_context_scope != NULL);
4186 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00004187 name,
4188 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004189 var_type,
4190 scope,
4191 symbol_context_scope,
4192 &decl,
4193 location,
4194 is_external,
4195 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00004196
Greg Clayton007d5be2011-05-30 00:49:24 +00004197 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004198 }
4199 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00004200 // Cache var_sp even if NULL (the variable was just a specification or
4201 // was missing vital information to be able to be displayed in the debugger
4202 // (missing location due to optimization, etc)) so we don't re-parse
4203 // this DIE over and over later...
4204 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004205 return var_sp;
4206}
4207
Greg Claytonc662ec82011-06-17 22:10:16 +00004208
4209const DWARFDebugInfoEntry *
4210SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4211 dw_offset_t spec_block_die_offset,
4212 DWARFCompileUnit **result_die_cu_handle)
4213{
4214 // Give the concrete function die specified by "func_die_offset", find the
4215 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4216 // to "spec_block_die_offset"
4217 DWARFDebugInfo* info = DebugInfo();
4218
4219 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4220 if (die)
4221 {
4222 assert (*result_die_cu_handle);
4223 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4224 }
4225 return NULL;
4226}
4227
4228
4229const DWARFDebugInfoEntry *
4230SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4231 const DWARFDebugInfoEntry *die,
4232 dw_offset_t spec_block_die_offset,
4233 DWARFCompileUnit **result_die_cu_handle)
4234{
4235 if (die)
4236 {
4237 switch (die->Tag())
4238 {
4239 case DW_TAG_subprogram:
4240 case DW_TAG_inlined_subroutine:
4241 case DW_TAG_lexical_block:
4242 {
4243 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4244 {
4245 *result_die_cu_handle = dwarf_cu;
4246 return die;
4247 }
4248
4249 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4250 {
4251 *result_die_cu_handle = dwarf_cu;
4252 return die;
4253 }
4254 }
4255 break;
4256 }
4257
4258 // Give the concrete function die specified by "func_die_offset", find the
4259 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4260 // to "spec_block_die_offset"
4261 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4262 {
4263 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4264 child_die,
4265 spec_block_die_offset,
4266 result_die_cu_handle);
4267 if (result_die)
4268 return result_die;
4269 }
4270 }
4271
4272 *result_die_cu_handle = NULL;
4273 return NULL;
4274}
4275
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004276size_t
4277SymbolFileDWARF::ParseVariables
4278(
4279 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004280 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004281 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004282 const DWARFDebugInfoEntry *orig_die,
4283 bool parse_siblings,
4284 bool parse_children,
4285 VariableList* cc_variable_list
4286)
4287{
4288 if (orig_die == NULL)
4289 return 0;
4290
Greg Claytonc662ec82011-06-17 22:10:16 +00004291 VariableListSP variable_list_sp;
4292
4293 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004294 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004295 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004296 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004297 dw_tag_t tag = die->Tag();
4298
4299 // Check to see if we have already parsed this variable or constant?
4300 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004301 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004302 if (cc_variable_list)
4303 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004304 }
4305 else
4306 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004307 // We haven't already parsed it, lets do that now.
4308 if ((tag == DW_TAG_variable) ||
4309 (tag == DW_TAG_constant) ||
4310 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004311 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004312 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004313 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004314 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4315 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4316 switch (parent_tag)
4317 {
4318 case DW_TAG_compile_unit:
4319 if (sc.comp_unit != NULL)
4320 {
4321 variable_list_sp = sc.comp_unit->GetVariableList(false);
4322 if (variable_list_sp.get() == NULL)
4323 {
4324 variable_list_sp.reset(new VariableList());
4325 sc.comp_unit->SetVariableList(variable_list_sp);
4326 }
4327 }
4328 else
4329 {
4330 fprintf (stderr,
4331 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
4332 sc_parent_die->GetOffset(),
4333 DW_TAG_value_to_name (parent_tag),
4334 orig_die->GetOffset(),
4335 DW_TAG_value_to_name (orig_die->Tag()));
4336 }
4337 break;
4338
4339 case DW_TAG_subprogram:
4340 case DW_TAG_inlined_subroutine:
4341 case DW_TAG_lexical_block:
4342 if (sc.function != NULL)
4343 {
4344 // Check to see if we already have parsed the variables for the given scope
4345
4346 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4347 if (block == NULL)
4348 {
4349 // This must be a specification or abstract origin with
4350 // a concrete block couterpart in the current function. We need
4351 // to find the concrete block so we can correctly add the
4352 // variable to it
4353 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4354 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4355 sc_parent_die->GetOffset(),
4356 &concrete_block_die_cu);
4357 if (concrete_block_die)
4358 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4359 }
4360
4361 if (block != NULL)
4362 {
4363 const bool can_create = false;
4364 variable_list_sp = block->GetBlockVariableList (can_create);
4365 if (variable_list_sp.get() == NULL)
4366 {
4367 variable_list_sp.reset(new VariableList());
4368 block->SetVariableList(variable_list_sp);
4369 }
4370 }
4371 }
4372 break;
4373
4374 default:
4375 fprintf (stderr,
4376 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
4377 orig_die->GetOffset(),
4378 DW_TAG_value_to_name (orig_die->Tag()));
4379 break;
4380 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004381 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004382
4383 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004384 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00004385 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4386 if (var_sp)
4387 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004388 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004389 if (cc_variable_list)
4390 cc_variable_list->AddVariableIfUnique (var_sp);
4391 ++vars_added;
4392 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004393 }
4394 }
4395 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004396
4397 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4398
4399 if (!skip_children && parse_children && die->HasChildren())
4400 {
4401 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4402 }
4403
4404 if (parse_siblings)
4405 die = die->GetSibling();
4406 else
4407 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004408 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004409 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004410}
4411
4412//------------------------------------------------------------------
4413// PluginInterface protocol
4414//------------------------------------------------------------------
4415const char *
4416SymbolFileDWARF::GetPluginName()
4417{
4418 return "SymbolFileDWARF";
4419}
4420
4421const char *
4422SymbolFileDWARF::GetShortPluginName()
4423{
4424 return GetPluginNameStatic();
4425}
4426
4427uint32_t
4428SymbolFileDWARF::GetPluginVersion()
4429{
4430 return 1;
4431}
4432
4433void
Greg Clayton6beaaa62011-01-17 03:46:26 +00004434SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4435{
4436 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4437 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4438 if (clang_type)
4439 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4440}
4441
4442void
4443SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4444{
4445 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4446 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4447 if (clang_type)
4448 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4449}
4450
Greg Claytona2721472011-06-25 00:44:06 +00004451void
Sean Callanancc427fa2011-07-30 02:42:06 +00004452SymbolFileDWARF::DumpIndexes ()
4453{
4454 StreamFile s(stdout, false);
4455
4456 s.Printf ("DWARF index for (%s) '%s/%s':",
4457 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4458 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4459 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4460 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4461 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4462 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4463 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4464 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4465 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4466 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4467 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4468}
4469
4470void
4471SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4472 const char *name,
4473 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00004474{
Sean Callanancc427fa2011-07-30 02:42:06 +00004475 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00004476
4477 if (iter == m_decl_ctx_to_die.end())
4478 return;
4479
Sean Callanancc427fa2011-07-30 02:42:06 +00004480 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytona2721472011-06-25 00:44:06 +00004481
4482 if (!results)
4483 return;
4484
4485 DWARFDebugInfo* info = DebugInfo();
4486
4487 std::vector<NameToDIE::Info> die_info_array;
4488
Greg Clayton1d4313b2011-07-07 04:49:07 +00004489 size_t num_matches = m_type_index.Find (ConstString(name), die_info_array);
Greg Claytona2721472011-06-25 00:44:06 +00004490
4491 if (num_matches)
4492 {
4493 for (int i = 0;
4494 i < num_matches;
4495 ++i)
4496 {
4497 DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
4498 compile_unit->ExtractDIEsIfNeeded (false);
4499 const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
4500
Sean Callanancc427fa2011-07-30 02:42:06 +00004501 if (die->GetParent() != context_die)
Greg Claytona2721472011-06-25 00:44:06 +00004502 continue;
4503
4504 Type *matching_type = ResolveType (compile_unit, die);
4505
4506 lldb::clang_type_t type = matching_type->GetClangFullType();
4507 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4508
Sean Callanancc427fa2011-07-30 02:42:06 +00004509 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004510 {
4511 clang::TagDecl *tag_decl = tag_type->getDecl();
4512 results->push_back(tag_decl);
4513 }
Sean Callanancc427fa2011-07-30 02:42:06 +00004514 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004515 {
4516 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4517 results->push_back(typedef_decl);
4518 }
4519 }
4520 }
4521}
4522
4523void
4524SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4525 const clang::DeclContext *DC,
4526 clang::DeclarationName Name,
4527 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4528{
4529 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4530
Sean Callanancc427fa2011-07-30 02:42:06 +00004531 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytona2721472011-06-25 00:44:06 +00004532}