//===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"

#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBTypes.h"

#include <unordered_set>
#include <utility>
#include <vector>

using namespace llvm;
using namespace llvm::pdb;

namespace {
class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
public:
  typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;

  FunctionArgEnumerator(const IPDBSession &PDBSession,
                        const PDBSymbolFunc &PDBFunc)
      : Session(PDBSession), Func(PDBFunc) {
    // Arguments can appear multiple times if they have live range
    // information, so we only take the first occurrence.
    std::unordered_set<std::string> SeenNames;
    auto DataChildren = Func.findAllChildren<PDBSymbolData>();
    while (auto Child = DataChildren->getNext()) {
      if (Child->getDataKind() == PDB_DataKind::Param) {
        std::string Name = Child->getName();
        if (SeenNames.find(Name) != SeenNames.end())
          continue;
        Args.push_back(std::move(Child));
        SeenNames.insert(Name);
      }
    }
    reset();
  }

  uint32_t getChildCount() const override { return Args.size(); }

  std::unique_ptr<PDBSymbolData>
  getChildAtIndex(uint32_t Index) const override {
    if (Index >= Args.size())
      return nullptr;

    return Session.getConcreteSymbolById<PDBSymbolData>(
        Args[Index]->getSymIndexId());
  }

  std::unique_ptr<PDBSymbolData> getNext() override {
    if (CurIter == Args.end())
      return nullptr;
    const auto &Result = **CurIter;
    ++CurIter;
    return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
  }

  void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }

  FunctionArgEnumerator *clone() const override {
    return new FunctionArgEnumerator(Session, Func);
  }

private:
  typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
  const IPDBSession &Session;
  const PDBSymbolFunc &Func;
  ArgListType Args;
  ArgListType::const_iterator CurIter;
};
}

PDBSymbolFunc::PDBSymbolFunc(const IPDBSession &PDBSession,
                             std::unique_ptr<IPDBRawSymbol> Symbol)
    : PDBSymbol(PDBSession, std::move(Symbol)) {
  assert(RawSymbol->getSymTag() == PDB_SymType::Function);
}

std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
PDBSymbolFunc::getArguments() const {
  return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
}

void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }

bool PDBSymbolFunc::isDestructor() const {
  std::string Name = getName();
  if (Name.empty())
    return false;
  if (Name[0] == '~')
    return true;
  if (Name == "__vecDelDtor")
    return true;
  return false;
}

std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
  auto Len = RawSymbol->getLength();
  return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
                                          Len ? Len : 1);
}

uint32_t PDBSymbolFunc::getCompilandId() const {
  if (auto Lines = getLineNumbers()) {
    if (auto FirstLine = Lines->getNext()) {
      return FirstLine->getCompilandId();
    }
  }
  return 0;
}
