diff --git a/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c new file mode 100644 index 0000000000000..41a6a46c92610 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/main.c @@ -0,0 +1,8 @@ +void relative(); + +int main() +{ + relative(); + // Hello Absolute! + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c new file mode 100644 index 0000000000000..02331834cf21f --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Inputs/relative.c @@ -0,0 +1,5 @@ +void stop() {} +void relative() { + stop(); + // Hello Relative! +} diff --git a/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile new file mode 100644 index 0000000000000..8c82c73b13fc6 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/Makefile @@ -0,0 +1,10 @@ +BOTDIR = $(BUILDDIR)/buildbot +USERDIR = $(BUILDDIR)/user +C_SOURCES = $(BOTDIR)/main.c +LD_EXTRAS = $(BOTDIR)/relative.o + +include Makefile.rules + +$(EXE): relative.o +relative.o: $(BOTDIR)/relative.c + cd $(BOTDIR) && $(CC) -c $(CFLAGS) -o $@ relative.c diff --git a/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py new file mode 100644 index 0000000000000..0f5daf51e975e --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/macosx/DBGSourcePathRemapping/TestDSYMSourcePathRemapping.py @@ -0,0 +1,61 @@ +import lldb +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbtest as lldbtest +import lldbsuite.test.lldbutil as lldbutil +import os +import unittest2 + + +class TestDSYMSourcePathRemapping(lldbtest.TestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def build(self): + botdir = self.getBuildArtifact('buildbot') + userdir = self.getBuildArtifact('user') + inputs = self.getSourcePath('Inputs') + lldbutil.mkdir_p(botdir) + lldbutil.mkdir_p(userdir) + import shutil + for f in ['main.c', 'relative.c']: + shutil.copyfile(os.path.join(inputs, f), os.path.join(botdir, f)) + shutil.copyfile(os.path.join(inputs, f), os.path.join(userdir, f)) + + super(TestDSYMSourcePathRemapping, self).build() + + # Remove the build sources. + self.assertTrue(os.path.isdir(botdir)) + shutil.rmtree(botdir) + + # Create a plist. + import subprocess + dsym = self.getBuildArtifact('a.out.dSYM') + uuid = subprocess.check_output(["/usr/bin/dwarfdump", "--uuid", dsym] + ).decode("utf-8").split(" ")[1] + import re + self.assertTrue(re.match(r'[0-9a-fA-F-]+', uuid)) + plist = os.path.join(dsym, 'Contents', 'Resources', uuid + '.plist') + with open(plist, 'w') as f: + f.write('\n') + f.write('\n') + f.write('\n') + f.write('\n') + f.write(' DBGSourcePathRemapping\n') + f.write(' \n') + f.write(' ' + botdir + '\n') + f.write(' ' + userdir + '\n') + f.write(' \n') + f.write('\n') + f.write('\n') + + + @skipIf(debug_info=no_match("dsym")) + def test(self): + self.build() + + target, process, _, _ = lldbutil.run_to_name_breakpoint( + self, 'main') + self.expect("source list -n main", substrs=["Hello Absolute"]) + bkpt = target.BreakpointCreateByName('relative') + lldbutil.continue_to_breakpoint(process, bkpt) + self.expect("source list -n relative", substrs=["Hello Relative"]) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 3800b81d9768a..45704b2925ff8 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -330,7 +330,8 @@ class ObjCRuntimeMethodType { const bool isInstance = instance; const bool isVariadic = false; - const bool isSynthesized = false; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; const bool isImplicitlyDeclared = true; const bool isDefined = false; const clang::ObjCMethodDecl::ImplementationControl impControl = @@ -377,8 +378,8 @@ class ObjCRuntimeMethodType { clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create( ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel, ret_type, nullptr, interface_decl, isInstance, isVariadic, - isSynthesized, isImplicitlyDeclared, isDefined, impControl, - HasRelatedResultType); + isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, + isDefined, impControl, HasRelatedResultType); std::vector parm_vars; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 20e6cd2d28a31..6dfeb1c5f7850 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -178,6 +178,23 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, return *line_table; } +static llvm::Optional +GetFileByIndex(const llvm::DWARFDebugLine::Prologue &prologue, size_t idx, + llvm::StringRef compile_dir, FileSpec::Style style) { + // Try to get an absolute path first. + std::string abs_path; + auto absolute = llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath; + if (prologue.getFileNameByIndex(idx, compile_dir, absolute, abs_path, style)) + return std::move(abs_path); + + // Otherwise ask for a relative path. + std::string rel_path; + auto relative = llvm::DILineInfoSpecifier::FileLineInfoKind::Default; + if (!prologue.getFileNameByIndex(idx, compile_dir, relative, rel_path, style)) + return {}; + return std::move(rel_path); +} + static FileSpecList ParseSupportFilesFromPrologue( const lldb::ModuleSP &module, const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style, @@ -189,35 +206,12 @@ static FileSpecList ParseSupportFilesFromPrologue( FileSpec::GuessPathStyle(compile_dir); const size_t number_of_files = prologue.FileNames.size(); for (size_t idx = 1; idx <= number_of_files; ++idx) { - std::string original_file; - if (!prologue.getFileNameByIndex( - idx, compile_dir, - llvm::DILineInfoSpecifier::FileLineInfoKind::Default, original_file, - style)) { - // Always add an entry so the indexes remain correct. - support_files.EmplaceBack(); - continue; - } - - FileSpec::Style style = FileSpec::Style::native; - if (compile_dir_style) { - style = *compile_dir_style; - } else if (llvm::Optional file_style = - FileSpec::GuessPathStyle(original_file)) { - style = *file_style; - } - std::string remapped_file; - if (!prologue.getFileNameByIndex( - idx, compile_dir, - llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, - remapped_file, style)) { - // Always add an entry so the indexes remain correct. - support_files.EmplaceBack(original_file, style); - continue; - } + if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) + if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file)) + remapped_file = std::move(*file_path); - module->RemapSourceFile(llvm::StringRef(original_file), remapped_file); + // Unconditionally add an entry, so the indices match up. support_files.EmplaceBack(remapped_file, style); } diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 2cb01ce016067..14e9144424fec 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -8528,7 +8528,8 @@ bool ClangASTContext::AddObjCClassProperty( ? class_interface_decl->lookupInstanceMethod(getter_sel) : class_interface_decl->lookupClassMethod(getter_sel))) { const bool isVariadic = false; - const bool isSynthesized = false; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; const bool isImplicitlyDeclared = true; const bool isDefined = false; const clang::ObjCMethodDecl::ImplementationControl impControl = @@ -8539,7 +8540,8 @@ bool ClangASTContext::AddObjCClassProperty( *clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, ClangUtil::GetQualType(property_clang_type_to_access), nullptr, class_interface_decl, isInstance, isVariadic, - isSynthesized, isImplicitlyDeclared, isDefined, impControl, + isPropertyAccessor, isSynthesizedAccessorStub, + isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); if (getter && metadata) @@ -8560,7 +8562,8 @@ bool ClangASTContext::AddObjCClassProperty( : class_interface_decl->lookupClassMethod(setter_sel))) { clang::QualType result_type = clang_ast->VoidTy; const bool isVariadic = false; - const bool isSynthesized = false; + const bool isPropertyAccessor = true; + const bool isSynthesizedAccessorStub = false; const bool isImplicitlyDeclared = true; const bool isDefined = false; const clang::ObjCMethodDecl::ImplementationControl impControl = @@ -8570,8 +8573,9 @@ bool ClangASTContext::AddObjCClassProperty( clang::ObjCMethodDecl *setter = clang::ObjCMethodDecl::Create( *clang_ast, clang::SourceLocation(), clang::SourceLocation(), setter_sel, result_type, nullptr, class_interface_decl, - isInstance, isVariadic, isSynthesized, isImplicitlyDeclared, - isDefined, impControl, HasRelatedResultType); + isInstance, isVariadic, isPropertyAccessor, + isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, + impControl, HasRelatedResultType); if (setter && metadata) ClangASTContext::SetMetadata(clang_ast, setter, *metadata); @@ -8673,10 +8677,16 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( if (!method_function_prototype) return nullptr; - bool is_synthesized = false; - bool is_defined = false; - clang::ObjCMethodDecl::ImplementationControl imp_control = + const bool isInstance = (name[0] == '-'); + const bool isVariadic = false; + const bool isPropertyAccessor = false; + const bool isSynthesizedAccessorStub = false; + /// Force this to true because we don't have source locations. + const bool isImplicitlyDeclared = true; + const bool isDefined = false; + const clang::ObjCMethodDecl::ImplementationControl impControl = clang::ObjCMethodDecl::None; + const bool HasRelatedResultType = false; const unsigned num_args = method_function_prototype->getNumParams(); @@ -8692,10 +8702,8 @@ clang::ObjCMethodDecl *ClangASTContext::AddMethodToObjCObjectType( nullptr, // TypeSourceInfo *ResultTInfo, ClangASTContext::GetASTContext(ast)->GetDeclContextForType( ClangUtil::GetQualType(type)), - name[0] == '-', is_variadic, is_synthesized, - true, // is_implicitly_declared; we force this to true because we don't - // have source locations - is_defined, imp_control, false /*has_related_result_type*/); + isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, + isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); if (objc_method_decl == nullptr) return nullptr;