Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -223,6 +223,8 @@ uint8_t GetUnitType() const { return m_header.GetUnitType(); } bool IsTypeUnit() const { return m_header.IsTypeUnit(); } + /// Note that this check only works for DWARF5+. + bool IsSkeletonUnit() const { return GetUnitType() == llvm::dwarf::DW_UT_skeleton; } std::optional GetStringOffsetSectionItem(uint32_t index) const; Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -162,12 +162,13 @@ // though as some functions have template parameter types and other things // that cause extra copies of types to be included, but we should find these // types in the .dwo file only as methods could have return types removed and - // we don't have to index incomplete types from the skeletone compile unit. + // we don't have to index incomplete types from the skeleton compile unit. if (unit.GetDWOId()) { + // Index the .dwo or dwp instead of the skeleton unit. if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { // Type units in a dwp file are indexed separately, so we just need to - // process the split unit here. However, if the split unit is in a dwo file, - // then we need to process type units here. + // process the split unit here. However, if the split unit is in a dwo + // file, then we need to process type units here. if (dwo_symbol_file == dwp) { IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); } else { @@ -175,11 +176,18 @@ for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); } + return; } - } else { - // We either have a normal compile unit which we want to index. - IndexUnitImpl(unit, cu_language, set); + // This was a DWARF5 skeleton CU and the .dwo file couldn't be located. + if (unit.IsSkeletonUnit()) + return; + + // Otherwise, the unit has a dwo_id, but this isn't a .dwo + // skeleton unit, so the assumption is that this is a file + // produced by -gmodules and that we want to index it. } + // We have a normal compile unit which we want to index. + IndexUnitImpl(unit, cu_language, set); } void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, Index: lldb/test/Shell/SymbolFile/DWARF/Inputs/pch.h =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/Inputs/pch.h @@ -0,0 +1,5 @@ +typedef int anchor_t; + +struct TypeFromPCH { + int field; +}; Index: lldb/test/Shell/SymbolFile/DWARF/clang-gmodules-type-lookup.c =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/clang-gmodules-type-lookup.c @@ -0,0 +1,18 @@ +// UNSUPPORTED: system-windows + +// Test that LLDB can follow DWO links produced by -gmodules debug +// info to find a type in a precompiled header. +// +// RUN: %clangxx_host -g -gmodules -fmodules -std=c99 -x c-header %S/Inputs/pch.h -g -c -o %t.pch +// RUN: %clangxx_host -g -gmodules -fmodules -std=c99 -x c -include-pch %t.pch %s -c -o %t.o +// RUN: %clangxx_host %t.o -o %t.exe +// RUN: lldb-test symbols -dump-clang-ast -find type --language=C99 \ +// RUN: -compiler-context 'AnyModule:*,Struct:TypeFromPCH' %t.exe | FileCheck %s + +anchor_t anchor; + +int main(int argc, char **argv) { return 0; } + +// CHECK: Found 1 type +// CHECK: "TypeFromPCH" +// CHECK: FieldDecl {{.*}} field