Skip to content

Commit 76c678c

Browse files
Merge pull request #7932 from adrian-prantl/110926168
Add support for inline DWARF source files.
2 parents b37c3c5 + 74f3f4c commit 76c678c

39 files changed

+421
-163
lines changed

lldb/include/lldb/Symbol/CompileUnit.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,13 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
112112
/// the compile unit is optimized will be made when
113113
/// CompileUnit::GetIsOptimized() is called.
114114
///
115+
/// \param[in] support_files
116+
/// An rvalue list of already parsed support files.
115117
/// \see lldb::LanguageType
116118
CompileUnit(const lldb::ModuleSP &module_sp, void *user_data,
117119
const FileSpec &file_spec, lldb::user_id_t uid,
118-
lldb::LanguageType language, lldb_private::LazyBool is_optimized);
120+
lldb::LanguageType language, lldb_private::LazyBool is_optimized,
121+
SupportFileList &&support_files = {});
119122

120123
/// Add a function to this compile unit.
121124
///
@@ -226,6 +229,9 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
226229
/// Return the primary source file associated with this compile unit.
227230
const FileSpec &GetPrimaryFile() const { return m_file_spec; }
228231

232+
/// Return the primary source file associated with this compile unit.
233+
void SetPrimaryFile(const FileSpec &fs) { m_file_spec = fs; }
234+
229235
/// Get the line table for the compile unit.
230236
///
231237
/// Called by clients and the SymbolFile plug-in. The SymbolFile plug-ins
@@ -265,7 +271,13 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
265271
///
266272
/// \return
267273
/// A support file list object.
268-
const FileSpecList &GetSupportFiles();
274+
const SupportFileList &GetSupportFiles();
275+
276+
/// Used by plugins that parse the support file list.
277+
SupportFileList &GetSupportFileList() {
278+
m_flags.Set(flagsParsedSupportFiles);
279+
return m_support_files;
280+
}
269281

270282
/// Get the compile unit's imported module list.
271283
///
@@ -331,9 +343,6 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
331343
/// A line table object pointer that this object now owns.
332344
void SetLineTable(LineTable *line_table);
333345

334-
void SetSupportFiles(const FileSpecList &support_files);
335-
void SetSupportFiles(FileSpecList &&support_files);
336-
337346
void SetDebugMacros(const DebugMacrosSP &debug_macros);
338347

339348
/// Set accessor for the variable list.
@@ -411,9 +420,8 @@ class CompileUnit : public std::enable_shared_from_this<CompileUnit>,
411420
std::vector<SourceModule> m_imported_modules;
412421
/// The primary file associated with this compile unit.
413422
FileSpec m_file_spec;
414-
/// Files associated with this compile unit's line table and
415-
/// declarations.
416-
FileSpecList m_support_files;
423+
/// Files associated with this compile unit's line table and declarations.
424+
SupportFileList m_support_files;
417425
/// Line table that will get parsed on demand.
418426
std::unique_ptr<LineTable> m_line_table_up;
419427
/// Debug macros that will get parsed on demand.

lldb/include/lldb/Symbol/SymbolFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class SymbolFile : public PluginInterface {
200200
return false;
201201
}
202202
virtual bool ParseSupportFiles(CompileUnit &comp_unit,
203-
FileSpecList &support_files) = 0;
203+
SupportFileList &support_files) = 0;
204204
virtual size_t ParseTypes(CompileUnit &comp_unit) = 0;
205205
virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; }
206206

lldb/include/lldb/Symbol/SymbolFileOnDemand.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
8181
llvm::function_ref<bool(lldb_private::Module &)>) override;
8282

8383
bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
84-
lldb_private::FileSpecList &support_files) override;
84+
lldb_private::SupportFileList &support_files) override;
8585

8686
bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
8787

lldb/include/lldb/Target/Target.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ class Target : public std::enable_shared_from_this<Target>,
768768
// Use this to create a breakpoint from a load address and a module file spec
769769
lldb::BreakpointSP CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,
770770
bool internal,
771-
const FileSpec *file_spec,
771+
const FileSpec &file_spec,
772772
bool request_hardware);
773773

774774
// Use this to create Address breakpoints:

lldb/include/lldb/Utility/FileSpecList.h

Lines changed: 80 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,86 @@
1717
namespace lldb_private {
1818
class Stream;
1919

20+
/// Wraps either a FileSpec that represents a local file or a source
21+
/// file whose contents is known (for example because it can be
22+
/// reconstructed from debug info), but that hasn't been written to a
23+
/// file yet.
24+
class SupportFile {
25+
protected:
26+
FileSpec m_file_spec;
27+
28+
public:
29+
SupportFile(const FileSpec &spec) : m_file_spec(spec) {}
30+
SupportFile(const SupportFile &other) = delete;
31+
SupportFile(SupportFile &&other) = default;
32+
virtual ~SupportFile() = default;
33+
bool operator==(const SupportFile &other) {
34+
return m_file_spec == other.m_file_spec;
35+
}
36+
/// Return the file name only. Useful for resolving breakpoints by file name.
37+
const FileSpec &GetSpecOnly() const { return m_file_spec; };
38+
/// Materialize the file to disk and return the path to that temporary file.
39+
virtual const FileSpec &Materialize() { return m_file_spec; }
40+
};
41+
42+
/// A list of support files for a CompileUnit.
43+
class SupportFileList {
44+
public:
45+
SupportFileList(){};
46+
SupportFileList(const SupportFileList &) = delete;
47+
SupportFileList(SupportFileList &&other) = default;
48+
49+
typedef std::vector<std::unique_ptr<SupportFile>> collection;
50+
typedef collection::const_iterator const_iterator;
51+
const_iterator begin() const { return m_files.begin(); }
52+
const_iterator end() const { return m_files.end(); }
53+
54+
void Append(const FileSpec &file) {
55+
return Append(std::make_unique<SupportFile>(file));
56+
}
57+
void Append(std::unique_ptr<SupportFile> &&file) {
58+
m_files.push_back(std::move(file));
59+
}
60+
// FIXME: Only used by SymbolFilePDB. Replace with a DenseSet at call site.
61+
bool AppendIfUnique(const FileSpec &file);
62+
size_t GetSize() const { return m_files.size(); }
63+
const FileSpec &GetFileSpecAtIndex(size_t idx) const;
64+
size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
65+
/// Find a compatible file index.
66+
///
67+
/// Find the index of a compatible file in the file spec list that matches \a
68+
/// file starting \a idx entries into the file spec list. A file is considered
69+
/// compatible if:
70+
/// - The file matches exactly (only filename if \a file has no directory)
71+
/// - If \a file is relative and any file in the list has this same suffix
72+
/// - If any file in the list is relative and the relative path is a suffix
73+
/// of \a file
74+
///
75+
/// This is used to implement better matching for setting breakpoints in
76+
/// source files where an IDE might specify a full path when setting the
77+
/// breakpoint and debug info contains relative paths, if a user specifies
78+
/// a relative path when setting a breakpoint.
79+
///
80+
/// \param[in] idx
81+
/// An index into the file list.
82+
///
83+
/// \param[in] file
84+
/// The file specification to search for.
85+
///
86+
/// \return
87+
/// The index of the file that matches \a file if it is found,
88+
/// else UINT32_MAX is returned.
89+
size_t FindCompatibleIndex(size_t idx, const FileSpec &file) const;
90+
91+
template <class... Args> void EmplaceBack(Args &&...args) {
92+
m_files.push_back(
93+
std::make_unique<SupportFile>(FileSpec(std::forward<Args>(args)...)));
94+
}
95+
96+
protected:
97+
collection m_files; ///< A collection of FileSpec objects.
98+
};
99+
20100
/// \class FileSpecList FileSpecList.h "lldb/Utility/FileSpecList.h"
21101
/// A file collection class.
22102
///
@@ -114,32 +194,6 @@ class FileSpecList {
114194
/// else UINT32_MAX is returned.
115195
size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
116196

117-
/// Find a compatible file index.
118-
///
119-
/// Find the index of a compatible file in the file spec list that matches \a
120-
/// file starting \a idx entries into the file spec list. A file is considered
121-
/// compatible if:
122-
/// - The file matches exactly (only filename if \a file has no directory)
123-
/// - If \a file is relative and any file in the list has this same suffix
124-
/// - If any file in the list is relative and the relative path is a suffix
125-
/// of \a file
126-
///
127-
/// This is used to implement better matching for setting breakpoints in
128-
/// source files where an IDE might specify a full path when setting the
129-
/// breakpoint and debug info contains relative paths, if a user specifies
130-
/// a relative path when setting a breakpoint.
131-
///
132-
/// \param[in] idx
133-
/// An index into the file list.
134-
///
135-
/// \param[in] file
136-
/// The file specification to search for.
137-
///
138-
/// \return
139-
/// The index of the file that matches \a file if it is found,
140-
/// else UINT32_MAX is returned.
141-
size_t FindCompatibleIndex(size_t idx, const FileSpec &file) const;
142-
143197
/// Get file at index.
144198
///
145199
/// Gets a file from the file list. If \a idx is not a valid index, an empty
@@ -155,19 +209,6 @@ class FileSpecList {
155209
/// returned.
156210
const FileSpec &GetFileSpecAtIndex(size_t idx) const;
157211

158-
/// Get file specification pointer at index.
159-
///
160-
/// Gets a file from the file list. The file objects that are returned can
161-
/// be tested using FileSpec::operator void*().
162-
///
163-
/// \param[in] idx
164-
/// An index into the file list.
165-
///
166-
/// \return
167-
/// A pointer to a contained FileSpec object at index \a idx.
168-
/// If \a idx is out of range, then an NULL is returned.
169-
const FileSpec *GetFileSpecPointerAtIndex(size_t idx) const;
170-
171212
/// Get the memory cost of this object.
172213
///
173214
/// Return the size in bytes that this object takes in memory. This returns

lldb/source/API/SBCompileUnit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ uint32_t SBCompileUnit::FindSupportFileIndex(uint32_t start_idx,
171171
LLDB_INSTRUMENT_VA(this, start_idx, sb_file, full);
172172

173173
if (m_opaque_ptr) {
174-
const FileSpecList &support_files = m_opaque_ptr->GetSupportFiles();
174+
const SupportFileList &support_files = m_opaque_ptr->GetSupportFiles();
175175
return support_files.FindFileIndex(start_idx, sb_file.ref(), full);
176176
}
177177
return 0;

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,8 @@ class CommandObjectBreakpointSet : public CommandObjectParsed {
608608
// will track the load location of the library.
609609
size_t num_modules_specified = m_options.m_modules.GetSize();
610610
if (num_modules_specified == 1) {
611-
const FileSpec *file_spec =
612-
m_options.m_modules.GetFileSpecPointerAtIndex(0);
611+
const FileSpec &file_spec =
612+
m_options.m_modules.GetFileSpecAtIndex(0);
613613
bp_sp = target.CreateAddressInModuleBreakpoint(
614614
m_options.m_load_addr, internal, file_spec, m_options.m_hardware);
615615
} else if (num_modules_specified == 0) {

lldb/source/Commands/CommandObjectSource.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class CommandObjectSourceInfo : public CommandObjectParsed {
204204
if (cu) {
205205
assert(file_spec.GetFilename().AsCString());
206206
bool has_path = (file_spec.GetDirectory().AsCString() != nullptr);
207-
const FileSpecList &cu_file_list = cu->GetSupportFiles();
207+
const SupportFileList &cu_file_list = cu->GetSupportFiles();
208208
size_t file_idx = cu_file_list.FindFileIndex(0, file_spec, has_path);
209209
if (file_idx != UINT32_MAX) {
210210
// Update the file to how it appears in the CU.

lldb/source/Core/ModuleList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ void ModuleListProperties::UpdateSymlinkMappings() {
281281
llvm::sys::ScopedWriter lock(m_symlink_paths_mutex);
282282
const bool notify = false;
283283
m_symlink_paths.Clear(notify);
284-
for (FileSpec symlink : list) {
284+
for (auto symlink : list) {
285285
FileSpec resolved;
286286
Status status = FileSystem::Instance().Readlink(symlink, resolved);
287287
if (status.Success())

lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,18 +489,18 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
489489

490490
// Build a list of files we need to analyze to build the configuration.
491491
FileSpecList files;
492-
for (const FileSpec &f : sc.comp_unit->GetSupportFiles())
493-
files.AppendIfUnique(f);
492+
for (auto &f : sc.comp_unit->GetSupportFiles())
493+
files.AppendIfUnique(f->Materialize());
494494
// We also need to look at external modules in the case of -gmodules as they
495495
// contain the support files for libc++ and the C library.
496496
llvm::DenseSet<SymbolFile *> visited_symbol_files;
497497
sc.comp_unit->ForEachExternalModule(
498498
visited_symbol_files, [&files](Module &module) {
499499
for (std::size_t i = 0; i < module.GetNumCompileUnits(); ++i) {
500-
const FileSpecList &support_files =
500+
const SupportFileList &support_files =
501501
module.GetCompileUnitAtIndex(i)->GetSupportFiles();
502-
for (const FileSpec &f : support_files) {
503-
files.AppendIfUnique(f);
502+
for (auto &f : support_files) {
503+
files.AppendIfUnique(f->Materialize());
504504
}
505505
}
506506
return false;
@@ -509,7 +509,7 @@ CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
509509
LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze",
510510
files.GetSize());
511511
if (log && log->GetVerbose()) {
512-
for (const FileSpec &f : files)
512+
for (auto &f : files)
513513
LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}",
514514
f.GetPath());
515515
}

lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ bool CppModuleConfiguration::hasValidConfig() {
134134
CppModuleConfiguration::CppModuleConfiguration(
135135
const FileSpecList &support_files, const llvm::Triple &triple) {
136136
// Analyze all files we were given to build the configuration.
137-
bool error = !llvm::all_of(support_files,
138-
std::bind(&CppModuleConfiguration::analyzeFile,
139-
this, std::placeholders::_1, triple));
137+
bool error = !llvm::all_of(support_files, [&](auto &file) {
138+
return CppModuleConfiguration::analyzeFile(file, triple);
139+
});
140140
// If we have a valid configuration at this point, set the
141141
// include directories and module list that should be used.
142142
if (!error && hasValidConfig()) {

lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,14 @@ bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
278278
}
279279

280280
bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit,
281-
FileSpecList &support_files) {
281+
SupportFileList &support_files) {
282282
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
283283
CompUnitData &data = m_cu_data->GetEntryRef(comp_unit.GetID()).data;
284284
if (!data.support_files)
285285
ParseLineTableAndSupportFiles(comp_unit, data);
286286

287-
support_files = std::move(*data.support_files);
287+
for (auto &fs : *data.support_files)
288+
support_files.Append(fs);
288289
return true;
289290
}
290291

lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class SymbolFileBreakpad : public SymbolFileCommon {
7373
bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
7474

7575
bool ParseSupportFiles(CompileUnit &comp_unit,
76-
FileSpecList &support_files) override;
76+
SupportFileList &support_files) override;
7777
size_t ParseTypes(CompileUnit &cu) override { return 0; }
7878

7979
bool ParseImportedModules(
@@ -204,7 +204,6 @@ class SymbolFileBreakpad : public SymbolFileCommon {
204204
Bookmark bookmark;
205205
std::optional<FileSpecList> support_files;
206206
std::unique_ptr<LineTable> line_table_up;
207-
208207
};
209208

210209
uint32_t CalculateNumCompileUnits() override;

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class SymbolFileCTF : public lldb_private::SymbolFileCommon {
6565
bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
6666

6767
bool ParseSupportFiles(CompileUnit &comp_unit,
68-
FileSpecList &support_files) override {
68+
SupportFileList &support_files) override {
6969
return false;
7070
}
7171

0 commit comments

Comments
 (0)