blob: bae44973a0940eea6215498d27b653eaabea2262 [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
Greg Clayton20568dd2011-10-13 23:13:20 +000037#include "lldb/Host/Host.h"
38
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000040#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Symbol/CompileUnit.h"
42#include "lldb/Symbol/LineTable.h"
43#include "lldb/Symbol/ObjectFile.h"
44#include "lldb/Symbol/SymbolVendor.h"
45#include "lldb/Symbol/VariableList.h"
46
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000047#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham4cda6e02011-10-07 22:23:45 +000048#include "lldb/Target/CPPLanguageRuntime.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000049
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "DWARFCompileUnit.h"
51#include "DWARFDebugAbbrev.h"
52#include "DWARFDebugAranges.h"
53#include "DWARFDebugInfo.h"
54#include "DWARFDebugInfoEntry.h"
55#include "DWARFDebugLine.h"
56#include "DWARFDebugPubnames.h"
57#include "DWARFDebugRanges.h"
58#include "DWARFDIECollection.h"
59#include "DWARFFormValue.h"
60#include "DWARFLocationList.h"
61#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000062#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
64#include <map>
65
Greg Clayton62742b12010-11-11 01:09:45 +000066//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000067
68#ifdef ENABLE_DEBUG_PRINTF
69#include <stdio.h>
70#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
71#else
72#define DEBUG_PRINTF(fmt, ...)
73#endif
74
Greg Clayton594e5ed2010-09-27 21:07:38 +000075#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076
77using namespace lldb;
78using namespace lldb_private;
79
80
Sean Callananc7fbf732010-08-06 00:32:49 +000081static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000082DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083{
84 switch (dwarf_accessibility)
85 {
Sean Callananc7fbf732010-08-06 00:32:49 +000086 case DW_ACCESS_public: return eAccessPublic;
87 case DW_ACCESS_private: return eAccessPrivate;
88 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000089 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090 }
Sean Callananc7fbf732010-08-06 00:32:49 +000091 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092}
93
94void
95SymbolFileDWARF::Initialize()
96{
97 LogChannelDWARF::Initialize();
98 PluginManager::RegisterPlugin (GetPluginNameStatic(),
99 GetPluginDescriptionStatic(),
100 CreateInstance);
101}
102
103void
104SymbolFileDWARF::Terminate()
105{
106 PluginManager::UnregisterPlugin (CreateInstance);
107 LogChannelDWARF::Initialize();
108}
109
110
111const char *
112SymbolFileDWARF::GetPluginNameStatic()
113{
Greg Claytond4a2b372011-09-12 23:21:58 +0000114 return "dwarf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115}
116
117const char *
118SymbolFileDWARF::GetPluginDescriptionStatic()
119{
120 return "DWARF and DWARF3 debug symbol file reader.";
121}
122
123
124SymbolFile*
125SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
126{
127 return new SymbolFileDWARF(obj_file);
128}
129
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000130TypeList *
131SymbolFileDWARF::GetTypeList ()
132{
133 if (m_debug_map_symfile)
134 return m_debug_map_symfile->GetTypeList();
135 return m_obj_file->GetModule()->GetTypeList();
136
137}
138
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139//----------------------------------------------------------------------
140// Gets the first parent that is a lexical block, function or inlined
141// subroutine, or compile unit.
142//----------------------------------------------------------------------
143static const DWARFDebugInfoEntry *
144GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
145{
146 const DWARFDebugInfoEntry *die;
147 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
148 {
149 dw_tag_t tag = die->Tag();
150
151 switch (tag)
152 {
153 case DW_TAG_compile_unit:
154 case DW_TAG_subprogram:
155 case DW_TAG_inlined_subroutine:
156 case DW_TAG_lexical_block:
157 return die;
158 }
159 }
160 return NULL;
161}
162
163
Greg Clayton450e3f32010-10-12 02:24:53 +0000164SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
165 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000166 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
Greg Clayton450e3f32010-10-12 02:24:53 +0000167 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000168 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000170 m_data_debug_abbrev (),
171 m_data_debug_aranges (),
172 m_data_debug_frame (),
173 m_data_debug_info (),
174 m_data_debug_line (),
175 m_data_debug_loc (),
176 m_data_debug_ranges (),
177 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000178 m_data_apple_names (),
179 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000180 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 m_info(),
183 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000184 m_apple_names_ap (),
185 m_apple_types_ap (),
186 m_apple_namespaces_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000187 m_function_basename_index(),
188 m_function_fullname_index(),
189 m_function_method_index(),
190 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000191 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000192 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000193 m_type_index(),
194 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000195 m_indexed (false),
196 m_is_external_ast_source (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000197 m_using_apple_tables (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000198 m_ranges(),
199 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200{
201}
202
203SymbolFileDWARF::~SymbolFileDWARF()
204{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000205 if (m_is_external_ast_source)
206 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
207}
208
209static const ConstString &
210GetDWARFMachOSegmentName ()
211{
212 static ConstString g_dwarf_section_name ("__DWARF");
213 return g_dwarf_section_name;
214}
215
Greg Claytone576ab22011-02-15 00:19:15 +0000216UniqueDWARFASTTypeMap &
217SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
218{
219 if (m_debug_map_symfile)
220 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
221 return m_unique_ast_type_map;
222}
223
Greg Clayton6beaaa62011-01-17 03:46:26 +0000224ClangASTContext &
225SymbolFileDWARF::GetClangASTContext ()
226{
227 if (m_debug_map_symfile)
228 return m_debug_map_symfile->GetClangASTContext ();
229
230 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
231 if (!m_is_external_ast_source)
232 {
233 m_is_external_ast_source = true;
234 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
235 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
236 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000237 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000238 this));
239
240 ast.SetExternalSource (ast_source_ap);
241 }
242 return ast;
243}
244
245void
246SymbolFileDWARF::InitializeObject()
247{
248 // Install our external AST source callbacks so we can complete Clang types.
249 Module *module = m_obj_file->GetModule();
250 if (module)
251 {
252 const SectionList *section_list = m_obj_file->GetSectionList();
253
254 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
255
256 // Memory map the DWARF mach-o segment so we have everything mmap'ed
257 // to keep our heap memory usage down.
258 if (section)
259 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
260 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000261 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000262 if (m_data_apple_names.GetByteSize() > 0)
263 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000264 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
265 if (m_apple_names_ap->IsValid())
266 m_using_apple_tables = true;
267 else
Greg Clayton7f995132011-10-04 22:41:51 +0000268 m_apple_names_ap.reset();
269 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000270 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000271 if (m_data_apple_types.GetByteSize() > 0)
272 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000273 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
274 if (m_apple_types_ap->IsValid())
275 m_using_apple_tables = true;
276 else
Greg Clayton7f995132011-10-04 22:41:51 +0000277 m_apple_types_ap.reset();
278 }
279
280 get_apple_namespaces_data();
281 if (m_data_apple_namespaces.GetByteSize() > 0)
282 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000283 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
284 if (m_apple_namespaces_ap->IsValid())
285 m_using_apple_tables = true;
286 else
Greg Clayton7f995132011-10-04 22:41:51 +0000287 m_apple_namespaces_ap.reset();
288 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000289
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290}
291
292bool
293SymbolFileDWARF::SupportedVersion(uint16_t version)
294{
295 return version == 2 || version == 3;
296}
297
298uint32_t
299SymbolFileDWARF::GetAbilities ()
300{
301 uint32_t abilities = 0;
302 if (m_obj_file != NULL)
303 {
304 const Section* section = NULL;
305 const SectionList *section_list = m_obj_file->GetSectionList();
306 if (section_list == NULL)
307 return 0;
308
309 uint64_t debug_abbrev_file_size = 0;
310 uint64_t debug_aranges_file_size = 0;
311 uint64_t debug_frame_file_size = 0;
312 uint64_t debug_info_file_size = 0;
313 uint64_t debug_line_file_size = 0;
314 uint64_t debug_loc_file_size = 0;
315 uint64_t debug_macinfo_file_size = 0;
316 uint64_t debug_pubnames_file_size = 0;
317 uint64_t debug_pubtypes_file_size = 0;
318 uint64_t debug_ranges_file_size = 0;
319 uint64_t debug_str_file_size = 0;
320
Greg Clayton6beaaa62011-01-17 03:46:26 +0000321 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322
323 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325
Greg Clayton4ceb9982010-07-21 22:54:26 +0000326 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 if (section != NULL)
328 {
329 debug_info_file_size = section->GetByteSize();
330
Greg Clayton4ceb9982010-07-21 22:54:26 +0000331 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332 if (section)
333 debug_abbrev_file_size = section->GetByteSize();
334 else
335 m_flags.Set (flagsGotDebugAbbrevData);
336
Greg Clayton4ceb9982010-07-21 22:54:26 +0000337 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338 if (section)
339 debug_aranges_file_size = section->GetByteSize();
340 else
341 m_flags.Set (flagsGotDebugArangesData);
342
Greg Clayton4ceb9982010-07-21 22:54:26 +0000343 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 if (section)
345 debug_frame_file_size = section->GetByteSize();
346 else
347 m_flags.Set (flagsGotDebugFrameData);
348
Greg Clayton4ceb9982010-07-21 22:54:26 +0000349 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 if (section)
351 debug_line_file_size = section->GetByteSize();
352 else
353 m_flags.Set (flagsGotDebugLineData);
354
Greg Clayton4ceb9982010-07-21 22:54:26 +0000355 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356 if (section)
357 debug_loc_file_size = section->GetByteSize();
358 else
359 m_flags.Set (flagsGotDebugLocData);
360
Greg Clayton4ceb9982010-07-21 22:54:26 +0000361 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 if (section)
363 debug_macinfo_file_size = section->GetByteSize();
364 else
365 m_flags.Set (flagsGotDebugMacInfoData);
366
Greg Clayton4ceb9982010-07-21 22:54:26 +0000367 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 if (section)
369 debug_pubnames_file_size = section->GetByteSize();
370 else
371 m_flags.Set (flagsGotDebugPubNamesData);
372
Greg Clayton4ceb9982010-07-21 22:54:26 +0000373 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 if (section)
375 debug_pubtypes_file_size = section->GetByteSize();
376 else
377 m_flags.Set (flagsGotDebugPubTypesData);
378
Greg Clayton4ceb9982010-07-21 22:54:26 +0000379 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 if (section)
381 debug_ranges_file_size = section->GetByteSize();
382 else
383 m_flags.Set (flagsGotDebugRangesData);
384
Greg Clayton4ceb9982010-07-21 22:54:26 +0000385 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 if (section)
387 debug_str_file_size = section->GetByteSize();
388 else
389 m_flags.Set (flagsGotDebugStrData);
390 }
391
392 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
393 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
394
395 if (debug_line_file_size > 0)
396 abilities |= LineTables;
397
398 if (debug_aranges_file_size > 0)
399 abilities |= AddressAcceleratorTable;
400
401 if (debug_pubnames_file_size > 0)
402 abilities |= FunctionAcceleratorTable;
403
404 if (debug_pubtypes_file_size > 0)
405 abilities |= TypeAcceleratorTable;
406
407 if (debug_macinfo_file_size > 0)
408 abilities |= MacroInformation;
409
410 if (debug_frame_file_size > 0)
411 abilities |= CallFrameInformation;
412 }
413 return abilities;
414}
415
416const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000417SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418{
419 if (m_flags.IsClear (got_flag))
420 {
421 m_flags.Set (got_flag);
422 const SectionList *section_list = m_obj_file->GetSectionList();
423 if (section_list)
424 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000425 Section *section = section_list->FindSectionByType(sect_type, true).get();
426 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 {
428 // See if we memory mapped the DWARF segment?
429 if (m_dwarf_data.GetByteSize())
430 {
431 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
432 }
433 else
434 {
435 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
436 data.Clear();
437 }
438 }
439 }
440 }
441 return data;
442}
443
444const DataExtractor&
445SymbolFileDWARF::get_debug_abbrev_data()
446{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000447 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448}
449
450const DataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000451SymbolFileDWARF::get_debug_aranges_data()
452{
453 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
454}
455
456const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457SymbolFileDWARF::get_debug_frame_data()
458{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000459 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460}
461
462const DataExtractor&
463SymbolFileDWARF::get_debug_info_data()
464{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000465 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466}
467
468const DataExtractor&
469SymbolFileDWARF::get_debug_line_data()
470{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000471 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472}
473
474const DataExtractor&
475SymbolFileDWARF::get_debug_loc_data()
476{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000477 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478}
479
480const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481SymbolFileDWARF::get_debug_ranges_data()
482{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000483 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484}
485
486const DataExtractor&
487SymbolFileDWARF::get_debug_str_data()
488{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000489 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490}
491
Greg Claytonf9eec202011-09-01 23:16:13 +0000492const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000493SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000494{
Greg Clayton17674402011-09-28 17:06:40 +0000495 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000496}
497
498const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000499SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000500{
Greg Clayton17674402011-09-28 17:06:40 +0000501 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000502}
503
Greg Clayton7f995132011-10-04 22:41:51 +0000504const DataExtractor&
505SymbolFileDWARF::get_apple_namespaces_data()
506{
Greg Clayton85ae2e12011-10-18 23:36:41 +0000507 return GetCachedSectionData (flagsGotDebugNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
Greg Clayton7f995132011-10-04 22:41:51 +0000508}
509
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510
511DWARFDebugAbbrev*
512SymbolFileDWARF::DebugAbbrev()
513{
514 if (m_abbr.get() == NULL)
515 {
516 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
517 if (debug_abbrev_data.GetByteSize() > 0)
518 {
519 m_abbr.reset(new DWARFDebugAbbrev());
520 if (m_abbr.get())
521 m_abbr->Parse(debug_abbrev_data);
522 }
523 }
524 return m_abbr.get();
525}
526
527const DWARFDebugAbbrev*
528SymbolFileDWARF::DebugAbbrev() const
529{
530 return m_abbr.get();
531}
532
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533
534DWARFDebugInfo*
535SymbolFileDWARF::DebugInfo()
536{
537 if (m_info.get() == NULL)
538 {
539 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
540 if (get_debug_info_data().GetByteSize() > 0)
541 {
542 m_info.reset(new DWARFDebugInfo());
543 if (m_info.get())
544 {
545 m_info->SetDwarfData(this);
546 }
547 }
548 }
549 return m_info.get();
550}
551
552const DWARFDebugInfo*
553SymbolFileDWARF::DebugInfo() const
554{
555 return m_info.get();
556}
557
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558DWARFCompileUnit*
559SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
560{
561 DWARFDebugInfo* info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +0000562 if (info && UserIDMatches(cu_uid))
563 return info->GetCompileUnit((dw_offset_t)cu_uid).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 return NULL;
565}
566
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000567
568DWARFDebugRanges*
569SymbolFileDWARF::DebugRanges()
570{
571 if (m_ranges.get() == NULL)
572 {
573 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
574 if (get_debug_ranges_data().GetByteSize() > 0)
575 {
576 m_ranges.reset(new DWARFDebugRanges());
577 if (m_ranges.get())
578 m_ranges->Extract(this);
579 }
580 }
581 return m_ranges.get();
582}
583
584const DWARFDebugRanges*
585SymbolFileDWARF::DebugRanges() const
586{
587 return m_ranges.get();
588}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589
590bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000591SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592{
Greg Clayton96d7d742010-11-10 23:42:09 +0000593 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000595 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 if (cu_die)
597 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000598 const char * cu_die_name = cu_die->GetName(this, curr_cu);
599 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham0f35ac22011-08-24 23:34:20 +0000600 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601 if (cu_die_name)
602 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000603 FileSpec cu_file_spec;
604
Greg Clayton7bd65b92011-02-09 23:39:34 +0000605 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000607 // If we have a full path to the compile unit, we don't need to resolve
608 // the file. This can be expensive e.g. when the source files are NFS mounted.
609 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 }
611 else
612 {
613 std::string fullpath(cu_comp_dir);
614 if (*fullpath.rbegin() != '/')
615 fullpath += '/';
616 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000617 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 }
619
Greg Clayton81c22f62011-10-19 18:09:39 +0000620 compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
621 curr_cu,
622 cu_file_spec,
623 MakeUserID(curr_cu->GetOffset()),
624 cu_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 if (compile_unit_sp.get())
626 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000627 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628 return true;
629 }
630 }
631 }
632 }
633 return false;
634}
635
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636uint32_t
637SymbolFileDWARF::GetNumCompileUnits()
638{
639 DWARFDebugInfo* info = DebugInfo();
640 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 return 0;
643}
644
645CompUnitSP
646SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
647{
648 CompUnitSP comp_unit;
649 DWARFDebugInfo* info = DebugInfo();
650 if (info)
651 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000652 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
653 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000654 {
655 // Our symbol vendor shouldn't be asking us to add a compile unit that
656 // has already been added to it, which this DWARF plug-in knows as it
657 // stores the lldb compile unit (CompileUnit) pointer in each
658 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000659 assert(curr_cu->GetUserData() == NULL);
660 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 }
662 }
663 return comp_unit;
664}
665
666static void
Greg Claytonea3e7d52011-10-08 00:49:15 +0000667AddRangesToBlock (Block& block,
668 DWARFDebugRanges::RangeList& ranges,
669 addr_t block_base_addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000671 const size_t num_ranges = ranges.GetSize();
672 for (size_t i = 0; i<num_ranges; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000674 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
675 const addr_t range_base = range.GetRangeBase();
676 assert (range_base >= block_base_addr);
677 block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678 }
Greg Claytonea3e7d52011-10-08 00:49:15 +0000679 block.FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000680}
681
682
683Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000684SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000685{
686 DWARFDebugRanges::RangeList func_ranges;
687 const char *name = NULL;
688 const char *mangled = NULL;
689 int decl_file = 0;
690 int decl_line = 0;
691 int decl_column = 0;
692 int call_file = 0;
693 int call_line = 0;
694 int call_column = 0;
695 DWARFExpression frame_base;
696
Greg Claytonc93237c2010-10-01 20:48:32 +0000697 assert (die->Tag() == DW_TAG_subprogram);
698
699 if (die->Tag() != DW_TAG_subprogram)
700 return NULL;
701
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
703 {
704 // Union of all ranges in the function DIE (if the function is discontiguous)
705 AddressRange func_range;
Greg Claytonea3e7d52011-10-08 00:49:15 +0000706 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
707 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
709 {
710 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
711 if (func_range.GetBaseAddress().IsValid())
712 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
713 }
714
715 if (func_range.GetBaseAddress().IsValid())
716 {
717 Mangled func_name;
718 if (mangled)
719 func_name.SetValue(mangled, true);
720 else if (name)
721 func_name.SetValue(name, false);
722
723 FunctionSP func_sp;
724 std::auto_ptr<Declaration> decl_ap;
725 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000726 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
727 decl_line,
728 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000729
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000730 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +0000731 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000732
733 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
734
735 func_range.GetBaseAddress().ResolveLinkedAddress();
736
Greg Clayton81c22f62011-10-19 18:09:39 +0000737 const user_id_t func_user_id = MakeUserID(die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000738 func_sp.reset(new Function (sc.comp_unit,
Greg Clayton81c22f62011-10-19 18:09:39 +0000739 func_user_id, // UserID is the DIE offset
740 func_user_id,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741 func_name,
742 func_type,
743 func_range)); // first address range
744
745 if (func_sp.get() != NULL)
746 {
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000747 if (frame_base.IsValid())
748 func_sp->GetFrameBaseExpression() = frame_base;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749 sc.comp_unit->AddFunction(func_sp);
750 return func_sp.get();
751 }
752 }
753 }
754 return NULL;
755}
756
757size_t
758SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
759{
760 assert (sc.comp_unit);
761 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000762 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000763 if (dwarf_cu)
764 {
765 DWARFDIECollection function_dies;
766 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
767 size_t func_idx;
768 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
769 {
770 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
Greg Clayton81c22f62011-10-19 18:09:39 +0000771 if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000772 {
773 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
774 ++functions_added;
775 }
776 }
777 //FixupTypes();
778 }
779 return functions_added;
780}
781
782bool
783SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
784{
785 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000786 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
787 assert (curr_cu);
788 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789
790 if (cu_die)
791 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000792 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
793 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 +0000794
795 // All file indexes in DWARF are one based and a file of index zero is
796 // supposed to be the compile unit itself.
797 support_files.Append (*sc.comp_unit);
798
799 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
800 }
801 return false;
802}
803
804struct ParseDWARFLineTableCallbackInfo
805{
806 LineTable* line_table;
807 const SectionList *section_list;
808 lldb::addr_t prev_sect_file_base_addr;
809 lldb::addr_t curr_sect_file_base_addr;
810 bool is_oso_for_debug_map;
811 bool prev_in_final_executable;
812 DWARFDebugLine::Row prev_row;
813 SectionSP prev_section_sp;
814 SectionSP curr_section_sp;
815};
816
817//----------------------------------------------------------------------
818// ParseStatementTableCallback
819//----------------------------------------------------------------------
820static void
821ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
822{
823 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
824 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
825 {
826 // Just started parsing the line table
827 }
828 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
829 {
830 // Done parsing line table, nothing to do for the cleanup
831 }
832 else
833 {
834 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
835 // We have a new row, lets append it
836
837 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
838 {
839 info->prev_section_sp = info->curr_section_sp;
840 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
841 // If this is an end sequence entry, then we subtract one from the
842 // address to make sure we get an address that is not the end of
843 // a section.
844 if (state.end_sequence && state.address != 0)
845 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
846 else
847 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
848
849 if (info->curr_section_sp.get())
850 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
851 else
852 info->curr_sect_file_base_addr = 0;
853 }
854 if (info->curr_section_sp.get())
855 {
856 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
857 // Check for the fancy section magic to determine if we
858
859 if (info->is_oso_for_debug_map)
860 {
861 // When this is a debug map object file that contains DWARF
862 // (referenced from an N_OSO debug map nlist entry) we will have
863 // a file address in the file range for our section from the
864 // original .o file, and a load address in the executable that
865 // contains the debug map.
866 //
867 // If the sections for the file range and load range are
868 // different, we have a remapped section for the function and
869 // this address is resolved. If they are the same, then the
870 // function for this address didn't make it into the final
871 // executable.
872 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
873
874 // If we are doing DWARF with debug map, then we need to carefully
875 // add each line table entry as there may be gaps as functions
876 // get moved around or removed.
877 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
878 {
879 if (info->prev_in_final_executable)
880 {
881 bool terminate_previous_entry = false;
882 if (!curr_in_final_executable)
883 {
884 // Check for the case where the previous line entry
885 // in a function made it into the final executable,
886 // yet the current line entry falls in a function
887 // that didn't. The line table used to be contiguous
888 // through this address range but now it isn't. We
889 // need to terminate the previous line entry so
890 // that we can reconstruct the line range correctly
891 // for it and to keep the line table correct.
892 terminate_previous_entry = true;
893 }
894 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
895 {
896 // Check for cases where the line entries used to be
897 // contiguous address ranges, but now they aren't.
898 // This can happen when order files specify the
899 // ordering of the functions.
900 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
901 Section *curr_sect = info->curr_section_sp.get();
902 Section *prev_sect = info->prev_section_sp.get();
903 assert (curr_sect->GetLinkedSection());
904 assert (prev_sect->GetLinkedSection());
905 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
906 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
907 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
908 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
909 if (object_file_addr_delta != linked_file_addr_delta)
910 terminate_previous_entry = true;
911 }
912
913 if (terminate_previous_entry)
914 {
915 line_table->InsertLineEntry (info->prev_section_sp,
916 state.address - info->prev_sect_file_base_addr,
917 info->prev_row.line,
918 info->prev_row.column,
919 info->prev_row.file,
920 false, // is_stmt
921 false, // basic_block
922 false, // state.prologue_end
923 false, // state.epilogue_begin
924 true); // end_sequence);
925 }
926 }
927 }
928
929 if (curr_in_final_executable)
930 {
931 line_table->InsertLineEntry (info->curr_section_sp,
932 curr_line_section_offset,
933 state.line,
934 state.column,
935 state.file,
936 state.is_stmt,
937 state.basic_block,
938 state.prologue_end,
939 state.epilogue_begin,
940 state.end_sequence);
941 info->prev_section_sp = info->curr_section_sp;
942 }
943 else
944 {
945 // If the current address didn't make it into the final
946 // executable, the current section will be the __text
947 // segment in the .o file, so we need to clear this so
948 // we can catch the next function that did make it into
949 // the final executable.
950 info->prev_section_sp.reset();
951 info->curr_section_sp.reset();
952 }
953
954 info->prev_in_final_executable = curr_in_final_executable;
955 }
956 else
957 {
958 // We are not in an object file that contains DWARF for an
959 // N_OSO, this is just a normal DWARF file. The DWARF spec
960 // guarantees that the addresses will be in increasing order
961 // so, since we store line tables in file address order, we
962 // can always just append the line entry without needing to
963 // search for the correct insertion point (we don't need to
964 // use LineEntry::InsertLineEntry()).
965 line_table->AppendLineEntry (info->curr_section_sp,
966 curr_line_section_offset,
967 state.line,
968 state.column,
969 state.file,
970 state.is_stmt,
971 state.basic_block,
972 state.prologue_end,
973 state.epilogue_begin,
974 state.end_sequence);
975 }
976 }
977
978 info->prev_row = state;
979 }
980}
981
982bool
983SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
984{
985 assert (sc.comp_unit);
986 if (sc.comp_unit->GetLineTable() != NULL)
987 return true;
988
989 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
990 if (dwarf_cu)
991 {
992 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
993 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
994 if (cu_line_offset != DW_INVALID_OFFSET)
995 {
996 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
997 if (line_table_ap.get())
998 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000999 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 +00001000 uint32_t offset = cu_line_offset;
1001 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1002 sc.comp_unit->SetLineTable(line_table_ap.release());
1003 return true;
1004 }
1005 }
1006 }
1007 return false;
1008}
1009
1010size_t
1011SymbolFileDWARF::ParseFunctionBlocks
1012(
1013 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001014 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001015 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016 const DWARFDebugInfoEntry *die,
1017 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001018 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001019)
1020{
1021 size_t blocks_added = 0;
1022 while (die != NULL)
1023 {
1024 dw_tag_t tag = die->Tag();
1025
1026 switch (tag)
1027 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001029 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030 case DW_TAG_lexical_block:
1031 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001032 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001033 if (tag == DW_TAG_subprogram)
1034 {
1035 // Skip any DW_TAG_subprogram DIEs that are inside
1036 // of a normal or inlined functions. These will be
1037 // parsed on their own as separate entities.
1038
1039 if (depth > 0)
1040 break;
1041
1042 block = parent_block;
1043 }
1044 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001045 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001046 BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001047 parent_block->AddChild(block_sp);
1048 block = block_sp.get();
1049 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001050 DWARFDebugRanges::RangeList ranges;
1051 const char *name = NULL;
1052 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001053
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054 int decl_file = 0;
1055 int decl_line = 0;
1056 int decl_column = 0;
1057 int call_file = 0;
1058 int call_line = 0;
1059 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001060 if (die->GetDIENamesAndRanges (this,
1061 dwarf_cu,
1062 name,
1063 mangled_name,
1064 ranges,
1065 decl_file, decl_line, decl_column,
1066 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 {
1068 if (tag == DW_TAG_subprogram)
1069 {
1070 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001071 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001073 else if (tag == DW_TAG_inlined_subroutine)
1074 {
1075 // We get called here for inlined subroutines in two ways.
1076 // The first time is when we are making the Function object
1077 // for this inlined concrete instance. Since we're creating a top level block at
1078 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1079 // adjust the containing address.
1080 // The second time is when we are parsing the blocks inside the function that contains
1081 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1082 // function the offset will be for that function.
1083 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1084 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001085 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001086 }
1087 }
1088
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001089 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090
1091 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1092 {
1093 std::auto_ptr<Declaration> decl_ap;
1094 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001095 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1096 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097
1098 std::auto_ptr<Declaration> call_ap;
1099 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001100 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1101 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001103 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 }
1105
1106 ++blocks_added;
1107
Greg Claytondd7feaf2011-08-12 17:54:33 +00001108 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001109 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001110 blocks_added += ParseFunctionBlocks (sc,
1111 block,
1112 dwarf_cu,
1113 die->GetFirstChild(),
1114 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001115 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001116 }
1117 }
1118 }
1119 break;
1120 default:
1121 break;
1122 }
1123
Greg Claytondd7feaf2011-08-12 17:54:33 +00001124 // Only parse siblings of the block if we are not at depth zero. A depth
1125 // of zero indicates we are currently parsing the top level
1126 // DW_TAG_subprogram DIE
1127
1128 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001130 else
1131 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 }
1133 return blocks_added;
1134}
1135
Greg Claytonf0705c82011-10-22 03:33:13 +00001136bool
1137SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
1138 const DWARFDebugInfoEntry *parent_die,
1139 ClangASTContext::TemplateParameterInfos &template_param_infos)
1140{
1141
1142 if (parent_die == NULL)
1143 return NULL;
1144
1145 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1146
1147 Args template_parameter_names;
1148 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
1149 die != NULL;
1150 die = die->GetSibling())
1151 {
1152 const dw_tag_t tag = die->Tag();
1153
1154 switch (tag)
1155 {
1156 case DW_TAG_template_type_parameter:
1157 case DW_TAG_template_value_parameter:
1158 {
1159 DWARFDebugInfoEntry::Attributes attributes;
1160 const size_t num_attributes = die->GetAttributes (this,
1161 dwarf_cu,
1162 fixed_form_sizes,
1163 attributes);
1164 const char *name = NULL;
1165 Type *lldb_type = NULL;
1166 clang_type_t clang_type = NULL;
1167 uint64_t uval64 = 0;
1168 bool uval64_valid = false;
1169 if (num_attributes > 0)
1170 {
1171 DWARFFormValue form_value;
1172 for (size_t i=0; i<num_attributes; ++i)
1173 {
1174 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1175
1176 switch (attr)
1177 {
1178 case DW_AT_name:
1179 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1180 name = form_value.AsCString(&get_debug_str_data());
1181 break;
1182
1183 case DW_AT_type:
1184 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1185 {
1186 const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu);
1187 lldb_type = ResolveTypeUID(type_die_offset);
1188 if (lldb_type)
1189 clang_type = lldb_type->GetClangForwardType();
1190 }
1191 break;
1192
1193 case DW_AT_const_value:
1194 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1195 {
1196 uval64_valid = true;
1197 uval64 = form_value.Unsigned();
1198 }
1199 break;
1200 default:
1201 break;
1202 }
1203 }
1204
1205 if (name && lldb_type && clang_type)
1206 {
1207 bool is_signed = false;
1208 template_param_infos.names.push_back(name);
1209 clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
1210 if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid)
1211 {
1212 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
1213 template_param_infos.args.push_back (clang::TemplateArgument (llvm::APSInt(apint), clang_qual_type));
1214 }
1215 else
1216 {
1217 template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
1218 }
1219 }
1220 else
1221 {
1222 return false;
1223 }
1224
1225 }
1226 }
1227 break;
1228
1229 default:
1230 break;
1231 }
1232 }
1233 if (template_param_infos.args.empty())
1234 return false;
1235 return template_param_infos.args.size() == template_param_infos.names.size();
1236}
1237
1238clang::ClassTemplateDecl *
1239SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
1240 const char *parent_name,
1241 int tag_decl_kind,
1242 const ClangASTContext::TemplateParameterInfos &template_param_infos)
1243{
1244 if (template_param_infos.IsValid())
1245 {
1246 std::string template_basename(parent_name);
1247 template_basename.erase (template_basename.find('<'));
1248 ClangASTContext &ast = GetClangASTContext();
1249
1250 return ast.CreateClassTemplateDecl (decl_ctx,
1251 template_basename.c_str(),
1252 tag_decl_kind,
1253 template_param_infos);
1254 }
1255 return NULL;
1256}
1257
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258size_t
1259SymbolFileDWARF::ParseChildMembers
1260(
1261 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001262 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001264 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001265 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1267 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001268 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001269 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001270 bool &is_a_class
1271)
1272{
1273 if (parent_die == NULL)
1274 return 0;
1275
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001276 size_t count = 0;
1277 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001278 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001279 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001280
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1282 {
1283 dw_tag_t tag = die->Tag();
1284
1285 switch (tag)
1286 {
1287 case DW_TAG_member:
1288 {
1289 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001290 const size_t num_attributes = die->GetAttributes (this,
1291 dwarf_cu,
1292 fixed_form_sizes,
1293 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 if (num_attributes > 0)
1295 {
1296 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001297 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001299 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001301 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001302 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001303 size_t byte_size = 0;
1304 size_t bit_offset = 0;
1305 size_t bit_size = 0;
1306 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001307 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001308 {
1309 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1310 DWARFFormValue form_value;
1311 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1312 {
1313 switch (attr)
1314 {
1315 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1316 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1317 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1318 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1319 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1320 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1321 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1322 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1323 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001324// if (form_value.BlockData())
1325// {
1326// Value initialValue(0);
1327// Value memberOffset(0);
1328// const DataExtractor& debug_info_data = get_debug_info_data();
1329// uint32_t block_length = form_value.Unsigned();
1330// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1331// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1332// {
1333// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1334// }
1335// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001336 break;
1337
Greg Clayton8cf05932010-07-22 18:30:50 +00001338 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001339 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001340 case DW_AT_declaration:
1341 case DW_AT_description:
1342 case DW_AT_mutable:
1343 case DW_AT_visibility:
1344 default:
1345 case DW_AT_sibling:
1346 break;
1347 }
1348 }
1349 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001350
Greg Clayton44953932011-10-25 01:25:35 +00001351 // Clang has a DWARF generation bug where sometimes it
1352 // represents fields that are references with bad byte size
1353 // and bit size/offset information such as:
1354 //
1355 // DW_AT_byte_size( 0x00 )
1356 // DW_AT_bit_size( 0x40 )
1357 // DW_AT_bit_offset( 0xffffffffffffffc0 )
1358 //
1359 // So check the bit offset to make sure it is sane, and if
1360 // the values are not sane, remove them. If we don't do this
1361 // then we will end up with a crash if we try to use this
1362 // type in an expression when clang becomes unhappy with its
1363 // recycled debug info.
Sean Callanan5a477cf2010-10-30 01:56:10 +00001364
Greg Clayton44953932011-10-25 01:25:35 +00001365 if (bit_offset > 128)
1366 {
1367 bit_size = 0;
1368 bit_offset = 0;
1369 }
1370
1371 // FIXME: Make Clang ignore Objective-C accessibility for expressions
Sean Callanan5a477cf2010-10-30 01:56:10 +00001372 if (class_language == eLanguageTypeObjC ||
1373 class_language == eLanguageTypeObjC_plus_plus)
1374 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001375
1376 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1377 {
1378 // Not all compilers will mark the vtable pointer
1379 // member as artificial (llvm-gcc). We can't have
1380 // the virtual members in our classes otherwise it
1381 // throws off all child offsets since we end up
1382 // having and extra pointer sized member in our
1383 // class layouts.
1384 is_artificial = true;
1385 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386
Greg Clayton24739922010-10-13 03:15:28 +00001387 if (is_artificial == false)
1388 {
1389 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001390 if (member_type)
1391 {
1392 if (accessibility == eAccessNone)
1393 accessibility = default_accessibility;
1394 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001395
Greg Claytond16e1e52011-07-12 17:06:17 +00001396 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1397 name,
1398 member_type->GetClangLayoutType(),
1399 accessibility,
1400 bit_size);
1401 }
1402 else
1403 {
1404 if (name)
Greg Clayton81c22f62011-10-19 18:09:39 +00001405 ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
1406 MakeUserID(die->GetOffset()),
Greg Claytond16e1e52011-07-12 17:06:17 +00001407 name,
1408 encoding_uid);
1409 else
Greg Clayton81c22f62011-10-19 18:09:39 +00001410 ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
1411 MakeUserID(die->GetOffset()),
Greg Claytond16e1e52011-07-12 17:06:17 +00001412 encoding_uid);
1413 }
Greg Clayton24739922010-10-13 03:15:28 +00001414 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001416 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001417 }
1418 break;
1419
1420 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001421 // Let the type parsing code handle this one for us.
1422 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001423 break;
1424
1425 case DW_TAG_inheritance:
1426 {
1427 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001428 if (default_accessibility == eAccessNone)
1429 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001430 // TODO: implement DW_TAG_inheritance type parsing
1431 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001432 const size_t num_attributes = die->GetAttributes (this,
1433 dwarf_cu,
1434 fixed_form_sizes,
1435 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001436 if (num_attributes > 0)
1437 {
1438 Declaration decl;
1439 DWARFExpression location;
1440 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001441 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001442 bool is_virtual = false;
1443 bool is_base_of_class = true;
1444 off_t member_offset = 0;
1445 uint32_t i;
1446 for (i=0; i<num_attributes; ++i)
1447 {
1448 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1449 DWARFFormValue form_value;
1450 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1451 {
1452 switch (attr)
1453 {
1454 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1455 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1456 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1457 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1458 case DW_AT_data_member_location:
1459 if (form_value.BlockData())
1460 {
1461 Value initialValue(0);
1462 Value memberOffset(0);
1463 const DataExtractor& debug_info_data = get_debug_info_data();
1464 uint32_t block_length = form_value.Unsigned();
1465 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001466 if (DWARFExpression::Evaluate (NULL,
1467 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001468 NULL,
1469 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001470 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001471 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001472 block_offset,
1473 block_length,
1474 eRegisterKindDWARF,
1475 &initialValue,
1476 memberOffset,
1477 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001478 {
1479 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1480 }
1481 }
1482 break;
1483
1484 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001485 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001486 break;
1487
1488 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1489 default:
1490 case DW_AT_sibling:
1491 break;
1492 }
1493 }
1494 }
1495
Greg Clayton526e5af2010-11-13 03:52:47 +00001496 Type *base_class_type = ResolveTypeUID(encoding_uid);
1497 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001498
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001499 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1500 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001501 if (class_language == eLanguageTypeObjC)
1502 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001503 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001504 }
1505 else
1506 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001507 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001508 accessibility,
1509 is_virtual,
1510 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001511 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001512 }
1513 }
1514 break;
1515
1516 default:
1517 break;
1518 }
1519 }
1520 return count;
1521}
1522
1523
1524clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001525SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001526{
1527 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +00001528 if (debug_info && UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529 {
1530 DWARFCompileUnitSP cu_sp;
1531 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1532 if (die)
Greg Claytoncb5860a2011-10-13 23:49:28 +00001533 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Sean Callanan72e49402011-08-05 23:43:37 +00001534 }
1535 return NULL;
1536}
1537
1538clang::DeclContext*
1539SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1540{
Greg Clayton81c22f62011-10-19 18:09:39 +00001541 if (UserIDMatches(type_uid))
1542 return GetClangDeclContextForDIEOffset (sc, type_uid);
1543 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544}
1545
1546Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001547SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001548{
Greg Clayton81c22f62011-10-19 18:09:39 +00001549 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001550 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001551 DWARFDebugInfo* debug_info = DebugInfo();
1552 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00001553 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001554 DWARFCompileUnitSP cu_sp;
1555 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1556 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001557 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001558 // We might be coming in in the middle of a type tree (a class
1559 // withing a class, an enum within a class), so parse any needed
1560 // parent DIEs before we get to this one...
1561 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die);
1562 switch (decl_ctx_die->Tag())
1563 {
1564 case DW_TAG_structure_type:
1565 case DW_TAG_union_type:
1566 case DW_TAG_class_type:
1567 ResolveType(cu_sp.get(), decl_ctx_die);
1568 break;
1569 }
1570 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001571 }
Greg Claytonca512b32011-01-14 04:54:56 +00001572 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001573 }
1574 return NULL;
1575}
1576
Greg Clayton6beaaa62011-01-17 03:46:26 +00001577// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1578// SymbolFileDWARF objects to detect if this DWARF file is the one that
1579// can resolve a clang_type.
1580bool
1581SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1582{
1583 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1584 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1585 return die != NULL;
1586}
1587
1588
Greg Clayton1be10fc2010-09-29 01:12:09 +00001589lldb::clang_type_t
1590SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1591{
1592 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001593 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1594 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001595 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001596 {
1597 // We have already resolved this type...
1598 return clang_type;
1599 }
1600 // Once we start resolving this type, remove it from the forward declaration
1601 // map in case anyone child members or other types require this type to get resolved.
1602 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1603 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001604 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001605
Greg Clayton1be10fc2010-09-29 01:12:09 +00001606
Greg Clayton85ae2e12011-10-18 23:36:41 +00001607 // Disable external storage for this type so we don't get anymore
1608 // clang::ExternalASTSource queries for this type.
1609 ClangASTContext::SetHasExternalStorage (clang_type, false);
1610
Greg Clayton450e3f32010-10-12 02:24:53 +00001611 DWARFDebugInfo* debug_info = DebugInfo();
1612
Greg Clayton96d7d742010-11-10 23:42:09 +00001613 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001614 Type *type = m_die_to_type.lookup (die);
1615
1616 const dw_tag_t tag = die->Tag();
1617
Greg Clayton81c22f62011-10-19 18:09:39 +00001618 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") - resolve forward declaration...\n",
1619 MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001620 DW_TAG_value_to_name(tag),
1621 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001622 assert (clang_type);
1623 DWARFDebugInfoEntry::Attributes attributes;
1624
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001625 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001626
1627 switch (tag)
1628 {
1629 case DW_TAG_structure_type:
1630 case DW_TAG_union_type:
1631 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001632 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001633 if (die->HasChildren())
1634 {
1635 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001636 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1637 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001638 class_language = eLanguageTypeObjC;
1639
1640 int tag_decl_kind = -1;
1641 AccessType default_accessibility = eAccessNone;
1642 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001643 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001644 tag_decl_kind = clang::TTK_Struct;
1645 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001646 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001647 else if (tag == DW_TAG_union_type)
1648 {
1649 tag_decl_kind = clang::TTK_Union;
1650 default_accessibility = eAccessPublic;
1651 }
1652 else if (tag == DW_TAG_class_type)
1653 {
1654 tag_decl_kind = clang::TTK_Class;
1655 default_accessibility = eAccessPrivate;
1656 }
1657
Greg Clayton96d7d742010-11-10 23:42:09 +00001658 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001659 std::vector<clang::CXXBaseSpecifier *> base_classes;
1660 std::vector<int> member_accessibilities;
1661 bool is_a_class = false;
1662 // Parse members and base classes first
1663 DWARFDIECollection member_function_dies;
1664
1665 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001666 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001667 die,
1668 clang_type,
1669 class_language,
1670 base_classes,
1671 member_accessibilities,
1672 member_function_dies,
1673 default_accessibility,
1674 is_a_class);
1675
1676 // Now parse any methods if there were any...
1677 size_t num_functions = member_function_dies.Size();
1678 if (num_functions > 0)
1679 {
1680 for (size_t i=0; i<num_functions; ++i)
1681 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001682 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001683 }
1684 }
1685
Greg Clayton450e3f32010-10-12 02:24:53 +00001686 if (class_language == eLanguageTypeObjC)
1687 {
Greg Claytone3055942011-06-30 02:28:26 +00001688 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001689 if (!class_str.empty())
1690 {
1691
1692 ConstString class_name (class_str.c_str());
Greg Claytond4a2b372011-09-12 23:21:58 +00001693 DIEArray method_die_offsets;
1694 if (m_objc_class_selectors_index.Find (class_name, method_die_offsets))
Greg Clayton450e3f32010-10-12 02:24:53 +00001695 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001696 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton450e3f32010-10-12 02:24:53 +00001697
Greg Claytond4a2b372011-09-12 23:21:58 +00001698 DWARFCompileUnit* method_cu = NULL;
1699 const size_t num_matches = method_die_offsets.size();
1700 for (size_t i=0; i<num_matches; ++i)
1701 {
1702 const dw_offset_t die_offset = method_die_offsets[i];
1703 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Greg Clayton450e3f32010-10-12 02:24:53 +00001704
1705 ResolveType (method_cu, method_die);
1706 }
1707 }
1708 }
1709 }
1710
Greg Claytonc93237c2010-10-01 20:48:32 +00001711 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1712 // need to tell the clang type it is actually a class.
1713 if (class_language != eLanguageTypeObjC)
1714 {
1715 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001716 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001717 }
1718
1719 // Since DW_TAG_structure_type gets used for both classes
1720 // and structures, we may need to set any DW_TAG_member
1721 // fields to have a "private" access if none was specified.
1722 // When we parsed the child members we tracked that actual
1723 // accessibility value for each DW_TAG_member in the
1724 // "member_accessibilities" array. If the value for the
1725 // member is zero, then it was set to the "default_accessibility"
1726 // which for structs was "public". Below we correct this
1727 // by setting any fields to "private" that weren't correctly
1728 // set.
1729 if (is_a_class && !member_accessibilities.empty())
1730 {
1731 // This is a class and all members that didn't have
1732 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001733 ast.SetDefaultAccessForRecordFields (clang_type,
1734 eAccessPrivate,
1735 &member_accessibilities.front(),
1736 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001737 }
1738
1739 if (!base_classes.empty())
1740 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001741 ast.SetBaseClassesForClassType (clang_type,
1742 &base_classes.front(),
1743 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001744
1745 // Clang will copy each CXXBaseSpecifier in "base_classes"
1746 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001747 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1748 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001749 }
1750
1751 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001752 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001753 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001754
1755 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001756 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001757 if (die->HasChildren())
1758 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001759 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1760 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001761 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001762 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001763 return clang_type;
1764
1765 default:
1766 assert(false && "not a forward clang type decl!");
1767 break;
1768 }
1769 return NULL;
1770}
1771
Greg Claytonc685f8e2010-09-15 04:15:46 +00001772Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001773SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001774{
1775 if (type_die != NULL)
1776 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001777 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001778 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001779 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001780 if (assert_not_being_parsed)
1781 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001782 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001783 }
1784 return NULL;
1785}
1786
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001787CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001788SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789{
1790 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001791 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001792 {
1793 // The symbol vendor doesn't know about this compile unit, we
1794 // need to parse and add it to the symbol vendor object.
1795 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001796 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001797 if (dc_cu.get())
1798 {
1799 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001800 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001801 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001802
1803 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001804
1805 if (m_debug_map_symfile)
1806 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001807 }
1808 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001809 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001810}
1811
1812bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001813SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001814{
1815 sc.Clear();
1816 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001817 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001818
Greg Clayton81c22f62011-10-19 18:09:39 +00001819 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001820 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001821 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Jim Ingham4cda6e02011-10-07 22:23:45 +00001822
1823 if (sc.function)
1824 {
1825 sc.module_sp = sc.function->CalculateSymbolContextModule();
1826 return true;
1827 }
1828
1829 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001830}
1831
1832uint32_t
1833SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1834{
1835 Timer scoped_timer(__PRETTY_FUNCTION__,
1836 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1837 so_addr.GetSection(),
1838 so_addr.GetOffset(),
1839 resolve_scope);
1840 uint32_t resolved = 0;
1841 if (resolve_scope & ( eSymbolContextCompUnit |
1842 eSymbolContextFunction |
1843 eSymbolContextBlock |
1844 eSymbolContextLineEntry))
1845 {
1846 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1847
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001849 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001850 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001851 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001852 if (cu_offset != DW_INVALID_OFFSET)
1853 {
1854 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001855 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1856 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001857 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001858 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001859 assert(sc.comp_unit != NULL);
1860 resolved |= eSymbolContextCompUnit;
1861
1862 if (resolve_scope & eSymbolContextLineEntry)
1863 {
1864 LineTable *line_table = sc.comp_unit->GetLineTable();
1865 if (line_table == NULL)
1866 {
1867 if (ParseCompileUnitLineTable(sc))
1868 line_table = sc.comp_unit->GetLineTable();
1869 }
1870 if (line_table != NULL)
1871 {
1872 if (so_addr.IsLinkedAddress())
1873 {
1874 Address linked_addr (so_addr);
1875 linked_addr.ResolveLinkedAddress();
1876 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1877 {
1878 resolved |= eSymbolContextLineEntry;
1879 }
1880 }
1881 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1882 {
1883 resolved |= eSymbolContextLineEntry;
1884 }
1885 }
1886 }
1887
1888 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1889 {
1890 DWARFDebugInfoEntry *function_die = NULL;
1891 DWARFDebugInfoEntry *block_die = NULL;
1892 if (resolve_scope & eSymbolContextBlock)
1893 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001894 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001895 }
1896 else
1897 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001898 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001899 }
1900
1901 if (function_die != NULL)
1902 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001903 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001904 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001905 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 }
1907
1908 if (sc.function != NULL)
1909 {
1910 resolved |= eSymbolContextFunction;
1911
1912 if (resolve_scope & eSymbolContextBlock)
1913 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001914 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915
1916 if (block_die != NULL)
Greg Clayton81c22f62011-10-19 18:09:39 +00001917 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001918 else
Greg Clayton81c22f62011-10-19 18:09:39 +00001919 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001920 if (sc.block)
1921 resolved |= eSymbolContextBlock;
1922 }
1923 }
1924 }
1925 }
1926 }
1927 }
1928 }
1929 return resolved;
1930}
1931
1932
1933
1934uint32_t
1935SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1936{
1937 const uint32_t prev_size = sc_list.GetSize();
1938 if (resolve_scope & eSymbolContextCompUnit)
1939 {
1940 DWARFDebugInfo* debug_info = DebugInfo();
1941 if (debug_info)
1942 {
1943 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001944 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001945
Greg Clayton96d7d742010-11-10 23:42:09 +00001946 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001947 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001948 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001949 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1950 if (check_inlines || file_spec_matches_cu_file_spec)
1951 {
1952 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001953 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001954 assert(sc.comp_unit != NULL);
1955
1956 uint32_t file_idx = UINT32_MAX;
1957
1958 // If we are looking for inline functions only and we don't
1959 // find it in the support files, we are done.
1960 if (check_inlines)
1961 {
Jim Ingham87df91b2011-09-23 00:54:11 +00001962 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001963 if (file_idx == UINT32_MAX)
1964 continue;
1965 }
1966
1967 if (line != 0)
1968 {
1969 LineTable *line_table = sc.comp_unit->GetLineTable();
1970
1971 if (line_table != NULL && line != 0)
1972 {
1973 // We will have already looked up the file index if
1974 // we are searching for inline entries.
1975 if (!check_inlines)
Jim Ingham87df91b2011-09-23 00:54:11 +00001976 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001977
1978 if (file_idx != UINT32_MAX)
1979 {
1980 uint32_t found_line;
1981 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1982 found_line = sc.line_entry.line;
1983
Greg Clayton016a95e2010-09-14 02:20:48 +00001984 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001985 {
1986 sc.function = NULL;
1987 sc.block = NULL;
1988 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1989 {
1990 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1991 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1992 {
1993 DWARFDebugInfoEntry *function_die = NULL;
1994 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001995 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001996
1997 if (function_die != NULL)
1998 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001999 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002000 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00002001 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002002 }
2003
2004 if (sc.function != NULL)
2005 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00002006 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002007
2008 if (block_die != NULL)
Greg Clayton81c22f62011-10-19 18:09:39 +00002009 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002010 else
Greg Clayton81c22f62011-10-19 18:09:39 +00002011 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002012 }
2013 }
2014 }
2015
2016 sc_list.Append(sc);
2017 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
2018 }
2019 }
2020 }
2021 else if (file_spec_matches_cu_file_spec && !check_inlines)
2022 {
2023 // only append the context if we aren't looking for inline call sites
2024 // by file and line and if the file spec matches that of the compile unit
2025 sc_list.Append(sc);
2026 }
2027 }
2028 else if (file_spec_matches_cu_file_spec && !check_inlines)
2029 {
2030 // only append the context if we aren't looking for inline call sites
2031 // by file and line and if the file spec matches that of the compile unit
2032 sc_list.Append(sc);
2033 }
2034
2035 if (!check_inlines)
2036 break;
2037 }
2038 }
2039 }
2040 }
2041 return sc_list.GetSize() - prev_size;
2042}
2043
2044void
2045SymbolFileDWARF::Index ()
2046{
2047 if (m_indexed)
2048 return;
2049 m_indexed = true;
2050 Timer scoped_timer (__PRETTY_FUNCTION__,
2051 "SymbolFileDWARF::Index (%s)",
2052 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
2053
2054 DWARFDebugInfo* debug_info = DebugInfo();
2055 if (debug_info)
2056 {
2057 uint32_t cu_idx = 0;
2058 const uint32_t num_compile_units = GetNumCompileUnits();
2059 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2060 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002061 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002062
Greg Clayton96d7d742010-11-10 23:42:09 +00002063 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002064
Greg Clayton96d7d742010-11-10 23:42:09 +00002065 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00002066 m_function_basename_index,
2067 m_function_fullname_index,
2068 m_function_method_index,
2069 m_function_selector_index,
2070 m_objc_class_selectors_index,
2071 m_global_index,
2072 m_type_index,
Greg Claytond4a2b372011-09-12 23:21:58 +00002073 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002074
2075 // Keep memory down by clearing DIEs if this generate function
2076 // caused them to be parsed
2077 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00002078 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002079 }
2080
Greg Claytond4a2b372011-09-12 23:21:58 +00002081 m_function_basename_index.Finalize();
2082 m_function_fullname_index.Finalize();
2083 m_function_method_index.Finalize();
2084 m_function_selector_index.Finalize();
2085 m_objc_class_selectors_index.Finalize();
2086 m_global_index.Finalize();
2087 m_type_index.Finalize();
2088 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002089
Greg Clayton24739922010-10-13 03:15:28 +00002090#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00002091 StreamFile s(stdout, false);
Greg Claytonf9eec202011-09-01 23:16:13 +00002092 s.Printf ("DWARF index for '%s/%s':",
Greg Clayton24739922010-10-13 03:15:28 +00002093 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
2094 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00002095 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
2096 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
2097 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
2098 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
2099 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
2100 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00002101 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00002102 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002103#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002104 }
2105}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002106
2107bool
2108SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
2109{
2110 if (namespace_decl == NULL)
2111 {
2112 // Invalid namespace decl which means we aren't matching only things
2113 // in this symbol file, so return true to indicate it matches this
2114 // symbol file.
2115 return true;
2116 }
2117
2118 clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
2119
2120 if (namespace_ast == NULL)
2121 return true; // No AST in the "namespace_decl", return true since it
2122 // could then match any symbol file, including this one
2123
2124 if (namespace_ast == GetClangASTContext().getASTContext())
2125 return true; // The ASTs match, return true
2126
2127 // The namespace AST was valid, and it does not match...
Sean Callananc41e68b2011-10-13 21:08:11 +00002128 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2129
2130 if (log)
2131 log->Printf("Valid namespace does not match symbol file");
2132
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002133 return false;
2134}
2135
Greg Clayton2506a7a2011-10-12 23:34:26 +00002136bool
2137SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
2138 DWARFCompileUnit* cu,
2139 const DWARFDebugInfoEntry* die)
2140{
2141 // No namespace specified, so the answesr i
2142 if (namespace_decl == NULL)
2143 return true;
Sean Callananebe60672011-10-13 21:50:33 +00002144
2145 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002146
Greg Clayton2506a7a2011-10-12 23:34:26 +00002147 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
2148 if (decl_ctx_die)
2149 {
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002150
Greg Clayton2506a7a2011-10-12 23:34:26 +00002151 clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
2152 if (clang_namespace_decl)
2153 {
2154 if (decl_ctx_die->Tag() != DW_TAG_namespace)
Sean Callananebe60672011-10-13 21:50:33 +00002155 {
2156 if (log)
2157 log->Printf("Found a match, but its parent is not a namespace");
Greg Clayton2506a7a2011-10-12 23:34:26 +00002158 return false;
Sean Callananebe60672011-10-13 21:50:33 +00002159 }
2160
Greg Clayton2506a7a2011-10-12 23:34:26 +00002161 DeclContextToDIEMap::iterator pos = m_decl_ctx_to_die.find(clang_namespace_decl);
2162
2163 if (pos == m_decl_ctx_to_die.end())
Sean Callananebe60672011-10-13 21:50:33 +00002164 {
2165 if (log)
2166 log->Printf("Found a match in a namespace, but its parent is not the requested namespace");
2167
Greg Clayton2506a7a2011-10-12 23:34:26 +00002168 return false;
Sean Callananebe60672011-10-13 21:50:33 +00002169 }
Greg Clayton2506a7a2011-10-12 23:34:26 +00002170
Greg Claytoncb5860a2011-10-13 23:49:28 +00002171 return pos->second.count (decl_ctx_die);
Greg Clayton2506a7a2011-10-12 23:34:26 +00002172 }
2173 else
2174 {
2175 // We have a namespace_decl that was not NULL but it contained
2176 // a NULL "clang::NamespaceDecl", so this means the global namespace
2177 // So as long the the contained decl context DIE isn't a namespace
2178 // we should be ok.
2179 if (decl_ctx_die->Tag() != DW_TAG_namespace)
2180 return true;
2181 }
2182 }
Sean Callananebe60672011-10-13 21:50:33 +00002183
2184 if (log)
2185 log->Printf("Found a match, but its parent doesn't exist");
2186
Greg Clayton2506a7a2011-10-12 23:34:26 +00002187 return false;
2188}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002189uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00002190SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002191{
Greg Clayton21f2a492011-10-06 00:09:08 +00002192 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2193
2194 if (log)
2195 {
2196 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", name=\"%s\", append=%u, max_matches=%u, variables)",
2197 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2198 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2199 name.GetCString(), append, max_matches);
2200 }
Sean Callanan213fdb82011-10-13 01:49:10 +00002201
2202 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2203 return 0;
2204
Greg Claytonc685f8e2010-09-15 04:15:46 +00002205 DWARFDebugInfo* info = DebugInfo();
2206 if (info == NULL)
2207 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002208
2209 // If we aren't appending the results to this list, then clear the list
2210 if (!append)
2211 variables.Clear();
2212
2213 // Remember how many variables are in the list before we search in case
2214 // we are appending the results to a variable list.
2215 const uint32_t original_size = variables.GetSize();
2216
Greg Claytond4a2b372011-09-12 23:21:58 +00002217 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002218
Greg Clayton97fbc342011-10-20 22:30:33 +00002219 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002220 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002221 if (m_apple_names_ap.get())
2222 {
2223 const char *name_cstr = name.GetCString();
2224 const char *base_name_start;
2225 const char *base_name_end = NULL;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002226
Greg Clayton97fbc342011-10-20 22:30:33 +00002227 if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end))
2228 base_name_start = name_cstr;
2229
2230 m_apple_names_ap->FindByName (base_name_start, die_offsets);
2231 }
Greg Clayton7f995132011-10-04 22:41:51 +00002232 }
2233 else
2234 {
2235 // Index the DWARF if we haven't already
2236 if (!m_indexed)
2237 Index ();
2238
2239 m_global_index.Find (name, die_offsets);
2240 }
2241
2242 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002243 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002244 {
Greg Clayton7f995132011-10-04 22:41:51 +00002245 SymbolContext sc;
2246 sc.module_sp = m_obj_file->GetModule();
2247 assert (sc.module_sp);
2248
Greg Claytond4a2b372011-09-12 23:21:58 +00002249 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00002250 DWARFCompileUnit* dwarf_cu = NULL;
2251 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002252 for (size_t i=0; i<num_matches; ++i)
2253 {
2254 const dw_offset_t die_offset = die_offsets[i];
2255 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002256
Greg Claytond4a2b372011-09-12 23:21:58 +00002257 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2258 assert(sc.comp_unit != NULL);
Sean Callanan213fdb82011-10-13 01:49:10 +00002259
2260 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2261 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002262
Greg Claytond4a2b372011-09-12 23:21:58 +00002263 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002264
Greg Claytond4a2b372011-09-12 23:21:58 +00002265 if (variables.GetSize() - original_size >= max_matches)
2266 break;
2267 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002268 }
2269
2270 // Return the number of variable that were appended to the list
2271 return variables.GetSize() - original_size;
2272}
2273
2274uint32_t
2275SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2276{
Greg Clayton21f2a492011-10-06 00:09:08 +00002277 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2278
2279 if (log)
2280 {
2281 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", regex=\"%s\", append=%u, max_matches=%u, variables)",
2282 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2283 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2284 regex.GetText(), append, max_matches);
2285 }
2286
Greg Claytonc685f8e2010-09-15 04:15:46 +00002287 DWARFDebugInfo* info = DebugInfo();
2288 if (info == NULL)
2289 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002290
2291 // If we aren't appending the results to this list, then clear the list
2292 if (!append)
2293 variables.Clear();
2294
2295 // Remember how many variables are in the list before we search in case
2296 // we are appending the results to a variable list.
2297 const uint32_t original_size = variables.GetSize();
2298
Greg Clayton7f995132011-10-04 22:41:51 +00002299 DIEArray die_offsets;
2300
Greg Clayton97fbc342011-10-20 22:30:33 +00002301 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002302 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002303 if (m_apple_names_ap.get())
2304 m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00002305 }
2306 else
2307 {
2308 // Index the DWARF if we haven't already
2309 if (!m_indexed)
2310 Index ();
2311
2312 m_global_index.Find (regex, die_offsets);
2313 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002314
Greg Claytonc685f8e2010-09-15 04:15:46 +00002315 SymbolContext sc;
Greg Claytona2eee182011-09-17 07:23:18 +00002316 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002317 assert (sc.module_sp);
2318
Greg Claytond4a2b372011-09-12 23:21:58 +00002319 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002320 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002321 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002322 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002323 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002324 DWARFDebugInfo* debug_info = DebugInfo();
2325 for (size_t i=0; i<num_matches; ++i)
2326 {
2327 const dw_offset_t die_offset = die_offsets[i];
2328 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2329 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002330
Greg Claytond4a2b372011-09-12 23:21:58 +00002331 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002332
Greg Claytond4a2b372011-09-12 23:21:58 +00002333 if (variables.GetSize() - original_size >= max_matches)
2334 break;
2335 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336 }
2337
2338 // Return the number of variable that were appended to the list
2339 return variables.GetSize() - original_size;
2340}
2341
Greg Claytonaa044962011-10-13 00:59:38 +00002342
Jim Ingham4cda6e02011-10-07 22:23:45 +00002343bool
2344SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
2345 DWARFCompileUnit *&dwarf_cu,
2346 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002347{
Greg Claytonaa044962011-10-13 00:59:38 +00002348 const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2349 return ResolveFunction (dwarf_cu, die, sc_list);
2350}
2351
2352
2353bool
2354SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
2355 const DWARFDebugInfoEntry *die,
2356 SymbolContextList& sc_list)
2357{
Greg Clayton9e315582011-09-02 04:03:59 +00002358 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00002359
2360 if (die == NULL)
2361 return false;
2362
Jim Ingham4cda6e02011-10-07 22:23:45 +00002363 // If we were passed a die that is not a function, just return false...
2364 if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine)
2365 return false;
2366
2367 const DWARFDebugInfoEntry* inlined_die = NULL;
2368 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002369 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002370 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002371
Jim Ingham4cda6e02011-10-07 22:23:45 +00002372 while ((die = die->GetParent()) != NULL)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002373 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002374 if (die->Tag() == DW_TAG_subprogram)
2375 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002376 }
2377 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002378 assert (die->Tag() == DW_TAG_subprogram);
Greg Claytonaa044962011-10-13 00:59:38 +00002379 if (GetFunction (cu, die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002380 {
2381 Address addr;
2382 // Parse all blocks if needed
2383 if (inlined_die)
2384 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002385 sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
Jim Ingham4cda6e02011-10-07 22:23:45 +00002386 assert (sc.block != NULL);
2387 if (sc.block->GetStartAddress (addr) == false)
2388 addr.Clear();
2389 }
2390 else
2391 {
2392 sc.block = NULL;
2393 addr = sc.function->GetAddressRange().GetBaseAddress();
2394 }
2395
2396 if (addr.IsValid())
2397 {
2398
2399 // We found the function, so we should find the line table
2400 // and line table entry as well
2401 LineTable *line_table = sc.comp_unit->GetLineTable();
2402 if (line_table == NULL)
2403 {
2404 if (ParseCompileUnitLineTable(sc))
2405 line_table = sc.comp_unit->GetLineTable();
2406 }
2407 if (line_table != NULL)
2408 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2409
2410 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00002411 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002412 }
2413 }
2414
Greg Claytonaa044962011-10-13 00:59:38 +00002415 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00002416}
2417
Greg Clayton7f995132011-10-04 22:41:51 +00002418void
2419SymbolFileDWARF::FindFunctions (const ConstString &name,
2420 const NameToDIE &name_to_die,
2421 SymbolContextList& sc_list)
2422{
Greg Claytond4a2b372011-09-12 23:21:58 +00002423 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002424 if (name_to_die.Find (name, die_offsets))
2425 {
2426 ParseFunctions (die_offsets, sc_list);
2427 }
2428}
2429
2430
2431void
2432SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2433 const NameToDIE &name_to_die,
2434 SymbolContextList& sc_list)
2435{
2436 DIEArray die_offsets;
2437 if (name_to_die.Find (regex, die_offsets))
2438 {
2439 ParseFunctions (die_offsets, sc_list);
2440 }
2441}
2442
2443
2444void
2445SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2446 const DWARFMappedHash::MemoryTable &memory_table,
2447 SymbolContextList& sc_list)
2448{
2449 DIEArray die_offsets;
2450 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
2451 {
2452 ParseFunctions (die_offsets, sc_list);
2453 }
2454}
2455
2456void
2457SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2458 SymbolContextList& sc_list)
2459{
2460 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002461 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002462 {
Greg Clayton7f995132011-10-04 22:41:51 +00002463 SymbolContext sc;
Greg Clayton7f995132011-10-04 22:41:51 +00002464
2465 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002466 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00002467 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002468 const dw_offset_t die_offset = die_offsets[i];
Jim Ingham4cda6e02011-10-07 22:23:45 +00002469 ResolveFunction (die_offset, dwarf_cu, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002470 }
2471 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002472}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002473
Jim Ingham4cda6e02011-10-07 22:23:45 +00002474bool
2475SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
2476 const DWARFCompileUnit *dwarf_cu,
2477 uint32_t name_type_mask,
2478 const char *partial_name,
2479 const char *base_name_start,
2480 const char *base_name_end)
2481{
2482 // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
2483 if (name_type_mask == eFunctionNameTypeMethod
2484 || name_type_mask == eFunctionNameTypeBase)
2485 {
Greg Claytonf0705c82011-10-22 03:33:13 +00002486 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
2487 if (!containing_decl_ctx)
2488 return false;
2489
2490 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
2491
2492 if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
2493 return false;
2494 if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
2495 return false;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002496 }
2497
2498 // Now we need to check whether the name we got back for this type matches the extra specifications
2499 // that were in the name we're looking up:
2500 if (base_name_start != partial_name || *base_name_end != '\0')
2501 {
2502 // First see if the stuff to the left matches the full name. To do that let's see if
2503 // we can pull out the mips linkage name attribute:
2504
2505 Mangled best_name;
2506
2507 DWARFDebugInfoEntry::Attributes attributes;
2508 die->GetAttributes(this, dwarf_cu, NULL, attributes);
2509 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
2510 if (idx != UINT32_MAX)
2511 {
2512 DWARFFormValue form_value;
2513 if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
2514 {
2515 const char *name = form_value.AsCString(&get_debug_str_data());
2516 best_name.SetValue (name, true);
2517 }
2518 }
2519 if (best_name)
2520 {
2521 const char *demangled = best_name.GetDemangledName().GetCString();
2522 if (demangled)
2523 {
2524 std::string name_no_parens(partial_name, base_name_end - partial_name);
2525 if (strstr (demangled, name_no_parens.c_str()) == NULL)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002526 return false;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002527 }
2528 }
2529 }
2530
2531 return true;
2532}
Greg Claytonc685f8e2010-09-15 04:15:46 +00002533
Greg Clayton0c5cd902010-06-28 21:30:43 +00002534uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00002535SymbolFileDWARF::FindFunctions (const ConstString &name,
Sean Callanan213fdb82011-10-13 01:49:10 +00002536 const lldb_private::ClangNamespaceDecl *namespace_decl,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002537 uint32_t name_type_mask,
2538 bool append,
2539 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002540{
2541 Timer scoped_timer (__PRETTY_FUNCTION__,
2542 "SymbolFileDWARF::FindFunctions (name = '%s')",
2543 name.AsCString());
2544
Greg Clayton21f2a492011-10-06 00:09:08 +00002545 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2546
2547 if (log)
2548 {
2549 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2550 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2551 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2552 name.GetCString(), name_type_mask, append);
2553 }
2554
Greg Clayton0c5cd902010-06-28 21:30:43 +00002555 // If we aren't appending the results to this list, then clear the list
2556 if (!append)
2557 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002558
2559 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2560 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002561
2562 // If name is empty then we won't find anything.
2563 if (name.IsEmpty())
2564 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002565
2566 // Remember how many sc_list are in the list before we search in case
2567 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002568
Greg Clayton9e315582011-09-02 04:03:59 +00002569 const uint32_t original_size = sc_list.GetSize();
Greg Clayton0c5cd902010-06-28 21:30:43 +00002570
Jim Ingham4cda6e02011-10-07 22:23:45 +00002571 const char *name_cstr = name.GetCString();
2572 uint32_t effective_name_type_mask = eFunctionNameTypeNone;
2573 const char *base_name_start = name_cstr;
2574 const char *base_name_end = name_cstr + strlen(name_cstr);
2575
2576 if (name_type_mask & eFunctionNameTypeAuto)
2577 {
2578 if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
2579 effective_name_type_mask = eFunctionNameTypeFull;
2580 else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
2581 effective_name_type_mask = eFunctionNameTypeFull;
2582 else
2583 {
2584 if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2585 effective_name_type_mask |= eFunctionNameTypeSelector;
2586
2587 if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2588 effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
2589 }
2590 }
2591 else
2592 {
2593 effective_name_type_mask = name_type_mask;
2594 if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
2595 {
2596 // If they've asked for a CPP method or function name and it can't be that, we don't
2597 // even need to search for CPP methods or names.
2598 if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2599 {
2600 effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
2601 if (effective_name_type_mask == eFunctionNameTypeNone)
2602 return 0;
2603 }
2604 }
2605
2606 if (effective_name_type_mask & eFunctionNameTypeSelector)
2607 {
2608 if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2609 {
2610 effective_name_type_mask &= ~(eFunctionNameTypeSelector);
2611 if (effective_name_type_mask == eFunctionNameTypeNone)
2612 return 0;
2613 }
2614 }
2615 }
2616
2617 DWARFDebugInfo* info = DebugInfo();
2618 if (info == NULL)
2619 return 0;
2620
Greg Claytonaa044962011-10-13 00:59:38 +00002621 DWARFCompileUnit *dwarf_cu = NULL;
Greg Clayton97fbc342011-10-20 22:30:33 +00002622 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00002623 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002624 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00002625 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002626
2627 DIEArray die_offsets;
2628
2629 uint32_t num_matches = 0;
2630
2631 if (effective_name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00002632 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002633 // If they asked for the full name, match what they typed. At some point we may
2634 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2635 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00002636 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002637 for (uint32_t i = 0; i < num_matches; i++)
2638 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002639 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
Greg Claytonaa044962011-10-13 00:59:38 +00002640 if (die)
2641 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002642 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2643 continue;
2644
Greg Claytonaa044962011-10-13 00:59:38 +00002645 ResolveFunction (dwarf_cu, die, sc_list);
2646 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002647 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002648 }
2649 else
2650 {
2651 if (effective_name_type_mask & eFunctionNameTypeSelector)
2652 {
2653 if (namespace_decl && *namespace_decl)
2654 return 0; // no selectors in namespaces
2655
2656 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2657 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2658 // and if it is an ObjC method name, we're good.
2659
2660 for (uint32_t i = 0; i < num_matches; i++)
2661 {
2662 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2663 if (die)
2664 {
2665 const char *die_name = die->GetName(this, dwarf_cu);
2666 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
2667 ResolveFunction (dwarf_cu, die, sc_list);
2668 }
2669 }
2670 die_offsets.clear();
2671 }
2672
2673 if (effective_name_type_mask & eFunctionNameTypeMethod
2674 || effective_name_type_mask & eFunctionNameTypeBase)
2675 {
2676 if ((effective_name_type_mask & eFunctionNameTypeMethod) &&
2677 (namespace_decl && *namespace_decl))
2678 return 0; // no methods in namespaces
2679
2680 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2681 // extract the base name, look that up, and if there is any other information in the name we were
2682 // passed in we have to post-filter based on that.
2683
2684 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2685 std::string base_name(base_name_start, base_name_end - base_name_start);
2686 num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
2687
2688 for (uint32_t i = 0; i < num_matches; i++)
2689 {
2690 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2691 if (die)
2692 {
2693 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2694 continue;
2695
2696 if (!FunctionDieMatchesPartialName(die,
2697 dwarf_cu,
2698 effective_name_type_mask,
2699 name_cstr,
2700 base_name_start,
2701 base_name_end))
2702 continue;
2703
2704 // If we get to here, the die is good, and we should add it:
2705 ResolveFunction (dwarf_cu, die, sc_list);
2706 }
2707 }
2708 die_offsets.clear();
2709 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002710 }
2711 }
Greg Clayton7f995132011-10-04 22:41:51 +00002712 }
2713 else
2714 {
2715
2716 // Index the DWARF if we haven't already
2717 if (!m_indexed)
2718 Index ();
2719
Greg Clayton7f995132011-10-04 22:41:51 +00002720 if (name_type_mask & eFunctionNameTypeFull)
2721 FindFunctions (name, m_function_fullname_index, sc_list);
2722
Jim Ingham4cda6e02011-10-07 22:23:45 +00002723 std::string base_name(base_name_start, base_name_end - base_name_start);
2724 ConstString base_name_const(base_name.c_str());
2725 DIEArray die_offsets;
2726 DWARFCompileUnit *dwarf_cu = NULL;
2727
2728 if (effective_name_type_mask & eFunctionNameTypeBase)
2729 {
2730 uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00002731 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002732 {
Greg Claytonaa044962011-10-13 00:59:38 +00002733 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2734 if (die)
2735 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002736 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2737 continue;
2738
Greg Claytonaa044962011-10-13 00:59:38 +00002739 if (!FunctionDieMatchesPartialName(die,
2740 dwarf_cu,
2741 effective_name_type_mask,
2742 name_cstr,
2743 base_name_start,
2744 base_name_end))
2745 continue;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002746
Greg Claytonaa044962011-10-13 00:59:38 +00002747 // If we get to here, the die is good, and we should add it:
2748 ResolveFunction (dwarf_cu, die, sc_list);
2749 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002750 }
2751 die_offsets.clear();
2752 }
2753
Jim Inghamea8005a2011-10-11 01:18:11 +00002754 if (effective_name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002755 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002756 if (namespace_decl && *namespace_decl)
2757 return 0; // no methods in namespaces
2758
Jim Ingham4cda6e02011-10-07 22:23:45 +00002759 uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
2760 {
Greg Claytonaa044962011-10-13 00:59:38 +00002761 for (uint32_t i = 0; i < num_base; i++)
2762 {
2763 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2764 if (die)
2765 {
2766 if (!FunctionDieMatchesPartialName(die,
2767 dwarf_cu,
2768 effective_name_type_mask,
2769 name_cstr,
2770 base_name_start,
2771 base_name_end))
2772 continue;
2773
2774 // If we get to here, the die is good, and we should add it:
2775 ResolveFunction (dwarf_cu, die, sc_list);
2776 }
2777 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002778 }
2779 die_offsets.clear();
2780 }
Greg Clayton7f995132011-10-04 22:41:51 +00002781
Sean Callanan213fdb82011-10-13 01:49:10 +00002782 if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002783 {
Greg Clayton7f995132011-10-04 22:41:51 +00002784 FindFunctions (name, m_function_selector_index, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002785 }
2786
Greg Clayton4d01ace2011-09-29 16:58:15 +00002787 }
2788
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002789 // Return the number of variable that were appended to the list
2790 return sc_list.GetSize() - original_size;
2791}
2792
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002793uint32_t
2794SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2795{
2796 Timer scoped_timer (__PRETTY_FUNCTION__,
2797 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2798 regex.GetText());
2799
Greg Clayton21f2a492011-10-06 00:09:08 +00002800 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2801
2802 if (log)
2803 {
2804 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", regex=\"%s\"append=%u, sc_list)",
2805 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2806 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2807 regex.GetText(), append);
2808 }
2809
2810
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002811 // If we aren't appending the results to this list, then clear the list
2812 if (!append)
2813 sc_list.Clear();
2814
2815 // Remember how many sc_list are in the list before we search in case
2816 // we are appending the results to a variable list.
2817 uint32_t original_size = sc_list.GetSize();
2818
Greg Clayton97fbc342011-10-20 22:30:33 +00002819 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002820 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002821 if (m_apple_names_ap.get())
2822 FindFunctions (regex, *m_apple_names_ap, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002823 }
2824 else
2825 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002826 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002827 if (!m_indexed)
2828 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002829
Greg Clayton7f995132011-10-04 22:41:51 +00002830 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002831
Greg Clayton7f995132011-10-04 22:41:51 +00002832 FindFunctions (regex, m_function_fullname_index, sc_list);
2833 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002834
2835 // Return the number of variable that were appended to the list
2836 return sc_list.GetSize() - original_size;
2837}
Jim Ingham318c9f22011-08-26 19:44:13 +00002838
Greg Claytond16e1e52011-07-12 17:06:17 +00002839void
2840SymbolFileDWARF::ReportError (const char *format, ...)
2841{
2842 ::fprintf (stderr,
2843 "error: %s/%s ",
2844 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2845 m_obj_file->GetFileSpec().GetFilename().GetCString());
2846
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002847 if (m_obj_file->GetModule()->GetObjectName())
2848 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2849
Greg Claytond16e1e52011-07-12 17:06:17 +00002850 va_list args;
2851 va_start (args, format);
2852 vfprintf (stderr, format, args);
2853 va_end (args);
2854}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002855
Jim Inghamc1663042011-09-29 22:12:35 +00002856void
2857SymbolFileDWARF::ReportWarning (const char *format, ...)
2858{
2859 ::fprintf (stderr,
2860 "warning: %s/%s ",
2861 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2862 m_obj_file->GetFileSpec().GetFilename().GetCString());
2863
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002864 if (m_obj_file->GetModule()->GetObjectName())
2865 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2866
Jim Inghamc1663042011-09-29 22:12:35 +00002867 va_list args;
2868 va_start (args, format);
2869 vfprintf (stderr, format, args);
2870 va_end (args);
2871}
2872
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002873uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00002874SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002875{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002876 DWARFDebugInfo* info = DebugInfo();
2877 if (info == NULL)
2878 return 0;
2879
Greg Clayton21f2a492011-10-06 00:09:08 +00002880 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2881
2882 if (log)
2883 {
Sean Callananc41e68b2011-10-13 21:08:11 +00002884 log->Printf ("SymbolFileDWARF::FindTypes (file=\"%s/%s\", sc, name=\"%s\", append=%u, max_matches=%u, type_list)",
Greg Clayton21f2a492011-10-06 00:09:08 +00002885 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2886 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2887 name.GetCString(), append, max_matches);
2888 }
2889
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890 // If we aren't appending the results to this list, then clear the list
2891 if (!append)
2892 types.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002893
2894 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2895 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896
Greg Claytond4a2b372011-09-12 23:21:58 +00002897 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002898
Greg Clayton97fbc342011-10-20 22:30:33 +00002899 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002900 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002901 if (m_apple_types_ap.get())
2902 {
2903 const char *name_cstr = name.GetCString();
2904 m_apple_types_ap->FindByName (name_cstr, die_offsets);
2905 }
Greg Clayton7f995132011-10-04 22:41:51 +00002906 }
2907 else
2908 {
2909 if (!m_indexed)
2910 Index ();
2911
2912 m_type_index.Find (name, die_offsets);
2913 }
2914
2915
2916 const size_t num_matches = die_offsets.size();
2917
Greg Claytond4a2b372011-09-12 23:21:58 +00002918 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002919 {
Greg Clayton7f995132011-10-04 22:41:51 +00002920 const uint32_t initial_types_size = types.GetSize();
2921 DWARFCompileUnit* dwarf_cu = NULL;
2922 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002923 DWARFDebugInfo* debug_info = DebugInfo();
2924 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002925 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002926 const dw_offset_t die_offset = die_offsets[i];
2927 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2928
Sean Callanan213fdb82011-10-13 01:49:10 +00002929 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2930 continue;
2931
Greg Claytond4a2b372011-09-12 23:21:58 +00002932 Type *matching_type = ResolveType (dwarf_cu, die);
2933 if (matching_type)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002934 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002935 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton85ae2e12011-10-18 23:36:41 +00002936 types.InsertUnique (TypeSP (matching_type));
2937 if (types.GetSize() >= max_matches)
2938 break;
Greg Clayton73bf5db2011-06-17 01:22:15 +00002939 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002940 }
Greg Clayton7f995132011-10-04 22:41:51 +00002941 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002942 }
Greg Clayton7f995132011-10-04 22:41:51 +00002943 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002944}
2945
2946
Greg Clayton526e5af2010-11-13 03:52:47 +00002947ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002948SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00002949 const ConstString &name,
2950 const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00002951{
Greg Clayton21f2a492011-10-06 00:09:08 +00002952 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2953
2954 if (log)
2955 {
2956 log->Printf ("SymbolFileDWARF::FindNamespace (file=\"%s/%s\", sc, name=\"%s\")",
2957 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2958 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2959 name.GetCString());
2960 }
Sean Callanan213fdb82011-10-13 01:49:10 +00002961
2962 if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
2963 return ClangNamespaceDecl();
Greg Clayton21f2a492011-10-06 00:09:08 +00002964
Greg Clayton526e5af2010-11-13 03:52:47 +00002965 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002966 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002967 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002968 {
Greg Clayton7f995132011-10-04 22:41:51 +00002969 DIEArray die_offsets;
2970
Greg Clayton526e5af2010-11-13 03:52:47 +00002971 // Index if we already haven't to make sure the compile units
2972 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00002973 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002974 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002975 if (m_apple_namespaces_ap.get())
2976 {
2977 const char *name_cstr = name.GetCString();
2978 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
2979 }
Greg Clayton7f995132011-10-04 22:41:51 +00002980 }
2981 else
2982 {
2983 if (!m_indexed)
2984 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002985
Greg Clayton7f995132011-10-04 22:41:51 +00002986 m_namespace_index.Find (name, die_offsets);
2987 }
Greg Claytond4a2b372011-09-12 23:21:58 +00002988
2989 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00002990 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002991 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002992 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00002993 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002994 DWARFDebugInfo* debug_info = DebugInfo();
2995 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00002996 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002997 const dw_offset_t die_offset = die_offsets[i];
2998 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Sean Callanan213fdb82011-10-13 01:49:10 +00002999
3000 if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
3001 continue;
Greg Claytond4a2b372011-09-12 23:21:58 +00003002
3003 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
3004 if (clang_namespace_decl)
3005 {
3006 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
3007 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
3008 }
Greg Clayton526e5af2010-11-13 03:52:47 +00003009 }
3010 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003011 }
Greg Clayton526e5af2010-11-13 03:52:47 +00003012 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00003013}
3014
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003015uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003016SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003017{
3018 // Remember how many sc_list are in the list before we search in case
3019 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003020 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021
3022 const uint32_t num_die_offsets = die_offsets.size();
3023 // Parse all of the types we found from the pubtypes matches
3024 uint32_t i;
3025 uint32_t num_matches = 0;
3026 for (i = 0; i < num_die_offsets; ++i)
3027 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003028 Type *matching_type = ResolveTypeUID (die_offsets[i]);
3029 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003031 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton85ae2e12011-10-18 23:36:41 +00003032 types.InsertUnique (TypeSP (matching_type));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003033 ++num_matches;
3034 if (num_matches >= max_matches)
3035 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036 }
3037 }
3038
3039 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003040 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003041}
3042
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003043
3044size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00003045SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
3046 clang::DeclContext *containing_decl_ctx,
3047 TypeSP& type_sp,
3048 DWARFCompileUnit* dwarf_cu,
3049 const DWARFDebugInfoEntry *parent_die,
3050 bool skip_artificial,
3051 bool &is_static,
3052 TypeList* type_list,
3053 std::vector<clang_type_t>& function_param_types,
3054 std::vector<clang::ParmVarDecl*>& function_param_decls,
3055 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003056{
3057 if (parent_die == NULL)
3058 return 0;
3059
Greg Claytond88d7592010-09-15 08:33:30 +00003060 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3061
Greg Clayton7fedea22010-11-16 02:10:54 +00003062 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003063 const DWARFDebugInfoEntry *die;
3064 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3065 {
3066 dw_tag_t tag = die->Tag();
3067 switch (tag)
3068 {
3069 case DW_TAG_formal_parameter:
3070 {
3071 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003072 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003073 if (num_attributes > 0)
3074 {
3075 const char *name = NULL;
3076 Declaration decl;
3077 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003078 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003079 // one of None, Auto, Register, Extern, Static, PrivateExtern
3080
Sean Callanane2ef6e32010-09-23 03:01:22 +00003081 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003082 uint32_t i;
3083 for (i=0; i<num_attributes; ++i)
3084 {
3085 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3086 DWARFFormValue form_value;
3087 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3088 {
3089 switch (attr)
3090 {
3091 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3092 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3093 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3094 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
3095 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003096 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003097 case DW_AT_location:
3098 // if (form_value.BlockData())
3099 // {
3100 // const DataExtractor& debug_info_data = debug_info();
3101 // uint32_t block_length = form_value.Unsigned();
3102 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
3103 // }
3104 // else
3105 // {
3106 // }
3107 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003108 case DW_AT_const_value:
3109 case DW_AT_default_value:
3110 case DW_AT_description:
3111 case DW_AT_endianity:
3112 case DW_AT_is_optional:
3113 case DW_AT_segment:
3114 case DW_AT_variable_parameter:
3115 default:
3116 case DW_AT_abstract_origin:
3117 case DW_AT_sibling:
3118 break;
3119 }
3120 }
3121 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00003122
Greg Clayton0fffff52010-09-24 05:15:53 +00003123 bool skip = false;
3124 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003125 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003126 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00003127 {
3128 // In order to determine if a C++ member function is
3129 // "const" we have to look at the const-ness of "this"...
3130 // Ugly, but that
3131 if (arg_idx == 0)
3132 {
Greg Claytonf0705c82011-10-22 03:33:13 +00003133 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
Sean Callanan763d72a2011-08-02 22:21:50 +00003134 {
Greg Clayton5113dc82011-08-12 06:47:54 +00003135 // Often times compilers omit the "this" name for the
3136 // specification DIEs, so we can't rely upon the name
3137 // being in the formal parameter DIE...
3138 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00003139 {
Greg Clayton5113dc82011-08-12 06:47:54 +00003140 Type *this_type = ResolveTypeUID (param_type_die_offset);
3141 if (this_type)
3142 {
3143 uint32_t encoding_mask = this_type->GetEncodingMask();
3144 if (encoding_mask & Type::eEncodingIsPointerUID)
3145 {
3146 is_static = false;
3147
3148 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3149 type_quals |= clang::Qualifiers::Const;
3150 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3151 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00003152 }
3153 }
3154 }
3155 }
3156 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003157 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00003158 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003159 else
3160 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003161
Greg Clayton0fffff52010-09-24 05:15:53 +00003162 // HACK: Objective C formal parameters "self" and "_cmd"
3163 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00003164 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
3165 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00003166 {
3167 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
3168 skip = true;
3169 }
3170 }
3171 }
3172
3173 if (!skip)
3174 {
3175 Type *type = ResolveTypeUID(param_type_die_offset);
3176 if (type)
3177 {
Greg Claytonc93237c2010-10-01 20:48:32 +00003178 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00003179
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003180 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00003181 assert(param_var_decl);
3182 function_param_decls.push_back(param_var_decl);
3183 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003184 }
3185 }
Greg Clayton7fedea22010-11-16 02:10:54 +00003186 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003187 }
3188 break;
3189
3190 default:
3191 break;
3192 }
3193 }
Greg Clayton7fedea22010-11-16 02:10:54 +00003194 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003195}
3196
3197size_t
3198SymbolFileDWARF::ParseChildEnumerators
3199(
3200 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003201 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003202 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00003203 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003204 const DWARFDebugInfoEntry *parent_die
3205)
3206{
3207 if (parent_die == NULL)
3208 return 0;
3209
3210 size_t enumerators_added = 0;
3211 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00003212 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3213
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003214 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3215 {
3216 const dw_tag_t tag = die->Tag();
3217 if (tag == DW_TAG_enumerator)
3218 {
3219 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003220 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003221 if (num_child_attributes > 0)
3222 {
3223 const char *name = NULL;
3224 bool got_value = false;
3225 int64_t enum_value = 0;
3226 Declaration decl;
3227
3228 uint32_t i;
3229 for (i=0; i<num_child_attributes; ++i)
3230 {
3231 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3232 DWARFFormValue form_value;
3233 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3234 {
3235 switch (attr)
3236 {
3237 case DW_AT_const_value:
3238 got_value = true;
3239 enum_value = form_value.Unsigned();
3240 break;
3241
3242 case DW_AT_name:
3243 name = form_value.AsCString(&get_debug_str_data());
3244 break;
3245
3246 case DW_AT_description:
3247 default:
3248 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3249 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3250 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3251 case DW_AT_sibling:
3252 break;
3253 }
3254 }
3255 }
3256
3257 if (name && name[0] && got_value)
3258 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003259 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
3260 enumerator_clang_type,
3261 decl,
3262 name,
3263 enum_value,
3264 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 ++enumerators_added;
3266 }
3267 }
3268 }
3269 }
3270 return enumerators_added;
3271}
3272
3273void
3274SymbolFileDWARF::ParseChildArrayInfo
3275(
3276 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003277 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003278 const DWARFDebugInfoEntry *parent_die,
3279 int64_t& first_index,
3280 std::vector<uint64_t>& element_orders,
3281 uint32_t& byte_stride,
3282 uint32_t& bit_stride
3283)
3284{
3285 if (parent_die == NULL)
3286 return;
3287
3288 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00003289 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003290 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3291 {
3292 const dw_tag_t tag = die->Tag();
3293 switch (tag)
3294 {
3295 case DW_TAG_enumerator:
3296 {
3297 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003298 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003299 if (num_child_attributes > 0)
3300 {
3301 const char *name = NULL;
3302 bool got_value = false;
3303 int64_t enum_value = 0;
3304
3305 uint32_t i;
3306 for (i=0; i<num_child_attributes; ++i)
3307 {
3308 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3309 DWARFFormValue form_value;
3310 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3311 {
3312 switch (attr)
3313 {
3314 case DW_AT_const_value:
3315 got_value = true;
3316 enum_value = form_value.Unsigned();
3317 break;
3318
3319 case DW_AT_name:
3320 name = form_value.AsCString(&get_debug_str_data());
3321 break;
3322
3323 case DW_AT_description:
3324 default:
3325 case DW_AT_decl_file:
3326 case DW_AT_decl_line:
3327 case DW_AT_decl_column:
3328 case DW_AT_sibling:
3329 break;
3330 }
3331 }
3332 }
3333 }
3334 }
3335 break;
3336
3337 case DW_TAG_subrange_type:
3338 {
3339 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003340 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003341 if (num_child_attributes > 0)
3342 {
3343 const char *name = NULL;
3344 bool got_value = false;
3345 uint64_t byte_size = 0;
3346 int64_t enum_value = 0;
3347 uint64_t num_elements = 0;
3348 uint64_t lower_bound = 0;
3349 uint64_t upper_bound = 0;
3350 uint32_t i;
3351 for (i=0; i<num_child_attributes; ++i)
3352 {
3353 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3354 DWARFFormValue form_value;
3355 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3356 {
3357 switch (attr)
3358 {
3359 case DW_AT_const_value:
3360 got_value = true;
3361 enum_value = form_value.Unsigned();
3362 break;
3363
3364 case DW_AT_name:
3365 name = form_value.AsCString(&get_debug_str_data());
3366 break;
3367
3368 case DW_AT_count:
3369 num_elements = form_value.Unsigned();
3370 break;
3371
3372 case DW_AT_bit_stride:
3373 bit_stride = form_value.Unsigned();
3374 break;
3375
3376 case DW_AT_byte_stride:
3377 byte_stride = form_value.Unsigned();
3378 break;
3379
3380 case DW_AT_byte_size:
3381 byte_size = form_value.Unsigned();
3382 break;
3383
3384 case DW_AT_lower_bound:
3385 lower_bound = form_value.Unsigned();
3386 break;
3387
3388 case DW_AT_upper_bound:
3389 upper_bound = form_value.Unsigned();
3390 break;
3391
3392 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003393 case DW_AT_abstract_origin:
3394 case DW_AT_accessibility:
3395 case DW_AT_allocated:
3396 case DW_AT_associated:
3397 case DW_AT_data_location:
3398 case DW_AT_declaration:
3399 case DW_AT_description:
3400 case DW_AT_sibling:
3401 case DW_AT_threads_scaled:
3402 case DW_AT_type:
3403 case DW_AT_visibility:
3404 break;
3405 }
3406 }
3407 }
3408
3409 if (upper_bound > lower_bound)
3410 num_elements = upper_bound - lower_bound + 1;
3411
3412 if (num_elements > 0)
3413 element_orders.push_back (num_elements);
3414 }
3415 }
3416 break;
3417 }
3418 }
3419}
3420
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00003422SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003423{
3424 TypeSP type_sp;
3425 if (die != NULL)
3426 {
Greg Clayton96d7d742010-11-10 23:42:09 +00003427 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003428 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003429 if (type_ptr == NULL)
3430 {
Greg Claytonca512b32011-01-14 04:54:56 +00003431 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
3432 assert (lldb_cu);
3433 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00003434 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003435 }
3436 else if (type_ptr != DIE_IS_BEING_PARSED)
3437 {
3438 // Grab the existing type from the master types lists
Greg Clayton85ae2e12011-10-18 23:36:41 +00003439 type_sp = type_ptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003440 }
3441
3442 }
3443 return type_sp;
3444}
3445
3446clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003447SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003448{
3449 if (die_offset != DW_INVALID_OFFSET)
3450 {
3451 DWARFCompileUnitSP cu_sp;
3452 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Greg Claytoncb5860a2011-10-13 23:49:28 +00003453 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003454 }
3455 return NULL;
3456}
3457
Sean Callanan72e49402011-08-05 23:43:37 +00003458clang::DeclContext *
3459SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
3460{
3461 if (die_offset != DW_INVALID_OFFSET)
3462 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003463 DWARFDebugInfo* debug_info = DebugInfo();
3464 if (debug_info)
3465 {
3466 DWARFCompileUnitSP cu_sp;
3467 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
3468 if (die)
3469 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
3470 }
Sean Callanan72e49402011-08-05 23:43:37 +00003471 }
3472 return NULL;
3473}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003474
Greg Clayton96d7d742010-11-10 23:42:09 +00003475clang::NamespaceDecl *
3476SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3477{
Greg Clayton030a2042011-10-14 21:34:45 +00003478 if (die && die->Tag() == DW_TAG_namespace)
Greg Clayton96d7d742010-11-10 23:42:09 +00003479 {
Greg Clayton030a2042011-10-14 21:34:45 +00003480 // See if we already parsed this namespace DIE and associated it with a
3481 // uniqued namespace declaration
3482 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
3483 if (namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00003484 return namespace_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00003485 else
3486 {
3487 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3488 if (namespace_name)
3489 {
3490 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (curr_cu, die, NULL);
3491 namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
3492 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3493 if (log)
3494 {
3495 const char *object_name = m_obj_file->GetModule()->GetObjectName().GetCString();
Greg Clayton81c22f62011-10-19 18:09:39 +00003496 log->Printf ("ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl * %p in %s/%s%s%s%s (original = %p)",
Greg Clayton030a2042011-10-14 21:34:45 +00003497 GetClangASTContext().getASTContext(),
Greg Clayton81c22f62011-10-19 18:09:39 +00003498 MakeUserID(die->GetOffset()),
Greg Clayton030a2042011-10-14 21:34:45 +00003499 namespace_name,
3500 namespace_decl,
3501 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
3502 m_obj_file->GetFileSpec().GetFilename().GetCString(),
3503 object_name ? "(" : "",
3504 object_name ? object_name : "",
3505 object_name ? "(" : "",
3506 namespace_decl->getOriginalNamespace());
3507 }
3508
3509 if (namespace_decl)
3510 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
3511 return namespace_decl;
3512 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003513 }
3514 }
3515 return NULL;
3516}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517
3518clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003519SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3520{
Greg Clayton5cf58b92011-10-05 22:22:08 +00003521 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3522 if (clang_decl_ctx)
3523 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003524 // If this DIE has a specification, or an abstract origin, then trace to those.
3525
3526 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
3527 if (die_offset != DW_INVALID_OFFSET)
3528 return GetClangDeclContextForDIEOffset (sc, die_offset);
3529
3530 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3531 if (die_offset != DW_INVALID_OFFSET)
3532 return GetClangDeclContextForDIEOffset (sc, die_offset);
3533
3534 // This is the DIE we want. Parse it, then query our map.
3535
3536 ParseType(sc, curr_cu, die, NULL);
3537
Greg Clayton5cf58b92011-10-05 22:22:08 +00003538 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3539
3540 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003541}
3542
3543clang::DeclContext *
Greg Claytoncb5860a2011-10-13 23:49:28 +00003544SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545{
Greg Claytonca512b32011-01-14 04:54:56 +00003546 if (m_clang_tu_decl == NULL)
3547 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003548
Greg Clayton2bc22f82011-09-30 03:20:47 +00003549 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
Greg Claytoncb5860a2011-10-13 23:49:28 +00003550
3551 if (decl_ctx_die_copy)
3552 *decl_ctx_die_copy = decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003553
3554 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003555 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00003556
Greg Clayton2bc22f82011-09-30 03:20:47 +00003557 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
3558 if (pos != m_die_to_decl_ctx.end())
3559 return pos->second;
3560
3561 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003562 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003563 case DW_TAG_compile_unit:
3564 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003565
Greg Clayton2bc22f82011-09-30 03:20:47 +00003566 case DW_TAG_namespace:
Greg Clayton030a2042011-10-14 21:34:45 +00003567 return ResolveNamespaceDIE (cu, decl_ctx_die);
Greg Clayton2bc22f82011-09-30 03:20:47 +00003568 break;
3569
3570 case DW_TAG_structure_type:
3571 case DW_TAG_union_type:
3572 case DW_TAG_class_type:
3573 {
3574 Type* type = ResolveType (cu, decl_ctx_die);
3575 if (type)
3576 {
3577 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
3578 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00003579 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003580 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
3581 if (decl_ctx)
3582 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00003583 }
3584 }
Greg Claytonca512b32011-01-14 04:54:56 +00003585 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00003586 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003587
Greg Clayton2bc22f82011-09-30 03:20:47 +00003588 default:
3589 break;
Greg Claytonca512b32011-01-14 04:54:56 +00003590 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003591 }
Greg Clayton7a345282010-11-09 23:46:37 +00003592 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593}
3594
Greg Clayton2bc22f82011-09-30 03:20:47 +00003595
3596const DWARFDebugInfoEntry *
3597SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
3598{
3599 if (cu && die)
3600 {
3601 const DWARFDebugInfoEntry * const decl_die = die;
3602
3603 while (die != NULL)
3604 {
3605 // If this is the original DIE that we are searching for a declaration
3606 // for, then don't look in the cache as we don't want our own decl
3607 // context to be our decl context...
3608 if (decl_die != die)
3609 {
3610 switch (die->Tag())
3611 {
3612 case DW_TAG_compile_unit:
3613 case DW_TAG_namespace:
3614 case DW_TAG_structure_type:
3615 case DW_TAG_union_type:
3616 case DW_TAG_class_type:
3617 return die;
3618
3619 default:
3620 break;
3621 }
3622 }
3623
3624 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
3625 if (die_offset != DW_INVALID_OFFSET)
3626 {
3627 DWARFCompileUnit *spec_cu = cu;
3628 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
3629 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
3630 if (spec_die_decl_ctx_die)
3631 return spec_die_decl_ctx_die;
3632 }
3633
3634 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3635 if (die_offset != DW_INVALID_OFFSET)
3636 {
3637 DWARFCompileUnit *abs_cu = cu;
3638 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
3639 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
3640 if (abs_die_decl_ctx_die)
3641 return abs_die_decl_ctx_die;
3642 }
3643
3644 die = die->GetParent();
3645 }
3646 }
3647 return NULL;
3648}
3649
3650
3651
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003652// This function can be used when a DIE is found that is a forward declaration
3653// DIE and we want to try and find a type that has the complete definition.
3654TypeSP
Greg Clayton7f995132011-10-04 22:41:51 +00003655SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
3656 const DWARFDebugInfoEntry *die,
3657 const ConstString &type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003658{
3659 TypeSP type_sp;
3660
Greg Clayton1a65ae12011-01-25 23:55:37 +00003661 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003662 return type_sp;
3663
Greg Clayton7f995132011-10-04 22:41:51 +00003664 DIEArray die_offsets;
3665
Greg Clayton97fbc342011-10-20 22:30:33 +00003666 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003667 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003668 if (m_apple_types_ap.get())
3669 {
3670 const char *name_cstr = type_name.GetCString();
3671 m_apple_types_ap->FindByName (name_cstr, die_offsets);
3672 }
Greg Clayton7f995132011-10-04 22:41:51 +00003673 }
3674 else
3675 {
3676 if (!m_indexed)
3677 Index ();
3678
3679 m_type_index.Find (type_name, die_offsets);
3680 }
3681
3682
3683 const size_t num_matches = die_offsets.size();
Greg Clayton69974892010-12-03 21:42:06 +00003684
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003685 const dw_tag_t type_tag = die->Tag();
Greg Claytond4a2b372011-09-12 23:21:58 +00003686
3687 DWARFCompileUnit* type_cu = NULL;
3688 const DWARFDebugInfoEntry* type_die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003689 if (num_matches)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003690 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003691 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003692 for (size_t i=0; i<num_matches; ++i)
3693 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003694 const dw_offset_t die_offset = die_offsets[i];
3695 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003696
3697 if (type_die != die && type_die->Tag() == type_tag)
3698 {
3699 // Hold off on comparing parent DIE tags until
3700 // we know what happens with stuff in namespaces
3701 // for gcc and clang...
3702 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3703 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3704 //if (parent_die->Tag() == parent_type_die->Tag())
3705 {
3706 Type *resolved_type = ResolveType (type_cu, type_die, false);
3707 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3708 {
Greg Clayton81c22f62011-10-19 18:09:39 +00003709 DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
3710 MakeUserID(die->GetOffset()),
3711 MakeUserID(curr_cu->GetOffset()),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003712 m_obj_file->GetFileSpec().GetFilename().AsCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00003713 MakeUserID(type_die->GetOffset()),
3714 MakeUserID(type_cu->GetOffset()));
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003715
3716 m_die_to_type[die] = resolved_type;
Greg Clayton85ae2e12011-10-18 23:36:41 +00003717 type_sp = resolved_type;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003718 break;
3719 }
3720 }
3721 }
3722 }
3723 }
3724 return type_sp;
3725}
3726
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003727TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003728SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003729{
3730 TypeSP type_sp;
3731
Greg Clayton1be10fc2010-09-29 01:12:09 +00003732 if (type_is_new_ptr)
3733 *type_is_new_ptr = false;
3734
Sean Callananc7fbf732010-08-06 00:32:49 +00003735 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003736 if (die != NULL)
3737 {
Greg Clayton21f2a492011-10-06 00:09:08 +00003738 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Jim Ingham16746d12011-08-25 23:21:43 +00003739 if (log && dwarf_cu)
3740 {
Jim Ingham318c9f22011-08-26 19:44:13 +00003741 StreamString s;
Jim Inghamd3d25d92011-08-27 01:24:54 +00003742 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham318c9f22011-08-26 19:44:13 +00003743 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3744
Jim Ingham16746d12011-08-25 23:21:43 +00003745 }
3746
Greg Clayton594e5ed2010-09-27 21:07:38 +00003747 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003748 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003749 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003750 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003751 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003752 if (type_is_new_ptr)
3753 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003754
Greg Clayton594e5ed2010-09-27 21:07:38 +00003755 const dw_tag_t tag = die->Tag();
3756
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003757 bool is_forward_declaration = false;
3758 DWARFDebugInfoEntry::Attributes attributes;
3759 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003760 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003761 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3762 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003763 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003764 Declaration decl;
3765
Greg Clayton4957bf62010-09-30 21:49:03 +00003766 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003767 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003768
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003769 dw_attr_t attr;
3770
3771 switch (tag)
3772 {
3773 case DW_TAG_base_type:
3774 case DW_TAG_pointer_type:
3775 case DW_TAG_reference_type:
3776 case DW_TAG_typedef:
3777 case DW_TAG_const_type:
3778 case DW_TAG_restrict_type:
3779 case DW_TAG_volatile_type:
3780 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003781 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003782 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003783
Greg Claytond88d7592010-09-15 08:33:30 +00003784 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003786 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3787
3788 if (num_attributes > 0)
3789 {
3790 uint32_t i;
3791 for (i=0; i<num_attributes; ++i)
3792 {
3793 attr = attributes.AttributeAtIndex(i);
3794 DWARFFormValue form_value;
3795 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3796 {
3797 switch (attr)
3798 {
3799 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3800 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3801 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3802 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003803
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003804 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003805 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3806 // include the "&"...
3807 if (tag == DW_TAG_reference_type)
3808 {
3809 if (strchr (type_name_cstr, '&') == NULL)
3810 type_name_cstr = NULL;
3811 }
3812 if (type_name_cstr)
3813 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003814 break;
Greg Clayton36909642011-03-15 04:38:20 +00003815 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003816 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3817 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3818 default:
3819 case DW_AT_sibling:
3820 break;
3821 }
3822 }
3823 }
3824 }
3825
Greg Clayton81c22f62011-10-19 18:09:39 +00003826 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
Greg Claytonc93237c2010-10-01 20:48:32 +00003827
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003828 switch (tag)
3829 {
3830 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003831 break;
3832
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003833 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003834 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003835 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3836 encoding,
3837 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003838 break;
3839
Greg Clayton526e5af2010-11-13 03:52:47 +00003840 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3841 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3842 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3843 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3844 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3845 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003846 }
3847
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003848 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3849 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3850 {
3851 static ConstString g_objc_type_name_id("id");
3852 static ConstString g_objc_type_name_Class("Class");
3853 static ConstString g_objc_type_name_selector("SEL");
3854
Greg Clayton24739922010-10-13 03:15:28 +00003855 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003856 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003857 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003858 resolve_state = Type::eResolveStateFull;
3859
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003860 }
Greg Clayton24739922010-10-13 03:15:28 +00003861 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003862 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003863 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003864 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003865 }
Greg Clayton24739922010-10-13 03:15:28 +00003866 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003867 {
Sean Callananf6c73082010-12-06 23:53:20 +00003868 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003869 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003870 }
3871 }
3872
Greg Clayton81c22f62011-10-19 18:09:39 +00003873 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003874 this,
3875 type_name_const_str,
3876 byte_size,
3877 NULL,
3878 encoding_uid,
3879 encoding_data_type,
3880 &decl,
3881 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003882 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003883
Greg Clayton594e5ed2010-09-27 21:07:38 +00003884 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003885
3886// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3887// if (encoding_type != NULL)
3888// {
3889// if (encoding_type != DIE_IS_BEING_PARSED)
3890// type_sp->SetEncodingType(encoding_type);
3891// else
3892// m_indirect_fixups.push_back(type_sp.get());
3893// }
3894 }
3895 break;
3896
3897 case DW_TAG_structure_type:
3898 case DW_TAG_union_type:
3899 case DW_TAG_class_type:
3900 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003901 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003902 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003903
Greg Clayton9e409562010-07-28 02:04:09 +00003904 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003905 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003906 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003907 if (num_attributes > 0)
3908 {
3909 uint32_t i;
3910 for (i=0; i<num_attributes; ++i)
3911 {
3912 attr = attributes.AttributeAtIndex(i);
3913 DWARFFormValue form_value;
3914 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3915 {
3916 switch (attr)
3917 {
Greg Clayton9e409562010-07-28 02:04:09 +00003918 case DW_AT_decl_file:
3919 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3920 break;
3921
3922 case DW_AT_decl_line:
3923 decl.SetLine(form_value.Unsigned());
3924 break;
3925
3926 case DW_AT_decl_column:
3927 decl.SetColumn(form_value.Unsigned());
3928 break;
3929
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003930 case DW_AT_name:
3931 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003932 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003933 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003934
3935 case DW_AT_byte_size:
3936 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003937 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003938 break;
3939
3940 case DW_AT_accessibility:
3941 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3942 break;
3943
3944 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003945 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003946 break;
3947
3948 case DW_AT_APPLE_runtime_class:
3949 class_language = (LanguageType)form_value.Signed();
3950 break;
3951
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003952 case DW_AT_allocated:
3953 case DW_AT_associated:
3954 case DW_AT_data_location:
3955 case DW_AT_description:
3956 case DW_AT_start_scope:
3957 case DW_AT_visibility:
3958 default:
3959 case DW_AT_sibling:
3960 break;
3961 }
3962 }
3963 }
3964 }
3965
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003966 UniqueDWARFASTType unique_ast_entry;
3967 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003968 {
Greg Claytone576ab22011-02-15 00:19:15 +00003969 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003970 this,
3971 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003972 die,
3973 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003974 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003975 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003976 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003977 // We have already parsed this type or from another
3978 // compile unit. GCC loves to use the "one definition
3979 // rule" which can result in multiple definitions
3980 // of the same class over and over in each compile
3981 // unit.
3982 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003983 if (type_sp)
3984 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003985 m_die_to_type[die] = type_sp.get();
3986 return type_sp;
3987 }
3988 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003989 }
3990
Greg Clayton81c22f62011-10-19 18:09:39 +00003991 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003992
3993 int tag_decl_kind = -1;
3994 AccessType default_accessibility = eAccessNone;
3995 if (tag == DW_TAG_structure_type)
3996 {
3997 tag_decl_kind = clang::TTK_Struct;
3998 default_accessibility = eAccessPublic;
3999 }
4000 else if (tag == DW_TAG_union_type)
4001 {
4002 tag_decl_kind = clang::TTK_Union;
4003 default_accessibility = eAccessPublic;
4004 }
4005 else if (tag == DW_TAG_class_type)
4006 {
4007 tag_decl_kind = clang::TTK_Class;
4008 default_accessibility = eAccessPrivate;
4009 }
4010
4011
4012 if (is_forward_declaration)
4013 {
4014 // We have a forward declaration to a type and we need
4015 // to try and find a full declaration. We look in the
4016 // current type index just in case we have a forward
4017 // declaration followed by an actual declarations in the
4018 // DWARF. If this fails, we need to look elsewhere...
4019
4020 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
4021
4022 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00004023 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004024 // We weren't able to find a full declaration in
4025 // this DWARF, see if we have a declaration anywhere
4026 // else...
4027 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00004028 }
4029
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004030 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00004031 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004032 // We found a real definition for this type elsewhere
4033 // so lets use it and cache the fact that we found
4034 // a complete type for this die
4035 m_die_to_type[die] = type_sp.get();
4036 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00004037 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004038 }
4039 assert (tag_decl_kind != -1);
4040 bool clang_type_was_created = false;
4041 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
4042 if (clang_type == NULL)
4043 {
Greg Claytonf0705c82011-10-22 03:33:13 +00004044 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
4045 if (type_name_cstr && strchr (type_name_cstr, '<'))
4046 {
4047 ClangASTContext::TemplateParameterInfos template_param_infos;
4048 if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
4049 {
4050 clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
4051 type_name_cstr,
4052 tag_decl_kind,
4053 template_param_infos);
4054
4055 clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
4056 class_template_decl,
4057 tag_decl_kind,
4058 template_param_infos);
4059 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
4060 clang_type_was_created = true;
4061 }
4062 }
4063
4064 if (!clang_type_was_created)
4065 {
4066 clang_type_was_created = true;
4067 clang_type = ast.CreateRecordType (type_name_cstr,
4068 tag_decl_kind,
4069 decl_ctx,
4070 class_language);
4071 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004072 }
4073
4074 // Store a forward declaration to this class type in case any
4075 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00004076 // types for function prototypes.
4077 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton81c22f62011-10-19 18:09:39 +00004078 type_sp.reset (new Type (MakeUserID(die->GetOffset()),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004079 this,
4080 type_name_const_str,
4081 byte_size,
4082 NULL,
4083 LLDB_INVALID_UID,
4084 Type::eEncodingIsUID,
4085 &decl,
4086 clang_type,
4087 Type::eResolveStateForward));
4088
4089
4090 // Add our type to the unique type map so we don't
4091 // end up creating many copies of the same type over
4092 // and over in the ASTContext for our module
4093 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00004094 unique_ast_entry.m_symfile = this;
4095 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004096 unique_ast_entry.m_die = die;
4097 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00004098 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
4099 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004100
4101 if (die->HasChildren() == false && is_forward_declaration == false)
4102 {
4103 // No children for this struct/union/class, lets finish it
4104 ast.StartTagDeclarationDefinition (clang_type);
4105 ast.CompleteTagDeclarationDefinition (clang_type);
4106 }
4107 else if (clang_type_was_created)
4108 {
4109 // Leave this as a forward declaration until we need
4110 // to know the details of the type. lldb_private::Type
4111 // will automatically call the SymbolFile virtual function
4112 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
4113 // When the definition needs to be defined.
4114 m_forward_decl_die_to_clang_type[die] = clang_type;
4115 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
4116 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00004117 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004118 }
4119 break;
4120
4121 case DW_TAG_enumeration_type:
4122 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004123 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004124 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004125
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004126 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004127
Greg Claytond88d7592010-09-15 08:33:30 +00004128 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004129 if (num_attributes > 0)
4130 {
4131 uint32_t i;
4132
4133 for (i=0; i<num_attributes; ++i)
4134 {
4135 attr = attributes.AttributeAtIndex(i);
4136 DWARFFormValue form_value;
4137 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4138 {
4139 switch (attr)
4140 {
Greg Clayton7a345282010-11-09 23:46:37 +00004141 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4142 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4143 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004144 case DW_AT_name:
4145 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004146 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004147 break;
Greg Clayton7a345282010-11-09 23:46:37 +00004148 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004149 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00004150 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
4151 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004152 case DW_AT_allocated:
4153 case DW_AT_associated:
4154 case DW_AT_bit_stride:
4155 case DW_AT_byte_stride:
4156 case DW_AT_data_location:
4157 case DW_AT_description:
4158 case DW_AT_start_scope:
4159 case DW_AT_visibility:
4160 case DW_AT_specification:
4161 case DW_AT_abstract_origin:
4162 case DW_AT_sibling:
4163 break;
4164 }
4165 }
4166 }
4167
Greg Clayton81c22f62011-10-19 18:09:39 +00004168 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004169
Greg Clayton1be10fc2010-09-29 01:12:09 +00004170 clang_type_t enumerator_clang_type = NULL;
4171 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
4172 if (clang_type == NULL)
4173 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004174 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
4175 DW_ATE_signed,
4176 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00004177 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Claytoncb5860a2011-10-13 23:49:28 +00004178 GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
Greg Claytonca512b32011-01-14 04:54:56 +00004179 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004180 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00004181 }
4182 else
4183 {
4184 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
4185 assert (enumerator_clang_type != NULL);
4186 }
4187
Greg Claytona2721472011-06-25 00:44:06 +00004188 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
4189
Greg Clayton81c22f62011-10-19 18:09:39 +00004190 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004191 this,
4192 type_name_const_str,
4193 byte_size,
4194 NULL,
4195 encoding_uid,
4196 Type::eEncodingIsUID,
4197 &decl,
4198 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004199 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004200
Greg Clayton6beaaa62011-01-17 03:46:26 +00004201 ast.StartTagDeclarationDefinition (clang_type);
4202 if (die->HasChildren())
4203 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00004204 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
4205 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004206 }
4207 ast.CompleteTagDeclarationDefinition (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004208 }
4209 }
4210 break;
4211
Jim Inghamb0be4422010-08-12 01:20:14 +00004212 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004213 case DW_TAG_subprogram:
4214 case DW_TAG_subroutine_type:
4215 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004216 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004217 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218
4219 const char *mangled = NULL;
4220 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00004221 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004222 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00004223 bool is_static = false;
4224 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00004225 bool is_explicit = false;
Greg Clayton72da3972011-08-16 18:40:23 +00004226 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
4227 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00004228
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004229 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00004230 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004231
4232
Greg Claytond88d7592010-09-15 08:33:30 +00004233 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004234 if (num_attributes > 0)
4235 {
4236 uint32_t i;
4237 for (i=0; i<num_attributes; ++i)
4238 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00004239 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004240 DWARFFormValue form_value;
4241 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4242 {
4243 switch (attr)
4244 {
4245 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4246 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4247 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4248 case DW_AT_name:
4249 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004250 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004251 break;
4252
4253 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4254 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004255 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004256 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00004257 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
4258 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00004259 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
4260
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004261 case DW_AT_external:
4262 if (form_value.Unsigned())
4263 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00004264 if (storage == clang::SC_None)
4265 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004266 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00004267 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004268 }
4269 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270
Greg Clayton72da3972011-08-16 18:40:23 +00004271 case DW_AT_specification:
4272 specification_die_offset = form_value.Reference(dwarf_cu);
4273 break;
4274
4275 case DW_AT_abstract_origin:
4276 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
4277 break;
4278
4279
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004280 case DW_AT_allocated:
4281 case DW_AT_associated:
4282 case DW_AT_address_class:
4283 case DW_AT_artificial:
4284 case DW_AT_calling_convention:
4285 case DW_AT_data_location:
4286 case DW_AT_elemental:
4287 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004288 case DW_AT_frame_base:
4289 case DW_AT_high_pc:
4290 case DW_AT_low_pc:
4291 case DW_AT_object_pointer:
4292 case DW_AT_prototyped:
4293 case DW_AT_pure:
4294 case DW_AT_ranges:
4295 case DW_AT_recursive:
4296 case DW_AT_return_addr:
4297 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004298 case DW_AT_start_scope:
4299 case DW_AT_static_link:
4300 case DW_AT_trampoline:
4301 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004302 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004303 case DW_AT_description:
4304 case DW_AT_sibling:
4305 break;
4306 }
4307 }
4308 }
Greg Clayton24739922010-10-13 03:15:28 +00004309 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004310
Greg Clayton81c22f62011-10-19 18:09:39 +00004311 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004312
Greg Clayton24739922010-10-13 03:15:28 +00004313 clang_type_t return_clang_type = NULL;
4314 Type *func_type = NULL;
4315
4316 if (type_die_offset != DW_INVALID_OFFSET)
4317 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00004318
Greg Clayton24739922010-10-13 03:15:28 +00004319 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00004320 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00004321 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004322 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004323
Greg Claytonf51de672010-10-01 02:31:07 +00004324
Greg Clayton24739922010-10-13 03:15:28 +00004325 std::vector<clang_type_t> function_param_types;
4326 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004327
Greg Clayton24739922010-10-13 03:15:28 +00004328 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00004329
Greg Claytoncb5860a2011-10-13 23:49:28 +00004330 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
4331 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton5113dc82011-08-12 06:47:54 +00004332 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
4333
Greg Claytonf0705c82011-10-22 03:33:13 +00004334 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
Greg Clayton5113dc82011-08-12 06:47:54 +00004335 // Start off static. This will be set to false in ParseChildParameters(...)
4336 // if we find a "this" paramters as the first parameter
4337 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00004338 is_static = true;
4339
Greg Clayton24739922010-10-13 03:15:28 +00004340 if (die->HasChildren())
4341 {
Greg Clayton0fffff52010-09-24 05:15:53 +00004342 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004343 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00004344 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004345 type_sp,
4346 dwarf_cu,
4347 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00004348 skip_artificial,
4349 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004350 type_list,
4351 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00004352 function_param_decls,
4353 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00004354 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004355
Greg Clayton24739922010-10-13 03:15:28 +00004356 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004357 clang_type = ast.CreateFunctionType (return_clang_type,
4358 &function_param_types[0],
4359 function_param_types.size(),
4360 is_variadic,
4361 type_quals);
4362
Greg Clayton24739922010-10-13 03:15:28 +00004363 if (type_name_cstr)
4364 {
4365 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00004366 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004367 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +00004368 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr))
Greg Clayton0fffff52010-09-24 05:15:53 +00004369 {
Greg Clayton24739922010-10-13 03:15:28 +00004370 // We need to find the DW_TAG_class_type or
4371 // DW_TAG_struct_type by name so we can add this
4372 // as a member function of the class.
4373 const char *class_name_start = type_name_cstr + 2;
4374 const char *class_name_end = ::strchr (class_name_start, ' ');
4375 SymbolContext empty_sc;
4376 clang_type_t class_opaque_type = NULL;
4377 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00004378 {
Greg Clayton24739922010-10-13 03:15:28 +00004379 ConstString class_name (class_name_start, class_name_end - class_name_start);
4380 TypeList types;
Sean Callanan213fdb82011-10-13 01:49:10 +00004381 const uint32_t match_count = FindTypes (empty_sc, class_name, NULL, true, UINT32_MAX, types);
Greg Clayton24739922010-10-13 03:15:28 +00004382 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00004383 {
Greg Clayton24739922010-10-13 03:15:28 +00004384 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00004385 {
Greg Clayton24739922010-10-13 03:15:28 +00004386 Type *type = types.GetTypeAtIndex (i).get();
4387 clang_type_t type_clang_forward_type = type->GetClangForwardType();
4388 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00004389 {
Greg Clayton24739922010-10-13 03:15:28 +00004390 class_opaque_type = type_clang_forward_type;
4391 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00004392 }
4393 }
4394 }
Greg Clayton24739922010-10-13 03:15:28 +00004395 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004396
Greg Clayton24739922010-10-13 03:15:28 +00004397 if (class_opaque_type)
4398 {
4399 // If accessibility isn't set to anything valid, assume public for
4400 // now...
4401 if (accessibility == eAccessNone)
4402 accessibility = eAccessPublic;
4403
4404 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004405 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
4406 type_name_cstr,
4407 clang_type,
4408 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004409 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00004410 type_handled = objc_method_decl != NULL;
4411 }
4412 }
Greg Clayton5113dc82011-08-12 06:47:54 +00004413 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00004414 {
4415 // Look at the parent of this DIE and see if is is
4416 // a class or struct and see if this is actually a
4417 // C++ method
Greg Claytoncb5860a2011-10-13 23:49:28 +00004418 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
Greg Clayton24739922010-10-13 03:15:28 +00004419 if (class_type)
4420 {
Greg Clayton72da3972011-08-16 18:40:23 +00004421 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00004422 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004423 // We have a specification which we are going to base our function
4424 // prototype off of, so we need this type to be completed so that the
4425 // m_die_to_decl_ctx for the method in the specification has a valid
4426 // clang decl context.
4427 class_type->GetClangFullType();
Greg Clayton72da3972011-08-16 18:40:23 +00004428 // If we have a specification, then the function type should have been
4429 // made with the specification and not with this die.
4430 DWARFCompileUnitSP spec_cu_sp;
4431 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004432 clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die);
4433 if (spec_clang_decl_ctx)
4434 {
4435 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
4436 }
4437 else
Jim Inghamc1663042011-09-29 22:12:35 +00004438 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004439 ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n",
4440 MakeUserID(die->GetOffset()),
Greg Clayton5cf58b92011-10-05 22:22:08 +00004441 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004442 }
Greg Clayton72da3972011-08-16 18:40:23 +00004443 type_handled = true;
4444 }
4445 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
4446 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004447 // We have a specification which we are going to base our function
4448 // prototype off of, so we need this type to be completed so that the
4449 // m_die_to_decl_ctx for the method in the abstract origin has a valid
4450 // clang decl context.
4451 class_type->GetClangFullType();
4452
Greg Clayton72da3972011-08-16 18:40:23 +00004453 DWARFCompileUnitSP abs_cu_sp;
4454 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004455 clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die);
4456 if (abs_clang_decl_ctx)
4457 {
4458 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
4459 }
4460 else
Jim Inghamc1663042011-09-29 22:12:35 +00004461 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004462 ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
4463 MakeUserID(die->GetOffset()),
Greg Clayton5cf58b92011-10-05 22:22:08 +00004464 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004465 }
Greg Clayton72da3972011-08-16 18:40:23 +00004466 type_handled = true;
4467 }
4468 else
4469 {
4470 clang_type_t class_opaque_type = class_type->GetClangForwardType();
4471 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton931180e2011-01-27 06:44:37 +00004472 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004473 if (ClangASTContext::IsBeingDefined (class_opaque_type))
Greg Clayton72da3972011-08-16 18:40:23 +00004474 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004475 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
4476 // in the DWARF for C++ methods... Default to public for now...
4477 if (accessibility == eAccessNone)
4478 accessibility = eAccessPublic;
4479
4480 if (!is_static && !die->HasChildren())
4481 {
4482 // We have a C++ member function with no children (this pointer!)
4483 // and clang will get mad if we try and make a function that isn't
4484 // well formed in the DWARF, so we will just skip it...
4485 type_handled = true;
4486 }
4487 else
4488 {
4489 clang::CXXMethodDecl *cxx_method_decl;
4490 // REMOVE THE CRASH DESCRIPTION BELOW
Greg Clayton81c22f62011-10-19 18:09:39 +00004491 Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s",
Greg Clayton20568dd2011-10-13 23:13:20 +00004492 type_name_cstr,
4493 class_type->GetName().GetCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00004494 MakeUserID(die->GetOffset()),
Greg Clayton20568dd2011-10-13 23:13:20 +00004495 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
4496 m_obj_file->GetFileSpec().GetFilename().GetCString());
4497
4498 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
4499 type_name_cstr,
4500 clang_type,
4501 accessibility,
4502 is_virtual,
4503 is_static,
4504 is_inline,
4505 is_explicit);
4506 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
4507
4508 type_handled = cxx_method_decl != NULL;
4509 }
Greg Clayton72da3972011-08-16 18:40:23 +00004510 }
4511 else
4512 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004513 // We were asked to parse the type for a method in a class, yet the
4514 // class hasn't been asked to complete itself through the
4515 // clang::ExternalASTSource protocol, so we need to just have the
4516 // class complete itself and do things the right way, then our
4517 // DIE should then have an entry in the m_die_to_type map. First
4518 // we need to modify the m_die_to_type so it doesn't think we are
4519 // trying to parse this DIE anymore...
4520 m_die_to_type[die] = NULL;
4521
4522 // Now we get the full type to force our class type to complete itself
4523 // using the clang::ExternalASTSource protocol which will parse all
4524 // base classes and all methods (including the method for this DIE).
4525 class_type->GetClangFullType();
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004526
Greg Clayton20568dd2011-10-13 23:13:20 +00004527 // The type for this DIE should have been filled in the function call above
4528 type_ptr = m_die_to_type[die];
4529 if (type_ptr)
4530 {
Greg Clayton85ae2e12011-10-18 23:36:41 +00004531 type_sp = type_ptr;
Greg Clayton20568dd2011-10-13 23:13:20 +00004532 break;
4533 }
Greg Clayton72da3972011-08-16 18:40:23 +00004534 }
Greg Clayton931180e2011-01-27 06:44:37 +00004535 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004536 }
4537 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004538 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004539 }
Greg Clayton24739922010-10-13 03:15:28 +00004540
4541 if (!type_handled)
4542 {
4543 // We just have a function that isn't part of a class
Greg Clayton147e1fa2011-10-14 22:47:18 +00004544 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx,
4545 type_name_cstr,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004546 clang_type,
4547 storage,
4548 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00004549
4550 // Add the decl to our DIE to decl context map
4551 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00004552 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00004553 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004554 ast.SetFunctionParameters (function_decl,
4555 &function_param_decls.front(),
4556 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00004557 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004558 }
Greg Clayton81c22f62011-10-19 18:09:39 +00004559 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004560 this,
4561 type_name_const_str,
4562 0,
4563 NULL,
4564 LLDB_INVALID_UID,
4565 Type::eEncodingIsUID,
4566 &decl,
4567 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004568 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00004569 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004570 }
4571 break;
4572
4573 case DW_TAG_array_type:
4574 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004575 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004576 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004577
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004578 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004579 int64_t first_index = 0;
4580 uint32_t byte_stride = 0;
4581 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00004582 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004583
4584 if (num_attributes > 0)
4585 {
4586 uint32_t i;
4587 for (i=0; i<num_attributes; ++i)
4588 {
4589 attr = attributes.AttributeAtIndex(i);
4590 DWARFFormValue form_value;
4591 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4592 {
4593 switch (attr)
4594 {
4595 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4596 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4597 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4598 case DW_AT_name:
4599 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004600 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004601 break;
4602
4603 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004604 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004605 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
4606 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004607 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004608 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004609 case DW_AT_allocated:
4610 case DW_AT_associated:
4611 case DW_AT_data_location:
4612 case DW_AT_description:
4613 case DW_AT_ordering:
4614 case DW_AT_start_scope:
4615 case DW_AT_visibility:
4616 case DW_AT_specification:
4617 case DW_AT_abstract_origin:
4618 case DW_AT_sibling:
4619 break;
4620 }
4621 }
4622 }
4623
Greg Clayton81c22f62011-10-19 18:09:39 +00004624 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004625
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004626 Type *element_type = ResolveTypeUID(type_die_offset);
4627
4628 if (element_type)
4629 {
4630 std::vector<uint64_t> element_orders;
4631 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00004632 // We have an array that claims to have no members, lets give it at least one member...
4633 if (element_orders.empty())
4634 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004635 if (byte_stride == 0 && bit_stride == 0)
4636 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00004637 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004638 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
4639 uint64_t num_elements = 0;
4640 std::vector<uint64_t>::const_reverse_iterator pos;
4641 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
4642 for (pos = element_orders.rbegin(); pos != end; ++pos)
4643 {
4644 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004645 clang_type = ast.CreateArrayType (array_element_type,
4646 num_elements,
4647 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004648 array_element_type = clang_type;
4649 array_element_bit_stride = array_element_bit_stride * num_elements;
4650 }
4651 ConstString empty_name;
Greg Clayton81c22f62011-10-19 18:09:39 +00004652 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004653 this,
4654 empty_name,
4655 array_element_bit_stride / 8,
4656 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00004657 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004658 Type::eEncodingIsUID,
4659 &decl,
4660 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004661 Type::eResolveStateFull));
4662 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004663 }
4664 }
4665 }
4666 break;
4667
Greg Clayton9b81a312010-06-12 01:20:30 +00004668 case DW_TAG_ptr_to_member_type:
4669 {
4670 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
4671 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
4672
Greg Claytond88d7592010-09-15 08:33:30 +00004673 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00004674
4675 if (num_attributes > 0) {
4676 uint32_t i;
4677 for (i=0; i<num_attributes; ++i)
4678 {
4679 attr = attributes.AttributeAtIndex(i);
4680 DWARFFormValue form_value;
4681 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4682 {
4683 switch (attr)
4684 {
4685 case DW_AT_type:
4686 type_die_offset = form_value.Reference(dwarf_cu); break;
4687 case DW_AT_containing_type:
4688 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4689 }
4690 }
4691 }
4692
4693 Type *pointee_type = ResolveTypeUID(type_die_offset);
4694 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4695
Greg Clayton526e5af2010-11-13 03:52:47 +00004696 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4697 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00004698
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004699 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4700 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00004701
Greg Clayton526e5af2010-11-13 03:52:47 +00004702 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4703 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00004704
Greg Clayton81c22f62011-10-19 18:09:39 +00004705 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004706 this,
4707 type_name_const_str,
4708 byte_size,
4709 NULL,
4710 LLDB_INVALID_UID,
4711 Type::eEncodingIsUID,
4712 NULL,
4713 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004714 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00004715 }
4716
4717 break;
4718 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004719 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00004720 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004721 break;
4722 }
4723
4724 if (type_sp.get())
4725 {
4726 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4727 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4728
4729 SymbolContextScope * symbol_context_scope = NULL;
4730 if (sc_parent_tag == DW_TAG_compile_unit)
4731 {
4732 symbol_context_scope = sc.comp_unit;
4733 }
4734 else if (sc.function != NULL)
4735 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004736 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004737 if (symbol_context_scope == NULL)
4738 symbol_context_scope = sc.function;
4739 }
4740
4741 if (symbol_context_scope != NULL)
4742 {
4743 type_sp->SetSymbolContextScope(symbol_context_scope);
4744 }
4745
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004746 // We are ready to put this type into the uniqued list up at the module level
4747 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00004748
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004749 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004750 }
4751 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00004752 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004753 {
Greg Clayton85ae2e12011-10-18 23:36:41 +00004754 type_sp = type_ptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004755 }
4756 }
4757 return type_sp;
4758}
4759
4760size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004761SymbolFileDWARF::ParseTypes
4762(
4763 const SymbolContext& sc,
4764 DWARFCompileUnit* dwarf_cu,
4765 const DWARFDebugInfoEntry *die,
4766 bool parse_siblings,
4767 bool parse_children
4768)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004769{
4770 size_t types_added = 0;
4771 while (die != NULL)
4772 {
4773 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00004774 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004775 {
4776 if (type_is_new)
4777 ++types_added;
4778 }
4779
4780 if (parse_children && die->HasChildren())
4781 {
4782 if (die->Tag() == DW_TAG_subprogram)
4783 {
4784 SymbolContext child_sc(sc);
Greg Clayton81c22f62011-10-19 18:09:39 +00004785 child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004786 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4787 }
4788 else
4789 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4790 }
4791
4792 if (parse_siblings)
4793 die = die->GetSibling();
4794 else
4795 die = NULL;
4796 }
4797 return types_added;
4798}
4799
4800
4801size_t
4802SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4803{
4804 assert(sc.comp_unit && sc.function);
4805 size_t functions_added = 0;
4806 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4807 if (dwarf_cu)
4808 {
4809 dw_offset_t function_die_offset = sc.function->GetID();
4810 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4811 if (function_die)
4812 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00004813 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004814 }
4815 }
4816
4817 return functions_added;
4818}
4819
4820
4821size_t
4822SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4823{
4824 // At least a compile unit must be valid
4825 assert(sc.comp_unit);
4826 size_t types_added = 0;
4827 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4828 if (dwarf_cu)
4829 {
4830 if (sc.function)
4831 {
4832 dw_offset_t function_die_offset = sc.function->GetID();
4833 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4834 if (func_die && func_die->HasChildren())
4835 {
4836 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4837 }
4838 }
4839 else
4840 {
4841 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4842 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4843 {
4844 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4845 }
4846 }
4847 }
4848
4849 return types_added;
4850}
4851
4852size_t
4853SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4854{
4855 if (sc.comp_unit != NULL)
4856 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004857 DWARFDebugInfo* info = DebugInfo();
4858 if (info == NULL)
4859 return 0;
4860
4861 uint32_t cu_idx = UINT32_MAX;
4862 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004863
4864 if (dwarf_cu == NULL)
4865 return 0;
4866
4867 if (sc.function)
4868 {
4869 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004870
4871 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4872 assert (func_lo_pc != DW_INVALID_ADDRESS);
4873
Greg Claytonc662ec82011-06-17 22:10:16 +00004874 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4875
4876 // Let all blocks know they have parse all their variables
4877 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4878
4879 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004880 }
4881 else if (sc.comp_unit)
4882 {
4883 uint32_t vars_added = 0;
4884 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4885
4886 if (variables.get() == NULL)
4887 {
4888 variables.reset(new VariableList());
4889 sc.comp_unit->SetVariableList(variables);
4890
Greg Claytond4a2b372011-09-12 23:21:58 +00004891 DWARFCompileUnit* match_dwarf_cu = NULL;
4892 const DWARFDebugInfoEntry* die = NULL;
4893 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00004894 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004895 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004896 if (m_apple_names_ap.get())
4897 m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
4898 dwarf_cu->GetNextCompileUnitOffset(),
4899 die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00004900 }
4901 else
4902 {
4903 // Index if we already haven't to make sure the compile units
4904 // get indexed and make their global DIE index list
4905 if (!m_indexed)
4906 Index ();
4907
4908 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
4909 dwarf_cu->GetNextCompileUnitOffset(),
4910 die_offsets);
4911 }
4912
4913 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004914 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004915 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004916 DWARFDebugInfo* debug_info = DebugInfo();
4917 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004918 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004919 const dw_offset_t die_offset = die_offsets[i];
4920 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
4921 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
4922 if (var_sp)
4923 {
4924 variables->AddVariableIfUnique (var_sp);
4925 ++vars_added;
4926 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004927 }
4928 }
4929 }
4930 return vars_added;
4931 }
4932 }
4933 return 0;
4934}
4935
4936
4937VariableSP
4938SymbolFileDWARF::ParseVariableDIE
4939(
4940 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004941 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004942 const DWARFDebugInfoEntry *die,
4943 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004944)
4945{
4946
Greg Clayton83c5cd92010-11-14 22:13:40 +00004947 VariableSP var_sp (m_die_to_variable_sp[die]);
4948 if (var_sp)
4949 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004950
4951 const dw_tag_t tag = die->Tag();
Greg Clayton7f995132011-10-04 22:41:51 +00004952
4953 if ((tag == DW_TAG_variable) ||
4954 (tag == DW_TAG_constant) ||
4955 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004956 {
Greg Clayton7f995132011-10-04 22:41:51 +00004957 DWARFDebugInfoEntry::Attributes attributes;
4958 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4959 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004960 {
Greg Clayton7f995132011-10-04 22:41:51 +00004961 const char *name = NULL;
4962 const char *mangled = NULL;
4963 Declaration decl;
4964 uint32_t i;
4965 Type *var_type = NULL;
4966 DWARFExpression location;
4967 bool is_external = false;
4968 bool is_artificial = false;
4969 bool location_is_const_value_data = false;
4970 AccessType accessibility = eAccessNone;
4971
4972 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004973 {
Greg Clayton7f995132011-10-04 22:41:51 +00004974 dw_attr_t attr = attributes.AttributeAtIndex(i);
4975 DWARFFormValue form_value;
4976 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004977 {
Greg Clayton7f995132011-10-04 22:41:51 +00004978 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004979 {
Greg Clayton7f995132011-10-04 22:41:51 +00004980 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4981 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4982 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4983 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
4984 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4985 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
4986 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
4987 case DW_AT_const_value:
4988 location_is_const_value_data = true;
4989 // Fall through...
4990 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004991 {
Greg Clayton7f995132011-10-04 22:41:51 +00004992 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004993 {
Greg Clayton7f995132011-10-04 22:41:51 +00004994 const DataExtractor& debug_info_data = get_debug_info_data();
4995
4996 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4997 uint32_t block_length = form_value.Unsigned();
4998 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
4999 }
5000 else
5001 {
5002 const DataExtractor& debug_loc_data = get_debug_loc_data();
5003 const dw_offset_t debug_loc_offset = form_value.Unsigned();
5004
5005 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
5006 if (loc_list_length > 0)
5007 {
5008 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
5009 assert (func_low_pc != LLDB_INVALID_ADDRESS);
5010 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
5011 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005012 }
5013 }
Greg Clayton7f995132011-10-04 22:41:51 +00005014 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005015
Greg Clayton7f995132011-10-04 22:41:51 +00005016 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
5017 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5018 case DW_AT_declaration:
5019 case DW_AT_description:
5020 case DW_AT_endianity:
5021 case DW_AT_segment:
5022 case DW_AT_start_scope:
5023 case DW_AT_visibility:
5024 default:
5025 case DW_AT_abstract_origin:
5026 case DW_AT_sibling:
5027 case DW_AT_specification:
5028 break;
5029 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005030 }
5031 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005032
Greg Clayton7f995132011-10-04 22:41:51 +00005033 if (location.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005034 {
Greg Clayton7f995132011-10-04 22:41:51 +00005035 assert(var_type != DIE_IS_BEING_PARSED);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005036
Greg Clayton7f995132011-10-04 22:41:51 +00005037 ValueType scope = eValueTypeInvalid;
5038
5039 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
5040 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5041
5042 if (tag == DW_TAG_formal_parameter)
5043 scope = eValueTypeVariableArgument;
5044 else if (is_external || parent_tag == DW_TAG_compile_unit)
5045 scope = eValueTypeVariableGlobal;
5046 else
5047 scope = eValueTypeVariableLocal;
5048
5049 SymbolContextScope * symbol_context_scope = NULL;
Greg Clayton5cf58b92011-10-05 22:22:08 +00005050 switch (parent_tag)
Greg Clayton7f995132011-10-04 22:41:51 +00005051 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00005052 case DW_TAG_subprogram:
5053 case DW_TAG_inlined_subroutine:
5054 case DW_TAG_lexical_block:
5055 if (sc.function)
5056 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005057 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Clayton5cf58b92011-10-05 22:22:08 +00005058 if (symbol_context_scope == NULL)
5059 symbol_context_scope = sc.function;
5060 }
5061 break;
5062
5063 default:
Greg Clayton7f995132011-10-04 22:41:51 +00005064 symbol_context_scope = sc.comp_unit;
Greg Clayton5cf58b92011-10-05 22:22:08 +00005065 break;
Greg Clayton7f995132011-10-04 22:41:51 +00005066 }
5067
Greg Clayton5cf58b92011-10-05 22:22:08 +00005068 if (symbol_context_scope)
5069 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005070 var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
5071 name,
5072 mangled,
5073 var_type,
5074 scope,
5075 symbol_context_scope,
5076 &decl,
5077 location,
5078 is_external,
5079 is_artificial));
Greg Clayton5cf58b92011-10-05 22:22:08 +00005080
5081 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
5082 }
5083 else
5084 {
5085 // Not ready to parse this variable yet. It might be a global
5086 // or static variable that is in a function scope and the function
5087 // in the symbol context wasn't filled in yet
5088 return var_sp;
5089 }
Greg Clayton7f995132011-10-04 22:41:51 +00005090 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005091 }
Greg Clayton7f995132011-10-04 22:41:51 +00005092 // Cache var_sp even if NULL (the variable was just a specification or
5093 // was missing vital information to be able to be displayed in the debugger
5094 // (missing location due to optimization, etc)) so we don't re-parse
5095 // this DIE over and over later...
5096 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005097 }
5098 return var_sp;
5099}
5100
Greg Claytonc662ec82011-06-17 22:10:16 +00005101
5102const DWARFDebugInfoEntry *
5103SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
5104 dw_offset_t spec_block_die_offset,
5105 DWARFCompileUnit **result_die_cu_handle)
5106{
5107 // Give the concrete function die specified by "func_die_offset", find the
5108 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
5109 // to "spec_block_die_offset"
5110 DWARFDebugInfo* info = DebugInfo();
5111
5112 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
5113 if (die)
5114 {
5115 assert (*result_die_cu_handle);
5116 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
5117 }
5118 return NULL;
5119}
5120
5121
5122const DWARFDebugInfoEntry *
5123SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
5124 const DWARFDebugInfoEntry *die,
5125 dw_offset_t spec_block_die_offset,
5126 DWARFCompileUnit **result_die_cu_handle)
5127{
5128 if (die)
5129 {
5130 switch (die->Tag())
5131 {
5132 case DW_TAG_subprogram:
5133 case DW_TAG_inlined_subroutine:
5134 case DW_TAG_lexical_block:
5135 {
5136 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
5137 {
5138 *result_die_cu_handle = dwarf_cu;
5139 return die;
5140 }
5141
5142 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
5143 {
5144 *result_die_cu_handle = dwarf_cu;
5145 return die;
5146 }
5147 }
5148 break;
5149 }
5150
5151 // Give the concrete function die specified by "func_die_offset", find the
5152 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
5153 // to "spec_block_die_offset"
5154 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
5155 {
5156 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
5157 child_die,
5158 spec_block_die_offset,
5159 result_die_cu_handle);
5160 if (result_die)
5161 return result_die;
5162 }
5163 }
5164
5165 *result_die_cu_handle = NULL;
5166 return NULL;
5167}
5168
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005169size_t
5170SymbolFileDWARF::ParseVariables
5171(
5172 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00005173 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00005174 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005175 const DWARFDebugInfoEntry *orig_die,
5176 bool parse_siblings,
5177 bool parse_children,
5178 VariableList* cc_variable_list
5179)
5180{
5181 if (orig_die == NULL)
5182 return 0;
5183
Greg Claytonc662ec82011-06-17 22:10:16 +00005184 VariableListSP variable_list_sp;
5185
5186 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005187 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00005188 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005189 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005190 dw_tag_t tag = die->Tag();
5191
5192 // Check to see if we have already parsed this variable or constant?
5193 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005194 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005195 if (cc_variable_list)
5196 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005197 }
5198 else
5199 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005200 // We haven't already parsed it, lets do that now.
5201 if ((tag == DW_TAG_variable) ||
5202 (tag == DW_TAG_constant) ||
5203 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005204 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005205 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00005206 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005207 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
5208 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5209 switch (parent_tag)
5210 {
5211 case DW_TAG_compile_unit:
5212 if (sc.comp_unit != NULL)
5213 {
5214 variable_list_sp = sc.comp_unit->GetVariableList(false);
5215 if (variable_list_sp.get() == NULL)
5216 {
5217 variable_list_sp.reset(new VariableList());
5218 sc.comp_unit->SetVariableList(variable_list_sp);
5219 }
5220 }
5221 else
5222 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005223 ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
5224 MakeUserID(sc_parent_die->GetOffset()),
5225 DW_TAG_value_to_name (parent_tag),
5226 MakeUserID(orig_die->GetOffset()),
5227 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005228 }
5229 break;
5230
5231 case DW_TAG_subprogram:
5232 case DW_TAG_inlined_subroutine:
5233 case DW_TAG_lexical_block:
5234 if (sc.function != NULL)
5235 {
5236 // Check to see if we already have parsed the variables for the given scope
5237
Greg Clayton81c22f62011-10-19 18:09:39 +00005238 Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005239 if (block == NULL)
5240 {
5241 // This must be a specification or abstract origin with
5242 // a concrete block couterpart in the current function. We need
5243 // to find the concrete block so we can correctly add the
5244 // variable to it
5245 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
5246 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
5247 sc_parent_die->GetOffset(),
5248 &concrete_block_die_cu);
5249 if (concrete_block_die)
Greg Clayton81c22f62011-10-19 18:09:39 +00005250 block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005251 }
5252
5253 if (block != NULL)
5254 {
5255 const bool can_create = false;
5256 variable_list_sp = block->GetBlockVariableList (can_create);
5257 if (variable_list_sp.get() == NULL)
5258 {
5259 variable_list_sp.reset(new VariableList());
5260 block->SetVariableList(variable_list_sp);
5261 }
5262 }
5263 }
5264 break;
5265
5266 default:
Greg Clayton81c22f62011-10-19 18:09:39 +00005267 ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
5268 MakeUserID(orig_die->GetOffset()),
5269 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005270 break;
5271 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00005272 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005273
5274 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005275 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00005276 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
5277 if (var_sp)
5278 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005279 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00005280 if (cc_variable_list)
5281 cc_variable_list->AddVariableIfUnique (var_sp);
5282 ++vars_added;
5283 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005284 }
5285 }
5286 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005287
5288 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
5289
5290 if (!skip_children && parse_children && die->HasChildren())
5291 {
5292 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
5293 }
5294
5295 if (parse_siblings)
5296 die = die->GetSibling();
5297 else
5298 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005299 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005300 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005301}
5302
5303//------------------------------------------------------------------
5304// PluginInterface protocol
5305//------------------------------------------------------------------
5306const char *
5307SymbolFileDWARF::GetPluginName()
5308{
5309 return "SymbolFileDWARF";
5310}
5311
5312const char *
5313SymbolFileDWARF::GetShortPluginName()
5314{
5315 return GetPluginNameStatic();
5316}
5317
5318uint32_t
5319SymbolFileDWARF::GetPluginVersion()
5320{
5321 return 1;
5322}
5323
5324void
Greg Clayton6beaaa62011-01-17 03:46:26 +00005325SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
5326{
5327 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5328 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
5329 if (clang_type)
5330 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
5331}
5332
5333void
5334SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
5335{
5336 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5337 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
5338 if (clang_type)
5339 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
5340}
5341
Greg Claytona2721472011-06-25 00:44:06 +00005342void
Sean Callanancc427fa2011-07-30 02:42:06 +00005343SymbolFileDWARF::DumpIndexes ()
5344{
5345 StreamFile s(stdout, false);
5346
5347 s.Printf ("DWARF index for (%s) '%s/%s':",
5348 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
5349 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
5350 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
5351 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
5352 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
5353 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
5354 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
5355 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
5356 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
5357 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
5358 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
5359}
5360
5361void
5362SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
5363 const char *name,
5364 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00005365{
Sean Callanancc427fa2011-07-30 02:42:06 +00005366 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00005367
5368 if (iter == m_decl_ctx_to_die.end())
5369 return;
5370
Greg Claytoncb5860a2011-10-13 23:49:28 +00005371 for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
Greg Claytona2721472011-06-25 00:44:06 +00005372 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00005373 const DWARFDebugInfoEntry *context_die = *pos;
5374
5375 if (!results)
5376 return;
5377
5378 DWARFDebugInfo* info = DebugInfo();
5379
5380 DIEArray die_offsets;
5381
5382 DWARFCompileUnit* dwarf_cu = NULL;
5383 const DWARFDebugInfoEntry* die = NULL;
5384 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets);
5385
5386 if (num_matches)
Greg Claytona2721472011-06-25 00:44:06 +00005387 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00005388 for (size_t i = 0; i < num_matches; ++i)
5389 {
5390 const dw_offset_t die_offset = die_offsets[i];
5391 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytond4a2b372011-09-12 23:21:58 +00005392
Greg Claytoncb5860a2011-10-13 23:49:28 +00005393 if (die->GetParent() != context_die)
5394 continue;
5395
5396 Type *matching_type = ResolveType (dwarf_cu, die);
5397
5398 lldb::clang_type_t type = matching_type->GetClangFullType();
5399 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
5400
5401 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
5402 {
5403 clang::TagDecl *tag_decl = tag_type->getDecl();
5404 results->push_back(tag_decl);
5405 }
5406 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
5407 {
5408 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
5409 results->push_back(typedef_decl);
5410 }
Greg Claytona2721472011-06-25 00:44:06 +00005411 }
5412 }
5413 }
5414}
5415
5416void
5417SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
Greg Clayton85ae2e12011-10-18 23:36:41 +00005418 const clang::DeclContext *decl_context,
5419 clang::DeclarationName decl_name,
Greg Claytona2721472011-06-25 00:44:06 +00005420 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
5421{
Greg Clayton85ae2e12011-10-18 23:36:41 +00005422
5423 switch (decl_context->getDeclKind())
5424 {
5425 case clang::Decl::Namespace:
5426 case clang::Decl::TranslationUnit:
5427 {
5428 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5429 symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
5430 }
5431 break;
5432 default:
5433 break;
5434 }
Greg Claytona2721472011-06-25 00:44:06 +00005435}