Index: lib/DebugInfo/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARFContext.cpp +++ lib/DebugInfo/DWARFContext.cpp @@ -430,7 +430,7 @@ uint64_t FileIndex, FileLineInfoKind Kind, std::string &FileName) { if (!U || !LineTable || Kind == FileLineInfoKind::None || - !LineTable->getFileNameByIndex(FileIndex, Kind, FileName)) + !LineTable->getFileNameByIndex(U, FileIndex, Kind, FileName)) return false; if (Kind == FileLineInfoKind::AbsoluteFilePath && sys::path::is_relative(FileName)) { Index: lib/DebugInfo/DWARFDebugInfoEntry.h =================================================================== --- lib/DebugInfo/DWARFDebugInfoEntry.h +++ lib/DebugInfo/DWARFDebugInfoEntry.h @@ -38,9 +38,9 @@ DWARFDebugInfoEntryMinimal() : Offset(0), SiblingIdx(0), AbbrevDecl(nullptr) {} - void dump(raw_ostream &OS, const DWARFUnit *u, unsigned recurseDepth, + void dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth, unsigned indent = 0) const; - void dumpAttribute(raw_ostream &OS, const DWARFUnit *u, uint32_t *offset_ptr, + void dumpAttribute(raw_ostream &OS, DWARFUnit *u, uint32_t *offset_ptr, uint16_t attr, uint16_t form, unsigned indent = 0) const; /// Extracts a debug info entry, which is a child of a given unit, Index: lib/DebugInfo/DWARFDebugInfoEntry.cpp =================================================================== --- lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -11,16 +11,21 @@ #include "DWARFCompileUnit.h" #include "DWARFContext.h" #include "DWARFDebugAbbrev.h" +#include "DWARFDebugLine.h" +#include "llvm/Config/config.h" #include "llvm/DebugInfo/DWARFFormValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" + +#include + using namespace llvm; using namespace dwarf; typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; -void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, +void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth, unsigned indent) const { DataExtractor debug_info_data = u->getDebugInfoExtractor(); @@ -63,7 +68,7 @@ } void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, - const DWARFUnit *u, + DWARFUnit *u, uint32_t *offset_ptr, uint16_t attr, uint16_t form, unsigned indent) const { @@ -89,11 +94,39 @@ Optional Val = formValue.getAsUnsignedConstant(); const char *Name = nullptr; + // We reserve PATH_MAX+3 so that we can surround or path with '"'s. + char ResolvedPath[PATH_MAX+3]; + if (Val) Name = AttributeValueString(attr, Val.getValue()); + if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { + typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; + const DWARFDebugLine::LineTable *LT; + std::string File; + + LT = u->getContext().getLineTableForUnit(u); + if (LT && + LT->getFileNameByIndex(u, formValue.getAsUnsignedConstant().getValue(), + FileLineInfoKind::AbsoluteFilePath, File)) { +#ifdef HAVE_REALPATH + // Calling realpath will resolve any '..' in the path. + if (realpath(File.c_str(), ResolvedPath+1)) { + size_t Len = strlen(ResolvedPath); + ResolvedPath[0] = ResolvedPath[Len] = '"'; + ResolvedPath[Len+1] = 0; + Name = ResolvedPath; + } else +#endif + snprintf(ResolvedPath, sizeof(ResolvedPath), "\"%s\"", File.c_str()); + Name = ResolvedPath; + } + } + if (Name) { - OS << Name; + OS << Name; + } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) { + OS << formValue.getAsUnsignedConstant().getValue(); } else { formValue.dump(OS, u); } Index: lib/DebugInfo/DWARFDebugLine.h =================================================================== --- lib/DebugInfo/DWARFDebugLine.h +++ lib/DebugInfo/DWARFDebugLine.h @@ -20,6 +20,7 @@ namespace llvm { class raw_ostream; +class DWARFUnit; class DWARFDebugLine { public: @@ -179,7 +180,8 @@ // Extracts filename by its index in filename table in prologue. // Returns true on success. - bool getFileNameByIndex(uint64_t FileIndex, + bool getFileNameByIndex(DWARFUnit* Unit, + uint64_t FileIndex, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const; Index: lib/DebugInfo/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARFDebugLine.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugLine.h" +#include "DWARFUnit.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" @@ -643,7 +644,8 @@ } bool -DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, +DWARFDebugLine::LineTable::getFileNameByIndex(DWARFUnit *Unit, + uint64_t FileIndex, FileLineInfoKind Kind, std::string &Result) const { if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() || @@ -663,6 +665,10 @@ IncludeDirIndex <= Prologue.IncludeDirectories.size()) { const char *IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]; sys::path::append(FilePath, IncludeDir); + } else if (IncludeDirIndex == 0) { + const char *CompDir = Unit->getCompilationDir(); + if (CompDir) + sys::path::append(FilePath, CompDir); } sys::path::append(FilePath, FileName); Result = FilePath.str(); Index: test/DebugInfo/X86/2011-09-26-GlobalVarContext.ll =================================================================== --- test/DebugInfo/X86/2011-09-26-GlobalVarContext.ll +++ test/DebugInfo/X86/2011-09-26-GlobalVarContext.ll @@ -40,16 +40,16 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-f]*}}] = "GLB") ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) +; CHECK: DW_AT_decl_file [DW_FORM_data1] ("/work/llvm/vanilla/test/DebugInfo/test.c") ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_decl_line [DW_FORM_data1] (0x01) +; CHECK: DW_AT_decl_line [DW_FORM_data1] (1) ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[0x{{[0-9a-f]*}}] = "LOC") ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) +; CHECK: DW_AT_decl_file [DW_FORM_data1] ("/work/llvm/vanilla/test/DebugInfo/test.c") ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_decl_line [DW_FORM_data1] (0x04) +; CHECK: DW_AT_decl_line [DW_FORM_data1] (4) !21 = metadata !{i32 1, metadata !"Debug Info Version", i32 1} Index: test/DebugInfo/X86/fission-cu.ll =================================================================== --- test/DebugInfo/X86/fission-cu.ll +++ test/DebugInfo/X86/fission-cu.ll @@ -76,7 +76,7 @@ ; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[0-9a-f]*}} => {[[TYPE:0x[0-9a-f]*]]}) ; CHECK: DW_AT_external [DW_FORM_flag_present] (true) ; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) -; CHECK: DW_AT_decl_line [DW_FORM_data1] (0x01) +; CHECK: DW_AT_decl_line [DW_FORM_data1] (1) ; CHECK: DW_AT_location [DW_FORM_exprloc] (<0x2> fb 00 ) ; CHECK: [[TYPE]]: DW_TAG_base_type ; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "int") Index: test/DebugInfo/namespace.ll =================================================================== --- test/DebugInfo/namespace.ll +++ test/DebugInfo/namespace.ll @@ -5,13 +5,13 @@ ; CHECK: debug_info contents ; CHECK: [[NS1:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace ; CHECK-NEXT: DW_AT_name{{.*}} = "A" -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1:[0-9]]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x03) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1:".*debug-info-namespace.cpp"]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(3) ; CHECK-NOT: NULL ; CHECK: [[NS2:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace ; CHECK-NEXT: DW_AT_name{{.*}} = "B" -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2:[0-9]]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x01) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2:".*foo.cpp"]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(1) ; CHECK-NOT: NULL ; CHECK: [[I:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable ; CHECK-NEXT: DW_AT_name{{.*}}= "i" @@ -39,16 +39,16 @@ ; CHECK: DW_TAG_imported_module ; This is a bug, it should be in F2 but it inherits the file from its ; enclosing scope -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x08) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(8) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS2]]}) ; CHECK: NULL ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_module ; Same bug as above, this should be F2, not F1 -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0b) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F1]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(11) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) ; CHECK-NOT: NULL @@ -59,55 +59,52 @@ ; CHECK: DW_AT_name{{.*}}= "func" ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_module -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x12) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(18) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x13) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(19) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FOO]]}) ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x14) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(20) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[BAR]]}) ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x15) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(21) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[FUNC1]]}) ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x16) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(22) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[I]]}) ; CHECK-NOT: NULL ; CHECK: [[X:0x[0-9a-f]*]]:{{ *}}DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x18) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(24) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) ; CHECK-NEXT: DW_AT_name{{.*}}"X" ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_declaration -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x19) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(25) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[X]]}) ; CHECK-NEXT: DW_AT_name{{.*}}"Y" ; CHECK-NOT: NULL ; CHECK: DW_TAG_lexical_block ; CHECK-NOT: NULL ; CHECK: DW_TAG_imported_module -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F2]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0f) +; CHECK-NEXT: DW_AT_decl_file{{.*}}([[F2]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(15) ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS2]]}) ; CHECK: NULL ; CHECK: NULL ; CHECK: NULL -; CHECK: file_names[ [[F1]]]{{.*}}debug-info-namespace.cpp -; CHECK: file_names[ [[F2]]]{{.*}}foo.cpp - ; IR generated from clang/test/CodeGenCXX/debug-info-namespace.cpp, file paths ; changed to protect the guilty. The C++ source code is: ; namespace A { Index: test/MC/MachO/gen-dwarf.s =================================================================== --- test/MC/MachO/gen-dwarf.s +++ test/MC/MachO/gen-dwarf.s @@ -50,8 +50,8 @@ // CHECK: DW_TAG_label [2] * // CHECK: DW_AT_name [DW_FORM_string] ("bar") -// CHECK: DW_AT_decl_file [DW_FORM_data4] (0x00000001) -// CHECK: DW_AT_decl_line [DW_FORM_data4] (0x00000005) +// CHECK: DW_AT_decl_file [DW_FORM_data4] ([[FILE:".*gen-dwarf.s"]]) +// CHECK: DW_AT_decl_line [DW_FORM_data4] (5) // CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) // CHECK: DW_AT_prototyped [DW_FORM_flag] (0x00) @@ -61,8 +61,8 @@ // CHECK: DW_TAG_label [2] * // CHECK: DW_AT_name [DW_FORM_string] ("foo") -// CHECK: DW_AT_decl_file [DW_FORM_data4] (0x00000001) -// CHECK: DW_AT_decl_line [DW_FORM_data4] (0x00000009) +// CHECK: DW_AT_decl_file [DW_FORM_data4] ([[FILE]]) +// CHECK: DW_AT_decl_line [DW_FORM_data4] (9) // CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000007) // CHECK: DW_AT_prototyped [DW_FORM_flag] (0x00) @@ -72,8 +72,8 @@ // CHECK: DW_TAG_label [2] * // CHECK: DW_AT_name [DW_FORM_string] ("baz") -// CHECK: DW_AT_decl_file [DW_FORM_data4] (0x00000001) -// CHECK: DW_AT_decl_line [DW_FORM_data4] (0x0000000a) +// CHECK: DW_AT_decl_file [DW_FORM_data4] ([[FILE]]) +// CHECK: DW_AT_decl_line [DW_FORM_data4] (10) // CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000007) // CHECK: DW_AT_prototyped [DW_FORM_flag] (0x00)