//===-- SBSymbol.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 "lldb/API/SBSymbol.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Instrumentation.h"

using namespace lldb;
using namespace lldb_private;

SBSymbol::SBSymbol() { LLDB_INSTRUMENT_VA(this); }

SBSymbol::SBSymbol(lldb_private::Symbol *lldb_object_ptr)
    : m_opaque_ptr(lldb_object_ptr) {}

SBSymbol::SBSymbol(const lldb::SBSymbol &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
  LLDB_INSTRUMENT_VA(this, rhs);
}

const SBSymbol &SBSymbol::operator=(const SBSymbol &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  m_opaque_ptr = rhs.m_opaque_ptr;
  return *this;
}

SBSymbol::~SBSymbol() { m_opaque_ptr = nullptr; }

void SBSymbol::SetSymbol(lldb_private::Symbol *lldb_object_ptr) {
  m_opaque_ptr = lldb_object_ptr;
}

bool SBSymbol::IsValid() const {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBSymbol::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr != nullptr;
}

const char *SBSymbol::GetName() const {
  LLDB_INSTRUMENT_VA(this);

  const char *name = nullptr;
  if (m_opaque_ptr)
    name = m_opaque_ptr->GetName().AsCString(nullptr);

  return name;
}

const char *SBSymbol::GetDisplayName() const {
  LLDB_INSTRUMENT_VA(this);

  const char *name = nullptr;
  if (m_opaque_ptr)
    name =
        m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(nullptr);

  return name;
}

const char *SBSymbol::GetMangledName() const {
  LLDB_INSTRUMENT_VA(this);

  const char *name = nullptr;
  if (m_opaque_ptr)
    name = m_opaque_ptr->GetMangled().GetMangledName().AsCString(nullptr);
  return name;
}

const char *SBSymbol::GetBaseName() const {
  LLDB_INSTRUMENT_VA(this);

  if (!m_opaque_ptr)
    return nullptr;

  return m_opaque_ptr->GetMangled().GetBaseName().AsCString(nullptr);
}

bool SBSymbol::operator==(const SBSymbol &rhs) const {
  LLDB_INSTRUMENT_VA(this, rhs);

  return m_opaque_ptr == rhs.m_opaque_ptr;
}

bool SBSymbol::operator!=(const SBSymbol &rhs) const {
  LLDB_INSTRUMENT_VA(this, rhs);

  return m_opaque_ptr != rhs.m_opaque_ptr;
}

bool SBSymbol::GetDescription(SBStream &description) {
  LLDB_INSTRUMENT_VA(this, description);

  Stream &strm = description.ref();

  if (m_opaque_ptr) {
    m_opaque_ptr->GetDescription(&strm, lldb::eDescriptionLevelFull, nullptr);
  } else
    strm.PutCString("No value");

  return true;
}

SBInstructionList SBSymbol::GetInstructions(SBTarget target) {
  LLDB_INSTRUMENT_VA(this, target);

  return GetInstructions(target, nullptr);
}

SBInstructionList SBSymbol::GetInstructions(SBTarget target,
                                            const char *flavor_string) {
  LLDB_INSTRUMENT_VA(this, target, flavor_string);

  SBInstructionList sb_instructions;
  if (m_opaque_ptr) {
    TargetSP target_sp(target.GetSP());
    TargetAPIMutex api_lock;
    std::unique_lock<TargetAPIMutex> guard;
    if (target_sp && m_opaque_ptr->ValueIsAddress()) {
      api_lock = TargetAPIMutex(target_sp->GetAPIMutex());
      guard = std::unique_lock<TargetAPIMutex>(api_lock);
      const Address &symbol_addr = m_opaque_ptr->GetAddressRef();
      ModuleSP module_sp = symbol_addr.GetModule();
      if (module_sp) {
        AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize());
        const bool force_live_memory = true;
        sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
            module_sp->GetArchitecture(), nullptr, flavor_string,
            target_sp->GetDisassemblyCPU(), target_sp->GetDisassemblyFeatures(),
            *target_sp, symbol_range, force_live_memory));
      }
    }
  }
  return sb_instructions;
}

lldb_private::Symbol *SBSymbol::get() { return m_opaque_ptr; }

void SBSymbol::reset(lldb_private::Symbol *symbol) { m_opaque_ptr = symbol; }

SBAddress SBSymbol::GetStartAddress() {
  LLDB_INSTRUMENT_VA(this);

  SBAddress addr;
  if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
    addr.SetAddress(m_opaque_ptr->GetAddressRef());
  }
  return addr;
}

SBAddress SBSymbol::GetEndAddress() {
  LLDB_INSTRUMENT_VA(this);

  SBAddress addr;
  if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) {
    lldb::addr_t range_size = m_opaque_ptr->GetByteSize();
    if (range_size > 0) {
      addr.SetAddress(m_opaque_ptr->GetAddressRef());
      addr->Slide(m_opaque_ptr->GetByteSize());
    }
  }
  return addr;
}

uint64_t SBSymbol::GetValue() {
  LLDB_INSTRUMENT_VA(this);
  if (m_opaque_ptr)
    return m_opaque_ptr->GetRawValue();
  return 0;
}

uint64_t SBSymbol::GetSize() {
  LLDB_INSTRUMENT_VA(this);
  if (m_opaque_ptr && m_opaque_ptr->GetByteSizeIsValid())
    return m_opaque_ptr->GetByteSize();
  return 0;
}

uint32_t SBSymbol::GetPrologueByteSize() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->GetPrologueByteSize();
  return 0;
}

SymbolType SBSymbol::GetType() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->GetType();
  return eSymbolTypeInvalid;
}

uint32_t SBSymbol::GetID() const {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->GetID();
  return LLDB_INVALID_SYMBOL_ID;
}

bool SBSymbol::IsExternal() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->IsExternal();
  return false;
}

bool SBSymbol::IsSynthetic() {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->IsSynthetic();
  return false;
}

bool SBSymbol::IsDebug() const {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return m_opaque_ptr->IsDebug();
  return false;
}

const char *SBSymbol::GetTypeAsString(lldb::SymbolType symbol_type) {
  LLDB_INSTRUMENT_VA(symbol_type);

  return Symbol::GetTypeAsString(symbol_type);
}

lldb::SymbolType SBSymbol::GetTypeFromString(const char *str) {
  LLDB_INSTRUMENT_VA(str);

  return Symbol::GetTypeFromString(str);
}
