blob: e25acbb28f95592df66a15a7204ed0eb3f0fc1d3 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
Sean Callanancc427fa2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000033#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
35#include "lldb/Core/Value.h"
36
37#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000038#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Symbol/CompileUnit.h"
40#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolVendor.h"
43#include "lldb/Symbol/VariableList.h"
44
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000045#include "lldb/Target/ObjCLanguageRuntime.h"
46
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "DWARFCompileUnit.h"
48#include "DWARFDebugAbbrev.h"
49#include "DWARFDebugAranges.h"
50#include "DWARFDebugInfo.h"
51#include "DWARFDebugInfoEntry.h"
52#include "DWARFDebugLine.h"
53#include "DWARFDebugPubnames.h"
54#include "DWARFDebugRanges.h"
55#include "DWARFDIECollection.h"
56#include "DWARFFormValue.h"
57#include "DWARFLocationList.h"
58#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000059#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
61#include <map>
62
Greg Clayton62742b12010-11-11 01:09:45 +000063//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000064
65#ifdef ENABLE_DEBUG_PRINTF
66#include <stdio.h>
67#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
68#else
69#define DEBUG_PRINTF(fmt, ...)
70#endif
71
Greg Clayton594e5ed2010-09-27 21:07:38 +000072#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
74using namespace lldb;
75using namespace lldb_private;
76
77
Sean Callananc7fbf732010-08-06 00:32:49 +000078static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000079DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080{
81 switch (dwarf_accessibility)
82 {
Sean Callananc7fbf732010-08-06 00:32:49 +000083 case DW_ACCESS_public: return eAccessPublic;
84 case DW_ACCESS_private: return eAccessPrivate;
85 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000086 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 }
Sean Callananc7fbf732010-08-06 00:32:49 +000088 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089}
90
91void
92SymbolFileDWARF::Initialize()
93{
94 LogChannelDWARF::Initialize();
95 PluginManager::RegisterPlugin (GetPluginNameStatic(),
96 GetPluginDescriptionStatic(),
97 CreateInstance);
98}
99
100void
101SymbolFileDWARF::Terminate()
102{
103 PluginManager::UnregisterPlugin (CreateInstance);
104 LogChannelDWARF::Initialize();
105}
106
107
108const char *
109SymbolFileDWARF::GetPluginNameStatic()
110{
Greg Claytond4a2b372011-09-12 23:21:58 +0000111 return "dwarf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112}
113
114const char *
115SymbolFileDWARF::GetPluginDescriptionStatic()
116{
117 return "DWARF and DWARF3 debug symbol file reader.";
118}
119
120
121SymbolFile*
122SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
123{
124 return new SymbolFileDWARF(obj_file);
125}
126
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000127TypeList *
128SymbolFileDWARF::GetTypeList ()
129{
130 if (m_debug_map_symfile)
131 return m_debug_map_symfile->GetTypeList();
132 return m_obj_file->GetModule()->GetTypeList();
133
134}
135
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136//----------------------------------------------------------------------
137// Gets the first parent that is a lexical block, function or inlined
138// subroutine, or compile unit.
139//----------------------------------------------------------------------
140static const DWARFDebugInfoEntry *
141GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
142{
143 const DWARFDebugInfoEntry *die;
144 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
145 {
146 dw_tag_t tag = die->Tag();
147
148 switch (tag)
149 {
150 case DW_TAG_compile_unit:
151 case DW_TAG_subprogram:
152 case DW_TAG_inlined_subroutine:
153 case DW_TAG_lexical_block:
154 return die;
155 }
156 }
157 return NULL;
158}
159
160
Greg Clayton450e3f32010-10-12 02:24:53 +0000161SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
162 SymbolFile (objfile),
163 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000164 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000166 m_data_debug_abbrev (),
167 m_data_debug_aranges (),
168 m_data_debug_frame (),
169 m_data_debug_info (),
170 m_data_debug_line (),
171 m_data_debug_loc (),
172 m_data_debug_ranges (),
173 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000174 m_data_apple_names (),
175 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000176 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 m_info(),
179 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000180 m_apple_names_ap (),
181 m_apple_types_ap (),
182 m_apple_namespaces_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000183 m_function_basename_index(),
184 m_function_fullname_index(),
185 m_function_method_index(),
186 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000187 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000188 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000189 m_type_index(),
190 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000191 m_indexed (false),
192 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000193 m_ranges(),
194 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195{
196}
197
198SymbolFileDWARF::~SymbolFileDWARF()
199{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000200 if (m_is_external_ast_source)
201 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
202}
203
204static const ConstString &
205GetDWARFMachOSegmentName ()
206{
207 static ConstString g_dwarf_section_name ("__DWARF");
208 return g_dwarf_section_name;
209}
210
Greg Claytone576ab22011-02-15 00:19:15 +0000211UniqueDWARFASTTypeMap &
212SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
213{
214 if (m_debug_map_symfile)
215 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
216 return m_unique_ast_type_map;
217}
218
Greg Clayton6beaaa62011-01-17 03:46:26 +0000219ClangASTContext &
220SymbolFileDWARF::GetClangASTContext ()
221{
222 if (m_debug_map_symfile)
223 return m_debug_map_symfile->GetClangASTContext ();
224
225 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
226 if (!m_is_external_ast_source)
227 {
228 m_is_external_ast_source = true;
229 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
230 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
231 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000232 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000233 this));
234
235 ast.SetExternalSource (ast_source_ap);
236 }
237 return ast;
238}
239
240void
241SymbolFileDWARF::InitializeObject()
242{
243 // Install our external AST source callbacks so we can complete Clang types.
244 Module *module = m_obj_file->GetModule();
245 if (module)
246 {
247 const SectionList *section_list = m_obj_file->GetSectionList();
248
249 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
250
251 // Memory map the DWARF mach-o segment so we have everything mmap'ed
252 // to keep our heap memory usage down.
253 if (section)
254 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
255 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000256 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000257 if (m_data_apple_names.GetByteSize() > 0)
258 {
259 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), true));
260 if (!m_apple_names_ap->IsValid())
261 m_apple_names_ap.reset();
262 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000263 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000264 if (m_data_apple_types.GetByteSize() > 0)
265 {
266 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), false));
267 if (!m_apple_types_ap->IsValid())
268 m_apple_types_ap.reset();
269 }
270
271 get_apple_namespaces_data();
272 if (m_data_apple_namespaces.GetByteSize() > 0)
273 {
274 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), false));
275 if (!m_apple_namespaces_ap->IsValid())
276 m_apple_namespaces_ap.reset();
277 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000278
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279}
280
281bool
282SymbolFileDWARF::SupportedVersion(uint16_t version)
283{
284 return version == 2 || version == 3;
285}
286
287uint32_t
288SymbolFileDWARF::GetAbilities ()
289{
290 uint32_t abilities = 0;
291 if (m_obj_file != NULL)
292 {
293 const Section* section = NULL;
294 const SectionList *section_list = m_obj_file->GetSectionList();
295 if (section_list == NULL)
296 return 0;
297
298 uint64_t debug_abbrev_file_size = 0;
299 uint64_t debug_aranges_file_size = 0;
300 uint64_t debug_frame_file_size = 0;
301 uint64_t debug_info_file_size = 0;
302 uint64_t debug_line_file_size = 0;
303 uint64_t debug_loc_file_size = 0;
304 uint64_t debug_macinfo_file_size = 0;
305 uint64_t debug_pubnames_file_size = 0;
306 uint64_t debug_pubtypes_file_size = 0;
307 uint64_t debug_ranges_file_size = 0;
308 uint64_t debug_str_file_size = 0;
309
Greg Clayton6beaaa62011-01-17 03:46:26 +0000310 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311
312 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000313 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314
Greg Clayton4ceb9982010-07-21 22:54:26 +0000315 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 if (section != NULL)
317 {
318 debug_info_file_size = section->GetByteSize();
319
Greg Clayton4ceb9982010-07-21 22:54:26 +0000320 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321 if (section)
322 debug_abbrev_file_size = section->GetByteSize();
323 else
324 m_flags.Set (flagsGotDebugAbbrevData);
325
Greg Clayton4ceb9982010-07-21 22:54:26 +0000326 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 if (section)
328 debug_aranges_file_size = section->GetByteSize();
329 else
330 m_flags.Set (flagsGotDebugArangesData);
331
Greg Clayton4ceb9982010-07-21 22:54:26 +0000332 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 if (section)
334 debug_frame_file_size = section->GetByteSize();
335 else
336 m_flags.Set (flagsGotDebugFrameData);
337
Greg Clayton4ceb9982010-07-21 22:54:26 +0000338 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000339 if (section)
340 debug_line_file_size = section->GetByteSize();
341 else
342 m_flags.Set (flagsGotDebugLineData);
343
Greg Clayton4ceb9982010-07-21 22:54:26 +0000344 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 if (section)
346 debug_loc_file_size = section->GetByteSize();
347 else
348 m_flags.Set (flagsGotDebugLocData);
349
Greg Clayton4ceb9982010-07-21 22:54:26 +0000350 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351 if (section)
352 debug_macinfo_file_size = section->GetByteSize();
353 else
354 m_flags.Set (flagsGotDebugMacInfoData);
355
Greg Clayton4ceb9982010-07-21 22:54:26 +0000356 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357 if (section)
358 debug_pubnames_file_size = section->GetByteSize();
359 else
360 m_flags.Set (flagsGotDebugPubNamesData);
361
Greg Clayton4ceb9982010-07-21 22:54:26 +0000362 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363 if (section)
364 debug_pubtypes_file_size = section->GetByteSize();
365 else
366 m_flags.Set (flagsGotDebugPubTypesData);
367
Greg Clayton4ceb9982010-07-21 22:54:26 +0000368 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 if (section)
370 debug_ranges_file_size = section->GetByteSize();
371 else
372 m_flags.Set (flagsGotDebugRangesData);
373
Greg Clayton4ceb9982010-07-21 22:54:26 +0000374 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375 if (section)
376 debug_str_file_size = section->GetByteSize();
377 else
378 m_flags.Set (flagsGotDebugStrData);
379 }
380
381 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
382 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
383
384 if (debug_line_file_size > 0)
385 abilities |= LineTables;
386
387 if (debug_aranges_file_size > 0)
388 abilities |= AddressAcceleratorTable;
389
390 if (debug_pubnames_file_size > 0)
391 abilities |= FunctionAcceleratorTable;
392
393 if (debug_pubtypes_file_size > 0)
394 abilities |= TypeAcceleratorTable;
395
396 if (debug_macinfo_file_size > 0)
397 abilities |= MacroInformation;
398
399 if (debug_frame_file_size > 0)
400 abilities |= CallFrameInformation;
401 }
402 return abilities;
403}
404
405const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000406SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407{
408 if (m_flags.IsClear (got_flag))
409 {
410 m_flags.Set (got_flag);
411 const SectionList *section_list = m_obj_file->GetSectionList();
412 if (section_list)
413 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000414 Section *section = section_list->FindSectionByType(sect_type, true).get();
415 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 {
417 // See if we memory mapped the DWARF segment?
418 if (m_dwarf_data.GetByteSize())
419 {
420 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
421 }
422 else
423 {
424 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
425 data.Clear();
426 }
427 }
428 }
429 }
430 return data;
431}
432
433const DataExtractor&
434SymbolFileDWARF::get_debug_abbrev_data()
435{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000436 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437}
438
439const DataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000440SymbolFileDWARF::get_debug_aranges_data()
441{
442 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
443}
444
445const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446SymbolFileDWARF::get_debug_frame_data()
447{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000448 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449}
450
451const DataExtractor&
452SymbolFileDWARF::get_debug_info_data()
453{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000454 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455}
456
457const DataExtractor&
458SymbolFileDWARF::get_debug_line_data()
459{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000460 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461}
462
463const DataExtractor&
464SymbolFileDWARF::get_debug_loc_data()
465{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000466 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467}
468
469const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470SymbolFileDWARF::get_debug_ranges_data()
471{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000472 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473}
474
475const DataExtractor&
476SymbolFileDWARF::get_debug_str_data()
477{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000478 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000479}
480
Greg Claytonf9eec202011-09-01 23:16:13 +0000481const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000482SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000483{
Greg Clayton17674402011-09-28 17:06:40 +0000484 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000485}
486
487const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000488SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000489{
Greg Clayton17674402011-09-28 17:06:40 +0000490 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000491}
492
Greg Clayton7f995132011-10-04 22:41:51 +0000493const DataExtractor&
494SymbolFileDWARF::get_apple_namespaces_data()
495{
496 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
497}
498
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499
500DWARFDebugAbbrev*
501SymbolFileDWARF::DebugAbbrev()
502{
503 if (m_abbr.get() == NULL)
504 {
505 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
506 if (debug_abbrev_data.GetByteSize() > 0)
507 {
508 m_abbr.reset(new DWARFDebugAbbrev());
509 if (m_abbr.get())
510 m_abbr->Parse(debug_abbrev_data);
511 }
512 }
513 return m_abbr.get();
514}
515
516const DWARFDebugAbbrev*
517SymbolFileDWARF::DebugAbbrev() const
518{
519 return m_abbr.get();
520}
521
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522
523DWARFDebugInfo*
524SymbolFileDWARF::DebugInfo()
525{
526 if (m_info.get() == NULL)
527 {
528 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
529 if (get_debug_info_data().GetByteSize() > 0)
530 {
531 m_info.reset(new DWARFDebugInfo());
532 if (m_info.get())
533 {
534 m_info->SetDwarfData(this);
535 }
536 }
537 }
538 return m_info.get();
539}
540
541const DWARFDebugInfo*
542SymbolFileDWARF::DebugInfo() const
543{
544 return m_info.get();
545}
546
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547DWARFCompileUnit*
548SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
549{
550 DWARFDebugInfo* info = DebugInfo();
551 if (info)
552 return info->GetCompileUnit(cu_uid).get();
553 return NULL;
554}
555
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556
557DWARFDebugRanges*
558SymbolFileDWARF::DebugRanges()
559{
560 if (m_ranges.get() == NULL)
561 {
562 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
563 if (get_debug_ranges_data().GetByteSize() > 0)
564 {
565 m_ranges.reset(new DWARFDebugRanges());
566 if (m_ranges.get())
567 m_ranges->Extract(this);
568 }
569 }
570 return m_ranges.get();
571}
572
573const DWARFDebugRanges*
574SymbolFileDWARF::DebugRanges() const
575{
576 return m_ranges.get();
577}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578
579bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000580SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581{
Greg Clayton96d7d742010-11-10 23:42:09 +0000582 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000583 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000584 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000585 if (cu_die)
586 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000587 const char * cu_die_name = cu_die->GetName(this, curr_cu);
588 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham0f35ac22011-08-24 23:34:20 +0000589 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000590 if (cu_die_name)
591 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000592 FileSpec cu_file_spec;
593
Greg Clayton7bd65b92011-02-09 23:39:34 +0000594 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000596 // If we have a full path to the compile unit, we don't need to resolve
597 // the file. This can be expensive e.g. when the source files are NFS mounted.
598 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599 }
600 else
601 {
602 std::string fullpath(cu_comp_dir);
603 if (*fullpath.rbegin() != '/')
604 fullpath += '/';
605 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000606 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 }
608
Jim Ingham0f35ac22011-08-24 23:34:20 +0000609 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), cu_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 if (compile_unit_sp.get())
611 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000612 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613 return true;
614 }
615 }
616 }
617 }
618 return false;
619}
620
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000621uint32_t
622SymbolFileDWARF::GetNumCompileUnits()
623{
624 DWARFDebugInfo* info = DebugInfo();
625 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000627 return 0;
628}
629
630CompUnitSP
631SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
632{
633 CompUnitSP comp_unit;
634 DWARFDebugInfo* info = DebugInfo();
635 if (info)
636 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000637 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
638 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 {
640 // Our symbol vendor shouldn't be asking us to add a compile unit that
641 // has already been added to it, which this DWARF plug-in knows as it
642 // stores the lldb compile unit (CompileUnit) pointer in each
643 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000644 assert(curr_cu->GetUserData() == NULL);
645 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646 }
647 }
648 return comp_unit;
649}
650
651static void
652AddRangesToBlock
653(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000654 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655 DWARFDebugRanges::RangeList& ranges,
656 addr_t block_base_addr
657)
658{
659 ranges.SubtractOffset (block_base_addr);
660 size_t range_idx = 0;
661 const DWARFDebugRanges::Range *debug_range;
662 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
663 {
Greg Clayton6c7f5612011-09-29 23:41:34 +0000664 block.AddRange(VMRange (debug_range->begin_offset, debug_range->end_offset));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665 }
666}
667
668
669Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000670SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671{
672 DWARFDebugRanges::RangeList func_ranges;
673 const char *name = NULL;
674 const char *mangled = NULL;
675 int decl_file = 0;
676 int decl_line = 0;
677 int decl_column = 0;
678 int call_file = 0;
679 int call_line = 0;
680 int call_column = 0;
681 DWARFExpression frame_base;
682
Greg Claytonc93237c2010-10-01 20:48:32 +0000683 assert (die->Tag() == DW_TAG_subprogram);
684
685 if (die->Tag() != DW_TAG_subprogram)
686 return NULL;
687
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
689 {
690 // Union of all ranges in the function DIE (if the function is discontiguous)
691 AddressRange func_range;
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 Clayton0bd4e1b2011-09-30 20:52:25 +0000716 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +0000717 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718
719 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
720
721 func_range.GetBaseAddress().ResolveLinkedAddress();
722
723 func_sp.reset(new Function (sc.comp_unit,
724 die->GetOffset(), // UserID is the DIE offset
725 die->GetOffset(),
726 func_name,
727 func_type,
728 func_range)); // first address range
729
730 if (func_sp.get() != NULL)
731 {
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000732 if (frame_base.IsValid())
733 func_sp->GetFrameBaseExpression() = frame_base;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000734 sc.comp_unit->AddFunction(func_sp);
735 return func_sp.get();
736 }
737 }
738 }
739 return NULL;
740}
741
742size_t
743SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
744{
745 assert (sc.comp_unit);
746 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000747 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748 if (dwarf_cu)
749 {
750 DWARFDIECollection function_dies;
751 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
752 size_t func_idx;
753 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
754 {
755 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
756 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
757 {
758 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
759 ++functions_added;
760 }
761 }
762 //FixupTypes();
763 }
764 return functions_added;
765}
766
767bool
768SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
769{
770 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000771 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
772 assert (curr_cu);
773 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000774
775 if (cu_die)
776 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000777 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
778 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779
780 // All file indexes in DWARF are one based and a file of index zero is
781 // supposed to be the compile unit itself.
782 support_files.Append (*sc.comp_unit);
783
784 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
785 }
786 return false;
787}
788
789struct ParseDWARFLineTableCallbackInfo
790{
791 LineTable* line_table;
792 const SectionList *section_list;
793 lldb::addr_t prev_sect_file_base_addr;
794 lldb::addr_t curr_sect_file_base_addr;
795 bool is_oso_for_debug_map;
796 bool prev_in_final_executable;
797 DWARFDebugLine::Row prev_row;
798 SectionSP prev_section_sp;
799 SectionSP curr_section_sp;
800};
801
802//----------------------------------------------------------------------
803// ParseStatementTableCallback
804//----------------------------------------------------------------------
805static void
806ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
807{
808 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
809 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
810 {
811 // Just started parsing the line table
812 }
813 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
814 {
815 // Done parsing line table, nothing to do for the cleanup
816 }
817 else
818 {
819 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
820 // We have a new row, lets append it
821
822 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
823 {
824 info->prev_section_sp = info->curr_section_sp;
825 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
826 // If this is an end sequence entry, then we subtract one from the
827 // address to make sure we get an address that is not the end of
828 // a section.
829 if (state.end_sequence && state.address != 0)
830 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
831 else
832 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
833
834 if (info->curr_section_sp.get())
835 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
836 else
837 info->curr_sect_file_base_addr = 0;
838 }
839 if (info->curr_section_sp.get())
840 {
841 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
842 // Check for the fancy section magic to determine if we
843
844 if (info->is_oso_for_debug_map)
845 {
846 // When this is a debug map object file that contains DWARF
847 // (referenced from an N_OSO debug map nlist entry) we will have
848 // a file address in the file range for our section from the
849 // original .o file, and a load address in the executable that
850 // contains the debug map.
851 //
852 // If the sections for the file range and load range are
853 // different, we have a remapped section for the function and
854 // this address is resolved. If they are the same, then the
855 // function for this address didn't make it into the final
856 // executable.
857 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
858
859 // If we are doing DWARF with debug map, then we need to carefully
860 // add each line table entry as there may be gaps as functions
861 // get moved around or removed.
862 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
863 {
864 if (info->prev_in_final_executable)
865 {
866 bool terminate_previous_entry = false;
867 if (!curr_in_final_executable)
868 {
869 // Check for the case where the previous line entry
870 // in a function made it into the final executable,
871 // yet the current line entry falls in a function
872 // that didn't. The line table used to be contiguous
873 // through this address range but now it isn't. We
874 // need to terminate the previous line entry so
875 // that we can reconstruct the line range correctly
876 // for it and to keep the line table correct.
877 terminate_previous_entry = true;
878 }
879 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
880 {
881 // Check for cases where the line entries used to be
882 // contiguous address ranges, but now they aren't.
883 // This can happen when order files specify the
884 // ordering of the functions.
885 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
886 Section *curr_sect = info->curr_section_sp.get();
887 Section *prev_sect = info->prev_section_sp.get();
888 assert (curr_sect->GetLinkedSection());
889 assert (prev_sect->GetLinkedSection());
890 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
891 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
892 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
893 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
894 if (object_file_addr_delta != linked_file_addr_delta)
895 terminate_previous_entry = true;
896 }
897
898 if (terminate_previous_entry)
899 {
900 line_table->InsertLineEntry (info->prev_section_sp,
901 state.address - info->prev_sect_file_base_addr,
902 info->prev_row.line,
903 info->prev_row.column,
904 info->prev_row.file,
905 false, // is_stmt
906 false, // basic_block
907 false, // state.prologue_end
908 false, // state.epilogue_begin
909 true); // end_sequence);
910 }
911 }
912 }
913
914 if (curr_in_final_executable)
915 {
916 line_table->InsertLineEntry (info->curr_section_sp,
917 curr_line_section_offset,
918 state.line,
919 state.column,
920 state.file,
921 state.is_stmt,
922 state.basic_block,
923 state.prologue_end,
924 state.epilogue_begin,
925 state.end_sequence);
926 info->prev_section_sp = info->curr_section_sp;
927 }
928 else
929 {
930 // If the current address didn't make it into the final
931 // executable, the current section will be the __text
932 // segment in the .o file, so we need to clear this so
933 // we can catch the next function that did make it into
934 // the final executable.
935 info->prev_section_sp.reset();
936 info->curr_section_sp.reset();
937 }
938
939 info->prev_in_final_executable = curr_in_final_executable;
940 }
941 else
942 {
943 // We are not in an object file that contains DWARF for an
944 // N_OSO, this is just a normal DWARF file. The DWARF spec
945 // guarantees that the addresses will be in increasing order
946 // so, since we store line tables in file address order, we
947 // can always just append the line entry without needing to
948 // search for the correct insertion point (we don't need to
949 // use LineEntry::InsertLineEntry()).
950 line_table->AppendLineEntry (info->curr_section_sp,
951 curr_line_section_offset,
952 state.line,
953 state.column,
954 state.file,
955 state.is_stmt,
956 state.basic_block,
957 state.prologue_end,
958 state.epilogue_begin,
959 state.end_sequence);
960 }
961 }
962
963 info->prev_row = state;
964 }
965}
966
967bool
968SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
969{
970 assert (sc.comp_unit);
971 if (sc.comp_unit->GetLineTable() != NULL)
972 return true;
973
974 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
975 if (dwarf_cu)
976 {
977 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
978 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
979 if (cu_line_offset != DW_INVALID_OFFSET)
980 {
981 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
982 if (line_table_ap.get())
983 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000984 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000985 uint32_t offset = cu_line_offset;
986 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
987 sc.comp_unit->SetLineTable(line_table_ap.release());
988 return true;
989 }
990 }
991 }
992 return false;
993}
994
995size_t
996SymbolFileDWARF::ParseFunctionBlocks
997(
998 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000999 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001000 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001001 const DWARFDebugInfoEntry *die,
1002 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001003 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001004)
1005{
1006 size_t blocks_added = 0;
1007 while (die != NULL)
1008 {
1009 dw_tag_t tag = die->Tag();
1010
1011 switch (tag)
1012 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001013 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001014 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015 case DW_TAG_lexical_block:
1016 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001017 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001018 if (tag == DW_TAG_subprogram)
1019 {
1020 // Skip any DW_TAG_subprogram DIEs that are inside
1021 // of a normal or inlined functions. These will be
1022 // parsed on their own as separate entities.
1023
1024 if (depth > 0)
1025 break;
1026
1027 block = parent_block;
1028 }
1029 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001030 {
1031 BlockSP block_sp(new Block (die->GetOffset()));
1032 parent_block->AddChild(block_sp);
1033 block = block_sp.get();
1034 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001035 DWARFDebugRanges::RangeList ranges;
1036 const char *name = NULL;
1037 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001038
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001039 int decl_file = 0;
1040 int decl_line = 0;
1041 int decl_column = 0;
1042 int call_file = 0;
1043 int call_line = 0;
1044 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001045 if (die->GetDIENamesAndRanges (this,
1046 dwarf_cu,
1047 name,
1048 mangled_name,
1049 ranges,
1050 decl_file, decl_line, decl_column,
1051 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001052 {
1053 if (tag == DW_TAG_subprogram)
1054 {
1055 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1056 subprogram_low_pc = ranges.LowestAddress(0);
1057 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001058 else if (tag == DW_TAG_inlined_subroutine)
1059 {
1060 // We get called here for inlined subroutines in two ways.
1061 // The first time is when we are making the Function object
1062 // for this inlined concrete instance. Since we're creating a top level block at
1063 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1064 // adjust the containing address.
1065 // The second time is when we are parsing the blocks inside the function that contains
1066 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1067 // function the offset will be for that function.
1068 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1069 {
1070 subprogram_low_pc = ranges.LowestAddress(0);
1071 }
1072 }
1073
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001074 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075
1076 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1077 {
1078 std::auto_ptr<Declaration> decl_ap;
1079 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001080 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1081 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082
1083 std::auto_ptr<Declaration> call_ap;
1084 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001085 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1086 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001088 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089 }
1090
1091 ++blocks_added;
1092
Greg Claytondd7feaf2011-08-12 17:54:33 +00001093 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001095 blocks_added += ParseFunctionBlocks (sc,
1096 block,
1097 dwarf_cu,
1098 die->GetFirstChild(),
1099 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001100 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001101 }
1102 }
1103 }
1104 break;
1105 default:
1106 break;
1107 }
1108
Greg Claytondd7feaf2011-08-12 17:54:33 +00001109 // Only parse siblings of the block if we are not at depth zero. A depth
1110 // of zero indicates we are currently parsing the top level
1111 // DW_TAG_subprogram DIE
1112
1113 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001114 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001115 else
1116 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001117 }
1118 return blocks_added;
1119}
1120
1121size_t
1122SymbolFileDWARF::ParseChildMembers
1123(
1124 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001125 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001126 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001127 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001128 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1130 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001131 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001132 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 bool &is_a_class
1134)
1135{
1136 if (parent_die == NULL)
1137 return 0;
1138
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 size_t count = 0;
1140 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001141 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001142 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001143
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1145 {
1146 dw_tag_t tag = die->Tag();
1147
1148 switch (tag)
1149 {
1150 case DW_TAG_member:
1151 {
1152 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001153 const size_t num_attributes = die->GetAttributes (this,
1154 dwarf_cu,
1155 fixed_form_sizes,
1156 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157 if (num_attributes > 0)
1158 {
1159 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001160 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001162 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001164 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001165 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 size_t byte_size = 0;
1167 size_t bit_offset = 0;
1168 size_t bit_size = 0;
1169 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001170 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 {
1172 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1173 DWARFFormValue form_value;
1174 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1175 {
1176 switch (attr)
1177 {
1178 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1179 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1180 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1181 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1182 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1183 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1184 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1185 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1186 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001187// if (form_value.BlockData())
1188// {
1189// Value initialValue(0);
1190// Value memberOffset(0);
1191// const DataExtractor& debug_info_data = get_debug_info_data();
1192// uint32_t block_length = form_value.Unsigned();
1193// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1194// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1195// {
1196// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1197// }
1198// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 break;
1200
Greg Clayton8cf05932010-07-22 18:30:50 +00001201 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001202 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203 case DW_AT_declaration:
1204 case DW_AT_description:
1205 case DW_AT_mutable:
1206 case DW_AT_visibility:
1207 default:
1208 case DW_AT_sibling:
1209 break;
1210 }
1211 }
1212 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001213
1214 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1215
1216 if (class_language == eLanguageTypeObjC ||
1217 class_language == eLanguageTypeObjC_plus_plus)
1218 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001219
1220 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1221 {
1222 // Not all compilers will mark the vtable pointer
1223 // member as artificial (llvm-gcc). We can't have
1224 // the virtual members in our classes otherwise it
1225 // throws off all child offsets since we end up
1226 // having and extra pointer sized member in our
1227 // class layouts.
1228 is_artificial = true;
1229 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230
Greg Clayton24739922010-10-13 03:15:28 +00001231 if (is_artificial == false)
1232 {
1233 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001234 if (member_type)
1235 {
1236 if (accessibility == eAccessNone)
1237 accessibility = default_accessibility;
1238 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239
Greg Claytond16e1e52011-07-12 17:06:17 +00001240 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1241 name,
1242 member_type->GetClangLayoutType(),
1243 accessibility,
1244 bit_size);
1245 }
1246 else
1247 {
1248 if (name)
1249 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1250 die->GetOffset(),
1251 name,
1252 encoding_uid);
1253 else
1254 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1255 die->GetOffset(),
1256 encoding_uid);
1257 }
Greg Clayton24739922010-10-13 03:15:28 +00001258 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001260 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001261 }
1262 break;
1263
1264 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001265 // Let the type parsing code handle this one for us.
1266 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 break;
1268
1269 case DW_TAG_inheritance:
1270 {
1271 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001272 if (default_accessibility == eAccessNone)
1273 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001274 // TODO: implement DW_TAG_inheritance type parsing
1275 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001276 const size_t num_attributes = die->GetAttributes (this,
1277 dwarf_cu,
1278 fixed_form_sizes,
1279 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001280 if (num_attributes > 0)
1281 {
1282 Declaration decl;
1283 DWARFExpression location;
1284 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001285 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001286 bool is_virtual = false;
1287 bool is_base_of_class = true;
1288 off_t member_offset = 0;
1289 uint32_t i;
1290 for (i=0; i<num_attributes; ++i)
1291 {
1292 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1293 DWARFFormValue form_value;
1294 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1295 {
1296 switch (attr)
1297 {
1298 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1299 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1300 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1301 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1302 case DW_AT_data_member_location:
1303 if (form_value.BlockData())
1304 {
1305 Value initialValue(0);
1306 Value memberOffset(0);
1307 const DataExtractor& debug_info_data = get_debug_info_data();
1308 uint32_t block_length = form_value.Unsigned();
1309 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001310 if (DWARFExpression::Evaluate (NULL,
1311 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001312 NULL,
1313 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001314 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001315 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001316 block_offset,
1317 block_length,
1318 eRegisterKindDWARF,
1319 &initialValue,
1320 memberOffset,
1321 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001322 {
1323 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1324 }
1325 }
1326 break;
1327
1328 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001329 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001330 break;
1331
1332 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1333 default:
1334 case DW_AT_sibling:
1335 break;
1336 }
1337 }
1338 }
1339
Greg Clayton526e5af2010-11-13 03:52:47 +00001340 Type *base_class_type = ResolveTypeUID(encoding_uid);
1341 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001342
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001343 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1344 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001345 if (class_language == eLanguageTypeObjC)
1346 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001347 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001348 }
1349 else
1350 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001351 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001352 accessibility,
1353 is_virtual,
1354 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001355 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 }
1357 }
1358 break;
1359
1360 default:
1361 break;
1362 }
1363 }
1364 return count;
1365}
1366
1367
1368clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001369SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001370{
1371 DWARFDebugInfo* debug_info = DebugInfo();
1372 if (debug_info)
1373 {
1374 DWARFCompileUnitSP cu_sp;
1375 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1376 if (die)
Sean Callanan72e49402011-08-05 23:43:37 +00001377 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
1378 }
1379 return NULL;
1380}
1381
1382clang::DeclContext*
1383SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1384{
Greg Clayton5cf58b92011-10-05 22:22:08 +00001385 return GetClangDeclContextForDIEOffset (sc, type_uid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386}
1387
1388Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001389SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001390{
1391 DWARFDebugInfo* debug_info = DebugInfo();
1392 if (debug_info)
1393 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001394 DWARFCompileUnitSP cu_sp;
1395 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001396 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001397 {
1398 // We might be coming in in the middle of a type tree (a class
1399 // withing a class, an enum within a class), so parse any needed
1400 // parent DIEs before we get to this one...
Greg Clayton5cf58b92011-10-05 22:22:08 +00001401 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die);
1402 switch (decl_ctx_die->Tag())
Greg Claytonca512b32011-01-14 04:54:56 +00001403 {
1404 case DW_TAG_structure_type:
1405 case DW_TAG_union_type:
1406 case DW_TAG_class_type:
Greg Clayton5cf58b92011-10-05 22:22:08 +00001407 ResolveType(cu_sp.get(), decl_ctx_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001408 break;
1409 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001410 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001411 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412 }
1413 return NULL;
1414}
1415
Greg Clayton6beaaa62011-01-17 03:46:26 +00001416// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1417// SymbolFileDWARF objects to detect if this DWARF file is the one that
1418// can resolve a clang_type.
1419bool
1420SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1421{
1422 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1423 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1424 return die != NULL;
1425}
1426
1427
Greg Clayton1be10fc2010-09-29 01:12:09 +00001428lldb::clang_type_t
1429SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1430{
1431 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001432 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1433 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001434 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001435 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001436// if (m_debug_map_symfile)
1437// {
1438// Type *type = m_die_to_type[die];
1439// if (type && type->GetSymbolFile() != this)
1440// return type->GetClangType();
1441// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001442 // We have already resolved this type...
1443 return clang_type;
1444 }
1445 // Once we start resolving this type, remove it from the forward declaration
1446 // map in case anyone child members or other types require this type to get resolved.
1447 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1448 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001449 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001450
Greg Clayton1be10fc2010-09-29 01:12:09 +00001451
Greg Clayton450e3f32010-10-12 02:24:53 +00001452 DWARFDebugInfo* debug_info = DebugInfo();
1453
Greg Clayton96d7d742010-11-10 23:42:09 +00001454 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001455 Type *type = m_die_to_type.lookup (die);
1456
1457 const dw_tag_t tag = die->Tag();
1458
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001459 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1460 die->GetOffset(),
1461 DW_TAG_value_to_name(tag),
1462 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001463 assert (clang_type);
1464 DWARFDebugInfoEntry::Attributes attributes;
1465
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001466 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001467
1468 switch (tag)
1469 {
1470 case DW_TAG_structure_type:
1471 case DW_TAG_union_type:
1472 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001473 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001474 if (die->HasChildren())
1475 {
1476 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001477 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1478 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001479 class_language = eLanguageTypeObjC;
1480
1481 int tag_decl_kind = -1;
1482 AccessType default_accessibility = eAccessNone;
1483 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001484 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001485 tag_decl_kind = clang::TTK_Struct;
1486 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001487 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001488 else if (tag == DW_TAG_union_type)
1489 {
1490 tag_decl_kind = clang::TTK_Union;
1491 default_accessibility = eAccessPublic;
1492 }
1493 else if (tag == DW_TAG_class_type)
1494 {
1495 tag_decl_kind = clang::TTK_Class;
1496 default_accessibility = eAccessPrivate;
1497 }
1498
Greg Clayton96d7d742010-11-10 23:42:09 +00001499 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001500 std::vector<clang::CXXBaseSpecifier *> base_classes;
1501 std::vector<int> member_accessibilities;
1502 bool is_a_class = false;
1503 // Parse members and base classes first
1504 DWARFDIECollection member_function_dies;
1505
1506 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001507 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001508 die,
1509 clang_type,
1510 class_language,
1511 base_classes,
1512 member_accessibilities,
1513 member_function_dies,
1514 default_accessibility,
1515 is_a_class);
1516
1517 // Now parse any methods if there were any...
1518 size_t num_functions = member_function_dies.Size();
1519 if (num_functions > 0)
1520 {
1521 for (size_t i=0; i<num_functions; ++i)
1522 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001523 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001524 }
1525 }
1526
Greg Clayton450e3f32010-10-12 02:24:53 +00001527 if (class_language == eLanguageTypeObjC)
1528 {
Greg Claytone3055942011-06-30 02:28:26 +00001529 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001530 if (!class_str.empty())
1531 {
1532
1533 ConstString class_name (class_str.c_str());
Greg Claytond4a2b372011-09-12 23:21:58 +00001534 DIEArray method_die_offsets;
1535 if (m_objc_class_selectors_index.Find (class_name, method_die_offsets))
Greg Clayton450e3f32010-10-12 02:24:53 +00001536 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001537 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton450e3f32010-10-12 02:24:53 +00001538
Greg Claytond4a2b372011-09-12 23:21:58 +00001539 DWARFCompileUnit* method_cu = NULL;
1540 const size_t num_matches = method_die_offsets.size();
1541 for (size_t i=0; i<num_matches; ++i)
1542 {
1543 const dw_offset_t die_offset = method_die_offsets[i];
1544 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Greg Clayton450e3f32010-10-12 02:24:53 +00001545
1546 ResolveType (method_cu, method_die);
1547 }
1548 }
1549 }
1550 }
1551
Greg Claytonc93237c2010-10-01 20:48:32 +00001552 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1553 // need to tell the clang type it is actually a class.
1554 if (class_language != eLanguageTypeObjC)
1555 {
1556 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001557 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001558 }
1559
1560 // Since DW_TAG_structure_type gets used for both classes
1561 // and structures, we may need to set any DW_TAG_member
1562 // fields to have a "private" access if none was specified.
1563 // When we parsed the child members we tracked that actual
1564 // accessibility value for each DW_TAG_member in the
1565 // "member_accessibilities" array. If the value for the
1566 // member is zero, then it was set to the "default_accessibility"
1567 // which for structs was "public". Below we correct this
1568 // by setting any fields to "private" that weren't correctly
1569 // set.
1570 if (is_a_class && !member_accessibilities.empty())
1571 {
1572 // This is a class and all members that didn't have
1573 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001574 ast.SetDefaultAccessForRecordFields (clang_type,
1575 eAccessPrivate,
1576 &member_accessibilities.front(),
1577 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001578 }
1579
1580 if (!base_classes.empty())
1581 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001582 ast.SetBaseClassesForClassType (clang_type,
1583 &base_classes.front(),
1584 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001585
1586 // Clang will copy each CXXBaseSpecifier in "base_classes"
1587 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001588 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1589 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001590 }
1591
1592 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001593 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001594 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001595
1596 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001597 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001598 if (die->HasChildren())
1599 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001600 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1601 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001602 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001603 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001604 return clang_type;
1605
1606 default:
1607 assert(false && "not a forward clang type decl!");
1608 break;
1609 }
1610 return NULL;
1611}
1612
Greg Claytonc685f8e2010-09-15 04:15:46 +00001613Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001614SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001615{
1616 if (type_die != NULL)
1617 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001618 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001619 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001620 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001621 if (assert_not_being_parsed)
1622 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001623 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001624 }
1625 return NULL;
1626}
1627
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001628CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001629SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001630{
1631 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001632 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633 {
1634 // The symbol vendor doesn't know about this compile unit, we
1635 // need to parse and add it to the symbol vendor object.
1636 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001637 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001638 if (dc_cu.get())
1639 {
1640 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001641 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001642 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001643
1644 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001645
1646 if (m_debug_map_symfile)
1647 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 }
1649 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001650 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001651}
1652
1653bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001654SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655{
1656 sc.Clear();
1657 // Check if the symbol vendor already knows about this compile unit?
Greg Claytona2eee182011-09-17 07:23:18 +00001658 sc.module_sp = m_obj_file->GetModule();
Greg Clayton96d7d742010-11-10 23:42:09 +00001659 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660
1661 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1662 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001663 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001664
1665 return sc.function != NULL;
1666}
1667
1668uint32_t
1669SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1670{
1671 Timer scoped_timer(__PRETTY_FUNCTION__,
1672 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1673 so_addr.GetSection(),
1674 so_addr.GetOffset(),
1675 resolve_scope);
1676 uint32_t resolved = 0;
1677 if (resolve_scope & ( eSymbolContextCompUnit |
1678 eSymbolContextFunction |
1679 eSymbolContextBlock |
1680 eSymbolContextLineEntry))
1681 {
1682 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1683
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001684 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001685 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001686 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001687 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001688 if (cu_offset != DW_INVALID_OFFSET)
1689 {
1690 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001691 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1692 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001693 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001694 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001695 assert(sc.comp_unit != NULL);
1696 resolved |= eSymbolContextCompUnit;
1697
1698 if (resolve_scope & eSymbolContextLineEntry)
1699 {
1700 LineTable *line_table = sc.comp_unit->GetLineTable();
1701 if (line_table == NULL)
1702 {
1703 if (ParseCompileUnitLineTable(sc))
1704 line_table = sc.comp_unit->GetLineTable();
1705 }
1706 if (line_table != NULL)
1707 {
1708 if (so_addr.IsLinkedAddress())
1709 {
1710 Address linked_addr (so_addr);
1711 linked_addr.ResolveLinkedAddress();
1712 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1713 {
1714 resolved |= eSymbolContextLineEntry;
1715 }
1716 }
1717 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1718 {
1719 resolved |= eSymbolContextLineEntry;
1720 }
1721 }
1722 }
1723
1724 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1725 {
1726 DWARFDebugInfoEntry *function_die = NULL;
1727 DWARFDebugInfoEntry *block_die = NULL;
1728 if (resolve_scope & eSymbolContextBlock)
1729 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001730 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001731 }
1732 else
1733 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001734 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001735 }
1736
1737 if (function_die != NULL)
1738 {
1739 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1740 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001741 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001742 }
1743
1744 if (sc.function != NULL)
1745 {
1746 resolved |= eSymbolContextFunction;
1747
1748 if (resolve_scope & eSymbolContextBlock)
1749 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001750 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001751
1752 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001753 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001754 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001755 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001756 if (sc.block)
1757 resolved |= eSymbolContextBlock;
1758 }
1759 }
1760 }
1761 }
1762 }
1763 }
1764 }
1765 return resolved;
1766}
1767
1768
1769
1770uint32_t
1771SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1772{
1773 const uint32_t prev_size = sc_list.GetSize();
1774 if (resolve_scope & eSymbolContextCompUnit)
1775 {
1776 DWARFDebugInfo* debug_info = DebugInfo();
1777 if (debug_info)
1778 {
1779 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001780 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001781
Greg Clayton96d7d742010-11-10 23:42:09 +00001782 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001783 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001784 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001785 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1786 if (check_inlines || file_spec_matches_cu_file_spec)
1787 {
1788 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001789 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790 assert(sc.comp_unit != NULL);
1791
1792 uint32_t file_idx = UINT32_MAX;
1793
1794 // If we are looking for inline functions only and we don't
1795 // find it in the support files, we are done.
1796 if (check_inlines)
1797 {
Jim Ingham87df91b2011-09-23 00:54:11 +00001798 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001799 if (file_idx == UINT32_MAX)
1800 continue;
1801 }
1802
1803 if (line != 0)
1804 {
1805 LineTable *line_table = sc.comp_unit->GetLineTable();
1806
1807 if (line_table != NULL && line != 0)
1808 {
1809 // We will have already looked up the file index if
1810 // we are searching for inline entries.
1811 if (!check_inlines)
Jim Ingham87df91b2011-09-23 00:54:11 +00001812 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001813
1814 if (file_idx != UINT32_MAX)
1815 {
1816 uint32_t found_line;
1817 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1818 found_line = sc.line_entry.line;
1819
Greg Clayton016a95e2010-09-14 02:20:48 +00001820 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001821 {
1822 sc.function = NULL;
1823 sc.block = NULL;
1824 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1825 {
1826 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1827 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1828 {
1829 DWARFDebugInfoEntry *function_die = NULL;
1830 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001831 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001832
1833 if (function_die != NULL)
1834 {
1835 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1836 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001837 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001838 }
1839
1840 if (sc.function != NULL)
1841 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001842 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001843
1844 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001845 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001846 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001847 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848 }
1849 }
1850 }
1851
1852 sc_list.Append(sc);
1853 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1854 }
1855 }
1856 }
1857 else if (file_spec_matches_cu_file_spec && !check_inlines)
1858 {
1859 // only append the context if we aren't looking for inline call sites
1860 // by file and line and if the file spec matches that of the compile unit
1861 sc_list.Append(sc);
1862 }
1863 }
1864 else if (file_spec_matches_cu_file_spec && !check_inlines)
1865 {
1866 // only append the context if we aren't looking for inline call sites
1867 // by file and line and if the file spec matches that of the compile unit
1868 sc_list.Append(sc);
1869 }
1870
1871 if (!check_inlines)
1872 break;
1873 }
1874 }
1875 }
1876 }
1877 return sc_list.GetSize() - prev_size;
1878}
1879
1880void
1881SymbolFileDWARF::Index ()
1882{
1883 if (m_indexed)
1884 return;
1885 m_indexed = true;
1886 Timer scoped_timer (__PRETTY_FUNCTION__,
1887 "SymbolFileDWARF::Index (%s)",
1888 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1889
1890 DWARFDebugInfo* debug_info = DebugInfo();
1891 if (debug_info)
1892 {
1893 uint32_t cu_idx = 0;
1894 const uint32_t num_compile_units = GetNumCompileUnits();
1895 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1896 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001897 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001898
Greg Clayton96d7d742010-11-10 23:42:09 +00001899 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900
Greg Clayton96d7d742010-11-10 23:42:09 +00001901 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001902 m_function_basename_index,
1903 m_function_fullname_index,
1904 m_function_method_index,
1905 m_function_selector_index,
1906 m_objc_class_selectors_index,
1907 m_global_index,
1908 m_type_index,
Greg Claytond4a2b372011-09-12 23:21:58 +00001909 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001910
1911 // Keep memory down by clearing DIEs if this generate function
1912 // caused them to be parsed
1913 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001914 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915 }
1916
Greg Claytond4a2b372011-09-12 23:21:58 +00001917 m_function_basename_index.Finalize();
1918 m_function_fullname_index.Finalize();
1919 m_function_method_index.Finalize();
1920 m_function_selector_index.Finalize();
1921 m_objc_class_selectors_index.Finalize();
1922 m_global_index.Finalize();
1923 m_type_index.Finalize();
1924 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001925
Greg Clayton24739922010-10-13 03:15:28 +00001926#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00001927 StreamFile s(stdout, false);
Greg Claytonf9eec202011-09-01 23:16:13 +00001928 s.Printf ("DWARF index for '%s/%s':",
Greg Clayton24739922010-10-13 03:15:28 +00001929 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1930 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001931 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1932 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1933 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1934 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1935 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1936 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001937 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001938 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001939#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001940 }
1941}
1942
1943uint32_t
1944SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1945{
Greg Clayton21f2a492011-10-06 00:09:08 +00001946 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
1947
1948 if (log)
1949 {
1950 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", name=\"%s\", append=%u, max_matches=%u, variables)",
1951 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
1952 m_obj_file->GetFileSpec().GetFilename().GetCString(),
1953 name.GetCString(), append, max_matches);
1954 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001955 DWARFDebugInfo* info = DebugInfo();
1956 if (info == NULL)
1957 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958
1959 // If we aren't appending the results to this list, then clear the list
1960 if (!append)
1961 variables.Clear();
1962
1963 // Remember how many variables are in the list before we search in case
1964 // we are appending the results to a variable list.
1965 const uint32_t original_size = variables.GetSize();
1966
Greg Claytond4a2b372011-09-12 23:21:58 +00001967 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00001968
1969 if (m_apple_names_ap.get())
1970 {
1971 const char *name_cstr = name.GetCString();
1972 DWARFMappedHash::MemoryTable::Pair kv_pair;
1973 if (m_apple_names_ap->Find (name_cstr, kv_pair))
1974 {
1975 die_offsets.swap(kv_pair.value);
1976 }
1977 }
1978 else
1979 {
1980 // Index the DWARF if we haven't already
1981 if (!m_indexed)
1982 Index ();
1983
1984 m_global_index.Find (name, die_offsets);
1985 }
1986
1987 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00001988 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001989 {
Greg Clayton7f995132011-10-04 22:41:51 +00001990 SymbolContext sc;
1991 sc.module_sp = m_obj_file->GetModule();
1992 assert (sc.module_sp);
1993
Greg Claytond4a2b372011-09-12 23:21:58 +00001994 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00001995 DWARFCompileUnit* dwarf_cu = NULL;
1996 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00001997 for (size_t i=0; i<num_matches; ++i)
1998 {
1999 const dw_offset_t die_offset = die_offsets[i];
2000 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002001
Greg Claytond4a2b372011-09-12 23:21:58 +00002002 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2003 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002004
Greg Claytond4a2b372011-09-12 23:21:58 +00002005 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002006
Greg Claytond4a2b372011-09-12 23:21:58 +00002007 if (variables.GetSize() - original_size >= max_matches)
2008 break;
2009 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002010 }
2011
2012 // Return the number of variable that were appended to the list
2013 return variables.GetSize() - original_size;
2014}
2015
2016uint32_t
2017SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2018{
Greg Clayton21f2a492011-10-06 00:09:08 +00002019 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2020
2021 if (log)
2022 {
2023 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", regex=\"%s\", append=%u, max_matches=%u, variables)",
2024 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2025 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2026 regex.GetText(), append, max_matches);
2027 }
2028
Greg Claytonc685f8e2010-09-15 04:15:46 +00002029 DWARFDebugInfo* info = DebugInfo();
2030 if (info == NULL)
2031 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002032
2033 // If we aren't appending the results to this list, then clear the list
2034 if (!append)
2035 variables.Clear();
2036
2037 // Remember how many variables are in the list before we search in case
2038 // we are appending the results to a variable list.
2039 const uint32_t original_size = variables.GetSize();
2040
Greg Clayton7f995132011-10-04 22:41:51 +00002041 DIEArray die_offsets;
2042
2043 if (m_apple_names_ap.get())
2044 {
2045 m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
2046 }
2047 else
2048 {
2049 // Index the DWARF if we haven't already
2050 if (!m_indexed)
2051 Index ();
2052
2053 m_global_index.Find (regex, die_offsets);
2054 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002055
Greg Claytonc685f8e2010-09-15 04:15:46 +00002056 SymbolContext sc;
Greg Claytona2eee182011-09-17 07:23:18 +00002057 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002058 assert (sc.module_sp);
2059
Greg Claytond4a2b372011-09-12 23:21:58 +00002060 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002061 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002062 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002063 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002064 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002065 DWARFDebugInfo* debug_info = DebugInfo();
2066 for (size_t i=0; i<num_matches; ++i)
2067 {
2068 const dw_offset_t die_offset = die_offsets[i];
2069 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2070 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002071
Greg Claytond4a2b372011-09-12 23:21:58 +00002072 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002073
Greg Claytond4a2b372011-09-12 23:21:58 +00002074 if (variables.GetSize() - original_size >= max_matches)
2075 break;
2076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002077 }
2078
2079 // Return the number of variable that were appended to the list
2080 return variables.GetSize() - original_size;
2081}
2082
2083
Greg Clayton9e315582011-09-02 04:03:59 +00002084uint32_t
2085SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002086 SymbolContextList& sc_list,
2087 const ConstString &name,
2088 uint32_t name_type_mask)
Greg Clayton9e315582011-09-02 04:03:59 +00002089{
2090 DWARFDebugInfo* info = DebugInfo();
2091 if (info == NULL)
2092 return 0;
2093
2094 const uint32_t sc_list_initial_size = sc_list.GetSize();
2095 SymbolContext sc;
Greg Claytona2eee182011-09-17 07:23:18 +00002096 sc.module_sp = m_obj_file->GetModule();
Greg Clayton9e315582011-09-02 04:03:59 +00002097 assert (sc.module_sp);
2098
2099 DWARFCompileUnit* dwarf_cu = NULL;
2100 const size_t num_matches = die_offsets.size();
2101 for (size_t i=0; i<num_matches; ++i)
2102 {
2103 const dw_offset_t die_offset = die_offsets[i];
2104 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2105
Greg Clayton2bc22f82011-09-30 03:20:47 +00002106 // If we aren't doing full names,
2107 if ((name_type_mask & eFunctionNameTypeFull) == 0)
2108 {
2109 const char *name_cstr = name.GetCString();
2110 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name_cstr))
2111 continue;
2112 }
2113
2114
Greg Clayton9e315582011-09-02 04:03:59 +00002115 const DWARFDebugInfoEntry* inlined_die = NULL;
2116 if (die->Tag() == DW_TAG_inlined_subroutine)
2117 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00002118 // We only are looking for selectors, which disallows anything inlined
2119 if (name_type_mask == eFunctionNameTypeSelector)
2120 continue;
2121
Greg Clayton9e315582011-09-02 04:03:59 +00002122 inlined_die = die;
2123
2124 while ((die = die->GetParent()) != NULL)
2125 {
2126 if (die->Tag() == DW_TAG_subprogram)
2127 break;
2128 }
2129 }
Greg Clayton7f995132011-10-04 22:41:51 +00002130 if (die->Tag() == DW_TAG_subprogram)
Greg Clayton9e315582011-09-02 04:03:59 +00002131 {
Greg Clayton7f995132011-10-04 22:41:51 +00002132 if (GetFunction (dwarf_cu, die, sc))
Greg Clayton9e315582011-09-02 04:03:59 +00002133 {
Greg Clayton7f995132011-10-04 22:41:51 +00002134 Address addr;
2135 // Parse all blocks if needed
2136 if (inlined_die)
Greg Clayton9e315582011-09-02 04:03:59 +00002137 {
Greg Clayton7f995132011-10-04 22:41:51 +00002138 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2139 assert (sc.block != NULL);
2140 if (sc.block->GetStartAddress (addr) == false)
2141 addr.Clear();
Greg Clayton9e315582011-09-02 04:03:59 +00002142 }
Greg Clayton7f995132011-10-04 22:41:51 +00002143 else
2144 {
2145 sc.block = NULL;
2146 addr = sc.function->GetAddressRange().GetBaseAddress();
2147 }
Greg Clayton9e315582011-09-02 04:03:59 +00002148
Greg Clayton7f995132011-10-04 22:41:51 +00002149 if (addr.IsValid())
2150 {
2151
2152 // We found the function, so we should find the line table
2153 // and line table entry as well
2154 LineTable *line_table = sc.comp_unit->GetLineTable();
2155 if (line_table == NULL)
2156 {
2157 if (ParseCompileUnitLineTable(sc))
2158 line_table = sc.comp_unit->GetLineTable();
2159 }
2160 if (line_table != NULL)
2161 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2162
2163 sc_list.Append(sc);
2164 }
Greg Clayton9e315582011-09-02 04:03:59 +00002165 }
2166 }
2167 }
2168 return sc_list.GetSize() - sc_list_initial_size;
2169}
2170
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002171
Greg Clayton7f995132011-10-04 22:41:51 +00002172
2173void
2174SymbolFileDWARF::FindFunctions (const ConstString &name,
2175 const NameToDIE &name_to_die,
2176 SymbolContextList& sc_list)
2177{
Greg Claytond4a2b372011-09-12 23:21:58 +00002178 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002179 if (name_to_die.Find (name, die_offsets))
2180 {
2181 ParseFunctions (die_offsets, sc_list);
2182 }
2183}
2184
2185
2186void
2187SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2188 const NameToDIE &name_to_die,
2189 SymbolContextList& sc_list)
2190{
2191 DIEArray die_offsets;
2192 if (name_to_die.Find (regex, die_offsets))
2193 {
2194 ParseFunctions (die_offsets, sc_list);
2195 }
2196}
2197
2198
2199void
2200SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2201 const DWARFMappedHash::MemoryTable &memory_table,
2202 SymbolContextList& sc_list)
2203{
2204 DIEArray die_offsets;
2205 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
2206 {
2207 ParseFunctions (die_offsets, sc_list);
2208 }
2209}
2210
2211void
2212SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2213 SymbolContextList& sc_list)
2214{
2215 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002216 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002217 {
Greg Clayton7f995132011-10-04 22:41:51 +00002218 SymbolContext sc;
2219 sc.module_sp = m_obj_file->GetModule();
2220
2221 DWARFCompileUnit* dwarf_cu = NULL;
2222 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002223 DWARFDebugInfo* debug_info = DebugInfo();
2224 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00002225 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002226 const dw_offset_t die_offset = die_offsets[i];
2227 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2228 const DWARFDebugInfoEntry* inlined_die = NULL;
2229 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Claytond7e05462010-11-14 00:22:48 +00002230 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002231 inlined_die = die;
2232
2233 while ((die = die->GetParent()) != NULL)
Greg Claytond7e05462010-11-14 00:22:48 +00002234 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002235 if (die->Tag() == DW_TAG_subprogram)
2236 break;
Greg Claytond7e05462010-11-14 00:22:48 +00002237 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002238 }
2239 assert (die->Tag() == DW_TAG_subprogram);
2240 if (GetFunction (dwarf_cu, die, sc))
2241 {
2242 Address addr;
2243 // Parse all blocks if needed
2244 if (inlined_die)
2245 {
2246 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2247 assert (sc.block != NULL);
2248 if (sc.block->GetStartAddress (addr) == false)
2249 addr.Clear();
2250 }
2251 else
2252 {
2253 sc.block = NULL;
2254 addr = sc.function->GetAddressRange().GetBaseAddress();
2255 }
Greg Clayton7f995132011-10-04 22:41:51 +00002256
Greg Claytond4a2b372011-09-12 23:21:58 +00002257 if (addr.IsValid())
2258 {
Greg Clayton7f995132011-10-04 22:41:51 +00002259
Greg Claytond4a2b372011-09-12 23:21:58 +00002260 // We found the function, so we should find the line table
2261 // and line table entry as well
2262 LineTable *line_table = sc.comp_unit->GetLineTable();
2263 if (line_table == NULL)
2264 {
2265 if (ParseCompileUnitLineTable(sc))
2266 line_table = sc.comp_unit->GetLineTable();
2267 }
2268 if (line_table != NULL)
2269 line_table->FindLineEntryByAddress (addr, sc.line_entry);
Greg Clayton7f995132011-10-04 22:41:51 +00002270
Greg Claytond4a2b372011-09-12 23:21:58 +00002271 sc_list.Append(sc);
2272 }
Greg Claytond7e05462010-11-14 00:22:48 +00002273 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002274 }
2275 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002276}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002277
Greg Claytonc685f8e2010-09-15 04:15:46 +00002278
Greg Clayton0c5cd902010-06-28 21:30:43 +00002279uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00002280SymbolFileDWARF::FindFunctions (const ConstString &name,
2281 uint32_t name_type_mask,
2282 bool append,
2283 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002284{
2285 Timer scoped_timer (__PRETTY_FUNCTION__,
2286 "SymbolFileDWARF::FindFunctions (name = '%s')",
2287 name.AsCString());
2288
Greg Clayton21f2a492011-10-06 00:09:08 +00002289 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2290
2291 if (log)
2292 {
2293 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2294 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2295 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2296 name.GetCString(), name_type_mask, append);
2297 }
2298
Greg Clayton0c5cd902010-06-28 21:30:43 +00002299 // If we aren't appending the results to this list, then clear the list
2300 if (!append)
2301 sc_list.Clear();
2302
2303 // Remember how many sc_list are in the list before we search in case
2304 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002305
Greg Clayton9e315582011-09-02 04:03:59 +00002306 const uint32_t original_size = sc_list.GetSize();
Greg Clayton0c5cd902010-06-28 21:30:43 +00002307
Greg Clayton7f995132011-10-04 22:41:51 +00002308 if (m_apple_names_ap.get())
Greg Clayton4d01ace2011-09-29 16:58:15 +00002309 {
Greg Clayton7f995132011-10-04 22:41:51 +00002310 const char *name_cstr = name.GetCString();
2311 DWARFMappedHash::MemoryTable::Pair kv_pair;
2312 if (m_apple_names_ap->Find (name_cstr, kv_pair))
2313 ResolveFunctions (kv_pair.value, sc_list, name, name_type_mask);
2314 }
2315 else
2316 {
2317
2318 // Index the DWARF if we haven't already
2319 if (!m_indexed)
2320 Index ();
2321
2322 if (name_type_mask & eFunctionNameTypeBase)
2323 FindFunctions (name, m_function_basename_index, sc_list);
2324
2325 if (name_type_mask & eFunctionNameTypeFull)
2326 FindFunctions (name, m_function_fullname_index, sc_list);
2327
2328 if (name_type_mask & eFunctionNameTypeMethod)
2329 FindFunctions (name, m_function_method_index, sc_list);
2330
2331 if (name_type_mask & eFunctionNameTypeSelector)
2332 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton4d01ace2011-09-29 16:58:15 +00002333 }
2334
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002335 // Return the number of variable that were appended to the list
2336 return sc_list.GetSize() - original_size;
2337}
2338
2339
2340uint32_t
2341SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2342{
2343 Timer scoped_timer (__PRETTY_FUNCTION__,
2344 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2345 regex.GetText());
2346
Greg Clayton21f2a492011-10-06 00:09:08 +00002347 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2348
2349 if (log)
2350 {
2351 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", regex=\"%s\"append=%u, sc_list)",
2352 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2353 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2354 regex.GetText(), append);
2355 }
2356
2357
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002358 // If we aren't appending the results to this list, then clear the list
2359 if (!append)
2360 sc_list.Clear();
2361
2362 // Remember how many sc_list are in the list before we search in case
2363 // we are appending the results to a variable list.
2364 uint32_t original_size = sc_list.GetSize();
2365
2366 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002367 if (m_apple_names_ap.get())
2368 {
2369 FindFunctions (regex, *m_apple_names_ap, sc_list);
2370 }
2371 else
2372 {
2373 if (!m_indexed)
2374 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002375
Greg Clayton7f995132011-10-04 22:41:51 +00002376 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002377
Greg Clayton7f995132011-10-04 22:41:51 +00002378 FindFunctions (regex, m_function_fullname_index, sc_list);
2379 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002380
2381 // Return the number of variable that were appended to the list
2382 return sc_list.GetSize() - original_size;
2383}
Jim Ingham318c9f22011-08-26 19:44:13 +00002384
Greg Claytond16e1e52011-07-12 17:06:17 +00002385void
2386SymbolFileDWARF::ReportError (const char *format, ...)
2387{
2388 ::fprintf (stderr,
2389 "error: %s/%s ",
2390 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2391 m_obj_file->GetFileSpec().GetFilename().GetCString());
2392
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002393 if (m_obj_file->GetModule()->GetObjectName())
2394 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2395
Greg Claytond16e1e52011-07-12 17:06:17 +00002396 va_list args;
2397 va_start (args, format);
2398 vfprintf (stderr, format, args);
2399 va_end (args);
2400}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002401
Jim Inghamc1663042011-09-29 22:12:35 +00002402void
2403SymbolFileDWARF::ReportWarning (const char *format, ...)
2404{
2405 ::fprintf (stderr,
2406 "warning: %s/%s ",
2407 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2408 m_obj_file->GetFileSpec().GetFilename().GetCString());
2409
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002410 if (m_obj_file->GetModule()->GetObjectName())
2411 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2412
Jim Inghamc1663042011-09-29 22:12:35 +00002413 va_list args;
2414 va_start (args, format);
2415 vfprintf (stderr, format, args);
2416 va_end (args);
2417}
2418
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002419uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002420SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002421{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002422 DWARFDebugInfo* info = DebugInfo();
2423 if (info == NULL)
2424 return 0;
2425
Greg Clayton21f2a492011-10-06 00:09:08 +00002426 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2427
2428 if (log)
2429 {
2430 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", sc, name=\"%s\", append=%u, max_matches=%u, type_list)",
2431 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2432 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2433 name.GetCString(), append, max_matches);
2434 }
2435
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002436 // If we aren't appending the results to this list, then clear the list
2437 if (!append)
2438 types.Clear();
2439
Greg Claytond4a2b372011-09-12 23:21:58 +00002440 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002441
2442 if (m_apple_types_ap.get())
2443 {
2444 const char *name_cstr = name.GetCString();
2445 DWARFMappedHash::MemoryTable::Pair kv_pair;
2446 if (m_apple_types_ap->Find (name_cstr, kv_pair))
2447 {
2448 die_offsets.swap(kv_pair.value);
2449 }
2450 }
2451 else
2452 {
2453 if (!m_indexed)
2454 Index ();
2455
2456 m_type_index.Find (name, die_offsets);
2457 }
2458
2459
2460 const size_t num_matches = die_offsets.size();
2461
Greg Claytond4a2b372011-09-12 23:21:58 +00002462 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002463 {
Greg Clayton7f995132011-10-04 22:41:51 +00002464 const uint32_t initial_types_size = types.GetSize();
2465 DWARFCompileUnit* dwarf_cu = NULL;
2466 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002467 DWARFDebugInfo* debug_info = DebugInfo();
2468 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002469 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002470 const dw_offset_t die_offset = die_offsets[i];
2471 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2472
2473 Type *matching_type = ResolveType (dwarf_cu, die);
2474 if (matching_type)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002475 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002476 // We found a type pointer, now find the shared pointer form our type list
2477 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2478 if (type_sp)
2479 {
2480 types.InsertUnique (type_sp);
2481 if (types.GetSize() >= max_matches)
2482 break;
2483 }
2484 else
2485 {
Jim Inghamc1663042011-09-29 22:12:35 +00002486 ReportError ("error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
Greg Claytond4a2b372011-09-12 23:21:58 +00002487 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00002488 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002489 }
Greg Clayton7f995132011-10-04 22:41:51 +00002490 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002491 }
Greg Clayton7f995132011-10-04 22:41:51 +00002492 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002493}
2494
2495
Greg Clayton526e5af2010-11-13 03:52:47 +00002496ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002497SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2498 const ConstString &name)
2499{
Greg Clayton21f2a492011-10-06 00:09:08 +00002500 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2501
2502 if (log)
2503 {
2504 log->Printf ("SymbolFileDWARF::FindNamespace (file=\"%s/%s\", sc, name=\"%s\")",
2505 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2506 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2507 name.GetCString());
2508 }
2509
Greg Clayton526e5af2010-11-13 03:52:47 +00002510 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002511 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002512 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002513 {
Greg Clayton7f995132011-10-04 22:41:51 +00002514 DIEArray die_offsets;
2515
Greg Clayton526e5af2010-11-13 03:52:47 +00002516 // Index if we already haven't to make sure the compile units
2517 // get indexed and make their global DIE index list
Greg Clayton7f995132011-10-04 22:41:51 +00002518 if (m_apple_namespaces_ap.get())
2519 {
2520 const char *name_cstr = name.GetCString();
2521 DWARFMappedHash::MemoryTable::Pair kv_pair;
2522 if (m_apple_namespaces_ap->Find (name_cstr, kv_pair))
2523 {
2524 die_offsets.swap(kv_pair.value);
2525 }
2526 }
2527 else
2528 {
2529 if (!m_indexed)
2530 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002531
Greg Clayton7f995132011-10-04 22:41:51 +00002532 m_namespace_index.Find (name, die_offsets);
2533 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002534
2535 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00002536 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002537 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002538 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00002539 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002540 DWARFDebugInfo* debug_info = DebugInfo();
2541 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00002542 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002543 const dw_offset_t die_offset = die_offsets[i];
2544 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2545
2546 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
2547 if (clang_namespace_decl)
2548 {
2549 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2550 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2551 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002552 }
2553 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002554 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002555 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002556}
2557
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002558uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002559SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002560{
2561 // Remember how many sc_list are in the list before we search in case
2562 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002563 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002564
2565 const uint32_t num_die_offsets = die_offsets.size();
2566 // Parse all of the types we found from the pubtypes matches
2567 uint32_t i;
2568 uint32_t num_matches = 0;
2569 for (i = 0; i < num_die_offsets; ++i)
2570 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002571 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2572 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002573 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002574 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002575 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002576 assert (type_sp.get() != NULL);
2577 types.InsertUnique (type_sp);
2578 ++num_matches;
2579 if (num_matches >= max_matches)
2580 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002581 }
2582 }
2583
2584 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002585 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002586}
2587
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002588
2589size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00002590SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
2591 clang::DeclContext *containing_decl_ctx,
2592 TypeSP& type_sp,
2593 DWARFCompileUnit* dwarf_cu,
2594 const DWARFDebugInfoEntry *parent_die,
2595 bool skip_artificial,
2596 bool &is_static,
2597 TypeList* type_list,
2598 std::vector<clang_type_t>& function_param_types,
2599 std::vector<clang::ParmVarDecl*>& function_param_decls,
2600 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002601{
2602 if (parent_die == NULL)
2603 return 0;
2604
Greg Claytond88d7592010-09-15 08:33:30 +00002605 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2606
Greg Clayton7fedea22010-11-16 02:10:54 +00002607 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002608 const DWARFDebugInfoEntry *die;
2609 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2610 {
2611 dw_tag_t tag = die->Tag();
2612 switch (tag)
2613 {
2614 case DW_TAG_formal_parameter:
2615 {
2616 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002617 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002618 if (num_attributes > 0)
2619 {
2620 const char *name = NULL;
2621 Declaration decl;
2622 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002623 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002624 // one of None, Auto, Register, Extern, Static, PrivateExtern
2625
Sean Callanane2ef6e32010-09-23 03:01:22 +00002626 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002627 uint32_t i;
2628 for (i=0; i<num_attributes; ++i)
2629 {
2630 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2631 DWARFFormValue form_value;
2632 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2633 {
2634 switch (attr)
2635 {
2636 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2637 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2638 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2639 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2640 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002641 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002642 case DW_AT_location:
2643 // if (form_value.BlockData())
2644 // {
2645 // const DataExtractor& debug_info_data = debug_info();
2646 // uint32_t block_length = form_value.Unsigned();
2647 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2648 // }
2649 // else
2650 // {
2651 // }
2652 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002653 case DW_AT_const_value:
2654 case DW_AT_default_value:
2655 case DW_AT_description:
2656 case DW_AT_endianity:
2657 case DW_AT_is_optional:
2658 case DW_AT_segment:
2659 case DW_AT_variable_parameter:
2660 default:
2661 case DW_AT_abstract_origin:
2662 case DW_AT_sibling:
2663 break;
2664 }
2665 }
2666 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002667
Greg Clayton0fffff52010-09-24 05:15:53 +00002668 bool skip = false;
2669 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002670 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002671 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002672 {
2673 // In order to determine if a C++ member function is
2674 // "const" we have to look at the const-ness of "this"...
2675 // Ugly, but that
2676 if (arg_idx == 0)
2677 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002678 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord)
Sean Callanan763d72a2011-08-02 22:21:50 +00002679 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002680 // Often times compilers omit the "this" name for the
2681 // specification DIEs, so we can't rely upon the name
2682 // being in the formal parameter DIE...
2683 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00002684 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002685 Type *this_type = ResolveTypeUID (param_type_die_offset);
2686 if (this_type)
2687 {
2688 uint32_t encoding_mask = this_type->GetEncodingMask();
2689 if (encoding_mask & Type::eEncodingIsPointerUID)
2690 {
2691 is_static = false;
2692
2693 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2694 type_quals |= clang::Qualifiers::Const;
2695 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2696 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002697 }
2698 }
2699 }
2700 }
2701 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002702 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002703 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002704 else
2705 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002706
Greg Clayton0fffff52010-09-24 05:15:53 +00002707 // HACK: Objective C formal parameters "self" and "_cmd"
2708 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002709 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2710 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002711 {
2712 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2713 skip = true;
2714 }
2715 }
2716 }
2717
2718 if (!skip)
2719 {
2720 Type *type = ResolveTypeUID(param_type_die_offset);
2721 if (type)
2722 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002723 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002724
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002725 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002726 assert(param_var_decl);
2727 function_param_decls.push_back(param_var_decl);
2728 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002729 }
2730 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002731 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002732 }
2733 break;
2734
2735 default:
2736 break;
2737 }
2738 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002739 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002740}
2741
2742size_t
2743SymbolFileDWARF::ParseChildEnumerators
2744(
2745 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002746 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002747 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002748 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002749 const DWARFDebugInfoEntry *parent_die
2750)
2751{
2752 if (parent_die == NULL)
2753 return 0;
2754
2755 size_t enumerators_added = 0;
2756 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002757 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2758
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002759 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2760 {
2761 const dw_tag_t tag = die->Tag();
2762 if (tag == DW_TAG_enumerator)
2763 {
2764 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002765 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002766 if (num_child_attributes > 0)
2767 {
2768 const char *name = NULL;
2769 bool got_value = false;
2770 int64_t enum_value = 0;
2771 Declaration decl;
2772
2773 uint32_t i;
2774 for (i=0; i<num_child_attributes; ++i)
2775 {
2776 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2777 DWARFFormValue form_value;
2778 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2779 {
2780 switch (attr)
2781 {
2782 case DW_AT_const_value:
2783 got_value = true;
2784 enum_value = form_value.Unsigned();
2785 break;
2786
2787 case DW_AT_name:
2788 name = form_value.AsCString(&get_debug_str_data());
2789 break;
2790
2791 case DW_AT_description:
2792 default:
2793 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2794 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2795 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2796 case DW_AT_sibling:
2797 break;
2798 }
2799 }
2800 }
2801
2802 if (name && name[0] && got_value)
2803 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002804 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2805 enumerator_clang_type,
2806 decl,
2807 name,
2808 enum_value,
2809 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002810 ++enumerators_added;
2811 }
2812 }
2813 }
2814 }
2815 return enumerators_added;
2816}
2817
2818void
2819SymbolFileDWARF::ParseChildArrayInfo
2820(
2821 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002822 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002823 const DWARFDebugInfoEntry *parent_die,
2824 int64_t& first_index,
2825 std::vector<uint64_t>& element_orders,
2826 uint32_t& byte_stride,
2827 uint32_t& bit_stride
2828)
2829{
2830 if (parent_die == NULL)
2831 return;
2832
2833 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002834 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002835 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2836 {
2837 const dw_tag_t tag = die->Tag();
2838 switch (tag)
2839 {
2840 case DW_TAG_enumerator:
2841 {
2842 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002843 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002844 if (num_child_attributes > 0)
2845 {
2846 const char *name = NULL;
2847 bool got_value = false;
2848 int64_t enum_value = 0;
2849
2850 uint32_t i;
2851 for (i=0; i<num_child_attributes; ++i)
2852 {
2853 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2854 DWARFFormValue form_value;
2855 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2856 {
2857 switch (attr)
2858 {
2859 case DW_AT_const_value:
2860 got_value = true;
2861 enum_value = form_value.Unsigned();
2862 break;
2863
2864 case DW_AT_name:
2865 name = form_value.AsCString(&get_debug_str_data());
2866 break;
2867
2868 case DW_AT_description:
2869 default:
2870 case DW_AT_decl_file:
2871 case DW_AT_decl_line:
2872 case DW_AT_decl_column:
2873 case DW_AT_sibling:
2874 break;
2875 }
2876 }
2877 }
2878 }
2879 }
2880 break;
2881
2882 case DW_TAG_subrange_type:
2883 {
2884 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002885 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886 if (num_child_attributes > 0)
2887 {
2888 const char *name = NULL;
2889 bool got_value = false;
2890 uint64_t byte_size = 0;
2891 int64_t enum_value = 0;
2892 uint64_t num_elements = 0;
2893 uint64_t lower_bound = 0;
2894 uint64_t upper_bound = 0;
2895 uint32_t i;
2896 for (i=0; i<num_child_attributes; ++i)
2897 {
2898 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2899 DWARFFormValue form_value;
2900 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2901 {
2902 switch (attr)
2903 {
2904 case DW_AT_const_value:
2905 got_value = true;
2906 enum_value = form_value.Unsigned();
2907 break;
2908
2909 case DW_AT_name:
2910 name = form_value.AsCString(&get_debug_str_data());
2911 break;
2912
2913 case DW_AT_count:
2914 num_elements = form_value.Unsigned();
2915 break;
2916
2917 case DW_AT_bit_stride:
2918 bit_stride = form_value.Unsigned();
2919 break;
2920
2921 case DW_AT_byte_stride:
2922 byte_stride = form_value.Unsigned();
2923 break;
2924
2925 case DW_AT_byte_size:
2926 byte_size = form_value.Unsigned();
2927 break;
2928
2929 case DW_AT_lower_bound:
2930 lower_bound = form_value.Unsigned();
2931 break;
2932
2933 case DW_AT_upper_bound:
2934 upper_bound = form_value.Unsigned();
2935 break;
2936
2937 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002938 case DW_AT_abstract_origin:
2939 case DW_AT_accessibility:
2940 case DW_AT_allocated:
2941 case DW_AT_associated:
2942 case DW_AT_data_location:
2943 case DW_AT_declaration:
2944 case DW_AT_description:
2945 case DW_AT_sibling:
2946 case DW_AT_threads_scaled:
2947 case DW_AT_type:
2948 case DW_AT_visibility:
2949 break;
2950 }
2951 }
2952 }
2953
2954 if (upper_bound > lower_bound)
2955 num_elements = upper_bound - lower_bound + 1;
2956
2957 if (num_elements > 0)
2958 element_orders.push_back (num_elements);
2959 }
2960 }
2961 break;
2962 }
2963 }
2964}
2965
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002966TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002967SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002968{
2969 TypeSP type_sp;
2970 if (die != NULL)
2971 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002972 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002973 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002974 if (type_ptr == NULL)
2975 {
Greg Claytonca512b32011-01-14 04:54:56 +00002976 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2977 assert (lldb_cu);
2978 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002979 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002980 }
2981 else if (type_ptr != DIE_IS_BEING_PARSED)
2982 {
2983 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002984 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002985 }
2986
2987 }
2988 return type_sp;
2989}
2990
2991clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00002992SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002993{
2994 if (die_offset != DW_INVALID_OFFSET)
2995 {
2996 DWARFCompileUnitSP cu_sp;
2997 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Sean Callanan72e49402011-08-05 23:43:37 +00002998 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002999 }
3000 return NULL;
3001}
3002
Sean Callanan72e49402011-08-05 23:43:37 +00003003clang::DeclContext *
3004SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
3005{
3006 if (die_offset != DW_INVALID_OFFSET)
3007 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003008 DWARFDebugInfo* debug_info = DebugInfo();
3009 if (debug_info)
3010 {
3011 DWARFCompileUnitSP cu_sp;
3012 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
3013 if (die)
3014 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
3015 }
Sean Callanan72e49402011-08-05 23:43:37 +00003016 }
3017 return NULL;
3018}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003019
Greg Clayton96d7d742010-11-10 23:42:09 +00003020clang::NamespaceDecl *
3021SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3022{
3023 if (die->Tag() == DW_TAG_namespace)
3024 {
3025 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3026 if (namespace_name)
3027 {
3028 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00003029 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent()));
Greg Clayton96d7d742010-11-10 23:42:09 +00003030 if (namespace_decl)
Greg Claytona2721472011-06-25 00:44:06 +00003031 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton96d7d742010-11-10 23:42:09 +00003032 return namespace_decl;
3033 }
3034 }
3035 return NULL;
3036}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003037
3038clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003039SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3040{
Greg Clayton5cf58b92011-10-05 22:22:08 +00003041 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3042 if (clang_decl_ctx)
3043 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003044 // If this DIE has a specification, or an abstract origin, then trace to those.
3045
3046 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
3047 if (die_offset != DW_INVALID_OFFSET)
3048 return GetClangDeclContextForDIEOffset (sc, die_offset);
3049
3050 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3051 if (die_offset != DW_INVALID_OFFSET)
3052 return GetClangDeclContextForDIEOffset (sc, die_offset);
3053
3054 // This is the DIE we want. Parse it, then query our map.
3055
3056 ParseType(sc, curr_cu, die, NULL);
3057
Greg Clayton5cf58b92011-10-05 22:22:08 +00003058 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3059
3060 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003061}
3062
3063clang::DeclContext *
Greg Clayton2bc22f82011-09-30 03:20:47 +00003064SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003065{
Greg Claytonca512b32011-01-14 04:54:56 +00003066 if (m_clang_tu_decl == NULL)
3067 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003068
Greg Clayton2bc22f82011-09-30 03:20:47 +00003069 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
3070
3071 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003073 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
3074 if (pos != m_die_to_decl_ctx.end())
3075 return pos->second;
3076
3077 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003078 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003079 case DW_TAG_compile_unit:
3080 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003081
Greg Clayton2bc22f82011-09-30 03:20:47 +00003082 case DW_TAG_namespace:
Greg Claytonca512b32011-01-14 04:54:56 +00003083 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003084 const char *namespace_name = decl_ctx_die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
3085 if (namespace_name)
Greg Claytonca512b32011-01-14 04:54:56 +00003086 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003087 Declaration decl; // TODO: fill in the decl object
3088 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (cu, decl_ctx_die));
3089 if (namespace_decl)
3090 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, decl_ctx_die);
3091 return namespace_decl;
3092 }
3093 }
3094 break;
3095
3096 case DW_TAG_structure_type:
3097 case DW_TAG_union_type:
3098 case DW_TAG_class_type:
3099 {
3100 Type* type = ResolveType (cu, decl_ctx_die);
3101 if (type)
3102 {
3103 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
3104 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00003105 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003106 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
3107 if (decl_ctx)
3108 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00003109 }
3110 }
Greg Claytonca512b32011-01-14 04:54:56 +00003111 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00003112 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003113
Greg Clayton2bc22f82011-09-30 03:20:47 +00003114 default:
3115 break;
Greg Claytonca512b32011-01-14 04:54:56 +00003116 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003117 }
Greg Clayton7a345282010-11-09 23:46:37 +00003118 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003119}
3120
Greg Clayton2bc22f82011-09-30 03:20:47 +00003121
3122const DWARFDebugInfoEntry *
3123SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
3124{
3125 if (cu && die)
3126 {
3127 const DWARFDebugInfoEntry * const decl_die = die;
3128
3129 while (die != NULL)
3130 {
3131 // If this is the original DIE that we are searching for a declaration
3132 // for, then don't look in the cache as we don't want our own decl
3133 // context to be our decl context...
3134 if (decl_die != die)
3135 {
3136 switch (die->Tag())
3137 {
3138 case DW_TAG_compile_unit:
3139 case DW_TAG_namespace:
3140 case DW_TAG_structure_type:
3141 case DW_TAG_union_type:
3142 case DW_TAG_class_type:
3143 return die;
3144
3145 default:
3146 break;
3147 }
3148 }
3149
3150 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
3151 if (die_offset != DW_INVALID_OFFSET)
3152 {
3153 DWARFCompileUnit *spec_cu = cu;
3154 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
3155 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
3156 if (spec_die_decl_ctx_die)
3157 return spec_die_decl_ctx_die;
3158 }
3159
3160 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3161 if (die_offset != DW_INVALID_OFFSET)
3162 {
3163 DWARFCompileUnit *abs_cu = cu;
3164 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
3165 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
3166 if (abs_die_decl_ctx_die)
3167 return abs_die_decl_ctx_die;
3168 }
3169
3170 die = die->GetParent();
3171 }
3172 }
3173 return NULL;
3174}
3175
3176
3177
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003178// This function can be used when a DIE is found that is a forward declaration
3179// DIE and we want to try and find a type that has the complete definition.
3180TypeSP
Greg Clayton7f995132011-10-04 22:41:51 +00003181SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
3182 const DWARFDebugInfoEntry *die,
3183 const ConstString &type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003184{
3185 TypeSP type_sp;
3186
Greg Clayton1a65ae12011-01-25 23:55:37 +00003187 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003188 return type_sp;
3189
Greg Clayton7f995132011-10-04 22:41:51 +00003190 DIEArray die_offsets;
3191
3192 if (m_apple_types_ap.get())
3193 {
3194 const char *name_cstr = type_name.GetCString();
3195 DWARFMappedHash::MemoryTable::Pair kv_pair;
3196 if (m_apple_types_ap->Find (name_cstr, kv_pair))
3197 {
3198 die_offsets.swap(kv_pair.value);
3199 }
3200 }
3201 else
3202 {
3203 if (!m_indexed)
3204 Index ();
3205
3206 m_type_index.Find (type_name, die_offsets);
3207 }
3208
3209
3210 const size_t num_matches = die_offsets.size();
Greg Clayton69974892010-12-03 21:42:06 +00003211
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003212 const dw_tag_t type_tag = die->Tag();
Greg Claytond4a2b372011-09-12 23:21:58 +00003213
3214 DWARFCompileUnit* type_cu = NULL;
3215 const DWARFDebugInfoEntry* type_die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003216 if (num_matches)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003217 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003218 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003219 for (size_t i=0; i<num_matches; ++i)
3220 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003221 const dw_offset_t die_offset = die_offsets[i];
3222 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003223
3224 if (type_die != die && type_die->Tag() == type_tag)
3225 {
3226 // Hold off on comparing parent DIE tags until
3227 // we know what happens with stuff in namespaces
3228 // for gcc and clang...
3229 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3230 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3231 //if (parent_die->Tag() == parent_type_die->Tag())
3232 {
3233 Type *resolved_type = ResolveType (type_cu, type_die, false);
3234 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3235 {
3236 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
3237 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00003238 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003239 m_obj_file->GetFileSpec().GetFilename().AsCString(),
3240 type_die->GetOffset(),
3241 type_cu->GetOffset());
3242
3243 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003244 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00003245 if (!type_sp)
3246 {
3247 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
3248 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003249 break;
3250 }
3251 }
3252 }
3253 }
3254 }
3255 return type_sp;
3256}
3257
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003258TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003259SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003260{
3261 TypeSP type_sp;
3262
Greg Clayton1be10fc2010-09-29 01:12:09 +00003263 if (type_is_new_ptr)
3264 *type_is_new_ptr = false;
3265
Sean Callananc7fbf732010-08-06 00:32:49 +00003266 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003267 if (die != NULL)
3268 {
Greg Clayton21f2a492011-10-06 00:09:08 +00003269 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Jim Ingham16746d12011-08-25 23:21:43 +00003270 if (log && dwarf_cu)
3271 {
Jim Ingham318c9f22011-08-26 19:44:13 +00003272 StreamString s;
Jim Inghamd3d25d92011-08-27 01:24:54 +00003273 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham318c9f22011-08-26 19:44:13 +00003274 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3275
Jim Ingham16746d12011-08-25 23:21:43 +00003276 }
3277
Greg Clayton594e5ed2010-09-27 21:07:38 +00003278 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003279 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003280 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003281 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003282 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003283 if (type_is_new_ptr)
3284 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003285
Greg Clayton594e5ed2010-09-27 21:07:38 +00003286 const dw_tag_t tag = die->Tag();
3287
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003288 bool is_forward_declaration = false;
3289 DWARFDebugInfoEntry::Attributes attributes;
3290 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003291 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003292 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3293 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003294 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003295 Declaration decl;
3296
Greg Clayton4957bf62010-09-30 21:49:03 +00003297 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003298 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003299
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003300 dw_attr_t attr;
3301
3302 switch (tag)
3303 {
3304 case DW_TAG_base_type:
3305 case DW_TAG_pointer_type:
3306 case DW_TAG_reference_type:
3307 case DW_TAG_typedef:
3308 case DW_TAG_const_type:
3309 case DW_TAG_restrict_type:
3310 case DW_TAG_volatile_type:
3311 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003312 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003313 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003314
Greg Claytond88d7592010-09-15 08:33:30 +00003315 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003316 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003317 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3318
3319 if (num_attributes > 0)
3320 {
3321 uint32_t i;
3322 for (i=0; i<num_attributes; ++i)
3323 {
3324 attr = attributes.AttributeAtIndex(i);
3325 DWARFFormValue form_value;
3326 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3327 {
3328 switch (attr)
3329 {
3330 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3331 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3332 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3333 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003334
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003335 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003336 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3337 // include the "&"...
3338 if (tag == DW_TAG_reference_type)
3339 {
3340 if (strchr (type_name_cstr, '&') == NULL)
3341 type_name_cstr = NULL;
3342 }
3343 if (type_name_cstr)
3344 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003345 break;
Greg Clayton36909642011-03-15 04:38:20 +00003346 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003347 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3348 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3349 default:
3350 case DW_AT_sibling:
3351 break;
3352 }
3353 }
3354 }
3355 }
3356
Greg Claytonc93237c2010-10-01 20:48:32 +00003357 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);
3358
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003359 switch (tag)
3360 {
3361 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003362 break;
3363
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003364 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003365 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003366 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3367 encoding,
3368 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003369 break;
3370
Greg Clayton526e5af2010-11-13 03:52:47 +00003371 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3372 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3373 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3374 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3375 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3376 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003377 }
3378
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003379 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3380 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3381 {
3382 static ConstString g_objc_type_name_id("id");
3383 static ConstString g_objc_type_name_Class("Class");
3384 static ConstString g_objc_type_name_selector("SEL");
3385
Greg Clayton24739922010-10-13 03:15:28 +00003386 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003387 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003388 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003389 resolve_state = Type::eResolveStateFull;
3390
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003391 }
Greg Clayton24739922010-10-13 03:15:28 +00003392 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003393 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003394 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003395 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003396 }
Greg Clayton24739922010-10-13 03:15:28 +00003397 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003398 {
Sean Callananf6c73082010-12-06 23:53:20 +00003399 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003400 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003401 }
3402 }
3403
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003404 type_sp.reset( new Type (die->GetOffset(),
3405 this,
3406 type_name_const_str,
3407 byte_size,
3408 NULL,
3409 encoding_uid,
3410 encoding_data_type,
3411 &decl,
3412 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003413 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003414
Greg Clayton594e5ed2010-09-27 21:07:38 +00003415 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003416
3417// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3418// if (encoding_type != NULL)
3419// {
3420// if (encoding_type != DIE_IS_BEING_PARSED)
3421// type_sp->SetEncodingType(encoding_type);
3422// else
3423// m_indirect_fixups.push_back(type_sp.get());
3424// }
3425 }
3426 break;
3427
3428 case DW_TAG_structure_type:
3429 case DW_TAG_union_type:
3430 case DW_TAG_class_type:
3431 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003432 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003433 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003434
Greg Clayton9e409562010-07-28 02:04:09 +00003435 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003436 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003437 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003438 if (num_attributes > 0)
3439 {
3440 uint32_t i;
3441 for (i=0; i<num_attributes; ++i)
3442 {
3443 attr = attributes.AttributeAtIndex(i);
3444 DWARFFormValue form_value;
3445 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3446 {
3447 switch (attr)
3448 {
Greg Clayton9e409562010-07-28 02:04:09 +00003449 case DW_AT_decl_file:
3450 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3451 break;
3452
3453 case DW_AT_decl_line:
3454 decl.SetLine(form_value.Unsigned());
3455 break;
3456
3457 case DW_AT_decl_column:
3458 decl.SetColumn(form_value.Unsigned());
3459 break;
3460
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003461 case DW_AT_name:
3462 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003463 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003464 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003465
3466 case DW_AT_byte_size:
3467 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003468 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003469 break;
3470
3471 case DW_AT_accessibility:
3472 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3473 break;
3474
3475 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003476 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003477 break;
3478
3479 case DW_AT_APPLE_runtime_class:
3480 class_language = (LanguageType)form_value.Signed();
3481 break;
3482
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003483 case DW_AT_allocated:
3484 case DW_AT_associated:
3485 case DW_AT_data_location:
3486 case DW_AT_description:
3487 case DW_AT_start_scope:
3488 case DW_AT_visibility:
3489 default:
3490 case DW_AT_sibling:
3491 break;
3492 }
3493 }
3494 }
3495 }
3496
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003497 UniqueDWARFASTType unique_ast_entry;
3498 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003499 {
Greg Claytone576ab22011-02-15 00:19:15 +00003500 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003501 this,
3502 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003503 die,
3504 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003505 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003506 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003507 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003508 // We have already parsed this type or from another
3509 // compile unit. GCC loves to use the "one definition
3510 // rule" which can result in multiple definitions
3511 // of the same class over and over in each compile
3512 // unit.
3513 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003514 if (type_sp)
3515 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003516 m_die_to_type[die] = type_sp.get();
3517 return type_sp;
3518 }
3519 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003520 }
3521
3522 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3523
3524 int tag_decl_kind = -1;
3525 AccessType default_accessibility = eAccessNone;
3526 if (tag == DW_TAG_structure_type)
3527 {
3528 tag_decl_kind = clang::TTK_Struct;
3529 default_accessibility = eAccessPublic;
3530 }
3531 else if (tag == DW_TAG_union_type)
3532 {
3533 tag_decl_kind = clang::TTK_Union;
3534 default_accessibility = eAccessPublic;
3535 }
3536 else if (tag == DW_TAG_class_type)
3537 {
3538 tag_decl_kind = clang::TTK_Class;
3539 default_accessibility = eAccessPrivate;
3540 }
3541
3542
3543 if (is_forward_declaration)
3544 {
3545 // We have a forward declaration to a type and we need
3546 // to try and find a full declaration. We look in the
3547 // current type index just in case we have a forward
3548 // declaration followed by an actual declarations in the
3549 // DWARF. If this fails, we need to look elsewhere...
3550
3551 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3552
3553 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003554 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003555 // We weren't able to find a full declaration in
3556 // this DWARF, see if we have a declaration anywhere
3557 // else...
3558 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003559 }
3560
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003561 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003562 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003563 // We found a real definition for this type elsewhere
3564 // so lets use it and cache the fact that we found
3565 // a complete type for this die
3566 m_die_to_type[die] = type_sp.get();
3567 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003568 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003569 }
3570 assert (tag_decl_kind != -1);
3571 bool clang_type_was_created = false;
3572 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3573 if (clang_type == NULL)
3574 {
3575 clang_type_was_created = true;
3576 clang_type = ast.CreateRecordType (type_name_cstr,
3577 tag_decl_kind,
Sean Callanan72e49402011-08-05 23:43:37 +00003578 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003579 class_language);
3580 }
3581
3582 // Store a forward declaration to this class type in case any
3583 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00003584 // types for function prototypes.
3585 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003586 type_sp.reset (new Type (die->GetOffset(),
3587 this,
3588 type_name_const_str,
3589 byte_size,
3590 NULL,
3591 LLDB_INVALID_UID,
3592 Type::eEncodingIsUID,
3593 &decl,
3594 clang_type,
3595 Type::eResolveStateForward));
3596
3597
3598 // Add our type to the unique type map so we don't
3599 // end up creating many copies of the same type over
3600 // and over in the ASTContext for our module
3601 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00003602 unique_ast_entry.m_symfile = this;
3603 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003604 unique_ast_entry.m_die = die;
3605 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00003606 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3607 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003608
3609 if (die->HasChildren() == false && is_forward_declaration == false)
3610 {
3611 // No children for this struct/union/class, lets finish it
3612 ast.StartTagDeclarationDefinition (clang_type);
3613 ast.CompleteTagDeclarationDefinition (clang_type);
3614 }
3615 else if (clang_type_was_created)
3616 {
3617 // Leave this as a forward declaration until we need
3618 // to know the details of the type. lldb_private::Type
3619 // will automatically call the SymbolFile virtual function
3620 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3621 // When the definition needs to be defined.
3622 m_forward_decl_die_to_clang_type[die] = clang_type;
3623 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3624 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003625 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003626 }
3627 break;
3628
3629 case DW_TAG_enumeration_type:
3630 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003631 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003632 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003633
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003634 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003635
Greg Claytond88d7592010-09-15 08:33:30 +00003636 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003637 if (num_attributes > 0)
3638 {
3639 uint32_t i;
3640
3641 for (i=0; i<num_attributes; ++i)
3642 {
3643 attr = attributes.AttributeAtIndex(i);
3644 DWARFFormValue form_value;
3645 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3646 {
3647 switch (attr)
3648 {
Greg Clayton7a345282010-11-09 23:46:37 +00003649 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3650 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3651 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003652 case DW_AT_name:
3653 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003654 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003655 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003656 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003657 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00003658 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3659 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003660 case DW_AT_allocated:
3661 case DW_AT_associated:
3662 case DW_AT_bit_stride:
3663 case DW_AT_byte_stride:
3664 case DW_AT_data_location:
3665 case DW_AT_description:
3666 case DW_AT_start_scope:
3667 case DW_AT_visibility:
3668 case DW_AT_specification:
3669 case DW_AT_abstract_origin:
3670 case DW_AT_sibling:
3671 break;
3672 }
3673 }
3674 }
3675
Greg Claytonc93237c2010-10-01 20:48:32 +00003676 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3677
Greg Clayton1be10fc2010-09-29 01:12:09 +00003678 clang_type_t enumerator_clang_type = NULL;
3679 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3680 if (clang_type == NULL)
3681 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003682 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3683 DW_ATE_signed,
3684 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003685 clang_type = ast.CreateEnumerationType (type_name_cstr,
Sean Callanan72e49402011-08-05 23:43:37 +00003686 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003687 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003688 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003689 }
3690 else
3691 {
3692 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3693 assert (enumerator_clang_type != NULL);
3694 }
3695
Greg Claytona2721472011-06-25 00:44:06 +00003696 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3697
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003698 type_sp.reset( new Type (die->GetOffset(),
3699 this,
3700 type_name_const_str,
3701 byte_size,
3702 NULL,
3703 encoding_uid,
3704 Type::eEncodingIsUID,
3705 &decl,
3706 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003707 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003708
Greg Clayton6beaaa62011-01-17 03:46:26 +00003709#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003710 // Leave this as a forward declaration until we need
3711 // to know the details of the type. lldb_private::Type
3712 // will automatically call the SymbolFile virtual function
3713 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3714 // When the definition needs to be defined.
3715 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003716 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003717 ClangASTContext::SetHasExternalStorage (clang_type, true);
3718#else
3719 ast.StartTagDeclarationDefinition (clang_type);
3720 if (die->HasChildren())
3721 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003722 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3723 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003724 }
3725 ast.CompleteTagDeclarationDefinition (clang_type);
3726#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003727 }
3728 }
3729 break;
3730
Jim Inghamb0be4422010-08-12 01:20:14 +00003731 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003732 case DW_TAG_subprogram:
3733 case DW_TAG_subroutine_type:
3734 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003735 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003736 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003737
3738 const char *mangled = NULL;
3739 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003740 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003741 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003742 bool is_static = false;
3743 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003744 bool is_explicit = false;
Greg Clayton72da3972011-08-16 18:40:23 +00003745 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
3746 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00003747
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003748 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003749 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003750
3751
Greg Claytond88d7592010-09-15 08:33:30 +00003752 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003753 if (num_attributes > 0)
3754 {
3755 uint32_t i;
3756 for (i=0; i<num_attributes; ++i)
3757 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003758 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003759 DWARFFormValue form_value;
3760 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3761 {
3762 switch (attr)
3763 {
3764 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3765 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3766 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3767 case DW_AT_name:
3768 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003769 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003770 break;
3771
3772 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3773 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003774 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003775 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003776 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3777 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003778 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3779
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003780 case DW_AT_external:
3781 if (form_value.Unsigned())
3782 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003783 if (storage == clang::SC_None)
3784 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003786 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003787 }
3788 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003789
Greg Clayton72da3972011-08-16 18:40:23 +00003790 case DW_AT_specification:
3791 specification_die_offset = form_value.Reference(dwarf_cu);
3792 break;
3793
3794 case DW_AT_abstract_origin:
3795 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
3796 break;
3797
3798
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003799 case DW_AT_allocated:
3800 case DW_AT_associated:
3801 case DW_AT_address_class:
3802 case DW_AT_artificial:
3803 case DW_AT_calling_convention:
3804 case DW_AT_data_location:
3805 case DW_AT_elemental:
3806 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003807 case DW_AT_frame_base:
3808 case DW_AT_high_pc:
3809 case DW_AT_low_pc:
3810 case DW_AT_object_pointer:
3811 case DW_AT_prototyped:
3812 case DW_AT_pure:
3813 case DW_AT_ranges:
3814 case DW_AT_recursive:
3815 case DW_AT_return_addr:
3816 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003817 case DW_AT_start_scope:
3818 case DW_AT_static_link:
3819 case DW_AT_trampoline:
3820 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003821 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822 case DW_AT_description:
3823 case DW_AT_sibling:
3824 break;
3825 }
3826 }
3827 }
Greg Clayton24739922010-10-13 03:15:28 +00003828 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003829
Greg Clayton24739922010-10-13 03:15:28 +00003830 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 +00003831
Greg Clayton24739922010-10-13 03:15:28 +00003832 clang_type_t return_clang_type = NULL;
3833 Type *func_type = NULL;
3834
3835 if (type_die_offset != DW_INVALID_OFFSET)
3836 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003837
Greg Clayton24739922010-10-13 03:15:28 +00003838 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003839 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003840 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003841 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003842
Greg Claytonf51de672010-10-01 02:31:07 +00003843
Greg Clayton24739922010-10-13 03:15:28 +00003844 std::vector<clang_type_t> function_param_types;
3845 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003846
Greg Clayton24739922010-10-13 03:15:28 +00003847 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00003848
Greg Clayton5113dc82011-08-12 06:47:54 +00003849 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
3850 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
3851
3852 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord;
3853 // Start off static. This will be set to false in ParseChildParameters(...)
3854 // if we find a "this" paramters as the first parameter
3855 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00003856 is_static = true;
3857
Greg Clayton24739922010-10-13 03:15:28 +00003858 if (die->HasChildren())
3859 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003860 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003861 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00003862 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003863 type_sp,
3864 dwarf_cu,
3865 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00003866 skip_artificial,
3867 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003868 type_list,
3869 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003870 function_param_decls,
3871 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003872 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003873
Greg Clayton24739922010-10-13 03:15:28 +00003874 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003875 clang_type = ast.CreateFunctionType (return_clang_type,
3876 &function_param_types[0],
3877 function_param_types.size(),
3878 is_variadic,
3879 type_quals);
3880
Greg Clayton24739922010-10-13 03:15:28 +00003881 if (type_name_cstr)
3882 {
3883 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00003884 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003885 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +00003886 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr))
Greg Clayton0fffff52010-09-24 05:15:53 +00003887 {
Greg Clayton24739922010-10-13 03:15:28 +00003888 // We need to find the DW_TAG_class_type or
3889 // DW_TAG_struct_type by name so we can add this
3890 // as a member function of the class.
3891 const char *class_name_start = type_name_cstr + 2;
3892 const char *class_name_end = ::strchr (class_name_start, ' ');
3893 SymbolContext empty_sc;
3894 clang_type_t class_opaque_type = NULL;
3895 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003896 {
Greg Clayton24739922010-10-13 03:15:28 +00003897 ConstString class_name (class_name_start, class_name_end - class_name_start);
3898 TypeList types;
3899 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3900 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003901 {
Greg Clayton24739922010-10-13 03:15:28 +00003902 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003903 {
Greg Clayton24739922010-10-13 03:15:28 +00003904 Type *type = types.GetTypeAtIndex (i).get();
3905 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3906 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003907 {
Greg Clayton24739922010-10-13 03:15:28 +00003908 class_opaque_type = type_clang_forward_type;
3909 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003910 }
3911 }
3912 }
Greg Clayton24739922010-10-13 03:15:28 +00003913 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003914
Greg Clayton24739922010-10-13 03:15:28 +00003915 if (class_opaque_type)
3916 {
3917 // If accessibility isn't set to anything valid, assume public for
3918 // now...
3919 if (accessibility == eAccessNone)
3920 accessibility = eAccessPublic;
3921
3922 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003923 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3924 type_name_cstr,
3925 clang_type,
3926 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00003927 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00003928 type_handled = objc_method_decl != NULL;
3929 }
3930 }
Greg Clayton5113dc82011-08-12 06:47:54 +00003931 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00003932 {
3933 // Look at the parent of this DIE and see if is is
3934 // a class or struct and see if this is actually a
3935 // C++ method
Greg Clayton5113dc82011-08-12 06:47:54 +00003936 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
Greg Clayton24739922010-10-13 03:15:28 +00003937 if (class_type)
3938 {
Greg Clayton72da3972011-08-16 18:40:23 +00003939 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00003940 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003941 // We have a specification which we are going to base our function
3942 // prototype off of, so we need this type to be completed so that the
3943 // m_die_to_decl_ctx for the method in the specification has a valid
3944 // clang decl context.
3945 class_type->GetClangFullType();
Greg Clayton72da3972011-08-16 18:40:23 +00003946 // If we have a specification, then the function type should have been
3947 // made with the specification and not with this die.
3948 DWARFCompileUnitSP spec_cu_sp;
3949 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00003950 clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die);
3951 if (spec_clang_decl_ctx)
3952 {
3953 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
3954 }
3955 else
Jim Inghamc1663042011-09-29 22:12:35 +00003956 {
3957 ReportWarning ("0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n",
Greg Clayton5cf58b92011-10-05 22:22:08 +00003958 die->GetOffset(),
3959 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00003960 }
Greg Clayton72da3972011-08-16 18:40:23 +00003961 type_handled = true;
3962 }
3963 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
3964 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003965 // We have a specification which we are going to base our function
3966 // prototype off of, so we need this type to be completed so that the
3967 // m_die_to_decl_ctx for the method in the abstract origin has a valid
3968 // clang decl context.
3969 class_type->GetClangFullType();
3970
Greg Clayton72da3972011-08-16 18:40:23 +00003971 DWARFCompileUnitSP abs_cu_sp;
3972 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00003973 clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die);
3974 if (abs_clang_decl_ctx)
3975 {
3976 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
3977 }
3978 else
Jim Inghamc1663042011-09-29 22:12:35 +00003979 {
3980 ReportWarning ("0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
Greg Clayton5cf58b92011-10-05 22:22:08 +00003981 die->GetOffset(),
3982 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00003983 }
Greg Clayton72da3972011-08-16 18:40:23 +00003984 type_handled = true;
3985 }
3986 else
3987 {
3988 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3989 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton931180e2011-01-27 06:44:37 +00003990 {
Greg Clayton72da3972011-08-16 18:40:23 +00003991 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3992 // in the DWARF for C++ methods... Default to public for now...
3993 if (accessibility == eAccessNone)
3994 accessibility = eAccessPublic;
3995
3996 if (!is_static && !die->HasChildren())
3997 {
3998 // We have a C++ member function with no children (this pointer!)
3999 // and clang will get mad if we try and make a function that isn't
4000 // well formed in the DWARF, so we will just skip it...
4001 type_handled = true;
4002 }
4003 else
4004 {
4005 clang::CXXMethodDecl *cxx_method_decl;
4006 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
4007 type_name_cstr,
4008 clang_type,
4009 accessibility,
4010 is_virtual,
4011 is_static,
4012 is_inline,
4013 is_explicit);
4014 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004015
Greg Clayton72da3972011-08-16 18:40:23 +00004016 type_handled = cxx_method_decl != NULL;
4017 }
Greg Clayton931180e2011-01-27 06:44:37 +00004018 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004019 }
4020 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004021 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004022 }
Greg Clayton24739922010-10-13 03:15:28 +00004023
4024 if (!type_handled)
4025 {
4026 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004027 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
4028 clang_type,
4029 storage,
4030 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00004031
4032 // Add the decl to our DIE to decl context map
4033 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00004034 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00004035 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004036 ast.SetFunctionParameters (function_decl,
4037 &function_param_decls.front(),
4038 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00004039 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004040 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004041 type_sp.reset( new Type (die->GetOffset(),
4042 this,
4043 type_name_const_str,
4044 0,
4045 NULL,
4046 LLDB_INVALID_UID,
4047 Type::eEncodingIsUID,
4048 &decl,
4049 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004050 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00004051 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004052 }
4053 break;
4054
4055 case DW_TAG_array_type:
4056 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004057 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004058 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004059
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004060 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004061 int64_t first_index = 0;
4062 uint32_t byte_stride = 0;
4063 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00004064 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004065
4066 if (num_attributes > 0)
4067 {
4068 uint32_t i;
4069 for (i=0; i<num_attributes; ++i)
4070 {
4071 attr = attributes.AttributeAtIndex(i);
4072 DWARFFormValue form_value;
4073 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4074 {
4075 switch (attr)
4076 {
4077 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4078 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4079 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4080 case DW_AT_name:
4081 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004082 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004083 break;
4084
4085 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004086 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004087 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
4088 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004089 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004090 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004091 case DW_AT_allocated:
4092 case DW_AT_associated:
4093 case DW_AT_data_location:
4094 case DW_AT_description:
4095 case DW_AT_ordering:
4096 case DW_AT_start_scope:
4097 case DW_AT_visibility:
4098 case DW_AT_specification:
4099 case DW_AT_abstract_origin:
4100 case DW_AT_sibling:
4101 break;
4102 }
4103 }
4104 }
4105
Greg Claytonc93237c2010-10-01 20:48:32 +00004106 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
4107
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004108 Type *element_type = ResolveTypeUID(type_die_offset);
4109
4110 if (element_type)
4111 {
4112 std::vector<uint64_t> element_orders;
4113 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00004114 // We have an array that claims to have no members, lets give it at least one member...
4115 if (element_orders.empty())
4116 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004117 if (byte_stride == 0 && bit_stride == 0)
4118 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00004119 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004120 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
4121 uint64_t num_elements = 0;
4122 std::vector<uint64_t>::const_reverse_iterator pos;
4123 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
4124 for (pos = element_orders.rbegin(); pos != end; ++pos)
4125 {
4126 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004127 clang_type = ast.CreateArrayType (array_element_type,
4128 num_elements,
4129 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004130 array_element_type = clang_type;
4131 array_element_bit_stride = array_element_bit_stride * num_elements;
4132 }
4133 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004134 type_sp.reset( new Type (die->GetOffset(),
4135 this,
4136 empty_name,
4137 array_element_bit_stride / 8,
4138 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00004139 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004140 Type::eEncodingIsUID,
4141 &decl,
4142 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004143 Type::eResolveStateFull));
4144 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004145 }
4146 }
4147 }
4148 break;
4149
Greg Clayton9b81a312010-06-12 01:20:30 +00004150 case DW_TAG_ptr_to_member_type:
4151 {
4152 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
4153 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
4154
Greg Claytond88d7592010-09-15 08:33:30 +00004155 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00004156
4157 if (num_attributes > 0) {
4158 uint32_t i;
4159 for (i=0; i<num_attributes; ++i)
4160 {
4161 attr = attributes.AttributeAtIndex(i);
4162 DWARFFormValue form_value;
4163 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4164 {
4165 switch (attr)
4166 {
4167 case DW_AT_type:
4168 type_die_offset = form_value.Reference(dwarf_cu); break;
4169 case DW_AT_containing_type:
4170 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4171 }
4172 }
4173 }
4174
4175 Type *pointee_type = ResolveTypeUID(type_die_offset);
4176 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4177
Greg Clayton526e5af2010-11-13 03:52:47 +00004178 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4179 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00004180
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004181 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4182 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00004183
Greg Clayton526e5af2010-11-13 03:52:47 +00004184 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4185 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00004186
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004187 type_sp.reset( new Type (die->GetOffset(),
4188 this,
4189 type_name_const_str,
4190 byte_size,
4191 NULL,
4192 LLDB_INVALID_UID,
4193 Type::eEncodingIsUID,
4194 NULL,
4195 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004196 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00004197 }
4198
4199 break;
4200 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004201 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00004202 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004203 break;
4204 }
4205
4206 if (type_sp.get())
4207 {
4208 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4209 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4210
4211 SymbolContextScope * symbol_context_scope = NULL;
4212 if (sc_parent_tag == DW_TAG_compile_unit)
4213 {
4214 symbol_context_scope = sc.comp_unit;
4215 }
4216 else if (sc.function != NULL)
4217 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004218 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004219 if (symbol_context_scope == NULL)
4220 symbol_context_scope = sc.function;
4221 }
4222
4223 if (symbol_context_scope != NULL)
4224 {
4225 type_sp->SetSymbolContextScope(symbol_context_scope);
4226 }
4227
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004228 // We are ready to put this type into the uniqued list up at the module level
4229 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00004230
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004231 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004232 }
4233 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00004234 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004235 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004236 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004237 }
4238 }
4239 return type_sp;
4240}
4241
4242size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004243SymbolFileDWARF::ParseTypes
4244(
4245 const SymbolContext& sc,
4246 DWARFCompileUnit* dwarf_cu,
4247 const DWARFDebugInfoEntry *die,
4248 bool parse_siblings,
4249 bool parse_children
4250)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004251{
4252 size_t types_added = 0;
4253 while (die != NULL)
4254 {
4255 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00004256 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004257 {
4258 if (type_is_new)
4259 ++types_added;
4260 }
4261
4262 if (parse_children && die->HasChildren())
4263 {
4264 if (die->Tag() == DW_TAG_subprogram)
4265 {
4266 SymbolContext child_sc(sc);
4267 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
4268 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4269 }
4270 else
4271 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4272 }
4273
4274 if (parse_siblings)
4275 die = die->GetSibling();
4276 else
4277 die = NULL;
4278 }
4279 return types_added;
4280}
4281
4282
4283size_t
4284SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4285{
4286 assert(sc.comp_unit && sc.function);
4287 size_t functions_added = 0;
4288 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4289 if (dwarf_cu)
4290 {
4291 dw_offset_t function_die_offset = sc.function->GetID();
4292 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4293 if (function_die)
4294 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00004295 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004296 }
4297 }
4298
4299 return functions_added;
4300}
4301
4302
4303size_t
4304SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4305{
4306 // At least a compile unit must be valid
4307 assert(sc.comp_unit);
4308 size_t types_added = 0;
4309 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4310 if (dwarf_cu)
4311 {
4312 if (sc.function)
4313 {
4314 dw_offset_t function_die_offset = sc.function->GetID();
4315 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4316 if (func_die && func_die->HasChildren())
4317 {
4318 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4319 }
4320 }
4321 else
4322 {
4323 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4324 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4325 {
4326 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4327 }
4328 }
4329 }
4330
4331 return types_added;
4332}
4333
4334size_t
4335SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4336{
4337 if (sc.comp_unit != NULL)
4338 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004339 DWARFDebugInfo* info = DebugInfo();
4340 if (info == NULL)
4341 return 0;
4342
4343 uint32_t cu_idx = UINT32_MAX;
4344 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004345
4346 if (dwarf_cu == NULL)
4347 return 0;
4348
4349 if (sc.function)
4350 {
4351 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004352
4353 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4354 assert (func_lo_pc != DW_INVALID_ADDRESS);
4355
Greg Claytonc662ec82011-06-17 22:10:16 +00004356 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4357
4358 // Let all blocks know they have parse all their variables
4359 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4360
4361 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004362 }
4363 else if (sc.comp_unit)
4364 {
4365 uint32_t vars_added = 0;
4366 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4367
4368 if (variables.get() == NULL)
4369 {
4370 variables.reset(new VariableList());
4371 sc.comp_unit->SetVariableList(variables);
4372
Greg Claytond4a2b372011-09-12 23:21:58 +00004373 DWARFCompileUnit* match_dwarf_cu = NULL;
4374 const DWARFDebugInfoEntry* die = NULL;
4375 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00004376 if (m_apple_names_ap.get())
4377 {
4378 // TODO: implement finding all items in
4379 m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
4380 dwarf_cu->GetNextCompileUnitOffset(),
4381 die_offsets);
4382 }
4383 else
4384 {
4385 // Index if we already haven't to make sure the compile units
4386 // get indexed and make their global DIE index list
4387 if (!m_indexed)
4388 Index ();
4389
4390 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
4391 dwarf_cu->GetNextCompileUnitOffset(),
4392 die_offsets);
4393 }
4394
4395 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004396 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004397 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004398 DWARFDebugInfo* debug_info = DebugInfo();
4399 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004400 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004401 const dw_offset_t die_offset = die_offsets[i];
4402 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
4403 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
4404 if (var_sp)
4405 {
4406 variables->AddVariableIfUnique (var_sp);
4407 ++vars_added;
4408 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004409 }
4410 }
4411 }
4412 return vars_added;
4413 }
4414 }
4415 return 0;
4416}
4417
4418
4419VariableSP
4420SymbolFileDWARF::ParseVariableDIE
4421(
4422 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004423 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004424 const DWARFDebugInfoEntry *die,
4425 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004426)
4427{
4428
Greg Clayton83c5cd92010-11-14 22:13:40 +00004429 VariableSP var_sp (m_die_to_variable_sp[die]);
4430 if (var_sp)
4431 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004432
4433 const dw_tag_t tag = die->Tag();
Greg Clayton7f995132011-10-04 22:41:51 +00004434
4435 if ((tag == DW_TAG_variable) ||
4436 (tag == DW_TAG_constant) ||
4437 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004438 {
Greg Clayton7f995132011-10-04 22:41:51 +00004439 DWARFDebugInfoEntry::Attributes attributes;
4440 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4441 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004442 {
Greg Clayton7f995132011-10-04 22:41:51 +00004443 const char *name = NULL;
4444 const char *mangled = NULL;
4445 Declaration decl;
4446 uint32_t i;
4447 Type *var_type = NULL;
4448 DWARFExpression location;
4449 bool is_external = false;
4450 bool is_artificial = false;
4451 bool location_is_const_value_data = false;
4452 AccessType accessibility = eAccessNone;
4453
4454 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004455 {
Greg Clayton7f995132011-10-04 22:41:51 +00004456 dw_attr_t attr = attributes.AttributeAtIndex(i);
4457 DWARFFormValue form_value;
4458 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004459 {
Greg Clayton7f995132011-10-04 22:41:51 +00004460 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004461 {
Greg Clayton7f995132011-10-04 22:41:51 +00004462 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4463 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4464 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4465 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
4466 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4467 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
4468 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
4469 case DW_AT_const_value:
4470 location_is_const_value_data = true;
4471 // Fall through...
4472 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004473 {
Greg Clayton7f995132011-10-04 22:41:51 +00004474 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004475 {
Greg Clayton7f995132011-10-04 22:41:51 +00004476 const DataExtractor& debug_info_data = get_debug_info_data();
4477
4478 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4479 uint32_t block_length = form_value.Unsigned();
4480 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
4481 }
4482 else
4483 {
4484 const DataExtractor& debug_loc_data = get_debug_loc_data();
4485 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4486
4487 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4488 if (loc_list_length > 0)
4489 {
4490 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4491 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4492 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
4493 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004494 }
4495 }
Greg Clayton7f995132011-10-04 22:41:51 +00004496 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004497
Greg Clayton7f995132011-10-04 22:41:51 +00004498 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
4499 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
4500 case DW_AT_declaration:
4501 case DW_AT_description:
4502 case DW_AT_endianity:
4503 case DW_AT_segment:
4504 case DW_AT_start_scope:
4505 case DW_AT_visibility:
4506 default:
4507 case DW_AT_abstract_origin:
4508 case DW_AT_sibling:
4509 case DW_AT_specification:
4510 break;
4511 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004512 }
4513 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004514
Greg Clayton7f995132011-10-04 22:41:51 +00004515 if (location.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004516 {
Greg Clayton7f995132011-10-04 22:41:51 +00004517 assert(var_type != DIE_IS_BEING_PARSED);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004518
Greg Clayton7f995132011-10-04 22:41:51 +00004519 ValueType scope = eValueTypeInvalid;
4520
4521 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4522 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4523
4524 if (tag == DW_TAG_formal_parameter)
4525 scope = eValueTypeVariableArgument;
4526 else if (is_external || parent_tag == DW_TAG_compile_unit)
4527 scope = eValueTypeVariableGlobal;
4528 else
4529 scope = eValueTypeVariableLocal;
4530
4531 SymbolContextScope * symbol_context_scope = NULL;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004532 switch (parent_tag)
Greg Clayton7f995132011-10-04 22:41:51 +00004533 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004534 case DW_TAG_subprogram:
4535 case DW_TAG_inlined_subroutine:
4536 case DW_TAG_lexical_block:
4537 if (sc.function)
4538 {
4539 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4540 if (symbol_context_scope == NULL)
4541 symbol_context_scope = sc.function;
4542 }
4543 break;
4544
4545 default:
Greg Clayton7f995132011-10-04 22:41:51 +00004546 symbol_context_scope = sc.comp_unit;
Greg Clayton5cf58b92011-10-05 22:22:08 +00004547 break;
Greg Clayton7f995132011-10-04 22:41:51 +00004548 }
4549
Greg Clayton5cf58b92011-10-05 22:22:08 +00004550 if (symbol_context_scope)
4551 {
4552 var_sp.reset (new Variable(die->GetOffset(),
4553 name,
4554 mangled,
4555 var_type,
4556 scope,
4557 symbol_context_scope,
4558 &decl,
4559 location,
4560 is_external,
4561 is_artificial));
4562
4563 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4564 }
4565 else
4566 {
4567 // Not ready to parse this variable yet. It might be a global
4568 // or static variable that is in a function scope and the function
4569 // in the symbol context wasn't filled in yet
4570 return var_sp;
4571 }
Greg Clayton7f995132011-10-04 22:41:51 +00004572 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004573 }
Greg Clayton7f995132011-10-04 22:41:51 +00004574 // Cache var_sp even if NULL (the variable was just a specification or
4575 // was missing vital information to be able to be displayed in the debugger
4576 // (missing location due to optimization, etc)) so we don't re-parse
4577 // this DIE over and over later...
4578 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004579 }
4580 return var_sp;
4581}
4582
Greg Claytonc662ec82011-06-17 22:10:16 +00004583
4584const DWARFDebugInfoEntry *
4585SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4586 dw_offset_t spec_block_die_offset,
4587 DWARFCompileUnit **result_die_cu_handle)
4588{
4589 // Give the concrete function die specified by "func_die_offset", find the
4590 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4591 // to "spec_block_die_offset"
4592 DWARFDebugInfo* info = DebugInfo();
4593
4594 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4595 if (die)
4596 {
4597 assert (*result_die_cu_handle);
4598 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4599 }
4600 return NULL;
4601}
4602
4603
4604const DWARFDebugInfoEntry *
4605SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4606 const DWARFDebugInfoEntry *die,
4607 dw_offset_t spec_block_die_offset,
4608 DWARFCompileUnit **result_die_cu_handle)
4609{
4610 if (die)
4611 {
4612 switch (die->Tag())
4613 {
4614 case DW_TAG_subprogram:
4615 case DW_TAG_inlined_subroutine:
4616 case DW_TAG_lexical_block:
4617 {
4618 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4619 {
4620 *result_die_cu_handle = dwarf_cu;
4621 return die;
4622 }
4623
4624 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4625 {
4626 *result_die_cu_handle = dwarf_cu;
4627 return die;
4628 }
4629 }
4630 break;
4631 }
4632
4633 // Give the concrete function die specified by "func_die_offset", find the
4634 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4635 // to "spec_block_die_offset"
4636 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4637 {
4638 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4639 child_die,
4640 spec_block_die_offset,
4641 result_die_cu_handle);
4642 if (result_die)
4643 return result_die;
4644 }
4645 }
4646
4647 *result_die_cu_handle = NULL;
4648 return NULL;
4649}
4650
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004651size_t
4652SymbolFileDWARF::ParseVariables
4653(
4654 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004655 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004656 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004657 const DWARFDebugInfoEntry *orig_die,
4658 bool parse_siblings,
4659 bool parse_children,
4660 VariableList* cc_variable_list
4661)
4662{
4663 if (orig_die == NULL)
4664 return 0;
4665
Greg Claytonc662ec82011-06-17 22:10:16 +00004666 VariableListSP variable_list_sp;
4667
4668 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004669 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004670 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004671 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004672 dw_tag_t tag = die->Tag();
4673
4674 // Check to see if we have already parsed this variable or constant?
4675 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004676 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004677 if (cc_variable_list)
4678 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004679 }
4680 else
4681 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004682 // We haven't already parsed it, lets do that now.
4683 if ((tag == DW_TAG_variable) ||
4684 (tag == DW_TAG_constant) ||
4685 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004686 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004687 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004688 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004689 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4690 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4691 switch (parent_tag)
4692 {
4693 case DW_TAG_compile_unit:
4694 if (sc.comp_unit != NULL)
4695 {
4696 variable_list_sp = sc.comp_unit->GetVariableList(false);
4697 if (variable_list_sp.get() == NULL)
4698 {
4699 variable_list_sp.reset(new VariableList());
4700 sc.comp_unit->SetVariableList(variable_list_sp);
4701 }
4702 }
4703 else
4704 {
Jim Inghamc1663042011-09-29 22:12:35 +00004705 ReportError ("parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
Greg Claytonc662ec82011-06-17 22:10:16 +00004706 sc_parent_die->GetOffset(),
4707 DW_TAG_value_to_name (parent_tag),
4708 orig_die->GetOffset(),
4709 DW_TAG_value_to_name (orig_die->Tag()));
4710 }
4711 break;
4712
4713 case DW_TAG_subprogram:
4714 case DW_TAG_inlined_subroutine:
4715 case DW_TAG_lexical_block:
4716 if (sc.function != NULL)
4717 {
4718 // Check to see if we already have parsed the variables for the given scope
4719
4720 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4721 if (block == NULL)
4722 {
4723 // This must be a specification or abstract origin with
4724 // a concrete block couterpart in the current function. We need
4725 // to find the concrete block so we can correctly add the
4726 // variable to it
4727 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4728 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4729 sc_parent_die->GetOffset(),
4730 &concrete_block_die_cu);
4731 if (concrete_block_die)
4732 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4733 }
4734
4735 if (block != NULL)
4736 {
4737 const bool can_create = false;
4738 variable_list_sp = block->GetBlockVariableList (can_create);
4739 if (variable_list_sp.get() == NULL)
4740 {
4741 variable_list_sp.reset(new VariableList());
4742 block->SetVariableList(variable_list_sp);
4743 }
4744 }
4745 }
4746 break;
4747
4748 default:
Jim Inghamc1663042011-09-29 22:12:35 +00004749 ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
Greg Claytonc662ec82011-06-17 22:10:16 +00004750 orig_die->GetOffset(),
4751 DW_TAG_value_to_name (orig_die->Tag()));
4752 break;
4753 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004754 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004755
4756 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004757 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00004758 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4759 if (var_sp)
4760 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004761 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004762 if (cc_variable_list)
4763 cc_variable_list->AddVariableIfUnique (var_sp);
4764 ++vars_added;
4765 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004766 }
4767 }
4768 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004769
4770 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4771
4772 if (!skip_children && parse_children && die->HasChildren())
4773 {
4774 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4775 }
4776
4777 if (parse_siblings)
4778 die = die->GetSibling();
4779 else
4780 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004781 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004782 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004783}
4784
4785//------------------------------------------------------------------
4786// PluginInterface protocol
4787//------------------------------------------------------------------
4788const char *
4789SymbolFileDWARF::GetPluginName()
4790{
4791 return "SymbolFileDWARF";
4792}
4793
4794const char *
4795SymbolFileDWARF::GetShortPluginName()
4796{
4797 return GetPluginNameStatic();
4798}
4799
4800uint32_t
4801SymbolFileDWARF::GetPluginVersion()
4802{
4803 return 1;
4804}
4805
4806void
Greg Clayton6beaaa62011-01-17 03:46:26 +00004807SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4808{
4809 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4810 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4811 if (clang_type)
4812 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4813}
4814
4815void
4816SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4817{
4818 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4819 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4820 if (clang_type)
4821 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4822}
4823
Greg Claytona2721472011-06-25 00:44:06 +00004824void
Sean Callanancc427fa2011-07-30 02:42:06 +00004825SymbolFileDWARF::DumpIndexes ()
4826{
4827 StreamFile s(stdout, false);
4828
4829 s.Printf ("DWARF index for (%s) '%s/%s':",
4830 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4831 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4832 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4833 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4834 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4835 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4836 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4837 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4838 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4839 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4840 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4841}
4842
4843void
4844SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4845 const char *name,
4846 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00004847{
Sean Callanancc427fa2011-07-30 02:42:06 +00004848 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00004849
4850 if (iter == m_decl_ctx_to_die.end())
4851 return;
4852
Sean Callanancc427fa2011-07-30 02:42:06 +00004853 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytona2721472011-06-25 00:44:06 +00004854
4855 if (!results)
4856 return;
4857
4858 DWARFDebugInfo* info = DebugInfo();
4859
Greg Claytond4a2b372011-09-12 23:21:58 +00004860 DIEArray die_offsets;
Greg Claytona2721472011-06-25 00:44:06 +00004861
Greg Claytond4a2b372011-09-12 23:21:58 +00004862 DWARFCompileUnit* dwarf_cu = NULL;
4863 const DWARFDebugInfoEntry* die = NULL;
4864 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets);
Greg Claytona2721472011-06-25 00:44:06 +00004865
4866 if (num_matches)
4867 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004868 for (size_t i = 0; i < num_matches; ++i)
Greg Claytona2721472011-06-25 00:44:06 +00004869 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004870 const dw_offset_t die_offset = die_offsets[i];
4871 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
4872
Sean Callanancc427fa2011-07-30 02:42:06 +00004873 if (die->GetParent() != context_die)
Greg Claytona2721472011-06-25 00:44:06 +00004874 continue;
4875
Greg Claytond4a2b372011-09-12 23:21:58 +00004876 Type *matching_type = ResolveType (dwarf_cu, die);
Greg Claytona2721472011-06-25 00:44:06 +00004877
4878 lldb::clang_type_t type = matching_type->GetClangFullType();
4879 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4880
Sean Callanancc427fa2011-07-30 02:42:06 +00004881 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004882 {
4883 clang::TagDecl *tag_decl = tag_type->getDecl();
4884 results->push_back(tag_decl);
4885 }
Sean Callanancc427fa2011-07-30 02:42:06 +00004886 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004887 {
4888 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4889 results->push_back(typedef_decl);
4890 }
4891 }
4892 }
4893}
4894
4895void
4896SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4897 const clang::DeclContext *DC,
4898 clang::DeclarationName Name,
4899 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4900{
4901 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4902
Sean Callanancc427fa2011-07-30 02:42:06 +00004903 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytona2721472011-06-25 00:44:06 +00004904}