Read macro info from .debug_macro section and use it for expression evaluation.

Summary:
DWARF 5 proposes a reinvented .debug_macro section. This change follows
that spec.

Currently, only GCC produces the .debug_macro section and hence
the added test is annottated with expectedFailureClang.

Reviewers: spyffe, clayborg, tberghammer

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D15437

llvm-svn: 255729
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index fd254ad..9c161eb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -39,6 +39,7 @@
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/DebugMacros.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/TypeSystem.h"
@@ -58,6 +59,7 @@
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
 #include "DWARFDebugLine.h"
+#include "DWARFDebugMacro.h"
 #include "DWARFDebugPubnames.h"
 #include "DWARFDebugRanges.h"
 #include "DWARFDeclContext.h"
@@ -436,6 +438,7 @@
     m_data_debug_frame (),
     m_data_debug_info (),
     m_data_debug_line (),
+    m_data_debug_macro (),
     m_data_debug_loc (),
     m_data_debug_ranges (),
     m_data_debug_str (),
@@ -709,6 +712,12 @@
 }
 
 const DWARFDataExtractor&
+SymbolFileDWARF::get_debug_macro_data()
+{
+    return GetCachedSectionData (eSectionTypeDWARFDebugMacro, m_data_debug_macro);
+}
+
+const DWARFDataExtractor&
 SymbolFileDWARF::get_debug_loc_data()
 {
     return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc);
@@ -1204,6 +1213,51 @@
     return false;
 }
 
+lldb_private::DebugMacrosSP
+SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset)
+{
+    auto iter = m_debug_macros_map.find(*offset);
+    if (iter != m_debug_macros_map.end())
+        return iter->second;
+
+    const DWARFDataExtractor &debug_macro_data = get_debug_macro_data();
+    if (debug_macro_data.GetByteSize() == 0)
+        return DebugMacrosSP();
+
+    lldb_private::DebugMacrosSP debug_macros_sp(new lldb_private::DebugMacros());
+    m_debug_macros_map[*offset] = debug_macros_sp;
+
+    const DWARFDebugMacroHeader &header = DWARFDebugMacroHeader::ParseHeader(debug_macro_data, offset);
+    DWARFDebugMacroEntry::ReadMacroEntries(
+        debug_macro_data, get_debug_str_data(), header.OffsetIs64Bit(), offset, this, debug_macros_sp);
+
+    return debug_macros_sp;
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext& sc)
+{
+    assert (sc.comp_unit);
+
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu == nullptr)
+        return false;
+
+    const DWARFDIE dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+    if (!dwarf_cu_die)
+        return false;
+
+    lldb::offset_t sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_macros, DW_INVALID_OFFSET);
+    if (sect_offset == DW_INVALID_OFFSET)
+        sect_offset = dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_macros, DW_INVALID_OFFSET);
+    if (sect_offset == DW_INVALID_OFFSET)
+        return false;
+
+    sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
+
+    return true;
+}
+
 size_t
 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext& sc,
                                       Block *parent_block,