// 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_, &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->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, &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, &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, &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, &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, &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, &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");

    function.size = 0x89808a5bdfa0a6a3ULL;
    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
