[DWARF parser] Use enums instead of bitfields in DILineInfoSpecifier.

It is more appropriate than the current situation, when one flag
(AbsoluteFilePath) is relevant only if another flag is set.

This refactoring would also simplify fetching the short function name
(stored in DW_AT_name) instead of a linkage name returned currently.

No functionality change.

llvm-svn: 208921
diff --git a/llvm/lib/DebugInfo/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARFContext.cpp
index 3d04e73..e52e8af 100644
--- a/llvm/lib/DebugInfo/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARFContext.cpp
@@ -25,6 +25,8 @@
 #define DEBUG_TYPE "dwarf"
 
 typedef DWARFDebugLine::LineTable DWARFLineTable;
+typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
 
 static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
                            bool LittleEndian, bool GnuStyle) {
@@ -425,14 +427,13 @@
 
 static bool getFileNameForCompileUnit(DWARFCompileUnit *CU,
                                       const DWARFLineTable *LineTable,
-                                      uint64_t FileIndex,
-                                      bool NeedsAbsoluteFilePath,
+                                      uint64_t FileIndex, FileLineInfoKind Kind,
                                       std::string &FileName) {
-  if (!CU || !LineTable ||
-      !LineTable->getFileNameByIndex(FileIndex, NeedsAbsoluteFilePath,
-                                     FileName))
+  if (!CU || !LineTable || Kind == FileLineInfoKind::None ||
+      !LineTable->getFileNameByIndex(FileIndex, Kind, FileName))
     return false;
-  if (NeedsAbsoluteFilePath && sys::path::is_relative(FileName)) {
+  if (Kind == FileLineInfoKind::AbsoluteFilePath &&
+      sys::path::is_relative(FileName)) {
     // We may still need to append compilation directory of compile unit.
     SmallString<16> AbsolutePath;
     if (const char *CompilationDir = CU->getCompilationDir()) {
@@ -447,7 +448,7 @@
 static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU,
                                           const DWARFLineTable *LineTable,
                                           uint64_t Address,
-                                          bool NeedsAbsoluteFilePath,
+                                          FileLineInfoKind Kind,
                                           DILineInfo &Result) {
   if (!CU || !LineTable)
     return false;
@@ -457,7 +458,7 @@
     return false;
   // Take file number and line/column from the row.
   const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
-  if (!getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
+  if (!getFileNameForCompileUnit(CU, LineTable, Row.File, Kind,
                                  Result.FileName))
     return false;
   Result.Line = Row.Line;
@@ -466,7 +467,10 @@
 }
 
 static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
+                                      FunctionNameKind Kind,
                                       std::string &FunctionName) {
+  if (Kind == FunctionNameKind::None)
+    return false;
   // The address may correspond to instruction in some inlined function,
   // so we have to build the chain of inlined functions and take the
   // name of the topmost function in it.
@@ -475,7 +479,8 @@
   if (InlinedChain.DIEs.size() == 0)
     return false;
   const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
-  if (const char *Name = TopFunctionDIE.getSubroutineName(InlinedChain.U)) {
+  if (const char *Name =
+          TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
     FunctionName = Name;
     return true;
   }
@@ -483,41 +488,34 @@
 }
 
 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
-    DILineInfoSpecifier Specifier) {
+                                               DILineInfoSpecifier Spec) {
   DILineInfo Result;
 
   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
   if (!CU)
     return Result;
-  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
-    getFunctionNameForAddress(CU, Address, Result.FunctionName);
-  }
-  if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+  getFunctionNameForAddress(CU, Address, Spec.FNKind, Result.FunctionName);
+  if (Spec.FLIKind != FileLineInfoKind::None) {
     const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
-    const bool NeedsAbsoluteFilePath =
-        Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
-    getFileLineInfoForCompileUnit(CU, LineTable, Address, NeedsAbsoluteFilePath,
-                                  Result);
+    getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind, Result);
   }
   return Result;
 }
 
-DILineInfoTable DWARFContext::getLineInfoForAddressRange(uint64_t Address,
-    uint64_t Size,
-    DILineInfoSpecifier Specifier) {
+DILineInfoTable
+DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
+                                         DILineInfoSpecifier Spec) {
   DILineInfoTable  Lines;
   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
   if (!CU)
     return Lines;
 
   std::string FunctionName = "<invalid>";
-  if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
-    getFunctionNameForAddress(CU, Address, FunctionName);
-  }
+  getFunctionNameForAddress(CU, Address, Spec.FNKind, FunctionName);
 
   // If the Specifier says we don't need FileLineInfo, just
   // return the top-most function at the starting address.
-  if (!Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+  if (Spec.FLIKind == FileLineInfoKind::None) {
     DILineInfo Result;
     Result.FunctionName = FunctionName;
     Lines.push_back(std::make_pair(Address, Result));
@@ -525,8 +523,6 @@
   }
 
   const DWARFLineTable *LineTable = getLineTableForCompileUnit(CU);
-  const bool NeedsAbsoluteFilePath =
-      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
 
   // Get the index of row we're looking for in the line table.
   std::vector<uint32_t> RowVector;
@@ -537,7 +533,7 @@
     // Take file number and line/column from the row.
     const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
     DILineInfo Result;
-    getFileNameForCompileUnit(CU, LineTable, Row.File, NeedsAbsoluteFilePath,
+    getFileNameForCompileUnit(CU, LineTable, Row.File, Spec.FLIKind,
                               Result.FileName);
     Result.FunctionName = FunctionName;
     Result.Line = Row.Line;
@@ -548,8 +544,9 @@
   return Lines;
 }
 
-DIInliningInfo DWARFContext::getInliningInfoForAddress(uint64_t Address,
-    DILineInfoSpecifier Specifier) {
+DIInliningInfo
+DWARFContext::getInliningInfoForAddress(uint64_t Address,
+                                        DILineInfoSpecifier Spec) {
   DIInliningInfo InliningInfo;
 
   DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
@@ -557,18 +554,16 @@
     return InliningInfo;
 
   const DWARFLineTable *LineTable = nullptr;
-  const bool NeedsAbsoluteFilePath =
-      Specifier.needs(DILineInfoSpecifier::AbsoluteFilePath);
   const DWARFDebugInfoEntryInlinedChain &InlinedChain =
       CU->getInlinedChainForAddress(Address);
   if (InlinedChain.DIEs.size() == 0) {
     // If there is no DIE for address (e.g. it is in unavailable .dwo file),
     // try to at least get file/line info from symbol table.
-    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+    if (Spec.FLIKind != FileLineInfoKind::None) {
       DILineInfo Frame;
       LineTable = getLineTableForCompileUnit(CU);
-      if (getFileLineInfoForCompileUnit(CU, LineTable, Address,
-                                        NeedsAbsoluteFilePath, Frame)) {
+      if (getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
+                                        Frame)) {
         InliningInfo.addFrame(Frame);
       }
     }
@@ -580,23 +575,22 @@
     const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
     DILineInfo Frame;
     // Get function name if necessary.
-    if (Specifier.needs(DILineInfoSpecifier::FunctionName)) {
-      if (const char *Name = FunctionDIE.getSubroutineName(InlinedChain.U))
-        Frame.FunctionName = Name;
-    }
-    if (Specifier.needs(DILineInfoSpecifier::FileLineInfo)) {
+    if (const char *Name =
+            FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
+      Frame.FunctionName = Name;
+    if (Spec.FLIKind != FileLineInfoKind::None) {
       if (i == 0) {
         // For the topmost frame, initialize the line table of this
         // compile unit and fetch file/line info from it.
         LineTable = getLineTableForCompileUnit(CU);
         // For the topmost routine, get file/line info from line table.
-        getFileLineInfoForCompileUnit(CU, LineTable, Address,
-                                      NeedsAbsoluteFilePath, Frame);
+        getFileLineInfoForCompileUnit(CU, LineTable, Address, Spec.FLIKind,
+                                      Frame);
       } else {
         // Otherwise, use call file, call line and call column from
         // previous DIE in inlined chain.
-        getFileNameForCompileUnit(CU, LineTable, CallFile,
-                                  NeedsAbsoluteFilePath, Frame.FileName);
+        getFileNameForCompileUnit(CU, LineTable, CallFile, Spec.FLIKind,
+                                  Frame.FileName);
         Frame.Line = CallLine;
         Frame.Column = CallColumn;
       }
diff --git a/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
index c23c9c6..d2b5293 100644
--- a/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
+++ b/llvm/lib/DebugInfo/DWARFDebugInfoEntry.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 using namespace dwarf;
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
 
 void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u,
                                       unsigned recurseDepth,
@@ -272,8 +273,9 @@
 }
 
 const char *
-DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U) const {
-  if (!isSubroutineDIE())
+DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
+                                              FunctionNameKind Kind) const {
+  if (!isSubroutineDIE() || Kind == FunctionNameKind::None)
     return nullptr;
   // Try to get mangled name if possible.
   if (const char *name =
@@ -290,7 +292,7 @@
   if (spec_ref != -1U) {
     DWARFDebugInfoEntryMinimal spec_die;
     if (spec_die.extractFast(U, &spec_ref)) {
-      if (const char *name = spec_die.getSubroutineName(U))
+      if (const char *name = spec_die.getSubroutineName(U, Kind))
         return name;
     }
   }
@@ -300,7 +302,7 @@
   if (abs_origin_ref != -1U) {
     DWARFDebugInfoEntryMinimal abs_origin_die;
     if (abs_origin_die.extractFast(U, &abs_origin_ref)) {
-      if (const char *name = abs_origin_die.getSubroutineName(U))
+      if (const char *name = abs_origin_die.getSubroutineName(U, Kind))
         return name;
     }
   }
diff --git a/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h b/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
index 35140d7..916e1ed 100644
--- a/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
+++ b/llvm/lib/DebugInfo/DWARFDebugInfoEntry.h
@@ -13,6 +13,7 @@
 #include "DWARFAbbreviationDeclaration.h"
 #include "DWARFDebugRangeList.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DIContext.h"
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
@@ -122,7 +123,9 @@
   /// returns its mangled name (or short name, if mangled is missing).
   /// This name may be fetched from specification or abstract origin
   /// for this subprogram. Returns null if no name is found.
-  const char *getSubroutineName(const DWARFUnit *U) const;
+  const char *
+  getSubroutineName(const DWARFUnit *U,
+                    DILineInfoSpecifier::FunctionNameKind Kind) const;
 
   /// Retrieves values of DW_AT_call_file, DW_AT_call_line and
   /// DW_AT_call_column from DIE (or zeroes if they are missing).
diff --git a/llvm/lib/DebugInfo/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARFDebugLine.cpp
index a5261d7..ce87635 100644
--- a/llvm/lib/DebugInfo/DWARFDebugLine.cpp
+++ b/llvm/lib/DebugInfo/DWARFDebugLine.cpp
@@ -15,6 +15,7 @@
 #include <algorithm>
 using namespace llvm;
 using namespace dwarf;
+typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
 
 DWARFDebugLine::Prologue::Prologue() {
   clear();
@@ -643,13 +644,14 @@
 
 bool
 DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
-                                              bool NeedsAbsoluteFilePath,
+                                              FileLineInfoKind Kind,
                                               std::string &Result) const {
-  if (FileIndex == 0 || FileIndex > Prologue.FileNames.size())
+  if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
+      Kind == FileLineInfoKind::None)
     return false;
   const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
   const char *FileName = Entry.Name;
-  if (!NeedsAbsoluteFilePath ||
+  if (Kind != FileLineInfoKind::AbsoluteFilePath ||
       sys::path::is_absolute(FileName)) {
     Result = FileName;
     return true;
diff --git a/llvm/lib/DebugInfo/DWARFDebugLine.h b/llvm/lib/DebugInfo/DWARFDebugLine.h
index 0b3e267..c7b7ec2 100644
--- a/llvm/lib/DebugInfo/DWARFDebugLine.h
+++ b/llvm/lib/DebugInfo/DWARFDebugLine.h
@@ -11,6 +11,7 @@
 #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H
 
 #include "DWARFRelocMap.h"
+#include "llvm/DebugInfo/DIContext.h"
 #include "llvm/Support/DataExtractor.h"
 #include <map>
 #include <string>
@@ -179,7 +180,7 @@
     // Extracts filename by its index in filename table in prologue.
     // Returns true on success.
     bool getFileNameByIndex(uint64_t FileIndex,
-                            bool NeedsAbsoluteFilePath,
+                            DILineInfoSpecifier::FileLineInfoKind Kind,
                             std::string &Result) const;
 
     void dump(raw_ostream &OS) const;