//===- MergingTypeTableBuilder.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 "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>

using namespace llvm;
using namespace llvm::codeview;

TypeIndex MergingTypeTableBuilder::nextTypeIndex() const {
  return TypeIndex::fromArrayIndex(SeenRecords.size());
}

MergingTypeTableBuilder::MergingTypeTableBuilder(BumpPtrAllocator &Storage)
    : RecordStorage(Storage) {
  SeenRecords.reserve(4096);
}

MergingTypeTableBuilder::~MergingTypeTableBuilder() = default;

Optional<TypeIndex> MergingTypeTableBuilder::getFirst() {
  if (empty())
    return None;

  return TypeIndex(TypeIndex::FirstNonSimpleIndex);
}

Optional<TypeIndex> MergingTypeTableBuilder::getNext(TypeIndex Prev) {
  if (++Prev == nextTypeIndex())
    return None;
  return Prev;
}

CVType MergingTypeTableBuilder::getType(TypeIndex Index) {
  CVType Type(SeenRecords[Index.toArrayIndex()]);
  return Type;
}

StringRef MergingTypeTableBuilder::getTypeName(TypeIndex Index) {
  llvm_unreachable("Method not implemented");
}

bool MergingTypeTableBuilder::contains(TypeIndex Index) {
  if (Index.isSimple() || Index.isNoneType())
    return false;

  return Index.toArrayIndex() < SeenRecords.size();
}

uint32_t MergingTypeTableBuilder::size() { return SeenRecords.size(); }

uint32_t MergingTypeTableBuilder::capacity() { return SeenRecords.size(); }

ArrayRef<ArrayRef<uint8_t>> MergingTypeTableBuilder::records() const {
  return SeenRecords;
}

void MergingTypeTableBuilder::reset() {
  HashedRecords.clear();
  SeenRecords.clear();
}

static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
                                          ArrayRef<uint8_t> Data) {
  uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
  memcpy(Stable, Data.data(), Data.size());
  return makeArrayRef(Stable, Data.size());
}

TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash,
                                                  ArrayRef<uint8_t> &Record) {
  assert(Record.size() < UINT32_MAX && "Record too big");
  assert(Record.size() % 4 == 0 &&
         "The type record size is not a multiple of 4 bytes which will cause "
         "misalignment in the output TPI stream!");

  LocallyHashedType WeakHash{Hash, Record};
  auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex());

  if (Result.second) {
    ArrayRef<uint8_t> RecordData = stabilize(RecordStorage, Record);
    Result.first->first.RecordData = RecordData;
    SeenRecords.push_back(RecordData);
  }

  // Update the caller's copy of Record to point a stable copy.
  TypeIndex ActualTI = Result.first->second;
  Record = SeenRecords[ActualTI.toArrayIndex()];
  return ActualTI;
}

TypeIndex
MergingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
  return insertRecordAs(hash_value(Record), Record);
}

TypeIndex
MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
  TypeIndex TI;
  auto Fragments = Builder.end(nextTypeIndex());
  assert(!Fragments.empty());
  for (auto C : Fragments)
    TI = insertRecordBytes(C.RecordData);
  return TI;
}

bool MergingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
                                          bool Stabilize) {
  assert(Index.toArrayIndex() < SeenRecords.size() &&
         "This function cannot be used to insert records!");

  ArrayRef<uint8_t> Record = Data.data();
  assert(Record.size() < UINT32_MAX && "Record too big");
  assert(Record.size() % 4 == 0 &&
         "The type record size is not a multiple of 4 bytes which will cause "
         "misalignment in the output TPI stream!");

  LocallyHashedType WeakHash{hash_value(Record), Record};
  auto Result = HashedRecords.try_emplace(WeakHash, Index.toArrayIndex());
  if (!Result.second) {
    Index = Result.first->second;
    return false; // The record is already there, at a different location
  }

  if (Stabilize) {
    Record = stabilize(RecordStorage, Record);
    Result.first->first.RecordData = Record;
  }

  SeenRecords[Index.toArrayIndex()] = Record;
  return true;
}
