//===-- PdbFPOProgramToDWARFExpression.cpp ----------------------*- C++ -*-===//
//
// 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 "PdbFPOProgramToDWARFExpression.h"
#include "CodeViewRegisterMapping.h"

#include "lldb/Core/StreamBuffer.h"
#include "lldb/Symbol/PostfixExpression.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/DenseMap.h"

#include "llvm/ADT/StringExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::postfix;

static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) {
  // lookup register name to get lldb register number
  llvm::codeview::CPUType cpu_type;
  switch (arch_type) {
    case llvm::Triple::ArchType::aarch64:
      cpu_type = llvm::codeview::CPUType::ARM64;
      break;

    default:
      cpu_type = llvm::codeview::CPUType::X64;
      break;
  }

  llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =
      llvm::codeview::getRegisterNames(cpu_type);
  auto it = llvm::find_if(
      register_names,
      [&reg_name](const llvm::EnumEntry<uint16_t> &register_entry) {
        return reg_name.compare_lower(register_entry.Name) == 0;
      });

  if (it == register_names.end())
    return LLDB_INVALID_REGNUM;

  auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value);
  return npdb::GetLLDBRegisterNumber(arch_type, reg_id);
}

static bool ParseFPOSingleAssignmentProgram(llvm::StringRef program,
                                            llvm::BumpPtrAllocator &alloc,
                                            llvm::StringRef &register_name,
                                            Node *&ast) {
  // lvalue of assignment is always first token
  // rvalue program goes next
  std::tie(register_name, program) = getToken(program);
  if (register_name.empty())
    return false;

  ast = Parse(program, alloc);
  return ast != nullptr;
}

static Node *ParseFPOProgram(llvm::StringRef program,
                             llvm::StringRef register_name,
                             llvm::Triple::ArchType arch_type,
                             llvm::BumpPtrAllocator &alloc) {
  llvm::DenseMap<llvm::StringRef, Node *> dependent_programs;

  size_t cur = 0;
  while (true) {
    size_t assign_index = program.find('=', cur);
    if (assign_index == llvm::StringRef::npos) {
      llvm::StringRef tail = program.slice(cur, llvm::StringRef::npos);
      if (!tail.trim().empty()) {
        // missing assign operator
        return nullptr;
      }
      break;
    }
    llvm::StringRef assignment_program = program.slice(cur, assign_index);

    llvm::StringRef lvalue_name;
    Node *rvalue_ast = nullptr;
    if (!ParseFPOSingleAssignmentProgram(assignment_program, alloc, lvalue_name,
                                         rvalue_ast)) {
      return nullptr;
    }

    lldbassert(rvalue_ast);

    // Emplace valid dependent subtrees to make target assignment independent
    // from predecessors. Resolve all other SymbolNodes as registers.
    bool success =
        ResolveSymbols(rvalue_ast, [&](SymbolNode &symbol) -> Node * {
          if (Node *node = dependent_programs.lookup(symbol.GetName()))
            return node;
          uint32_t reg_num =
              ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);

          if (reg_num == LLDB_INVALID_REGNUM)
            return nullptr;

          return MakeNode<RegisterNode>(alloc, reg_num);
        });
    if (!success)
      return nullptr;

    if (lvalue_name == register_name) {
      // found target assignment program - no need to parse further
      return rvalue_ast;
    }

    dependent_programs[lvalue_name] = rvalue_ast;
    cur = assign_index + 1;
  }

  return nullptr;
}

bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(
    llvm::StringRef program, llvm::StringRef register_name,
    llvm::Triple::ArchType arch_type, Stream &stream) {
  llvm::BumpPtrAllocator node_alloc;
  Node *target_program =
      ParseFPOProgram(program, register_name, arch_type, node_alloc);
  if (target_program == nullptr) {
    return false;
  }

  ToDWARF(*target_program, stream);
  return true;
}
