Index: lldb/trunk/include/lldb/Host/FileSpec.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSpec.h +++ lldb/trunk/include/lldb/Host/FileSpec.h @@ -739,14 +739,26 @@ FileSpec CopyByRemovingLastPathComponent () const; - + + void + PrependPathComponent(const char *new_path); + + void + PrependPathComponent(const std::string &new_path); + + void + PrependPathComponent(const FileSpec &new_path); + void - AppendPathComponent (const char *new_path); + AppendPathComponent(const char *new_path); void AppendPathComponent(const std::string &new_path); void + AppendPathComponent(const FileSpec &new_path); + + void RemoveLastPathComponent (); ConstString Index: lldb/trunk/source/Host/common/FileSpec.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp +++ lldb/trunk/source/Host/common/FileSpec.cpp @@ -1362,21 +1362,54 @@ } void -FileSpec::AppendPathComponent (const char *new_path) +FileSpec::PrependPathComponent(const char *new_path) { + if (!new_path) return; const bool resolve = false; if (m_filename.IsEmpty() && m_directory.IsEmpty()) { - SetFile(new_path,resolve); + SetFile(new_path, resolve); return; } StreamString stream; if (m_filename.IsEmpty()) - stream.Printf("%s/%s",m_directory.GetCString(),new_path); + stream.Printf("%s/%s", new_path, m_directory.GetCString()); else if (m_directory.IsEmpty()) - stream.Printf("%s/%s",m_filename.GetCString(),new_path); + stream.Printf("%s/%s", new_path, m_filename.GetCString()); else - stream.Printf("%s/%s/%s",m_directory.GetCString(), m_filename.GetCString(),new_path); + stream.Printf("%s/%s/%s", new_path, m_directory.GetCString(), m_filename.GetCString()); + SetFile(stream.GetData(), resolve); +} + +void +FileSpec::PrependPathComponent(const std::string &new_path) +{ + return PrependPathComponent(new_path.c_str()); +} + +void +FileSpec::PrependPathComponent(const FileSpec &new_path) +{ + return PrependPathComponent(new_path.GetPath(false)); +} + +void +FileSpec::AppendPathComponent(const char *new_path) +{ + if (!new_path) return; + const bool resolve = false; + if (m_filename.IsEmpty() && m_directory.IsEmpty()) + { + SetFile(new_path, resolve); + return; + } + StreamString stream; + if (m_filename.IsEmpty()) + stream.Printf("%s/%s", m_directory.GetCString(), new_path); + else if (m_directory.IsEmpty()) + stream.Printf("%s/%s", m_filename.GetCString(), new_path); + else + stream.Printf("%s/%s/%s", m_directory.GetCString(), m_filename.GetCString(), new_path); SetFile(stream.GetData(), resolve); } @@ -1387,6 +1420,12 @@ } void +FileSpec::AppendPathComponent(const FileSpec &new_path) +{ + return AppendPathComponent(new_path.GetPath(false)); +} + +void FileSpec::RemoveLastPathComponent () { const bool resolve = false; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -488,7 +488,6 @@ lldb::offset_t offset = stmt_list; // Skip the total length (void)debug_line_data.GetDWARFInitialLength(&offset); - const char * s; uint32_t version = debug_line_data.GetU16(&offset); if (version < 2 || version > 4) return false; @@ -502,68 +501,38 @@ // Skip opcode base, and all opcode lengths const uint8_t opcode_base = debug_line_data.GetU8(&offset); offset += opcode_base - 1; - std::vector include_directories; - include_directories.push_back(""); // Directory at index zero doesn't exist + std::vector include_directories{{}}; // Directory at index zero doesn't exist while (offset < end_prologue_offset) { - s = debug_line_data.GetCStr(&offset); - if (s && s[0]) - include_directories.push_back(s); + FileSpec dir{debug_line_data.GetCStr(&offset), false}; + if (dir) + include_directories.emplace_back(std::move(dir)); else break; } - std::string fullpath; - std::string remapped_fullpath; while (offset < end_prologue_offset) { - const char* path = debug_line_data.GetCStr( &offset ); - if (path && path[0]) + FileSpec file_spec{debug_line_data.GetCStr(&offset), false}; + if (file_spec) { - uint32_t dir_idx = debug_line_data.GetULEB128( &offset ); + uint32_t dir_idx = debug_line_data.GetULEB128(&offset); debug_line_data.Skip_LEB128(&offset); // Skip mod_time debug_line_data.Skip_LEB128(&offset); // Skip length - if (path[0] == '/') - { - // The path starts with a directory delimiter, so we are done. - if (module_sp->RemapSourceFile (path, fullpath)) - support_files.Append(FileSpec (fullpath.c_str(), false)); - else - support_files.Append(FileSpec (path, false)); - } - else + if (file_spec.IsRelativeToCurrentWorkingDirectory()) { - if (dir_idx > 0 && dir_idx < include_directories.size()) - { - if (cu_comp_dir && include_directories[dir_idx][0] != '/') - { - fullpath = cu_comp_dir; - - if (*fullpath.rbegin() != '/') - fullpath += '/'; - fullpath += include_directories[dir_idx]; - - } - else - fullpath = include_directories[dir_idx]; - } - else if (cu_comp_dir && cu_comp_dir[0]) + if (0 < dir_idx && dir_idx < include_directories.size()) { - fullpath = cu_comp_dir; + const FileSpec &dir = include_directories[dir_idx]; + file_spec.PrependPathComponent(dir); } - - if (!fullpath.empty()) - { - if (*fullpath.rbegin() != '/') - fullpath += '/'; - } - fullpath += path; - if (module_sp->RemapSourceFile (fullpath.c_str(), remapped_fullpath)) - support_files.Append(FileSpec (remapped_fullpath.c_str(), false)); - else - support_files.Append(FileSpec (fullpath.c_str(), false)); + if (file_spec.IsRelativeToCurrentWorkingDirectory()) + file_spec.PrependPathComponent(cu_comp_dir); } - + std::string remapped_file; + if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file)) + file_spec.SetFile(remapped_file, false); + support_files.Append(file_spec); } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -972,39 +972,25 @@ const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly (); if (cu_die) { - const char * cu_die_name = cu_die->GetName(this, dwarf_cu); - const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL); - LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0); - if (cu_die_name) - { - std::string ramapped_file; - FileSpec cu_file_spec; - - if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0') - { - // If we have a full path to the compile unit, we don't need to resolve - // the file. This can be expensive e.g. when the source files are NFS mounted. - if (module_sp->RemapSourceFile(cu_die_name, ramapped_file)) - cu_file_spec.SetFile (ramapped_file.c_str(), false); - else - cu_file_spec.SetFile (cu_die_name, false); - } - else + FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false}; + if (cu_file_spec) + { + // If we have a full path to the compile unit, we don't need to resolve + // the file. This can be expensive e.g. when the source files are NFS mounted. + if (cu_file_spec.IsRelativeToCurrentWorkingDirectory()) { // DWARF2/3 suggests the form hostname:pathname for compilation directory. // Remove the host part if present. - cu_comp_dir = removeHostnameFromPathname(cu_comp_dir); - std::string fullpath(cu_comp_dir); - - if (*fullpath.rbegin() != '/') - fullpath += '/'; - fullpath += cu_die_name; - if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file)) - cu_file_spec.SetFile (ramapped_file.c_str(), false); - else - cu_file_spec.SetFile (fullpath.c_str(), false); + const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)}; + cu_file_spec.PrependPathComponent(removeHostnameFromPathname(cu_comp_dir)); } + std::string remapped_file; + if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) + cu_file_spec.SetFile(remapped_file, false); + + LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0); + cu_sp.reset(new CompileUnit (module_sp, dwarf_cu, cu_file_spec,