//===- CVTypeVisitor.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 "llvm/DebugInfo/CodeView/CVTypeVisitor.h"

#include "llvm/DebugInfo/CodeView/CodeViewError.h"
#include "llvm/DebugInfo/CodeView/TypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"

using namespace llvm;
using namespace llvm::codeview;


template <typename T>
static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
  TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
  T KnownRecord(RK);
  if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
    return EC;
  return Error::success();
}

template <typename T>
static Error visitKnownMember(CVMemberRecord &Record,
                              TypeVisitorCallbacks &Callbacks) {
  TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Kind);
  T KnownRecord(RK);
  if (auto EC = Callbacks.visitKnownMember(Record, KnownRecord))
    return EC;
  return Error::success();
}

static Error visitMemberRecord(CVMemberRecord &Record,
                               TypeVisitorCallbacks &Callbacks) {
  if (auto EC = Callbacks.visitMemberBegin(Record))
    return EC;

  switch (Record.Kind) {
  default:
    if (auto EC = Callbacks.visitUnknownMember(Record))
      return EC;
    break;
#define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
  case EnumName: {                                                             \
    if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks))           \
      return EC;                                                               \
    break;                                                                     \
  }
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                \
  MEMBER_RECORD(EnumVal, EnumVal, AliasName)
#define TYPE_RECORD(EnumName, EnumVal, Name)
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  }

  if (auto EC = Callbacks.visitMemberEnd(Record))
    return EC;

  return Error::success();
}

namespace {

class CVTypeVisitor {
public:
  explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);

  Error visitTypeRecord(CVType &Record, TypeIndex Index);
  Error visitTypeRecord(CVType &Record);

  /// Visits the type records in Data. Sets the error flag on parse failures.
  Error visitTypeStream(const CVTypeArray &Types);
  Error visitTypeStream(CVTypeRange Types);
  Error visitTypeStream(TypeCollection &Types);

  Error visitMemberRecord(CVMemberRecord Record);
  Error visitFieldListMemberStream(BinaryStreamReader &Stream);

private:
  Error finishVisitation(CVType &Record);

  /// The interface to the class that gets notified of each visitation.
  TypeVisitorCallbacks &Callbacks;
};

CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
    : Callbacks(Callbacks) {}

Error CVTypeVisitor::finishVisitation(CVType &Record) {
  switch (Record.kind()) {
  default:
    if (auto EC = Callbacks.visitUnknownType(Record))
      return EC;
    break;
#define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
  case EnumName: {                                                             \
    if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks))           \
      return EC;                                                               \
    break;                                                                     \
  }
#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                  \
  TYPE_RECORD(EnumVal, EnumVal, AliasName)
#define MEMBER_RECORD(EnumName, EnumVal, Name)
#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  }

  if (auto EC = Callbacks.visitTypeEnd(Record))
    return EC;

  return Error::success();
}

Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) {
  if (auto EC = Callbacks.visitTypeBegin(Record, Index))
    return EC;

  return finishVisitation(Record);
}

Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
  if (auto EC = Callbacks.visitTypeBegin(Record))
    return EC;

  return finishVisitation(Record);
}

Error CVTypeVisitor::visitMemberRecord(CVMemberRecord Record) {
  return ::visitMemberRecord(Record, Callbacks);
}

/// Visits the type records in Data. Sets the error flag on parse failures.
Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
  for (auto I : Types) {
    if (auto EC = visitTypeRecord(I))
      return EC;
  }
  return Error::success();
}

Error CVTypeVisitor::visitTypeStream(CVTypeRange Types) {
  for (auto I : Types) {
    if (auto EC = visitTypeRecord(I))
      return EC;
  }
  return Error::success();
}

Error CVTypeVisitor::visitTypeStream(TypeCollection &Types) {
  Optional<TypeIndex> I = Types.getFirst();
  while (I) {
    CVType Type = Types.getType(*I);
    if (auto EC = visitTypeRecord(Type, *I))
      return EC;
    I = Types.getNext(*I);
  }
  return Error::success();
}

Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader &Reader) {
  TypeLeafKind Leaf;
  while (!Reader.empty()) {
    if (auto EC = Reader.readEnum(Leaf))
      return EC;

    CVMemberRecord Record;
    Record.Kind = Leaf;
    if (auto EC = ::visitMemberRecord(Record, Callbacks))
      return EC;
  }

  return Error::success();
}

struct FieldListVisitHelper {
  FieldListVisitHelper(TypeVisitorCallbacks &Callbacks, ArrayRef<uint8_t> Data,
                       VisitorDataSource Source)
      : Stream(Data, llvm::support::little), Reader(Stream),
        Deserializer(Reader),
        Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
    if (Source == VDS_BytesPresent) {
      Pipeline.addCallbackToPipeline(Deserializer);
      Pipeline.addCallbackToPipeline(Callbacks);
    }
  }

  BinaryByteStream Stream;
  BinaryStreamReader Reader;
  FieldListDeserializer Deserializer;
  TypeVisitorCallbackPipeline Pipeline;
  CVTypeVisitor Visitor;
};

struct VisitHelper {
  VisitHelper(TypeVisitorCallbacks &Callbacks, VisitorDataSource Source)
      : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
    if (Source == VDS_BytesPresent) {
      Pipeline.addCallbackToPipeline(Deserializer);
      Pipeline.addCallbackToPipeline(Callbacks);
    }
  }

  TypeDeserializer Deserializer;
  TypeVisitorCallbackPipeline Pipeline;
  CVTypeVisitor Visitor;
};
}

Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
                                      TypeVisitorCallbacks &Callbacks,
                                      VisitorDataSource Source) {
  VisitHelper V(Callbacks, Source);
  return V.Visitor.visitTypeRecord(Record, Index);
}

Error llvm::codeview::visitTypeRecord(CVType &Record,
                                      TypeVisitorCallbacks &Callbacks,
                                      VisitorDataSource Source) {
  VisitHelper V(Callbacks, Source);
  return V.Visitor.visitTypeRecord(Record);
}

Error llvm::codeview::visitTypeStream(const CVTypeArray &Types,
                                      TypeVisitorCallbacks &Callbacks,
                                      VisitorDataSource Source) {
  VisitHelper V(Callbacks, Source);
  return V.Visitor.visitTypeStream(Types);
}

Error llvm::codeview::visitTypeStream(CVTypeRange Types,
                                      TypeVisitorCallbacks &Callbacks) {
  VisitHelper V(Callbacks, VDS_BytesPresent);
  return V.Visitor.visitTypeStream(Types);
}

Error llvm::codeview::visitTypeStream(TypeCollection &Types,
                                      TypeVisitorCallbacks &Callbacks) {
  // When the internal visitor calls Types.getType(Index) the interface is
  // required to return a CVType with the bytes filled out.  So we can assume
  // that the bytes will be present when individual records are visited.
  VisitHelper V(Callbacks, VDS_BytesPresent);
  return V.Visitor.visitTypeStream(Types);
}

Error llvm::codeview::visitMemberRecord(CVMemberRecord Record,
                                        TypeVisitorCallbacks &Callbacks,
                                        VisitorDataSource Source) {
  FieldListVisitHelper V(Callbacks, Record.Data, Source);
  return V.Visitor.visitMemberRecord(Record);
}

Error llvm::codeview::visitMemberRecord(TypeLeafKind Kind,
                                        ArrayRef<uint8_t> Record,
                                        TypeVisitorCallbacks &Callbacks) {
  CVMemberRecord R;
  R.Data = Record;
  R.Kind = Kind;
  return visitMemberRecord(R, Callbacks, VDS_BytesPresent);
}

Error llvm::codeview::visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
                                              TypeVisitorCallbacks &Callbacks) {
  FieldListVisitHelper V(Callbacks, FieldList, VDS_BytesPresent);
  return V.Visitor.visitFieldListMemberStream(V.Reader);
}
