DebugInfo library: add support for fetching absolute paths to source files
(instead of basenames) from DWARF. Use this behavior in llvm-dwarfdump tool.

Reviewed by Benjamin Kramer.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160496 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 08e5db2..a4e0d8e 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -8,8 +8,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "DWARFContext.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 using namespace llvm;
@@ -148,8 +150,8 @@
   DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset);
   if (!cu)
     return DILineInfo();
-  const char *fileName = "<invalid>";
-  const char *functionName = "<invalid>";
+  SmallString<16> fileName("<invalid>");
+  SmallString<16> functionName("<invalid>");
   uint32_t line = 0;
   uint32_t column = 0;
   if (specifier.needs(DILineInfoSpecifier::FunctionName)) {
@@ -171,7 +173,29 @@
       if (rowIndex != -1U) {
         const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex];
         // Take file/line info from the line table.
-        fileName = lineTable->Prologue.FileNames[row.File - 1].Name.c_str();
+        const DWARFDebugLine::FileNameEntry &fileNameEntry =
+            lineTable->Prologue.FileNames[row.File - 1];
+        fileName = fileNameEntry.Name;
+        if (specifier.needs(DILineInfoSpecifier::AbsoluteFilePath) &&
+            sys::path::is_relative(fileName.str())) {
+          // Append include directory of file (if it is present in line table)
+          // and compilation directory of compile unit to make path absolute.
+          const char *includeDir = 0;
+          if (uint64_t includeDirIndex = fileNameEntry.DirIdx) {
+            includeDir = lineTable->Prologue
+                         .IncludeDirectories[includeDirIndex - 1];
+          }
+          SmallString<16> absFileName;
+          if (includeDir == 0 || sys::path::is_relative(includeDir)) {
+            if (const char *compilationDir = cu->getCompilationDir())
+              sys::path::append(absFileName, compilationDir);
+          }
+          if (includeDir) {
+            sys::path::append(absFileName, includeDir);
+          }
+          sys::path::append(absFileName, fileName.str());
+          fileName = absFileName;
+        }
         line = row.Line;
         column = row.Column;
       }