//===-- TestLineEntry.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include <iostream>

#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"

#include "lldb/Core/Module.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"

#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
#include "llvm/Testing/Support/Error.h"

using namespace lldb_private;
using namespace lldb;

class LineEntryTest : public testing::Test {
  SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
                TypeSystemClang>
      subsystem;

public:
  void SetUp() override;

protected:
  llvm::Expected<SymbolContextList>
  GetLineEntriesForLine(uint32_t line, llvm::Optional<uint16_t> column);
  llvm::Optional<TestFile> m_file;
  ModuleSP m_module_sp;
};

void LineEntryTest::SetUp() {
  auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml");
  ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
  m_file.emplace(std::move(*ExpectedFile));
  m_module_sp = std::make_shared<Module>(m_file->moduleSpec());
}

  // TODO: Handle SourceLocationSpec column information
llvm::Expected<SymbolContextList> LineEntryTest::GetLineEntriesForLine(
    uint32_t line, llvm::Optional<uint16_t> column = llvm::None) {
  SymbolContextList sc_comp_units;
  SymbolContextList sc_line_entries;
  FileSpec file_spec("inlined-functions.cpp");
  m_module_sp->ResolveSymbolContextsForFileSpec(
      file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit,
      sc_comp_units);
  if (sc_comp_units.GetSize() == 0)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "No comp unit found on the test object.");

  SourceLocationSpec location_spec(file_spec, line, column,
                                   /*check_inlines=*/true,
                                   /*exact_match=*/true);

  sc_comp_units[0].comp_unit->ResolveSymbolContext(
      location_spec, eSymbolContextLineEntry, sc_line_entries);
  if (sc_line_entries.GetSize() == 0)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "No line entry found on the test object.");
  return sc_line_entries;
}

// This tests if we can get all line entries that match the passed line, if
// no column is specified.
TEST_F(LineEntryTest, GetAllExactLineMatchesWithoutColumn) {
  auto sc_line_entries = GetLineEntriesForLine(12);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 6u);
}

// This tests if we can get exact line and column matches.
TEST_F(LineEntryTest, GetAllExactLineColumnMatches) {
  auto sc_line_entries = GetLineEntriesForLine(12, 39);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 1u);
  auto line_entry = sc_line_entries.get()[0].line_entry;
  ASSERT_EQ(line_entry.column, 39);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) {
  auto sc_line_entries = GetLineEntriesForLine(18);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = false;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x24);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeOneInline) {
  auto sc_line_entries = GetLineEntriesForLine(18);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = true;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x49);
}

TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNestedInline) {
  auto sc_line_entries = GetLineEntriesForLine(12);
  ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
  auto line_entry = sc_line_entries.get()[0].line_entry;
  bool include_inlined_functions = true;
  auto range =
      line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
  ASSERT_EQ(range.GetByteSize(), (uint64_t)0x33);
}

/*
# inlined-functions.cpp
inline __attribute__((always_inline)) int sum2(int a, int b) {
    int result = a + b;
    return result;
}

int sum3(int a, int b, int c) {
    int result = a + b + c;
    return result;
}

inline __attribute__((always_inline)) int sum4(int a, int b, int c, int d) {
    int result = sum2(a, b) + sum2(c, d);
    result += 0;
    return result;
}

int main(int argc, char** argv) {
    sum3(3, 4, 5) + sum2(1, 2);
    int sum = sum4(1, 2, 3, 4);
    sum2(5, 6);
    return 0;
}

// g++ -c inlined-functions.cpp -o inlined-functions.o -g -Wno-unused-value
// obj2yaml inlined-functions.o > inlined-functions.yaml

# Dump of source line per address:
# inlined-functions.cpp is src.cpp for space considerations.
0x20: src.cpp:17
0x21: src.cpp:17
0x26: src.cpp:17
0x27: src.cpp:17
0x29: src.cpp:17
0x2e: src.cpp:17
0x2f: src.cpp:17
0x31: src.cpp:17
0x36: src.cpp:18
0x37: src.cpp:18
0x39: src.cpp:18
0x3e: src.cpp:18
0x3f: src.cpp:18
0x41: src.cpp:18
0x46: src.cpp:18
0x47: src.cpp:18
0x49: src.cpp:18
0x4e: src.cpp:18
0x4f: src.cpp:18
0x51: src.cpp:18
0x56: src.cpp:18
0x57: src.cpp:18
0x59: src.cpp:18
0x5e: src.cpp:18 -> sum2@src.cpp:2
0x5f: src.cpp:18 -> sum2@src.cpp:2
0x61: src.cpp:18 -> sum2@src.cpp:2
0x66: src.cpp:18 -> sum2@src.cpp:2
0x67: src.cpp:18 -> sum2@src.cpp:2
0x69: src.cpp:18 -> sum2@src.cpp:2
0x6e: src.cpp:18 -> sum2@src.cpp:2
0x6f: src.cpp:18 -> sum2@src.cpp:2
0x71: src.cpp:18 -> sum2@src.cpp:2
0x76: src.cpp:18 -> sum2@src.cpp:2
0x77: src.cpp:18 -> sum2@src.cpp:2
0x79: src.cpp:18 -> sum2@src.cpp:2
0x7e: src.cpp:18 -> sum2@src.cpp:2
0x7f: src.cpp:19 -> sum4@src.cpp:12
0x81: src.cpp:19 -> sum4@src.cpp:12
0x86: src.cpp:19 -> sum4@src.cpp:12
0x87: src.cpp:19 -> sum4@src.cpp:12
0x89: src.cpp:19 -> sum4@src.cpp:12
0x8e: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x8f: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x91: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0x96: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:3
0x97: src.cpp:19 -> sum4@src.cpp:12
0x99: src.cpp:19 -> sum4@src.cpp:12
0x9e: src.cpp:19 -> sum4@src.cpp:12
0x9f: src.cpp:19 -> sum4@src.cpp:12
0xa1: src.cpp:19 -> sum4@src.cpp:12
0xa6: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xa7: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xa9: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
0xae: src.cpp:19 -> sum4@src.cpp:12
0xaf: src.cpp:19 -> sum4@src.cpp:12
0xb1: src.cpp:19 -> sum4@src.cpp:12
0xb6: src.cpp:19 -> sum4@src.cpp:13
0xb7: src.cpp:19 -> sum4@src.cpp:13
0xb9: src.cpp:19 -> sum4@src.cpp:14
0xbe: src.cpp:19
0xbf: src.cpp:19
0xc1: src.cpp:19
0xc6: src.cpp:19
0xc7: src.cpp:19
0xc9: src.cpp:19
0xce: src.cpp:20 -> sum2@src.cpp:2
0xcf: src.cpp:20 -> sum2@src.cpp:2
0xd1: src.cpp:20 -> sum2@src.cpp:2
0xd6: src.cpp:21
0xd7: src.cpp:21
0xd9: src.cpp:21
0xde: src.cpp:21
*/
