Index: lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test =================================================================== --- lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test +++ lldb/trunk/lit/SymbolFile/PDB/function-nested-block.test @@ -1,7 +1,12 @@ REQUIRES: windows, lld RUN: clang-cl /c /Zi %S/Inputs/FunctionNestedBlockTest.cpp /o %t.obj RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe -RUN: lldb-test symbols -find=function -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck %s +RUN: lldb-test symbols -find=function -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck --check-prefix=CHECK-FUNCTION %s +RUN: lldb-test symbols -find=block -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck --check-prefix=CHECK-BLOCK %s -CHECK: Found 1 functions: -CHECK: name = "{{.*}}", mangled = "{{_?}}main" +CHECK-FUNCTION: Found 1 functions: +CHECK-FUNCTION: name = "{{.*}}", mangled = "{{_?}}main" + +CHECK-BLOCK: Found 1 blocks: +CHECK-BLOCK: Blocks: id = {{.*}}, range = {{.*}} +CHECK-BLOCK: id = {{.*}}, range = {{.*}} Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -629,7 +629,8 @@ lldbassert(sc.module_sp == cu_sp->GetModule()); } - if (resolve_scope & eSymbolContextFunction) { + if (resolve_scope & eSymbolContextFunction || + resolve_scope & eSymbolContextBlock) { addr_t file_vm_addr = so_addr.GetFileAddress(); auto symbol_up = m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function); @@ -643,8 +644,11 @@ if (sc.function) { resolved_flags |= eSymbolContextFunction; if (resolve_scope & eSymbolContextBlock) { - Block &block = sc.function->GetBlock(true); - sc.block = block.FindBlockByID(sc.function->GetID()); + auto block_symbol = m_session_up->findSymbolByAddress( + file_vm_addr, PDB_SymType::Block); + auto block_id = block_symbol ? block_symbol->getSymIndexId() + : sc.function->GetID(); + sc.block = sc.function->GetBlock(true).FindBlockByID(block_id); if (sc.block) resolved_flags |= eSymbolContextBlock; } Index: lldb/trunk/tools/lldb-test/lldb-test.cpp =================================================================== --- lldb/trunk/tools/lldb-test/lldb-test.cpp +++ lldb/trunk/tools/lldb-test/lldb-test.cpp @@ -103,6 +103,7 @@ enum class FindType { None, Function, + Block, Namespace, Type, Variable, @@ -112,6 +113,7 @@ cl::values( clEnumValN(FindType::None, "none", "No search, just dump the module."), clEnumValN(FindType::Function, "function", "Find functions."), + clEnumValN(FindType::Block, "block", "Find blocks."), clEnumValN(FindType::Namespace, "namespace", "Find namespaces."), clEnumValN(FindType::Type, "type", "Find types."), clEnumValN(FindType::Variable, "variable", "Find global variables.")), @@ -158,6 +160,7 @@ static Expected getDeclContext(SymbolVendor &Vendor); static Error findFunctions(lldb_private::Module &Module); +static Error findBlocks(lldb_private::Module &Module); static Error findNamespaces(lldb_private::Module &Module); static Error findTypes(lldb_private::Module &Module); static Error findVariables(lldb_private::Module &Module); @@ -383,6 +386,42 @@ return Error::success(); } +Error opts::symbols::findBlocks(lldb_private::Module &Module) { + assert(!Regex); + assert(!File.empty()); + assert(Line != 0); + + SymbolContextList List; + + FileSpec src_file(File, false); + size_t cu_count = Module.GetNumCompileUnits(); + for (size_t i = 0; i < cu_count; i++) { + lldb::CompUnitSP cu_sp = Module.GetCompileUnitAtIndex(i); + if (!cu_sp) + continue; + + LineEntry le; + cu_sp->FindLineEntry(0, Line, &src_file, false, &le); + if (!le.IsValid()) + continue; + + auto addr = le.GetSameLineContiguousAddressRange().GetBaseAddress(); + if (!addr.IsValid()) + continue; + + SymbolContext sc; + uint32_t resolved = addr.CalculateSymbolContext(&sc, eSymbolContextBlock); + if (resolved & eSymbolContextBlock) + List.Append(sc); + } + + outs() << formatv("Found {0} blocks:\n", List.GetSize()); + StreamString Stream; + List.Dump(&Stream, nullptr); + outs() << Stream.GetData() << "\n"; + return Error::success(); +} + Error opts::symbols::findNamespaces(lldb_private::Module &Module) { SymbolVendor &Vendor = *Module.GetSymbolVendor(); Expected ContextOr = getDeclContext(Vendor); @@ -566,6 +605,15 @@ "when searching a function."); return findFunctions; + case FindType::Block: + if (File.empty() || Line == 0) + return make_string_error("Both file name and line number must be " + "specified when searching a block."); + if (Regex || getFunctionNameFlags() != 0) + return make_string_error("Cannot use regular expression or " + "function-flags for searching a block."); + return findBlocks; + case FindType::Namespace: if (Regex || !File.empty() || Line != 0) return make_string_error("Cannot search for namespaces using regular "