// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// dwarf_cu_to_module.cc: Unit tests for google_breakpad::DwarfCUToModule.

#include <stdint.h>

#include <string>
#include <utility>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "common/dwarf_cu_to_module.h"
#include "common/using_std_string.h"

using std::make_pair;
using std::vector;

using dwarf2reader::DIEHandler;
using dwarf2reader::DwarfTag;
using dwarf2reader::DwarfAttribute;
using dwarf2reader::DwarfForm;
using dwarf2reader::DwarfInline;
using dwarf2reader::RootDIEHandler;
using google_breakpad::DwarfCUToModule;
using google_breakpad::Module;

using ::testing::_;
using ::testing::AtMost;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::Test;
using ::testing::TestWithParam;
using ::testing::Values;
using ::testing::ValuesIn;

// Mock classes.

class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler {
 public:
  MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir));
  MOCK_METHOD4(ReadProgram, void(const uint8_t *program, uint64 length,
                                 Module *module, vector<Module::Line> *lines));
};

class MockWarningReporter: public DwarfCUToModule::WarningReporter {
 public:
  MockWarningReporter(const string &filename, uint64 cu_offset)
      : DwarfCUToModule::WarningReporter(filename, cu_offset) { }
  MOCK_METHOD1(SetCUName, void(const string &name));
  MOCK_METHOD2(UnknownSpecification, void(uint64 offset, uint64 target));
  MOCK_METHOD2(UnknownAbstractOrigin, void(uint64 offset, uint64 target));
  MOCK_METHOD1(MissingSection, void(const string &section_name));
  MOCK_METHOD1(BadLineInfoOffset, void(uint64 offset));
  MOCK_METHOD1(UncoveredFunction, void(const Module::Function &function));
  MOCK_METHOD1(UncoveredLine, void(const Module::Line &line));
  MOCK_METHOD1(UnnamedFunction, void(uint64 offset));
  MOCK_METHOD1(DemangleError, void(const string &input));
  MOCK_METHOD2(UnhandledInterCUReference, void(uint64 offset, uint64 target));
};

// A fixture class including all the objects needed to handle a
// compilation unit, and their entourage. It includes member functions
// for doing common kinds of setup and tests.
class CUFixtureBase {
 public:
  // If we have:
  //
  //   vector<Module::Line> lines;
  //   AppendLinesFunctor appender(lines);
  //
  // then doing:
  //
  //   appender(line_program, length, module, line_vector);
  //
  // will append lines to the end of line_vector.  We can use this with
  // MockLineToModuleHandler like this:
  //
  //   MockLineToModuleHandler l2m;
  //   EXPECT_CALL(l2m, ReadProgram(_,_,_,_))
  //       .WillOnce(DoAll(Invoke(appender), Return()));
  //
  // in which case calling l2m with some line vector will append lines.
  class AppendLinesFunctor {
   public:
    explicit AppendLinesFunctor(
        const vector<Module::Line> *lines) : lines_(lines) { }
    void operator()(const uint8_t *program, uint64 length,
                    Module *module, vector<Module::Line> *lines) {
      lines->insert(lines->end(), lines_->begin(), lines_->end());
    }
   private:
    const vector<Module::Line> *lines_;
  };

  CUFixtureBase()
      : module_("module-name", "module-os", "module-arch", "module-id"),
        file_context_("dwarf-filename", &module_, true),
        language_(dwarf2reader::DW_LANG_none),
        language_signed_(false),
        appender_(&lines_),
        reporter_("dwarf-filename", 0xcf8f9bb6443d29b5LL),
        root_handler_(&file_context_, &line_reader_,
                      /* ranges_reader */ nullptr, &reporter_),
        functions_filled_(false) {
    // By default, expect no warnings to be reported, and expect the
    // compilation unit's name to be provided. The test can override
    // these expectations.
    EXPECT_CALL(reporter_, SetCUName("compilation-unit-name")).Times(1);
    EXPECT_CALL(reporter_, UnknownSpecification(_, _)).Times(0);
    EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, _)).Times(0);
    EXPECT_CALL(reporter_, MissingSection(_)).Times(0);
    EXPECT_CALL(reporter_, BadLineInfoOffset(_)).Times(0);
    EXPECT_CALL(reporter_, UncoveredFunction(_)).Times(0);
    EXPECT_CALL(reporter_, UncoveredLine(_)).Times(0);
    EXPECT_CALL(reporter_, UnnamedFunction(_)).Times(0);
    EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(0);

    // By default, expect the line program reader not to be invoked. We
    // may override this in StartCU.
    EXPECT_CALL(line_reader_, StartCompilationUnit(_)).Times(0);
    EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_)).Times(0);

    // The handler will consult this section map to decide what to
    // pass to our line reader.
    file_context_.AddSectionToSectionMap(".debug_line",
                                         dummy_line_program_,
                                         dummy_line_size_);
  }

  // Add a line with the given address, size, filename, and line
  // number to the end of the statement list the handler will receive
  // when it invokes its LineToModuleHandler. Call this before calling
  // StartCU.
  void PushLine(Module::Address address, Module::Address size,
                const string &filename, int line_number);

  // Use LANGUAGE for the compilation unit. More precisely, arrange
  // for StartCU to pass the compilation unit's root DIE a
  // DW_AT_language attribute whose value is LANGUAGE.
  void SetLanguage(dwarf2reader::DwarfLanguage language) {
    language_ = language;
  }

  // If SIGNED true, have StartCU report DW_AT_language as a signed
  // attribute; if false, have it report it as unsigned.
  void SetLanguageSigned(bool is_signed) { language_signed_ = is_signed; }

  // Call the handler this.root_handler_'s StartCompilationUnit and
  // StartRootDIE member functions, passing it appropriate attributes as
  // determined by prior calls to PushLine and SetLanguage. Leave
  // this.root_handler_ ready to hear about children: call
  // this.root_handler_.EndAttributes, but not this.root_handler_.Finish.
  void StartCU();

  // Have HANDLER process some strange attribute/form/value triples.
  void ProcessStrangeAttributes(dwarf2reader::DIEHandler *handler);

  // Start a child DIE of PARENT with the given tag and name. Leave
  // the handler ready to hear about children: call EndAttributes, but
  // not Finish.
  DIEHandler *StartNamedDIE(DIEHandler *parent, DwarfTag tag,
                            const string &name);

  // Start a child DIE of PARENT with the given tag and a
  // DW_AT_specification attribute whose value is SPECIFICATION. Leave
  // the handler ready to hear about children: call EndAttributes, but
  // not Finish. If NAME is non-zero, use it as the DW_AT_name
  // attribute.
  DIEHandler *StartSpecifiedDIE(DIEHandler *parent, DwarfTag tag,
                                uint64 specification, const char *name = NULL);

  // Define a function as a child of PARENT with the given name, address, and
  // size. If high_pc_form is DW_FORM_addr then the DW_AT_high_pc attribute
  // will be written as an address; otherwise it will be written as the
  // function's size. Call EndAttributes and Finish; one cannot define
  // children of the defined function's DIE.
  void DefineFunction(DIEHandler *parent, const string &name,
                      Module::Address address, Module::Address size,
                      const char* mangled_name,
                      DwarfForm high_pc_form = dwarf2reader::DW_FORM_addr);

  // Create a declaration DIE as a child of PARENT with the given
  // offset, tag and name. If NAME is the empty string, don't provide
  // a DW_AT_name attribute. Call EndAttributes and Finish.
  void DeclarationDIE(DIEHandler *parent, uint64 offset,
                      DwarfTag tag, const string &name,
                      const string &mangled_name);

  // Create a definition DIE as a child of PARENT with the given tag
  // that refers to the declaration DIE at offset SPECIFICATION as its
  // specification. If NAME is non-empty, pass it as the DW_AT_name
  // attribute. If SIZE is non-zero, record ADDRESS and SIZE as
  // low_pc/high_pc attributes.
  void DefinitionDIE(DIEHandler *parent, DwarfTag tag,
                     uint64 specification, const string &name,
                     Module::Address address = 0, Module::Address size = 0);

  // Create an inline DW_TAG_subprogram DIE as a child of PARENT.  If
  // SPECIFICATION is non-zero, then the DIE refers to the declaration DIE at
  // offset SPECIFICATION as its specification.  If Name is non-empty, pass it
  // as the DW_AT_name attribute.
  void AbstractInstanceDIE(DIEHandler *parent, uint64 offset,
                           DwarfInline type, uint64 specification,
                           const string &name,
                           DwarfForm form = dwarf2reader::DW_FORM_data1);

  // Create a DW_TAG_subprogram DIE as a child of PARENT that refers to
  // ORIGIN in its DW_AT_abstract_origin attribute.  If NAME is the empty
  // string, don't provide a DW_AT_name attribute.
  void DefineInlineInstanceDIE(DIEHandler *parent, const string &name,
                               uint64 origin, Module::Address address,
                               Module::Address size);

  // The following Test* functions should be called after calling
  // this.root_handler_.Finish. After that point, no further calls
  // should be made on the handler.

  // Test that the number of functions defined in the module this.module_ is
  // equal to EXPECTED.
  void TestFunctionCount(size_t expected);

  // Test that the I'th function (ordered by address) in the module
  // this.module_ has the given name, address, and size, and that its
  // parameter size is zero.
  void TestFunction(int i, const string &name,
                    Module::Address address, Module::Address size);

  // Test that the number of source lines owned by the I'th function
  // in the module this.module_ is equal to EXPECTED.
  void TestLineCount(int i, size_t expected);

  // Test that the J'th line (ordered by address) of the I'th function
  // (again, by address) has the given address, size, filename, and
  // line number.
  void TestLine(int i, int j, Module::Address address, Module::Address size,
                const string &filename, int number);

  // Actual objects under test.
  Module module_;
  DwarfCUToModule::FileContext file_context_;

  // If this is not DW_LANG_none, we'll pass it as a DW_AT_language
  // attribute to the compilation unit. This defaults to DW_LANG_none.
  dwarf2reader::DwarfLanguage language_;

  // If this is true, report DW_AT_language as a signed value; if false,
  // report it as an unsigned value.
  bool language_signed_;

  // If this is not empty, we'll give the CU a DW_AT_comp_dir attribute that
  // indicates the path that this compilation unit was compiled in.
  string compilation_dir_;

  // If this is not empty, we'll give the CU a DW_AT_stmt_list
  // attribute that, when passed to line_reader_, adds these lines to the
  // provided lines array.
  vector<Module::Line> lines_;

  // Mock line program reader.
  MockLineToModuleHandler line_reader_;
  AppendLinesFunctor appender_;
  static const uint8_t dummy_line_program_[];
  static const size_t dummy_line_size_;

  MockWarningReporter reporter_;
  DwarfCUToModule root_handler_;

 private:
  // Fill functions_, if we haven't already.
  void FillFunctions();

  // If functions_filled_ is true, this is a table of functions we've
  // extracted from module_, sorted by address.
  vector<Module::Function *> functions_;
  // True if we have filled the above vector with this.module_'s function list.
  bool functions_filled_;
};

const uint8_t CUFixtureBase::dummy_line_program_[] = "lots of fun data";
const size_t CUFixtureBase::dummy_line_size_ =
    sizeof(CUFixtureBase::dummy_line_program_);

void CUFixtureBase::PushLine(Module::Address address, Module::Address size,
                             const string &filename, int line_number) {
  Module::Line l;
  l.address = address;
  l.size = size;
  l.file = module_.FindFile(filename);
  l.number = line_number;
  lines_.push_back(l);
}

void CUFixtureBase::StartCU() {
  if (!compilation_dir_.empty())
    EXPECT_CALL(line_reader_,
                StartCompilationUnit(compilation_dir_)).Times(1);

  // If we have lines, make the line reader expect to be invoked at
  // most once. (Hey, if the handler can pass its tests without
  // bothering to read the line number data, that's great.)
  // Have it add the lines passed to PushLine. Otherwise, leave the
  // initial expectation (no calls) in force.
  if (!lines_.empty())
    EXPECT_CALL(line_reader_,
                ReadProgram(&dummy_line_program_[0], dummy_line_size_,
                            &module_, _))
        .Times(AtMost(1))
        .WillOnce(DoAll(Invoke(appender_), Return()));

  ASSERT_TRUE(root_handler_
              .StartCompilationUnit(0x51182ec307610b51ULL, 0x81, 0x44,
                                    0x4241b4f33720dd5cULL, 3));
  {
    ASSERT_TRUE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
                                           dwarf2reader::DW_TAG_compile_unit));
  }
  root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
                                       dwarf2reader::DW_FORM_strp,
                                       "compilation-unit-name");
  if (!compilation_dir_.empty())
    root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_comp_dir,
                                         dwarf2reader::DW_FORM_strp,
                                         compilation_dir_);
  if (!lines_.empty())
    root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
                                           dwarf2reader::DW_FORM_ref4,
                                           0);
  if (language_ != dwarf2reader::DW_LANG_none) {
    if (language_signed_)
      root_handler_.ProcessAttributeSigned(dwarf2reader::DW_AT_language,
                                           dwarf2reader::DW_FORM_sdata,
                                           language_);
    else
      root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_language,
                                             dwarf2reader::DW_FORM_udata,
                                             language_);
  }
  ASSERT_TRUE(root_handler_.EndAttributes());
}

void CUFixtureBase::ProcessStrangeAttributes(
    dwarf2reader::DIEHandler *handler) {
  handler->ProcessAttributeUnsigned((DwarfAttribute) 0xf560dead,
                                    (DwarfForm) 0x4106e4db,
                                    0xa592571997facda1ULL);
  handler->ProcessAttributeSigned((DwarfAttribute) 0x85380095,
                                  (DwarfForm) 0x0f16fe87,
                                  0x12602a4e3bf1f446LL);
  handler->ProcessAttributeReference((DwarfAttribute) 0xf7f7480f,
                                     (DwarfForm) 0x829e038a,
                                     0x50fddef44734fdecULL);
  static const uint8_t buffer[10] = "frobynode";
  handler->ProcessAttributeBuffer((DwarfAttribute) 0xa55ffb51,
                                  (DwarfForm) 0x2f43b041,
                                  buffer, sizeof(buffer));
  handler->ProcessAttributeString((DwarfAttribute) 0x2f43b041,
                                  (DwarfForm) 0x895ffa23,
                                  "strange string");
}

DIEHandler *CUFixtureBase::StartNamedDIE(DIEHandler *parent,
                                         DwarfTag tag,
                                         const string &name) {
  dwarf2reader::DIEHandler *handler
    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag);
  if (!handler)
    return NULL;
  handler->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                  dwarf2reader::DW_FORM_strp,
                                  name);
  ProcessStrangeAttributes(handler);
  if (!handler->EndAttributes()) {
    handler->Finish();
    delete handler;
    return NULL;
  }

  return handler;
}

DIEHandler *CUFixtureBase::StartSpecifiedDIE(DIEHandler *parent,
                                             DwarfTag tag,
                                             uint64 specification,
                                             const char *name) {
  dwarf2reader::DIEHandler *handler
    = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag);
  if (!handler)
    return NULL;
  if (name)
    handler->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                    dwarf2reader::DW_FORM_strp,
                                    name);
  handler->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
                                     dwarf2reader::DW_FORM_ref4,
                                     specification);
  if (!handler->EndAttributes()) {
    handler->Finish();
    delete handler;
    return NULL;
  }

  return handler;
}

void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent,
                                   const string &name, Module::Address address,
                                   Module::Address size,
                                   const char* mangled_name,
                                   DwarfForm high_pc_form) {
  dwarf2reader::DIEHandler *func
      = parent->FindChildHandler(0xe34797c7e68590a8LL,
                                 dwarf2reader::DW_TAG_subprogram);
  ASSERT_TRUE(func != NULL);
  func->ProcessAttributeString(dwarf2reader::DW_AT_name,
                               dwarf2reader::DW_FORM_strp,
                               name);
  func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
                                 dwarf2reader::DW_FORM_addr,
                                 address);

  Module::Address high_pc = size;
  if (high_pc_form == dwarf2reader::DW_FORM_addr) {
    high_pc += address;
  }
  func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
                                 high_pc_form,
                                 high_pc);

  if (mangled_name)
    func->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name,
                                 dwarf2reader::DW_FORM_strp,
                                 mangled_name);

  ProcessStrangeAttributes(func);
  EXPECT_TRUE(func->EndAttributes());
  func->Finish();
  delete func;
}

void CUFixtureBase::DeclarationDIE(DIEHandler *parent, uint64 offset,
                                   DwarfTag tag,
                                   const string &name,
                                   const string &mangled_name) {
  dwarf2reader::DIEHandler *die = parent->FindChildHandler(offset, tag);
  ASSERT_TRUE(die != NULL);
  if (!name.empty())
    die->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                dwarf2reader::DW_FORM_strp,
                                name);
  if (!mangled_name.empty())
    die->ProcessAttributeString(dwarf2reader::DW_AT_MIPS_linkage_name,
                                dwarf2reader::DW_FORM_strp,
                                mangled_name);

  die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_declaration,
                                dwarf2reader::DW_FORM_flag,
                                1);
  EXPECT_TRUE(die->EndAttributes());
  die->Finish();
  delete die;
}

void CUFixtureBase::DefinitionDIE(DIEHandler *parent,
                                  DwarfTag tag,
                                  uint64 specification,
                                  const string &name,
                                  Module::Address address,
                                  Module::Address size) {
  dwarf2reader::DIEHandler *die
    = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag);
  ASSERT_TRUE(die != NULL);
  die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
                                 dwarf2reader::DW_FORM_ref4,
                                 specification);
  if (!name.empty())
    die->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                dwarf2reader::DW_FORM_strp,
                                name);
  if (size) {
    die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
                                  dwarf2reader::DW_FORM_addr,
                                  address);
    die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
                                  dwarf2reader::DW_FORM_addr,
                                  address + size);
  }
  EXPECT_TRUE(die->EndAttributes());
  die->Finish();
  delete die;
}

void CUFixtureBase::AbstractInstanceDIE(DIEHandler *parent,
                                        uint64 offset,
                                        DwarfInline type,
                                        uint64 specification,
                                        const string &name,
                                        DwarfForm form) {
  dwarf2reader::DIEHandler *die
    = parent->FindChildHandler(offset, dwarf2reader::DW_TAG_subprogram);
  ASSERT_TRUE(die != NULL);
  if (specification != 0ULL)
    die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
                                   dwarf2reader::DW_FORM_ref4,
                                   specification);
  if (form == dwarf2reader::DW_FORM_sdata) {
    die->ProcessAttributeSigned(dwarf2reader::DW_AT_inline, form, type);
  } else {
    die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_inline, form, type);
  }
  if (!name.empty())
    die->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                dwarf2reader::DW_FORM_strp,
                                name);

  EXPECT_TRUE(die->EndAttributes());
  die->Finish();
  delete die;
}

void CUFixtureBase::DefineInlineInstanceDIE(DIEHandler *parent,
                                            const string &name,
                                            uint64 origin,
                                            Module::Address address,
                                            Module::Address size) {
  dwarf2reader::DIEHandler *func
      = parent->FindChildHandler(0x11c70f94c6e87ccdLL,
                                 dwarf2reader::DW_TAG_subprogram);
  ASSERT_TRUE(func != NULL);
  if (!name.empty()) {
    func->ProcessAttributeString(dwarf2reader::DW_AT_name,
                                 dwarf2reader::DW_FORM_strp,
                                 name);
  }
  func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
                                 dwarf2reader::DW_FORM_addr,
                                 address);
  func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
                                 dwarf2reader::DW_FORM_addr,
                                 address + size);
  func->ProcessAttributeReference(dwarf2reader::DW_AT_abstract_origin,
                                 dwarf2reader::DW_FORM_ref4,
                                 origin);
  ProcessStrangeAttributes(func);
  EXPECT_TRUE(func->EndAttributes());
  func->Finish();
  delete func;
}

void CUFixtureBase::FillFunctions() {
  if (functions_filled_)
    return;
  module_.GetFunctions(&functions_, functions_.end());
  sort(functions_.begin(), functions_.end(),
       Module::Function::CompareByAddress);
  functions_filled_ = true;
}

void CUFixtureBase::TestFunctionCount(size_t expected) {
  FillFunctions();
  ASSERT_EQ(expected, functions_.size());
}

void CUFixtureBase::TestFunction(int i, const string &name,
                                 Module::Address address,
                                 Module::Address size) {
  FillFunctions();
  ASSERT_LT((size_t) i, functions_.size());

  Module::Function *function = functions_[i];
  EXPECT_EQ(name,    function->name);
  EXPECT_EQ(address, function->address);
  EXPECT_EQ(size,    function->ranges[0].size);
  EXPECT_EQ(0U,      function->parameter_size);
}

void CUFixtureBase::TestLineCount(int i, size_t expected) {
  FillFunctions();
  ASSERT_LT((size_t) i, functions_.size());

  ASSERT_EQ(expected, functions_[i]->lines.size());
}

void CUFixtureBase::TestLine(int i, int j,
                             Module::Address address, Module::Address size,
                             const string &filename, int number) {
  FillFunctions();
  ASSERT_LT((size_t) i, functions_.size());
  ASSERT_LT((size_t) j, functions_[i]->lines.size());

  Module::Line *line = &functions_[i]->lines[j];
  EXPECT_EQ(address,  line->address);
  EXPECT_EQ(size,     line->size);
  EXPECT_EQ(filename, line->file->name.c_str());
  EXPECT_EQ(number,   line->number);
}

// Include caller locations for our test subroutines.
#define TRACE(call) do { SCOPED_TRACE("called from here"); call; } while (0)
#define PushLine(a,b,c,d)         TRACE(PushLine((a),(b),(c),(d)))
#define SetLanguage(a)            TRACE(SetLanguage(a))
#define StartCU()                 TRACE(StartCU())
#define DefineFunction(a,b,c,d,e) TRACE(DefineFunction((a),(b),(c),(d),(e)))
// (DefineFunction) instead of DefineFunction to avoid macro expansion.
#define DefineFunction6(a,b,c,d,e,f) \
    TRACE((DefineFunction)((a),(b),(c),(d),(e),(f)))
#define DeclarationDIE(a,b,c,d,e) TRACE(DeclarationDIE((a),(b),(c),(d),(e)))
#define DefinitionDIE(a,b,c,d,e,f) \
    TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
#define TestFunctionCount(a)      TRACE(TestFunctionCount(a))
#define TestFunction(a,b,c,d)     TRACE(TestFunction((a),(b),(c),(d)))
#define TestLineCount(a,b)        TRACE(TestLineCount((a),(b)))
#define TestLine(a,b,c,d,e,f)     TRACE(TestLine((a),(b),(c),(d),(e),(f)))

class SimpleCU: public CUFixtureBase, public Test {
};

TEST_F(SimpleCU, CompilationDir) {
  compilation_dir_ = "/src/build/";

  StartCU();
  root_handler_.Finish();
}

TEST_F(SimpleCU, OneFunc) {
  PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);

  StartCU();
  DefineFunction(&root_handler_, "function1",
                 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
  TestLineCount(0, 1);
  TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file",
           246571772);
}

// As above, only DW_AT_high_pc is a length rather than an address.
TEST_F(SimpleCU, OneFuncHighPcIsLength) {
  PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);

  StartCU();
  DefineFunction6(&root_handler_, "function1",
                  0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, NULL,
                  dwarf2reader::DW_FORM_udata);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
  TestLineCount(0, 1);
  TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file",
           246571772);
}

TEST_F(SimpleCU, MangledName) {
  PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);

  StartCU();
  DefineFunction(&root_handler_, "function1",
                 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "_ZN1n1fEi");
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "n::f(int)", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
}

TEST_F(SimpleCU, IrrelevantRootChildren) {
  StartCU();
  EXPECT_FALSE(root_handler_
               .FindChildHandler(0x7db32bff4e2dcfb1ULL,
                                 dwarf2reader::DW_TAG_lexical_block));
}

TEST_F(SimpleCU, IrrelevantNamedScopeChildren) {
  StartCU();
  DIEHandler *class_A_handler
    = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A");
  EXPECT_TRUE(class_A_handler != NULL);
  EXPECT_FALSE(class_A_handler
               ->FindChildHandler(0x02e55999b865e4e9ULL,
                                  dwarf2reader::DW_TAG_lexical_block));
  delete class_A_handler;
}

// Verify that FileContexts can safely be deleted unused.
TEST_F(SimpleCU, UnusedFileContext) {
  Module m("module-name", "module-os", "module-arch", "module-id");
  DwarfCUToModule::FileContext fc("dwarf-filename", &m, true);

  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");
}

TEST_F(SimpleCU, InlineFunction) {
  PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);

  StartCU();
  AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
                      dwarf2reader::DW_INL_inlined, 0, "inline-name");
  DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
                       0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "inline-name",
               0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}

TEST_F(SimpleCU, InlineFunctionSignedAttribute) {
  PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);

  StartCU();
  AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
                      dwarf2reader::DW_INL_inlined, 0, "inline-name",
                      dwarf2reader::DW_FORM_sdata);
  DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
                       0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "inline-name",
               0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}

// Any DIE with an DW_AT_inline attribute can be cited by
// DW_AT_abstract_origin attributes --- even if the value of the
// DW_AT_inline attribute is DW_INL_not_inlined.
TEST_F(SimpleCU, AbstractOriginNotInlined) {
  PushLine(0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL, "line-file", 6111581);

  StartCU();
  AbstractInstanceDIE(&root_handler_, 0x93e9cdad52826b39ULL,
                      dwarf2reader::DW_INL_not_inlined, 0, "abstract-instance");
  DefineInlineInstanceDIE(&root_handler_, "", 0x93e9cdad52826b39ULL,
                          0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "abstract-instance",
               0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
}

TEST_F(SimpleCU, UnknownAbstractOrigin) {
  EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, 1ULL)).WillOnce(Return());
  EXPECT_CALL(reporter_, UnnamedFunction(0x11c70f94c6e87ccdLL))
    .WillOnce(Return());
  PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);

  StartCU();
  AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
                      dwarf2reader::DW_INL_inlined, 0, "inline-name");
  DefineInlineInstanceDIE(&root_handler_, "", 1ULL,
                       0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "<name omitted>",
               0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}

TEST_F(SimpleCU, UnnamedFunction) {
  EXPECT_CALL(reporter_, UnnamedFunction(0xe34797c7e68590a8LL))
    .WillOnce(Return());
  PushLine(0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, "line-file", 14044850);

  StartCU();
  DefineFunction(&root_handler_, "",
                 0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL, NULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "<name omitted>",
               0x72b80e41a0ac1d40ULL, 0x537174f231ee181cULL);
}

// An address range.
struct Range {
  Module::Address start, end;
};

// Test data for pairing functions and lines.
struct Situation {
  // Two function intervals, and two line intervals.
  Range functions[2], lines[2];

  // The number of lines we expect to be assigned to each of the
  // functions, and the address ranges.
  int paired_count[2];
  Range paired[2][2];

  // The number of functions that are not entirely covered by lines,
  // and vice versa.
  int uncovered_functions, uncovered_lines;
};

#define PAIRING(func1_start, func1_end, func2_start, func2_end, \
                line1_start, line1_end, line2_start, line2_end, \
                func1_num_lines, func2_num_lines,               \
                func1_line1_start, func1_line1_end,             \
                func1_line2_start, func1_line2_end,             \
                func2_line1_start, func2_line1_end,             \
                func2_line2_start, func2_line2_end,             \
                uncovered_functions, uncovered_lines)           \
  { { { func1_start, func1_end }, { func2_start, func2_end } }, \
    { { line1_start, line1_end }, { line2_start, line2_end } }, \
    { func1_num_lines, func2_num_lines },                       \
    { { { func1_line1_start, func1_line1_end },                 \
        { func1_line2_start, func1_line2_end } },               \
      { { func2_line1_start, func2_line1_end },                 \
          { func2_line2_start, func2_line2_end } } },           \
    uncovered_functions, uncovered_lines },

Situation situations[] = {
#include "common/testdata/func-line-pairing.h"
};

#undef PAIRING

class FuncLinePairing: public CUFixtureBase,
                       public TestWithParam<Situation> { };

INSTANTIATE_TEST_CASE_P(AllSituations, FuncLinePairing,
                        ValuesIn(situations));

TEST_P(FuncLinePairing, Pairing) {
  const Situation &s = GetParam();
  PushLine(s.lines[0].start,
           s.lines[0].end - s.lines[0].start,
           "line-file", 67636963);
  PushLine(s.lines[1].start,
           s.lines[1].end - s.lines[1].start,
           "line-file", 67636963);
  if (s.uncovered_functions)
    EXPECT_CALL(reporter_, UncoveredFunction(_))
      .Times(s.uncovered_functions)
      .WillRepeatedly(Return());
  if (s.uncovered_lines)
    EXPECT_CALL(reporter_, UncoveredLine(_))
      .Times(s.uncovered_lines)
      .WillRepeatedly(Return());

  StartCU();
  DefineFunction(&root_handler_, "function1",
                 s.functions[0].start,
                 s.functions[0].end - s.functions[0].start, NULL);
  DefineFunction(&root_handler_, "function2",
                 s.functions[1].start,
                 s.functions[1].end - s.functions[1].start, NULL);
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "function1",
               s.functions[0].start,
               s.functions[0].end - s.functions[0].start);
  TestLineCount(0, s.paired_count[0]);
  for (int i = 0; i < s.paired_count[0]; i++)
    TestLine(0, i, s.paired[0][i].start,
             s.paired[0][i].end - s.paired[0][i].start,
             "line-file", 67636963);
  TestFunction(1, "function2",
               s.functions[1].start,
               s.functions[1].end - s.functions[1].start);
  TestLineCount(1, s.paired_count[1]);
  for (int i = 0; i < s.paired_count[1]; i++)
    TestLine(1, i, s.paired[1][i].start,
             s.paired[1][i].end - s.paired[1][i].start,
             "line-file", 67636963);
}

TEST_F(FuncLinePairing, EmptyCU) {
  StartCU();
  root_handler_.Finish();

  TestFunctionCount(0);
}

TEST_F(FuncLinePairing, LinesNoFuncs) {
  PushLine(40, 2, "line-file", 82485646);
  EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());

  StartCU();
  root_handler_.Finish();

  TestFunctionCount(0);
}

TEST_F(FuncLinePairing, FuncsNoLines) {
  EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());

  StartCU();
  DefineFunction(&root_handler_, "function1", 0x127da12ffcf5c51fULL, 0x1000U,
                 NULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "function1", 0x127da12ffcf5c51fULL, 0x1000U);
}

TEST_F(FuncLinePairing, GapThenFunction) {
  PushLine(20, 2, "line-file-2", 174314698);
  PushLine(10, 2, "line-file-1", 263008005);

  StartCU();
  DefineFunction(&root_handler_, "function1", 10, 2, NULL);
  DefineFunction(&root_handler_, "function2", 20, 2, NULL);
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "function1", 10, 2);
  TestLineCount(0, 1);
  TestLine(0, 0, 10, 2, "line-file-1", 263008005);
  TestFunction(1, "function2", 20, 2);
  TestLineCount(1, 1);
  TestLine(1, 0, 20, 2, "line-file-2", 174314698);
}

// If GCC emits padding after one function to align the start of
// the next, then it will attribute the padding instructions to
// the last source line of function (to reduce the size of the
// line number info), but omit it from the DW_AT_{low,high}_pc
// range given in .debug_info (since it costs nothing to be
// precise there).  If we did use at least some of the line
// we're about to skip, then assume this is what happened, and
// don't warn.
TEST_F(FuncLinePairing, GCCAlignmentStretch) {
  PushLine(10, 10, "line-file", 63351048);
  PushLine(20, 10, "line-file", 61661044);

  StartCU();
  DefineFunction(&root_handler_, "function1", 10, 5, NULL);
  // five-byte gap between functions, covered by line 63351048.
  // This should not elicit a warning.
  DefineFunction(&root_handler_, "function2", 20, 10, NULL);
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "function1", 10, 5);
  TestLineCount(0, 1);
  TestLine(0, 0, 10, 5, "line-file", 63351048);
  TestFunction(1, "function2", 20, 10);
  TestLineCount(1, 1);
  TestLine(1, 0, 20, 10, "line-file", 61661044);
}

// Unfortunately, neither the DWARF parser's handler interface nor the
// DIEHandler interface is capable of expressing a function that abuts
// the end of the address space: the high_pc value looks like zero.

TEST_F(FuncLinePairing, LineAtEndOfAddressSpace) {
  PushLine(0xfffffffffffffff0ULL, 16, "line-file", 63351048);
  EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());

  StartCU();
  DefineFunction(&root_handler_, "function1", 0xfffffffffffffff0ULL, 6, NULL);
  DefineFunction(&root_handler_, "function2", 0xfffffffffffffffaULL, 5, NULL);
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "function1", 0xfffffffffffffff0ULL, 6);
  TestLineCount(0, 1);
  TestLine(0, 0, 0xfffffffffffffff0ULL, 6, "line-file", 63351048);
  TestFunction(1, "function2", 0xfffffffffffffffaULL, 5);
  TestLineCount(1, 1);
  TestLine(1, 0, 0xfffffffffffffffaULL, 5, "line-file", 63351048);
}

// A function with more than one uncovered area should only be warned
// about once.
TEST_F(FuncLinePairing, WarnOnceFunc) {
  PushLine(20, 1, "line-file-2", 262951329);
  PushLine(11, 1, "line-file-1", 219964021);
  EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());

  StartCU();
  DefineFunction(&root_handler_, "function", 10, 11, NULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "function", 10, 11);
  TestLineCount(0, 2);
  TestLine(0, 0, 11, 1, "line-file-1", 219964021);
  TestLine(0, 1, 20, 1, "line-file-2", 262951329);
}

// A line with more than one uncovered area should only be warned
// about once.
TEST_F(FuncLinePairing, WarnOnceLine) {
  PushLine(10, 20, "filename1", 118581871);
  EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());

  StartCU();
  DefineFunction(&root_handler_, "function1", 11, 1, NULL);
  DefineFunction(&root_handler_, "function2", 13, 1, NULL);
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "function1", 11, 1);
  TestLineCount(0, 1);
  TestLine(0, 0, 11, 1, "filename1", 118581871);
  TestFunction(1, "function2", 13, 1);
  TestLineCount(1, 1);
  TestLine(1, 0, 13, 1, "filename1", 118581871);
}

class CXXQualifiedNames: public CUFixtureBase,
                         public TestWithParam<DwarfTag> { };

INSTANTIATE_TEST_CASE_P(VersusEnclosures, CXXQualifiedNames,
                        Values(dwarf2reader::DW_TAG_class_type,
                               dwarf2reader::DW_TAG_structure_type,
                               dwarf2reader::DW_TAG_union_type,
                               dwarf2reader::DW_TAG_namespace));

TEST_P(CXXQualifiedNames, TwoFunctions) {
  DwarfTag tag = GetParam();

  SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
  PushLine(10, 1, "filename1", 69819327);
  PushLine(20, 1, "filename2", 95115701);

  StartCU();
  DIEHandler *enclosure_handler = StartNamedDIE(&root_handler_, tag,
                                                "Enclosure");
  EXPECT_TRUE(enclosure_handler != NULL);
  DefineFunction(enclosure_handler, "func_B", 10, 1, NULL);
  DefineFunction(enclosure_handler, "func_C", 20, 1, NULL);
  enclosure_handler->Finish();
  delete enclosure_handler;
  root_handler_.Finish();

  TestFunctionCount(2);
  TestFunction(0, "Enclosure::func_B", 10, 1);
  TestFunction(1, "Enclosure::func_C", 20, 1);
}

TEST_P(CXXQualifiedNames, FuncInEnclosureInNamespace) {
  DwarfTag tag = GetParam();

  SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
  PushLine(10, 1, "line-file", 69819327);

  StartCU();
  DIEHandler *namespace_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                      "Namespace");
  EXPECT_TRUE(namespace_handler != NULL);
  DIEHandler *enclosure_handler = StartNamedDIE(namespace_handler, tag,
                                                "Enclosure");
  EXPECT_TRUE(enclosure_handler != NULL);
  DefineFunction(enclosure_handler, "function", 10, 1, NULL);
  enclosure_handler->Finish();
  delete enclosure_handler;
  namespace_handler->Finish();
  delete namespace_handler;
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "Namespace::Enclosure::function", 10, 1);
}

TEST_F(CXXQualifiedNames, FunctionInClassInStructInNamespace) {
  SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
  PushLine(10, 1, "filename1", 69819327);

  StartCU();
  DIEHandler *namespace_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                      "namespace_A");
  EXPECT_TRUE(namespace_handler != NULL);
  DIEHandler *struct_handler
      = StartNamedDIE(namespace_handler, dwarf2reader::DW_TAG_structure_type,
                      "struct_B");
  EXPECT_TRUE(struct_handler != NULL);
  DIEHandler *class_handler
      = StartNamedDIE(struct_handler, dwarf2reader::DW_TAG_class_type,
                      "class_C");
  DefineFunction(class_handler, "function_D", 10, 1, NULL);
  class_handler->Finish();
  delete class_handler;
  struct_handler->Finish();
  delete struct_handler;
  namespace_handler->Finish();
  delete namespace_handler;
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "namespace_A::struct_B::class_C::function_D", 10, 1);
}

struct LanguageAndQualifiedName {
  dwarf2reader::DwarfLanguage language;
  const char *name;
};

const LanguageAndQualifiedName LanguageAndQualifiedNameCases[] = {
  { dwarf2reader::DW_LANG_none,           "class_A::function_B" },
  { dwarf2reader::DW_LANG_C,              "class_A::function_B" },
  { dwarf2reader::DW_LANG_C89,            "class_A::function_B" },
  { dwarf2reader::DW_LANG_C99,            "class_A::function_B" },
  { dwarf2reader::DW_LANG_C_plus_plus,    "class_A::function_B" },
  { dwarf2reader::DW_LANG_Java,           "class_A.function_B" },
  { dwarf2reader::DW_LANG_Cobol74,        "class_A::function_B" },
  { dwarf2reader::DW_LANG_Mips_Assembler, NULL }
};

class QualifiedForLanguage
    : public CUFixtureBase,
      public TestWithParam<LanguageAndQualifiedName> { };

INSTANTIATE_TEST_CASE_P(LanguageAndQualifiedName, QualifiedForLanguage,
                        ValuesIn(LanguageAndQualifiedNameCases));

TEST_P(QualifiedForLanguage, MemberFunction) {
  const LanguageAndQualifiedName &param = GetParam();

  PushLine(10, 1, "line-file", 212966758);
  SetLanguage(param.language);

  StartCU();
  DIEHandler *class_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                      "class_A");
  DefineFunction(class_handler, "function_B", 10, 1, NULL);
  class_handler->Finish();
  delete class_handler;
  root_handler_.Finish();

  if (param.name) {
    TestFunctionCount(1);
    TestFunction(0, param.name, 10, 1);
  } else {
    TestFunctionCount(0);
  }
}

TEST_P(QualifiedForLanguage, MemberFunctionSignedLanguage) {
  const LanguageAndQualifiedName &param = GetParam();

  PushLine(10, 1, "line-file", 212966758);
  SetLanguage(param.language);
  SetLanguageSigned(true);

  StartCU();
  DIEHandler *class_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                      "class_A");
  DefineFunction(class_handler, "function_B", 10, 1, NULL);
  class_handler->Finish();
  delete class_handler;
  root_handler_.Finish();

  if (param.name) {
    TestFunctionCount(1);
    TestFunction(0, param.name, 10, 1);
  } else {
    TestFunctionCount(0);
  }
}

class Specifications: public CUFixtureBase, public Test { };

TEST_F(Specifications, Function) {
  PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);

  StartCU();
  DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name", "");
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0xcd3c51b946fb1eeeLL, "",
                0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "declaration-name",
               0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}

TEST_F(Specifications, MangledName) {
  // Language defaults to C++, so no need to set it here.
  PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);

  StartCU();
  DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name",
                 "_ZN1C1fEi");
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0xcd3c51b946fb1eeeLL, "",
                0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "C::f(int)",
               0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}

TEST_F(Specifications, MangledNameSwift) {
  // Swift mangled names should pass through untouched.
  SetLanguage(dwarf2reader::DW_LANG_Swift);
  PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);
  StartCU();
  const string kName = "_TFC9swifttest5Shape17simpleDescriptionfS0_FT_Si";
  DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name",
                 kName);
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0xcd3c51b946fb1eeeLL, "",
                0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, kName,
               0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}

TEST_F(Specifications, MangledNameRust) {
  SetLanguage(dwarf2reader::DW_LANG_Rust);
  PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);

  StartCU();
  const string kName = "_ZN14rustc_demangle8demangle17h373defa94bffacdeE";
  DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name",
                 kName);
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0xcd3c51b946fb1eeeLL, "",
                0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0,
#ifndef HAVE_RUST_DEMANGLE
               // Rust mangled names should pass through untouched if not
               // using rust-demangle.
               kName,
#else
               // If rust-demangle is available this should be properly
               // demangled.
               "rustc_demangle::demangle",
#endif
               0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}

TEST_F(Specifications, MemberFunction) {
  PushLine(0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL, "line-file", 18116691);

  StartCU();
  DIEHandler *class_handler
    = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A");
  DeclarationDIE(class_handler, 0x7d83028c431406e8ULL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name", "");
  class_handler->Finish();
  delete class_handler;
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0x7d83028c431406e8ULL, "",
                0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "class_A::declaration-name",
               0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL);
}

// This case should gather the name from both the definition and the
// declaration's parent.
TEST_F(Specifications, FunctionDeclarationParent) {
  PushLine(0x463c9ddf405be227ULL, 0x6a47774af5049680ULL, "line-file", 70254922);

  StartCU();
  {
    DIEHandler *class_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                      "class_A");
    ASSERT_TRUE(class_handler != NULL);
    DeclarationDIE(class_handler, 0x0e0e877c8404544aULL,
                   dwarf2reader::DW_TAG_subprogram, "declaration-name", "");
    class_handler->Finish();
    delete class_handler;
  }

  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0x0e0e877c8404544aULL, "definition-name",
                0x463c9ddf405be227ULL, 0x6a47774af5049680ULL);

  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "class_A::definition-name",
               0x463c9ddf405be227ULL, 0x6a47774af5049680ULL);
}

// Named scopes should also gather enclosing name components from
// their declarations.
TEST_F(Specifications, NamedScopeDeclarationParent) {
  PushLine(0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, "line-file", 77392604);

  StartCU();
  {
    DIEHandler *space_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                      "space_A");
    ASSERT_TRUE(space_handler != NULL);
    DeclarationDIE(space_handler, 0x419bb1d12f9a73a2ULL,
                   dwarf2reader::DW_TAG_class_type, "class-declaration-name",
                   "");
    space_handler->Finish();
    delete space_handler;
  }

  {
    DIEHandler *class_handler
      = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                          0x419bb1d12f9a73a2ULL, "class-definition-name");
    ASSERT_TRUE(class_handler != NULL);
    DefineFunction(class_handler, "function",
                   0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, NULL);
    class_handler->Finish();
    delete class_handler;
  }

  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "space_A::class-definition-name::function",
               0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL);
}

// This test recreates bug 364.
TEST_F(Specifications, InlineFunction) {
  PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);

  StartCU();
  DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
                 dwarf2reader::DW_TAG_subprogram, "inline-name", "");
  AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
                      dwarf2reader::DW_INL_inlined, 0xcd3c51b946fb1eeeLL, "");
  DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
                       0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "inline-name",
               0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}

// An inline function in a namespace should correctly derive its
// name from its abstract origin, and not just the namespace name.
TEST_F(Specifications, InlineFunctionInNamespace) {
  PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);

  StartCU();
  DIEHandler* space_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                      "Namespace");
  ASSERT_TRUE(space_handler != NULL);
  AbstractInstanceDIE(space_handler, 0x1e8dac5d507ed7abULL,
                      dwarf2reader::DW_INL_inlined, 0LL, "func-name");
  DefineInlineInstanceDIE(space_handler, "", 0x1e8dac5d507ed7abULL,
                       0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
  space_handler->Finish();
  delete space_handler;
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "Namespace::func-name",
               0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}

// Check name construction for a long chain containing each combination of:
// - struct, union, class, namespace
// - direct and definition
TEST_F(Specifications, LongChain) {
  PushLine(0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL, "line-file", 21192926);
  SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);

  StartCU();
  // The structure we're building here is:
  // space_A full definition
  //   space_B declaration
  // space_B definition
  //   struct_C full definition
  //     struct_D declaration
  // struct_D definition
  //   union_E full definition
  //     union_F declaration
  // union_F definition
  //   class_G full definition
  //     class_H declaration
  // class_H definition
  //   func_I declaration
  // func_I definition
  //
  // So:
  // - space_A, struct_C, union_E, and class_G don't use specifications;
  // - space_B, struct_D, union_F, and class_H do.
  // - func_I uses a specification.
  //
  // The full name for func_I is thus:
  //
  // space_A::space_B::struct_C::struct_D::union_E::union_F::
  //   class_G::class_H::func_I
  {
    DIEHandler *space_A_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                      "space_A");
    DeclarationDIE(space_A_handler, 0x2e111126496596e2ULL,
                   dwarf2reader::DW_TAG_namespace, "space_B", "");
    space_A_handler->Finish();
    delete space_A_handler;
  }

  {
    DIEHandler *space_B_handler
      = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
                          0x2e111126496596e2ULL);
    DIEHandler *struct_C_handler
      = StartNamedDIE(space_B_handler, dwarf2reader::DW_TAG_structure_type,
                      "struct_C");
    DeclarationDIE(struct_C_handler, 0x20cd423bf2a25a4cULL,
                   dwarf2reader::DW_TAG_structure_type, "struct_D", "");
    struct_C_handler->Finish();
    delete struct_C_handler;
    space_B_handler->Finish();
    delete space_B_handler;
  }

  {
    DIEHandler *struct_D_handler
      = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_structure_type,
                          0x20cd423bf2a25a4cULL);
    DIEHandler *union_E_handler
      = StartNamedDIE(struct_D_handler, dwarf2reader::DW_TAG_union_type,
                      "union_E");
    DeclarationDIE(union_E_handler, 0xe25c84805aa58c32ULL,
                   dwarf2reader::DW_TAG_union_type, "union_F", "");
    union_E_handler->Finish();
    delete union_E_handler;
    struct_D_handler->Finish();
    delete struct_D_handler;
  }

  {
    DIEHandler *union_F_handler
      = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_union_type,
                          0xe25c84805aa58c32ULL);
    DIEHandler *class_G_handler
      = StartNamedDIE(union_F_handler, dwarf2reader::DW_TAG_class_type,
                      "class_G");
    DeclarationDIE(class_G_handler, 0xb70d960dcc173b6eULL,
                   dwarf2reader::DW_TAG_class_type, "class_H", "");
    class_G_handler->Finish();
    delete class_G_handler;
    union_F_handler->Finish();
    delete union_F_handler;
  }

  {
    DIEHandler *class_H_handler
      = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                          0xb70d960dcc173b6eULL);
    DeclarationDIE(class_H_handler, 0x27ff829e3bf69f37ULL,
                   dwarf2reader::DW_TAG_subprogram, "func_I", "");
    class_H_handler->Finish();
    delete class_H_handler;
  }

  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0x27ff829e3bf69f37ULL, "",
                0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "space_A::space_B::struct_C::struct_D::union_E::union_F"
               "::class_G::class_H::func_I",
               0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL);
}

TEST_F(Specifications, InterCU) {
  Module m("module-name", "module-os", "module-arch", "module-id");
  DwarfCUToModule::FileContext fc("dwarf-filename", &m, true);
  EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
  MockLineToModuleHandler lr;
  EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0);

  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  // First CU.  Declares class_A.
  {
    DwarfCUToModule root1_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root1_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ProcessStrangeAttributes(&root1_handler);
    ASSERT_TRUE(root1_handler.EndAttributes());
    DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL,
                   dwarf2reader::DW_TAG_class_type, "class_A", "");
    root1_handler.Finish();
  }

  // Second CU.  Defines class_A, declares member_func_B.
  {
    DwarfCUToModule root2_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root2_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ASSERT_TRUE(root2_handler.EndAttributes());
    DIEHandler *class_A_handler
      = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type,
                          0xb8fbfdd5f0b26fceULL);
    DeclarationDIE(class_A_handler, 0xb01fef8b380bd1a2ULL,
                   dwarf2reader::DW_TAG_subprogram, "member_func_B", "");
    class_A_handler->Finish();
    delete class_A_handler;
    root2_handler.Finish();
  }

  // Third CU.  Defines member_func_B.
  {
    DwarfCUToModule root3_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root3_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ASSERT_TRUE(root3_handler.EndAttributes());
    DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram,
                  0xb01fef8b380bd1a2ULL, "",
                  0x2618f00a1a711e53ULL, 0x4fd94b76d7c2caf5ULL);
    root3_handler.Finish();
  }

  vector<Module::Function *> functions;
  m.GetFunctions(&functions, functions.end());
  EXPECT_EQ(1U, functions.size());
  EXPECT_STREQ("class_A::member_func_B", functions[0]->name.c_str());
}

TEST_F(Specifications, UnhandledInterCU) {
  Module m("module-name", "module-os", "module-arch", "module-id");
  DwarfCUToModule::FileContext fc("dwarf-filename", &m, false);
  EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
  MockLineToModuleHandler lr;
  EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0);

  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  // First CU.  Declares class_A.
  {
    DwarfCUToModule root1_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root1_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ProcessStrangeAttributes(&root1_handler);
    ASSERT_TRUE(root1_handler.EndAttributes());
    DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL,
                   dwarf2reader::DW_TAG_class_type, "class_A", "");
    root1_handler.Finish();
  }

  // Second CU.  Defines class_A, declares member_func_B.
  {
    DwarfCUToModule root2_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root2_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ASSERT_TRUE(root2_handler.EndAttributes());
    EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(1);
    DIEHandler *class_A_handler
      = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type,
                          0xb8fbfdd5f0b26fceULL);
    DeclarationDIE(class_A_handler, 0xb01fef8b380bd1a2ULL,
                   dwarf2reader::DW_TAG_subprogram, "member_func_B", "");
    class_A_handler->Finish();
    delete class_A_handler;
    root2_handler.Finish();
  }

  // Third CU.  Defines member_func_B.
  {
    DwarfCUToModule root3_handler(&fc, &lr, nullptr, &reporter_);
    ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3));
    ASSERT_TRUE(root3_handler.StartRootDIE(1,
                                           dwarf2reader::DW_TAG_compile_unit));
    ASSERT_TRUE(root3_handler.EndAttributes());
    EXPECT_CALL(reporter_, UnhandledInterCUReference(_, _)).Times(1);
    EXPECT_CALL(reporter_, UnnamedFunction(_)).Times(1);
    DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram,
                  0xb01fef8b380bd1a2ULL, "",
                  0x2618f00a1a711e53ULL, 0x4fd94b76d7c2caf5ULL);
    root3_handler.Finish();
  }
}

TEST_F(Specifications, BadOffset) {
  PushLine(0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL, "line-file", 56636272);
  EXPECT_CALL(reporter_, UnknownSpecification(_, 0x2be953efa6f9a996ULL))
    .WillOnce(Return());

  StartCU();
  DeclarationDIE(&root_handler_, 0xefd7f7752c27b7e4ULL,
                 dwarf2reader::DW_TAG_subprogram, "", "");
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0x2be953efa6f9a996ULL, "function",
                0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL);
  root_handler_.Finish();
}

TEST_F(Specifications, FunctionDefinitionHasOwnName) {
  PushLine(0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL, "line-file", 56792403);

  StartCU();
  DeclarationDIE(&root_handler_, 0xc34ff4786cae78bdULL,
                 dwarf2reader::DW_TAG_subprogram, "declaration-name", "");
  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0xc34ff4786cae78bdULL, "definition-name",
                0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL);
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "definition-name",
               0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL);
}

TEST_F(Specifications, ClassDefinitionHasOwnName) {
  PushLine(0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL, "line-file", 57119241);

  StartCU();
  DeclarationDIE(&root_handler_, 0xd0fe467ec2f1a58cULL,
                 dwarf2reader::DW_TAG_class_type, "class-declaration-name", "");

  dwarf2reader::DIEHandler *class_definition
    = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                        0xd0fe467ec2f1a58cULL, "class-definition-name");
  ASSERT_TRUE(class_definition);
  DeclarationDIE(class_definition, 0x6d028229c15623dbULL,
                 dwarf2reader::DW_TAG_subprogram,
                 "function-declaration-name", "");
  class_definition->Finish();
  delete class_definition;

  DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
                0x6d028229c15623dbULL, "function-definition-name",
                0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL);

  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "class-definition-name::function-definition-name",
               0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL);
}

// DIEs that cite a specification should prefer the specification's
// parents over their own when choosing qualified names. In this test,
// we take the name from our definition but the enclosing scope name
// from our declaration. I don't see why they'd ever be different, but
// we want to verify what DwarfCUToModule is looking at.
TEST_F(Specifications, PreferSpecificationParents) {
  PushLine(0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL, "line-file", 79488694);

  StartCU();
  {
    dwarf2reader::DIEHandler *declaration_class_handler =
      StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                    "declaration-class");
    DeclarationDIE(declaration_class_handler, 0x9ddb35517455ef7aULL,
                   dwarf2reader::DW_TAG_subprogram, "function-declaration",
                   "");
    declaration_class_handler->Finish();
    delete declaration_class_handler;
  }
  {
    dwarf2reader::DIEHandler *definition_class_handler
      = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
                      "definition-class");
    DefinitionDIE(definition_class_handler, dwarf2reader::DW_TAG_subprogram,
                  0x9ddb35517455ef7aULL, "function-definition",
                  0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL);
    definition_class_handler->Finish();
    delete definition_class_handler;
  }
  root_handler_.Finish();

  TestFunctionCount(1);
  TestFunction(0, "declaration-class::function-definition",
               0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL);
}

class CUErrors: public CUFixtureBase, public Test { };

TEST_F(CUErrors, BadStmtList) {
  EXPECT_CALL(reporter_, BadLineInfoOffset(dummy_line_size_ + 10)).Times(1);

  ASSERT_TRUE(root_handler_
              .StartCompilationUnit(0xc591d5b037543d7cULL, 0x11, 0xcd,
                                    0x2d7d19546cf6590cULL, 3));
  ASSERT_TRUE(root_handler_.StartRootDIE(0xae789dc102cfca54ULL,
                                         dwarf2reader::DW_TAG_compile_unit));
  root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
                                       dwarf2reader::DW_FORM_strp,
                                       "compilation-unit-name");
  root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
                                         dwarf2reader::DW_FORM_ref4,
                                         dummy_line_size_ + 10);
  root_handler_.EndAttributes();
  root_handler_.Finish();
}

TEST_F(CUErrors, NoLineSection) {
  EXPECT_CALL(reporter_, MissingSection(".debug_line")).Times(1);
  PushLine(0x88507fb678052611ULL, 0x42c8e9de6bbaa0faULL, "line-file", 64472290);
  // Delete the entry for .debug_line added by the fixture class's constructor.
  file_context_.ClearSectionMapForTest();

  StartCU();
  root_handler_.Finish();
}

TEST_F(CUErrors, BadDwarfVersion1) {
  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  ASSERT_FALSE(root_handler_
               .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
                                     0xc9de224ccb99ac3eULL, 1));
}

TEST_F(CUErrors, GoodDwarfVersion2) {
  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  ASSERT_TRUE(root_handler_
               .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
                                     0xc9de224ccb99ac3eULL, 2));
}

TEST_F(CUErrors, GoodDwarfVersion3) {
  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  ASSERT_TRUE(root_handler_
               .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
                                     0xc9de224ccb99ac3eULL, 3));
}

TEST_F(CUErrors, BadCURootDIETag) {
  // Kludge: satisfy reporter_'s expectation.
  reporter_.SetCUName("compilation-unit-name");

  ASSERT_TRUE(root_handler_
               .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
                                     0xc9de224ccb99ac3eULL, 3));

  ASSERT_FALSE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
                                          dwarf2reader::DW_TAG_subprogram));
}

// Tests for DwarfCUToModule::Reporter. These just produce (or fail to
// produce) output, so their results need to be checked by hand.
struct Reporter: public Test {
  Reporter()
      : reporter("filename", 0x123456789abcdef0ULL),
        function("function name", 0x19c45c30770c1eb0ULL),
        file("source file name") {
    reporter.SetCUName("compilation-unit-name");

    Module::Range range(0x19c45c30770c1eb0ULL, 0x89808a5bdfa0a6a3ULL);
    function.ranges.push_back(range);
    function.parameter_size = 0x6a329f18683dcd51ULL;

    line.address = 0x3606ac6267aebeccULL;
    line.size = 0x5de482229f32556aULL;
    line.file = &file;
    line.number = 93400201;
  }

  DwarfCUToModule::WarningReporter reporter;
  Module::Function function;
  Module::File file;
  Module::Line line;
};

TEST_F(Reporter, UnknownSpecification) {
  reporter.UnknownSpecification(0x123456789abcdef1ULL, 0x323456789abcdef2ULL);
}

TEST_F(Reporter, UnknownAbstractOrigin) {
  reporter.UnknownAbstractOrigin(0x123456789abcdef1ULL, 0x323456789abcdef2ULL);
}

TEST_F(Reporter, MissingSection) {
  reporter.MissingSection("section name");
}

TEST_F(Reporter, BadLineInfoOffset) {
  reporter.BadLineInfoOffset(0x123456789abcdef1ULL);
}

TEST_F(Reporter, UncoveredFunctionDisabled) {
  reporter.UncoveredFunction(function);
  EXPECT_FALSE(reporter.uncovered_warnings_enabled());
}

TEST_F(Reporter, UncoveredFunctionEnabled) {
  reporter.set_uncovered_warnings_enabled(true);
  reporter.UncoveredFunction(function);
  EXPECT_TRUE(reporter.uncovered_warnings_enabled());
}

TEST_F(Reporter, UncoveredLineDisabled) {
  reporter.UncoveredLine(line);
  EXPECT_FALSE(reporter.uncovered_warnings_enabled());
}

TEST_F(Reporter, UncoveredLineEnabled) {
  reporter.set_uncovered_warnings_enabled(true);
  reporter.UncoveredLine(line);
  EXPECT_TRUE(reporter.uncovered_warnings_enabled());
}

TEST_F(Reporter, UnnamedFunction) {
  reporter.UnnamedFunction(0x90c0baff9dedb2d9ULL);
}

// Would be nice to also test:
// - overlapping lines, functions
