|
13 | 13 | #include "DWARFDebugInfoEntry.h"
|
14 | 14 | #include "DWARFDeclContext.h"
|
15 | 15 | #include "DWARFUnit.h"
|
| 16 | +#include "lldb/Symbol/Type.h" |
16 | 17 |
|
17 | 18 | #include "llvm/ADT/iterator.h"
|
18 | 19 |
|
@@ -379,108 +380,118 @@ std::vector<DWARFDIE> DWARFDIE::GetDeclContextDIEs() const {
|
379 | 380 | return result;
|
380 | 381 | }
|
381 | 382 |
|
382 |
| -static std::vector<lldb_private::CompilerContext> |
383 |
| -GetDeclContextImpl(llvm::SmallSet<lldb::user_id_t, 4> &seen, DWARFDIE die) { |
384 |
| - std::vector<lldb_private::CompilerContext> context; |
| 383 | +static void GetDeclContextImpl(DWARFDIE die, |
| 384 | + llvm::SmallSet<lldb::user_id_t, 4> &seen, |
| 385 | + std::vector<CompilerContext> &context) { |
385 | 386 | // Stop if we hit a cycle.
|
386 |
| - if (!die || !seen.insert(die.GetID()).second) |
387 |
| - return context; |
388 |
| - |
389 |
| - // Handle outline member function DIEs by following the specification. |
390 |
| - if (DWARFDIE spec = die.GetReferencedDIE(DW_AT_specification)) |
391 |
| - return GetDeclContextImpl(seen, spec); |
392 |
| - |
393 |
| - // Get the parent context chain. |
394 |
| - context = GetDeclContextImpl(seen, die.GetParent()); |
| 387 | + while (die && seen.insert(die.GetID()).second) { |
| 388 | + // Handle outline member function DIEs by following the specification. |
| 389 | + if (DWARFDIE spec = die.GetReferencedDIE(DW_AT_specification)) { |
| 390 | + die = spec; |
| 391 | + continue; |
| 392 | + } |
395 | 393 |
|
396 |
| - // Add this DIE's contribution at the end of the chain. |
397 |
| - auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) { |
398 |
| - context.push_back({kind, ConstString(name)}); |
399 |
| - }; |
400 |
| - switch (die.Tag()) { |
401 |
| - case DW_TAG_module: |
402 |
| - push_ctx(CompilerContextKind::Module, die.GetName()); |
403 |
| - break; |
404 |
| - case DW_TAG_namespace: |
405 |
| - push_ctx(CompilerContextKind::Namespace, die.GetName()); |
406 |
| - break; |
407 |
| - case DW_TAG_structure_type: |
408 |
| - push_ctx(CompilerContextKind::Struct, die.GetName()); |
409 |
| - break; |
410 |
| - case DW_TAG_union_type: |
411 |
| - push_ctx(CompilerContextKind::Union, die.GetName()); |
412 |
| - break; |
413 |
| - case DW_TAG_class_type: |
414 |
| - push_ctx(CompilerContextKind::Class, die.GetName()); |
415 |
| - break; |
416 |
| - case DW_TAG_enumeration_type: |
417 |
| - push_ctx(CompilerContextKind::Enum, die.GetName()); |
418 |
| - break; |
419 |
| - case DW_TAG_subprogram: |
420 |
| - push_ctx(CompilerContextKind::Function, die.GetName()); |
421 |
| - break; |
422 |
| - case DW_TAG_variable: |
423 |
| - push_ctx(CompilerContextKind::Variable, die.GetPubname()); |
424 |
| - break; |
425 |
| - case DW_TAG_typedef: |
426 |
| - push_ctx(CompilerContextKind::Typedef, die.GetName()); |
427 |
| - break; |
428 |
| - default: |
429 |
| - break; |
| 394 | + // Add this DIE's contribution at the end of the chain. |
| 395 | + auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) { |
| 396 | + context.push_back({kind, ConstString(name)}); |
| 397 | + }; |
| 398 | + switch (die.Tag()) { |
| 399 | + case DW_TAG_module: |
| 400 | + push_ctx(CompilerContextKind::Module, die.GetName()); |
| 401 | + break; |
| 402 | + case DW_TAG_namespace: |
| 403 | + push_ctx(CompilerContextKind::Namespace, die.GetName()); |
| 404 | + break; |
| 405 | + case DW_TAG_structure_type: |
| 406 | + push_ctx(CompilerContextKind::Struct, die.GetName()); |
| 407 | + break; |
| 408 | + case DW_TAG_union_type: |
| 409 | + push_ctx(CompilerContextKind::Union, die.GetName()); |
| 410 | + break; |
| 411 | + case DW_TAG_class_type: |
| 412 | + push_ctx(CompilerContextKind::Class, die.GetName()); |
| 413 | + break; |
| 414 | + case DW_TAG_enumeration_type: |
| 415 | + push_ctx(CompilerContextKind::Enum, die.GetName()); |
| 416 | + break; |
| 417 | + case DW_TAG_subprogram: |
| 418 | + push_ctx(CompilerContextKind::Function, die.GetName()); |
| 419 | + break; |
| 420 | + case DW_TAG_variable: |
| 421 | + push_ctx(CompilerContextKind::Variable, die.GetPubname()); |
| 422 | + break; |
| 423 | + case DW_TAG_typedef: |
| 424 | + push_ctx(CompilerContextKind::Typedef, die.GetName()); |
| 425 | + break; |
| 426 | + default: |
| 427 | + break; |
| 428 | + } |
| 429 | + // Now process the parent. |
| 430 | + die = die.GetParent(); |
430 | 431 | }
|
431 |
| - return context; |
432 | 432 | }
|
433 | 433 |
|
434 |
| -std::vector<lldb_private::CompilerContext> DWARFDIE::GetDeclContext() const { |
| 434 | +std::vector<CompilerContext> DWARFDIE::GetDeclContext() const { |
435 | 435 | llvm::SmallSet<lldb::user_id_t, 4> seen;
|
436 |
| - return GetDeclContextImpl(seen, *this); |
| 436 | + std::vector<CompilerContext> context; |
| 437 | + GetDeclContextImpl(*this, seen, context); |
| 438 | + std::reverse(context.begin(), context.end()); |
| 439 | + return context; |
437 | 440 | }
|
438 | 441 |
|
439 |
| -std::vector<lldb_private::CompilerContext> |
440 |
| -DWARFDIE::GetTypeLookupContext() const { |
441 |
| - std::vector<lldb_private::CompilerContext> context; |
442 |
| - // If there is no name, then there is no need to look anything up for this |
443 |
| - // DIE. |
444 |
| - const char *name = GetName(); |
445 |
| - if (!name || !name[0]) |
446 |
| - return context; |
447 |
| - const dw_tag_t tag = Tag(); |
448 |
| - if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) |
449 |
| - return context; |
450 |
| - DWARFDIE parent = GetParent(); |
451 |
| - if (parent) |
452 |
| - context = parent.GetTypeLookupContext(); |
453 |
| - auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) { |
454 |
| - context.push_back({kind, ConstString(name)}); |
455 |
| - }; |
456 |
| - switch (tag) { |
457 |
| - case DW_TAG_namespace: |
458 |
| - push_ctx(CompilerContextKind::Namespace, name); |
459 |
| - break; |
460 |
| - case DW_TAG_structure_type: |
461 |
| - push_ctx(CompilerContextKind::Struct, name); |
462 |
| - break; |
463 |
| - case DW_TAG_union_type: |
464 |
| - push_ctx(CompilerContextKind::Union, name); |
465 |
| - break; |
466 |
| - case DW_TAG_class_type: |
467 |
| - push_ctx(CompilerContextKind::Class, name); |
468 |
| - break; |
469 |
| - case DW_TAG_enumeration_type: |
470 |
| - push_ctx(CompilerContextKind::Enum, name); |
471 |
| - break; |
472 |
| - case DW_TAG_variable: |
473 |
| - push_ctx(CompilerContextKind::Variable, GetPubname()); |
474 |
| - break; |
475 |
| - case DW_TAG_typedef: |
476 |
| - push_ctx(CompilerContextKind::Typedef, name); |
477 |
| - break; |
478 |
| - case DW_TAG_base_type: |
479 |
| - push_ctx(CompilerContextKind::Builtin, name); |
480 |
| - break; |
481 |
| - default: |
482 |
| - break; |
| 442 | +static void GetTypeLookupContextImpl(DWARFDIE die, |
| 443 | + llvm::SmallSet<lldb::user_id_t, 4> &seen, |
| 444 | + std::vector<CompilerContext> &context) { |
| 445 | + // Stop if we hit a cycle. |
| 446 | + while (die && seen.insert(die.GetID()).second) { |
| 447 | + // If there is no name, then there is no need to look anything up for this |
| 448 | + // DIE. |
| 449 | + const char *name = die.GetName(); |
| 450 | + if (!name || !name[0]) |
| 451 | + return; |
| 452 | + |
| 453 | + // Add this DIE's contribution at the end of the chain. |
| 454 | + auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) { |
| 455 | + context.push_back({kind, ConstString(name)}); |
| 456 | + }; |
| 457 | + switch (die.Tag()) { |
| 458 | + case DW_TAG_namespace: |
| 459 | + push_ctx(CompilerContextKind::Namespace, die.GetName()); |
| 460 | + break; |
| 461 | + case DW_TAG_structure_type: |
| 462 | + push_ctx(CompilerContextKind::Struct, die.GetName()); |
| 463 | + break; |
| 464 | + case DW_TAG_union_type: |
| 465 | + push_ctx(CompilerContextKind::Union, die.GetName()); |
| 466 | + break; |
| 467 | + case DW_TAG_class_type: |
| 468 | + push_ctx(CompilerContextKind::Class, die.GetName()); |
| 469 | + break; |
| 470 | + case DW_TAG_enumeration_type: |
| 471 | + push_ctx(CompilerContextKind::Enum, die.GetName()); |
| 472 | + break; |
| 473 | + case DW_TAG_variable: |
| 474 | + push_ctx(CompilerContextKind::Variable, die.GetPubname()); |
| 475 | + break; |
| 476 | + case DW_TAG_typedef: |
| 477 | + push_ctx(CompilerContextKind::Typedef, die.GetName()); |
| 478 | + break; |
| 479 | + case DW_TAG_base_type: |
| 480 | + push_ctx(CompilerContextKind::Builtin, name); |
| 481 | + break; |
| 482 | + default: |
| 483 | + break; |
| 484 | + } |
| 485 | + // Now process the parent. |
| 486 | + die = die.GetParent(); |
483 | 487 | }
|
| 488 | +} |
| 489 | + |
| 490 | +std::vector<CompilerContext> DWARFDIE::GetTypeLookupContext() const { |
| 491 | + llvm::SmallSet<lldb::user_id_t, 4> seen; |
| 492 | + std::vector<CompilerContext> context; |
| 493 | + GetTypeLookupContextImpl(*this, seen, context); |
| 494 | + std::reverse(context.begin(), context.end()); |
484 | 495 | return context;
|
485 | 496 | }
|
486 | 497 |
|
|
0 commit comments