//===- Symbols.cpp --------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Symbols.h"
#include "Config.h"
#include "InputChunks.h"
#include "InputFiles.h"
#include "InputGlobal.h"
#include "OutputSegment.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Strings.h"

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::wasm;
using namespace lld;
using namespace lld::wasm;

DefinedFunction *WasmSym::CallCtors;
DefinedData *WasmSym::DsoHandle;
DefinedData *WasmSym::DataEnd;
DefinedData *WasmSym::HeapBase;
DefinedGlobal *WasmSym::StackPointer;

WasmSymbolType Symbol::getWasmType() const {
  if (isa<FunctionSymbol>(this))
    return WASM_SYMBOL_TYPE_FUNCTION;
  if (isa<DataSymbol>(this))
    return WASM_SYMBOL_TYPE_DATA;
  if (isa<GlobalSymbol>(this))
    return WASM_SYMBOL_TYPE_GLOBAL;
  if (isa<SectionSymbol>(this))
    return WASM_SYMBOL_TYPE_SECTION;
  llvm_unreachable("invalid symbol kind");
}

InputChunk *Symbol::getChunk() const {
  if (auto *F = dyn_cast<DefinedFunction>(this))
    return F->Function;
  if (auto *D = dyn_cast<DefinedData>(this))
    return D->Segment;
  return nullptr;
}

bool Symbol::isLive() const {
  if (auto *G = dyn_cast<DefinedGlobal>(this))
    return G->Global->Live;
  if (InputChunk *C = getChunk())
    return C->Live;
  return Referenced;
}

void Symbol::markLive() {
  if (auto *G = dyn_cast<DefinedGlobal>(this))
    G->Global->Live = true;
  if (InputChunk *C = getChunk())
    C->Live = true;
  Referenced = true;
}

uint32_t Symbol::getOutputSymbolIndex() const {
  assert(OutputSymbolIndex != INVALID_INDEX);
  return OutputSymbolIndex;
}

void Symbol::setOutputSymbolIndex(uint32_t Index) {
  LLVM_DEBUG(dbgs() << "setOutputSymbolIndex " << Name << " -> " << Index
                    << "\n");
  assert(OutputSymbolIndex == INVALID_INDEX);
  OutputSymbolIndex = Index;
}

bool Symbol::isWeak() const {
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
}

bool Symbol::isLocal() const {
  return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_LOCAL;
}

bool Symbol::isHidden() const {
  return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
}

void Symbol::setHidden(bool IsHidden) {
  LLVM_DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
  if (IsHidden)
    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
  else
    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
}

bool Symbol::isExported() const {
  if (!isDefined() || isLocal())
    return false;

  if (ForceExport || Config->ExportAll)
    return true;

  if (!Config->ExportDefault)
    return false;

  return !isHidden();
}

uint32_t FunctionSymbol::getFunctionIndex() const {
  if (auto *F = dyn_cast<DefinedFunction>(this))
    return F->Function->getFunctionIndex();
  assert(FunctionIndex != INVALID_INDEX);
  return FunctionIndex;
}

void FunctionSymbol::setFunctionIndex(uint32_t Index) {
  LLVM_DEBUG(dbgs() << "setFunctionIndex " << Name << " -> " << Index << "\n");
  assert(FunctionIndex == INVALID_INDEX);
  FunctionIndex = Index;
}

bool FunctionSymbol::hasFunctionIndex() const {
  if (auto *F = dyn_cast<DefinedFunction>(this))
    return F->Function->hasFunctionIndex();
  return FunctionIndex != INVALID_INDEX;
}

uint32_t FunctionSymbol::getTableIndex() const {
  if (auto *F = dyn_cast<DefinedFunction>(this))
    return F->Function->getTableIndex();
  assert(TableIndex != INVALID_INDEX);
  return TableIndex;
}

bool FunctionSymbol::hasTableIndex() const {
  if (auto *F = dyn_cast<DefinedFunction>(this))
    return F->Function->hasTableIndex();
  return TableIndex != INVALID_INDEX;
}

void FunctionSymbol::setTableIndex(uint32_t Index) {
  // For imports, we set the table index here on the Symbol; for defined
  // functions we set the index on the InputFunction so that we don't export
  // the same thing twice (keeps the table size down).
  if (auto *F = dyn_cast<DefinedFunction>(this)) {
    F->Function->setTableIndex(Index);
    return;
  }
  LLVM_DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
  assert(TableIndex == INVALID_INDEX);
  TableIndex = Index;
}

DefinedFunction::DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F,
                                 InputFunction *Function)
    : FunctionSymbol(Name, DefinedFunctionKind, Flags, F,
                     Function ? &Function->Signature : nullptr),
      Function(Function) {}

uint32_t DefinedData::getVirtualAddress() const {
  LLVM_DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
  if (Segment)
    return Segment->OutputSeg->StartVA + Segment->OutputSegmentOffset + Offset;
  return Offset;
}

void DefinedData::setVirtualAddress(uint32_t Value) {
  LLVM_DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
  assert(!Segment);
  Offset = Value;
}

uint32_t DefinedData::getOutputSegmentOffset() const {
  LLVM_DEBUG(dbgs() << "getOutputSegmentOffset: " << getName() << "\n");
  return Segment->OutputSegmentOffset + Offset;
}

uint32_t DefinedData::getOutputSegmentIndex() const {
  LLVM_DEBUG(dbgs() << "getOutputSegmentIndex: " << getName() << "\n");
  return Segment->OutputSeg->Index;
}

uint32_t GlobalSymbol::getGlobalIndex() const {
  if (auto *F = dyn_cast<DefinedGlobal>(this))
    return F->Global->getGlobalIndex();
  assert(GlobalIndex != INVALID_INDEX);
  return GlobalIndex;
}

void GlobalSymbol::setGlobalIndex(uint32_t Index) {
  LLVM_DEBUG(dbgs() << "setGlobalIndex " << Name << " -> " << Index << "\n");
  assert(GlobalIndex == INVALID_INDEX);
  GlobalIndex = Index;
}

bool GlobalSymbol::hasGlobalIndex() const {
  if (auto *F = dyn_cast<DefinedGlobal>(this))
    return F->Global->hasGlobalIndex();
  return GlobalIndex != INVALID_INDEX;
}

DefinedGlobal::DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File,
                             InputGlobal *Global)
    : GlobalSymbol(Name, DefinedGlobalKind, Flags, File,
                   Global ? &Global->getType() : nullptr),
      Global(Global) {}

uint32_t SectionSymbol::getOutputSectionIndex() const {
  LLVM_DEBUG(dbgs() << "getOutputSectionIndex: " << getName() << "\n");
  assert(OutputSectionIndex != INVALID_INDEX);
  return OutputSectionIndex;
}

void SectionSymbol::setOutputSectionIndex(uint32_t Index) {
  LLVM_DEBUG(dbgs() << "setOutputSectionIndex: " << getName() << " -> " << Index
                    << "\n");
  assert(Index != INVALID_INDEX);
  OutputSectionIndex = Index;
}

void LazySymbol::fetch() { cast<ArchiveFile>(File)->addMember(&ArchiveSymbol); }

std::string lld::toString(const wasm::Symbol &Sym) {
  if (Config->Demangle)
    if (Optional<std::string> S = demangleItanium(Sym.getName()))
      return *S;
  return Sym.getName();
}

std::string lld::toString(wasm::Symbol::Kind Kind) {
  switch (Kind) {
  case wasm::Symbol::DefinedFunctionKind:
    return "DefinedFunction";
  case wasm::Symbol::DefinedDataKind:
    return "DefinedData";
  case wasm::Symbol::DefinedGlobalKind:
    return "DefinedGlobal";
  case wasm::Symbol::UndefinedFunctionKind:
    return "UndefinedFunction";
  case wasm::Symbol::UndefinedDataKind:
    return "UndefinedData";
  case wasm::Symbol::UndefinedGlobalKind:
    return "UndefinedGlobal";
  case wasm::Symbol::LazyKind:
    return "LazyKind";
  case wasm::Symbol::SectionKind:
    return "SectionKind";
  }
  llvm_unreachable("invalid symbol kind");
}
