Skip to content

Commit 15c93f2

Browse files
committed
[lldb] Extend FindTypes to optionally search by mangled type name (llvm#113007)
Swift types have mangled type names. This adds functionality to look up those types through the FindTypes API by searching for the mangled type name instead of the regular name. (cherry picked from commit d6b9028)
1 parent 2449073 commit 15c93f2

File tree

6 files changed

+132
-4
lines changed

6 files changed

+132
-4
lines changed

lldb/include/lldb/Symbol/Type.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ FLAGS_ENUM(TypeQueryOptions){
8282
/// When true, the find types call should stop the query as soon as a single
8383
/// matching type is found. When false, the type query should find all
8484
/// matching types.
85-
e_find_one = (1u << 2),
85+
e_find_one = (1u << 4),
86+
// If set, treat TypeQuery::m_name as a mangled name that should be
87+
// searched.
88+
e_search_by_mangled_name = (1u << 5),
8689
};
8790
LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
8891

@@ -280,6 +283,19 @@ class TypeQuery {
280283
m_options &= (e_exact_match | e_find_one);
281284
}
282285

286+
/// Returns true if the type query is supposed to treat the name to be
287+
/// searched as a mangled name.
288+
bool GetSearchByMangledName() const {
289+
return (m_options & e_search_by_mangled_name) != 0;
290+
}
291+
292+
void SetSearchByMangledName(bool b) {
293+
if (b)
294+
m_options |= e_search_by_mangled_name;
295+
else
296+
m_options &= ~e_search_by_mangled_name;
297+
}
298+
283299
/// Access the internal compiler context array.
284300
///
285301
/// Clients can use this to populate the context manually.

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
198198
return result;
199199
}
200200

201-
const char *DWARFDIE::GetMangledName() const {
201+
const char *DWARFDIE::GetMangledName(bool substitute_name_allowed) const {
202202
if (IsValid())
203-
return m_die->GetMangledName(m_cu);
203+
return m_die->GetMangledName(m_cu, substitute_name_allowed);
204204
else
205205
return nullptr;
206206
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class DWARFDIE : public DWARFBaseDIE {
2828
// Accessors
2929

3030
// Accessing information about a DIE
31-
const char *GetMangledName() const;
31+
const char *GetMangledName(bool substitute_name_allowed = true) const;
3232

3333
bool IsGenericTrampoline() const;
3434

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2776,6 +2776,20 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
27762776
return true; // Keep iterating over index types, language mismatch.
27772777
}
27782778

2779+
// Since mangled names are unique, we only need to check if the names are
2780+
// the same.
2781+
if (query.GetSearchByMangledName()) {
2782+
if (die.GetMangledName(/*substitute_name_allowed=*/false) !=
2783+
query.GetTypeBasename().GetStringRef())
2784+
return true; // Keep iterating over index types, mangled name mismatch.
2785+
if (Type *matching_type = ResolveType(die, true, true)) {
2786+
results.InsertUnique(matching_type->shared_from_this());
2787+
return !results.Done(query); // Keep iterating if we aren't done.
2788+
}
2789+
return true; // Keep iterating over index types, weren't able to resolve
2790+
// this type
2791+
}
2792+
27792793
// Check the context matches
27802794
std::vector<lldb_private::CompilerContext> die_context;
27812795
if (query.GetModuleSearch())
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
; Test finding types by CompilerContext.
2+
; REQUIRES: aarch64
3+
; RUN: llc %s -filetype=obj -o %t.o
4+
; RUN: lldb-test symbols %t.o -find=type --mangled-name=UniqueDifferentName | FileCheck %s
5+
;
6+
; NORESULTS: Found 0 types
7+
; CHECK: Found 1 types:
8+
; CHECK: struct DifferentName {
9+
; CHECK-NEXT: int i;
10+
; CHECK-NEXT: }
11+
12+
source_filename = "t.c"
13+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
14+
target triple = "arm64-unknown-linux-gnu"
15+
16+
%struct.SameName = type { i32 }
17+
%struct.DifferentName = type { i32 }
18+
19+
; Function Attrs: noinline nounwind optnone uwtable
20+
define dso_local i32 @main() #0 !dbg !10 {
21+
entry:
22+
%retval = alloca i32, align 4
23+
%s = alloca %struct.SameName, align 4
24+
%d = alloca %struct.DifferentName, align 4
25+
store i32 0, ptr %retval, align 4
26+
#dbg_declare(ptr %s, !16, !DIExpression(), !20)
27+
#dbg_declare(ptr %d, !21, !DIExpression(), !25)
28+
ret i32 0, !dbg !26
29+
}
30+
31+
attributes #0 = { noinline optnone }
32+
33+
!llvm.dbg.cu = !{!0}
34+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
35+
!llvm.ident = !{!9}
36+
37+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
38+
!1 = !DIFile(filename: "t.c", directory: "/")
39+
!2 = !{i32 7, !"Dwarf Version", i32 5}
40+
!3 = !{i32 2, !"Debug Info Version", i32 3}
41+
!4 = !{i32 1, !"wchar_size", i32 4}
42+
!5 = !{i32 8, !"PIC Level", i32 2}
43+
!6 = !{i32 7, !"PIE Level", i32 2}
44+
!7 = !{i32 7, !"uwtable", i32 2}
45+
!8 = !{i32 7, !"frame-pointer", i32 1}
46+
!9 = !{!""}
47+
!10 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 9, type: !12, scopeLine: 9, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !15)
48+
!11 = !DIFile(filename: "t.c", directory: "")
49+
!12 = !DISubroutineType(types: !13)
50+
!13 = !{!14}
51+
!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
52+
!15 = !{}
53+
!16 = !DILocalVariable(name: "s", scope: !10, file: !11, line: 10, type: !17)
54+
!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !11, line: 1, size: 32, elements: !18, runtimeLang: DW_LANG_Swift, identifier: "SameName")
55+
!18 = !{!19}
56+
!19 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !17, file: !11, line: 2, baseType: !14, size: 32)
57+
!20 = !DILocation(line: 10, column: 19, scope: !10)
58+
!21 = !DILocalVariable(name: "d", scope: !10, file: !11, line: 11, type: !22)
59+
!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !11, line: 5, size: 32, elements: !23, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
60+
!23 = !{!24}
61+
!24 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !22, file: !11, line: 6, baseType: !14, size: 32)
62+
!25 = !DILocation(line: 11, column: 24, scope: !10)
63+
!26 = !DILocation(line: 12, column: 3, scope: !10)

lldb/tools/lldb-test/lldb-test.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
1414
#include "lldb/Breakpoint/BreakpointLocation.h"
1515
#include "lldb/Core/Debugger.h"
16+
#include "lldb/Core/Mangled.h"
1617
#include "lldb/Core/Module.h"
1718
#include "lldb/Core/Section.h"
1819
#include "lldb/Expression/IRMemoryMap.h"
@@ -23,6 +24,7 @@
2324
#include "lldb/Symbol/LineTable.h"
2425
#include "lldb/Symbol/SymbolFile.h"
2526
#include "lldb/Symbol/Symtab.h"
27+
#include "lldb/Symbol/Type.h"
2628
#include "lldb/Symbol/TypeList.h"
2729
#include "lldb/Symbol/TypeMap.h"
2830
#include "lldb/Symbol/VariableList.h"
@@ -179,6 +181,10 @@ static cl::opt<FindType> Find(
179181

180182
static cl::opt<std::string> Name("name", cl::desc("Name to find."),
181183
cl::sub(SymbolsSubcommand));
184+
static cl::opt<std::string> MangledName(
185+
"mangled-name",
186+
cl::desc("Mangled name to find. Only compatible when searching types"),
187+
cl::sub(SymbolsSubcommand));
182188
static cl::opt<bool>
183189
Regex("regex",
184190
cl::desc("Search using regular expressions (available for variables "
@@ -463,6 +469,9 @@ static lldb::DescriptionLevel GetDescriptionLevel() {
463469
}
464470

465471
Error opts::symbols::findFunctions(lldb_private::Module &Module) {
472+
if (!MangledName.empty())
473+
return make_string_error("Cannot search functions by mangled name.");
474+
466475
SymbolFile &Symfile = *Module.GetSymbolFile();
467476
SymbolContextList List;
468477
auto compiler_context = parseCompilerContext();
@@ -524,6 +533,8 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
524533
assert(!Regex);
525534
assert(!File.empty());
526535
assert(Line != 0);
536+
if (!MangledName.empty())
537+
return make_string_error("Cannot search blocks by mangled name.");
527538

528539
SymbolContextList List;
529540

@@ -558,6 +569,9 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
558569
}
559570

560571
Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
572+
if (!MangledName.empty())
573+
return make_string_error("Cannot search namespaces by mangled name.");
574+
561575
SymbolFile &Symfile = *Module.GetSymbolFile();
562576
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
563577
if (!ContextOr)
@@ -580,8 +594,12 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
580594
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
581595
if (!ContextOr)
582596
return ContextOr.takeError();
597+
;
583598

584599
TypeResults results;
600+
if (!Name.empty() && !MangledName.empty())
601+
return make_string_error("Cannot search by both name and mangled name.");
602+
585603
if (!Name.empty()) {
586604
if (ContextOr->IsValid()) {
587605
TypeQuery query(*ContextOr, ConstString(Name),
@@ -595,6 +613,20 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
595613
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
596614
Symfile.FindTypes(query, results);
597615
}
616+
} else if (!MangledName.empty()) {
617+
auto Opts = TypeQueryOptions::e_search_by_mangled_name;
618+
if (ContextOr->IsValid()) {
619+
TypeQuery query(*ContextOr, ConstString(MangledName), Opts);
620+
if (!Language.empty())
621+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
622+
Symfile.FindTypes(query, results);
623+
} else {
624+
TypeQuery query(MangledName, Opts);
625+
if (!Language.empty())
626+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
627+
Symfile.FindTypes(query, results);
628+
}
629+
598630
} else {
599631
TypeQuery query(parseCompilerContext(), TypeQueryOptions::e_module_search);
600632
if (!Language.empty())
@@ -612,6 +644,9 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
612644
}
613645

614646
Error opts::symbols::findVariables(lldb_private::Module &Module) {
647+
if (!MangledName.empty())
648+
return make_string_error("Cannot search variables by mangled name.");
649+
615650
SymbolFile &Symfile = *Module.GetSymbolFile();
616651
VariableList List;
617652
if (Regex) {

0 commit comments

Comments
 (0)