//===--  BitcodeWriter.cpp - ClangDoc Bitcode Writer ------------*- 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 "BitcodeWriter.h"
#include "llvm/ADT/IndexedMap.h"
#include <initializer_list>

namespace clang {
namespace doc {

// Empty SymbolID for comparison, so we don't have to construct one every time.
static const SymbolID EmptySID = SymbolID();

// Since id enums are not zero-indexed, we need to transform the given id into
// its associated index.
struct BlockIdToIndexFunctor {
  using argument_type = unsigned;
  unsigned operator()(unsigned ID) const { return ID - BI_FIRST; }
};

struct RecordIdToIndexFunctor {
  using argument_type = unsigned;
  unsigned operator()(unsigned ID) const { return ID - RI_FIRST; }
};

using AbbrevDsc = void (*)(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev);

static void AbbrevGen(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev,
                      const std::initializer_list<llvm::BitCodeAbbrevOp> Ops) {
  for (const auto &Op : Ops)
    Abbrev->Add(Op);
}

static void BoolAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
  AbbrevGen(Abbrev,
            {// 0. Boolean
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                                   BitCodeConstants::BoolSize)});
}

static void IntAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
  AbbrevGen(Abbrev,
            {// 0. Fixed-size integer
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                                   BitCodeConstants::IntSize)});
}

static void SymbolIDAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
  AbbrevGen(Abbrev,
            {// 0. Fixed-size integer (length of the sha1'd USR)
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                                   BitCodeConstants::USRLengthSize),
             // 1. Fixed-size array of Char6 (USR)
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array),
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                                   BitCodeConstants::USRBitLengthSize)});
}

static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
  AbbrevGen(Abbrev,
            {// 0. Fixed-size integer (length of the following string)
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                                   BitCodeConstants::StringLengthSize),
             // 1. The string blob
             llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
}

// Assumes that the file will not have more than 65535 lines.
static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
  AbbrevGen(
      Abbrev,
      {// 0. Fixed-size integer (line number)
       llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                             BitCodeConstants::LineNumberSize),
       // 1. Boolean (IsFileInRootDir)
       llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                             BitCodeConstants::BoolSize),
       // 2. Fixed-size integer (length of the following string (filename))
       llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
                             BitCodeConstants::StringLengthSize),
       // 3. The string blob
       llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
}

struct RecordIdDsc {
  llvm::StringRef Name;
  AbbrevDsc Abbrev = nullptr;

  RecordIdDsc() = default;
  RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev)
      : Name(Name), Abbrev(Abbrev) {}

  // Is this 'description' valid?
  operator bool() const {
    return Abbrev != nullptr && Name.data() != nullptr && !Name.empty();
  }
};

static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
    BlockIdNameMap = []() {
      llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor> BlockIdNameMap;
      BlockIdNameMap.resize(BlockIdCount);

      // There is no init-list constructor for the IndexedMap, so have to
      // improvise
      static const std::vector<std::pair<BlockId, const char *const>> Inits = {
          {BI_VERSION_BLOCK_ID, "VersionBlock"},
          {BI_NAMESPACE_BLOCK_ID, "NamespaceBlock"},
          {BI_ENUM_BLOCK_ID, "EnumBlock"},
          {BI_ENUM_VALUE_BLOCK_ID, "EnumValueBlock"},
          {BI_TYPEDEF_BLOCK_ID, "TypedefBlock"},
          {BI_TYPE_BLOCK_ID, "TypeBlock"},
          {BI_FIELD_TYPE_BLOCK_ID, "FieldTypeBlock"},
          {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"},
          {BI_RECORD_BLOCK_ID, "RecordBlock"},
          {BI_BASE_RECORD_BLOCK_ID, "BaseRecordBlock"},
          {BI_FUNCTION_BLOCK_ID, "FunctionBlock"},
          {BI_COMMENT_BLOCK_ID, "CommentBlock"},
          {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"},
          {BI_TEMPLATE_BLOCK_ID, "TemplateBlock"},
          {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"},
          {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}};
      assert(Inits.size() == BlockIdCount);
      for (const auto &Init : Inits)
        BlockIdNameMap[Init.first] = Init.second;
      assert(BlockIdNameMap.size() == BlockIdCount);
      return BlockIdNameMap;
    }();

static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
    RecordIdNameMap = []() {
      llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap;
      RecordIdNameMap.resize(RecordIdCount);

      // There is no init-list constructor for the IndexedMap, so have to
      // improvise
      static const std::vector<std::pair<RecordId, RecordIdDsc>> Inits = {
          {VERSION, {"Version", &IntAbbrev}},
          {COMMENT_KIND, {"Kind", &StringAbbrev}},
          {COMMENT_TEXT, {"Text", &StringAbbrev}},
          {COMMENT_NAME, {"Name", &StringAbbrev}},
          {COMMENT_DIRECTION, {"Direction", &StringAbbrev}},
          {COMMENT_PARAMNAME, {"ParamName", &StringAbbrev}},
          {COMMENT_CLOSENAME, {"CloseName", &StringAbbrev}},
          {COMMENT_SELFCLOSING, {"SelfClosing", &BoolAbbrev}},
          {COMMENT_EXPLICIT, {"Explicit", &BoolAbbrev}},
          {COMMENT_ATTRKEY, {"AttrKey", &StringAbbrev}},
          {COMMENT_ATTRVAL, {"AttrVal", &StringAbbrev}},
          {COMMENT_ARG, {"Arg", &StringAbbrev}},
          {FIELD_TYPE_NAME, {"Name", &StringAbbrev}},
          {FIELD_DEFAULT_VALUE, {"DefaultValue", &StringAbbrev}},
          {MEMBER_TYPE_NAME, {"Name", &StringAbbrev}},
          {MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}},
          {NAMESPACE_USR, {"USR", &SymbolIDAbbrev}},
          {NAMESPACE_NAME, {"Name", &StringAbbrev}},
          {NAMESPACE_PATH, {"Path", &StringAbbrev}},
          {ENUM_USR, {"USR", &SymbolIDAbbrev}},
          {ENUM_NAME, {"Name", &StringAbbrev}},
          {ENUM_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
          {ENUM_LOCATION, {"Location", &LocationAbbrev}},
          {ENUM_SCOPED, {"Scoped", &BoolAbbrev}},
          {ENUM_VALUE_NAME, {"Name", &StringAbbrev}},
          {ENUM_VALUE_VALUE, {"Value", &StringAbbrev}},
          {ENUM_VALUE_EXPR, {"Expr", &StringAbbrev}},
          {RECORD_USR, {"USR", &SymbolIDAbbrev}},
          {RECORD_NAME, {"Name", &StringAbbrev}},
          {RECORD_PATH, {"Path", &StringAbbrev}},
          {RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
          {RECORD_LOCATION, {"Location", &LocationAbbrev}},
          {RECORD_TAG_TYPE, {"TagType", &IntAbbrev}},
          {RECORD_IS_TYPE_DEF, {"IsTypeDef", &BoolAbbrev}},
          {BASE_RECORD_USR, {"USR", &SymbolIDAbbrev}},
          {BASE_RECORD_NAME, {"Name", &StringAbbrev}},
          {BASE_RECORD_PATH, {"Path", &StringAbbrev}},
          {BASE_RECORD_TAG_TYPE, {"TagType", &IntAbbrev}},
          {BASE_RECORD_IS_VIRTUAL, {"IsVirtual", &BoolAbbrev}},
          {BASE_RECORD_ACCESS, {"Access", &IntAbbrev}},
          {BASE_RECORD_IS_PARENT, {"IsParent", &BoolAbbrev}},
          {FUNCTION_USR, {"USR", &SymbolIDAbbrev}},
          {FUNCTION_NAME, {"Name", &StringAbbrev}},
          {FUNCTION_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
          {FUNCTION_LOCATION, {"Location", &LocationAbbrev}},
          {FUNCTION_ACCESS, {"Access", &IntAbbrev}},
          {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}},
          {REFERENCE_USR, {"USR", &SymbolIDAbbrev}},
          {REFERENCE_NAME, {"Name", &StringAbbrev}},
          {REFERENCE_QUAL_NAME, {"QualName", &StringAbbrev}},
          {REFERENCE_TYPE, {"RefType", &IntAbbrev}},
          {REFERENCE_PATH, {"Path", &StringAbbrev}},
          {REFERENCE_FIELD, {"Field", &IntAbbrev}},
          {TEMPLATE_PARAM_CONTENTS, {"Contents", &StringAbbrev}},
          {TEMPLATE_SPECIALIZATION_OF, {"SpecializationOf", &SymbolIDAbbrev}},
          {TYPEDEF_USR, {"USR", &SymbolIDAbbrev}},
          {TYPEDEF_NAME, {"Name", &StringAbbrev}},
          {TYPEDEF_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
          {TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}}};
      assert(Inits.size() == RecordIdCount);
      for (const auto &Init : Inits) {
        RecordIdNameMap[Init.first] = Init.second;
        assert((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize);
      }
      assert(RecordIdNameMap.size() == RecordIdCount);
      return RecordIdNameMap;
    }();

static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
    RecordsByBlock{
        // Version Block
        {BI_VERSION_BLOCK_ID, {VERSION}},
        // Comment Block
        {BI_COMMENT_BLOCK_ID,
         {COMMENT_KIND, COMMENT_TEXT, COMMENT_NAME, COMMENT_DIRECTION,
          COMMENT_PARAMNAME, COMMENT_CLOSENAME, COMMENT_SELFCLOSING,
          COMMENT_EXPLICIT, COMMENT_ATTRKEY, COMMENT_ATTRVAL, COMMENT_ARG}},
        // Type Block
        {BI_TYPE_BLOCK_ID, {}},
        // FieldType Block
        {BI_FIELD_TYPE_BLOCK_ID, {FIELD_TYPE_NAME, FIELD_DEFAULT_VALUE}},
        // MemberType Block
        {BI_MEMBER_TYPE_BLOCK_ID, {MEMBER_TYPE_NAME, MEMBER_TYPE_ACCESS}},
        // Enum Block
        {BI_ENUM_BLOCK_ID,
         {ENUM_USR, ENUM_NAME, ENUM_DEFLOCATION, ENUM_LOCATION, ENUM_SCOPED}},
        // Enum Value Block
        {BI_ENUM_VALUE_BLOCK_ID,
         {ENUM_VALUE_NAME, ENUM_VALUE_VALUE, ENUM_VALUE_EXPR}},
        // Typedef Block
        {BI_TYPEDEF_BLOCK_ID,
         {TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DEFLOCATION, TYPEDEF_IS_USING}},
        // Namespace Block
        {BI_NAMESPACE_BLOCK_ID,
         {NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH}},
        // Record Block
        {BI_RECORD_BLOCK_ID,
         {RECORD_USR, RECORD_NAME, RECORD_PATH, RECORD_DEFLOCATION,
          RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF}},
        // BaseRecord Block
        {BI_BASE_RECORD_BLOCK_ID,
         {BASE_RECORD_USR, BASE_RECORD_NAME, BASE_RECORD_PATH,
          BASE_RECORD_TAG_TYPE, BASE_RECORD_IS_VIRTUAL, BASE_RECORD_ACCESS,
          BASE_RECORD_IS_PARENT}},
        // Function Block
        {BI_FUNCTION_BLOCK_ID,
         {FUNCTION_USR, FUNCTION_NAME, FUNCTION_DEFLOCATION, FUNCTION_LOCATION,
          FUNCTION_ACCESS, FUNCTION_IS_METHOD}},
        // Reference Block
        {BI_REFERENCE_BLOCK_ID,
         {REFERENCE_USR, REFERENCE_NAME, REFERENCE_QUAL_NAME, REFERENCE_TYPE,
          REFERENCE_PATH, REFERENCE_FIELD}},
        // Template Blocks.
        {BI_TEMPLATE_BLOCK_ID, {}},
        {BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}},
        {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}};

// AbbreviationMap

constexpr unsigned char BitCodeConstants::Signature[];

void ClangDocBitcodeWriter::AbbreviationMap::add(RecordId RID,
                                                 unsigned AbbrevID) {
  assert(RecordIdNameMap[RID] && "Unknown RecordId.");
  assert(!Abbrevs.contains(RID) && "Abbreviation already added.");
  Abbrevs[RID] = AbbrevID;
}

unsigned ClangDocBitcodeWriter::AbbreviationMap::get(RecordId RID) const {
  assert(RecordIdNameMap[RID] && "Unknown RecordId.");
  assert(Abbrevs.contains(RID) && "Unknown abbreviation.");
  return Abbrevs.lookup(RID);
}

// Validation and Overview Blocks

/// Emits the magic number header to check that its the right format,
/// in this case, 'DOCS'.
void ClangDocBitcodeWriter::emitHeader() {
  for (char C : BitCodeConstants::Signature)
    Stream.Emit((unsigned)C, BitCodeConstants::SignatureBitSize);
}

void ClangDocBitcodeWriter::emitVersionBlock() {
  StreamSubBlockGuard Block(Stream, BI_VERSION_BLOCK_ID);
  emitRecord(VersionNumber, VERSION);
}

/// Emits a block ID and the block name to the BLOCKINFO block.
void ClangDocBitcodeWriter::emitBlockID(BlockId BID) {
  const auto &BlockIdName = BlockIdNameMap[BID];
  assert(BlockIdName.data() && BlockIdName.size() && "Unknown BlockId.");

  Record.clear();
  Record.push_back(BID);
  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
                    ArrayRef<unsigned char>(BlockIdName.bytes_begin(),
                                            BlockIdName.bytes_end()));
}

/// Emits a record name to the BLOCKINFO block.
void ClangDocBitcodeWriter::emitRecordID(RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  prepRecordData(ID);
  Record.append(RecordIdNameMap[ID].Name.begin(),
                RecordIdNameMap[ID].Name.end());
  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
}

// Abbreviations

void ClangDocBitcodeWriter::emitAbbrev(RecordId ID, BlockId Block) {
  assert(RecordIdNameMap[ID] && "Unknown abbreviation.");
  auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
  Abbrev->Add(llvm::BitCodeAbbrevOp(ID));
  RecordIdNameMap[ID].Abbrev(Abbrev);
  Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev)));
}

// Records

void ClangDocBitcodeWriter::emitRecord(const SymbolID &Sym, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &SymbolIDAbbrev &&
         "Abbrev type mismatch.");
  if (!prepRecordData(ID, Sym != EmptySID))
    return;
  assert(Sym.size() == 20);
  Record.push_back(Sym.size());
  Record.append(Sym.begin(), Sym.end());
  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
}

void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &StringAbbrev &&
         "Abbrev type mismatch.");
  if (!prepRecordData(ID, !Str.empty()))
    return;
  assert(Str.size() < (1U << BitCodeConstants::StringLengthSize));
  Record.push_back(Str.size());
  Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
}

void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &LocationAbbrev &&
         "Abbrev type mismatch.");
  if (!prepRecordData(ID, true))
    return;
  // FIXME: Assert that the line number is of the appropriate size.
  Record.push_back(Loc.LineNumber);
  assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
  Record.push_back(Loc.IsFileInRootDir);
  Record.push_back(Loc.Filename.size());
  Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Loc.Filename);
}

void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &BoolAbbrev && "Abbrev type mismatch.");
  if (!prepRecordData(ID, Val))
    return;
  Record.push_back(Val);
  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
}

void ClangDocBitcodeWriter::emitRecord(int Val, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
  if (!prepRecordData(ID, Val))
    return;
  // FIXME: Assert that the integer is of the appropriate size.
  Record.push_back(Val);
  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
}

void ClangDocBitcodeWriter::emitRecord(unsigned Val, RecordId ID) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
  if (!prepRecordData(ID, Val))
    return;
  assert(Val < (1U << BitCodeConstants::IntSize));
  Record.push_back(Val);
  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
}

void ClangDocBitcodeWriter::emitRecord(const TemplateInfo &Templ) {}

bool ClangDocBitcodeWriter::prepRecordData(RecordId ID, bool ShouldEmit) {
  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
  if (!ShouldEmit)
    return false;
  Record.clear();
  Record.push_back(ID);
  return true;
}

// BlockInfo Block

void ClangDocBitcodeWriter::emitBlockInfoBlock() {
  Stream.EnterBlockInfoBlock();
  for (const auto &Block : RecordsByBlock) {
    assert(Block.second.size() < (1U << BitCodeConstants::SubblockIDSize));
    emitBlockInfo(Block.first, Block.second);
  }
  Stream.ExitBlock();
}

void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID,
                                          const std::vector<RecordId> &RIDs) {
  assert(RIDs.size() < (1U << BitCodeConstants::SubblockIDSize));
  emitBlockID(BID);
  for (RecordId RID : RIDs) {
    emitRecordID(RID);
    emitAbbrev(RID, BID);
  }
}

// Block emission

void ClangDocBitcodeWriter::emitBlock(const Reference &R, FieldId Field) {
  if (R.USR == EmptySID && R.Name.empty())
    return;
  StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID);
  emitRecord(R.USR, REFERENCE_USR);
  emitRecord(R.Name, REFERENCE_NAME);
  emitRecord(R.QualName, REFERENCE_QUAL_NAME);
  emitRecord((unsigned)R.RefType, REFERENCE_TYPE);
  emitRecord(R.Path, REFERENCE_PATH);
  emitRecord((unsigned)Field, REFERENCE_FIELD);
}

void ClangDocBitcodeWriter::emitBlock(const TypeInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID);
  emitBlock(T.Type, FieldId::F_type);
}

void ClangDocBitcodeWriter::emitBlock(const TypedefInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_TYPEDEF_BLOCK_ID);
  emitRecord(T.USR, TYPEDEF_USR);
  emitRecord(T.Name, TYPEDEF_NAME);
  for (const auto &N : T.Namespace)
    emitBlock(N, FieldId::F_namespace);
  for (const auto &CI : T.Description)
    emitBlock(CI);
  if (T.DefLoc)
    emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION);
  emitRecord(T.IsUsing, TYPEDEF_IS_USING);
  emitBlock(T.Underlying);
}

void ClangDocBitcodeWriter::emitBlock(const FieldTypeInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID);
  emitBlock(T.Type, FieldId::F_type);
  emitRecord(T.Name, FIELD_TYPE_NAME);
  emitRecord(T.DefaultValue, FIELD_DEFAULT_VALUE);
}

void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID);
  emitBlock(T.Type, FieldId::F_type);
  emitRecord(T.Name, MEMBER_TYPE_NAME);
  emitRecord(T.Access, MEMBER_TYPE_ACCESS);
  for (const auto &CI : T.Description)
    emitBlock(CI);
}

void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
  for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
           {I.Kind, COMMENT_KIND},
           {I.Text, COMMENT_TEXT},
           {I.Name, COMMENT_NAME},
           {I.Direction, COMMENT_DIRECTION},
           {I.ParamName, COMMENT_PARAMNAME},
           {I.CloseName, COMMENT_CLOSENAME}})
    emitRecord(L.first, L.second);
  emitRecord(I.SelfClosing, COMMENT_SELFCLOSING);
  emitRecord(I.Explicit, COMMENT_EXPLICIT);
  for (const auto &A : I.AttrKeys)
    emitRecord(A, COMMENT_ATTRKEY);
  for (const auto &A : I.AttrValues)
    emitRecord(A, COMMENT_ATTRVAL);
  for (const auto &A : I.Args)
    emitRecord(A, COMMENT_ARG);
  for (const auto &C : I.Children)
    emitBlock(*C);
}

void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_NAMESPACE_BLOCK_ID);
  emitRecord(I.USR, NAMESPACE_USR);
  emitRecord(I.Name, NAMESPACE_NAME);
  emitRecord(I.Path, NAMESPACE_PATH);
  for (const auto &N : I.Namespace)
    emitBlock(N, FieldId::F_namespace);
  for (const auto &CI : I.Description)
    emitBlock(CI);
  for (const auto &C : I.Children.Namespaces)
    emitBlock(C, FieldId::F_child_namespace);
  for (const auto &C : I.Children.Records)
    emitBlock(C, FieldId::F_child_record);
  for (const auto &C : I.Children.Functions)
    emitBlock(C);
  for (const auto &C : I.Children.Enums)
    emitBlock(C);
  for (const auto &C : I.Children.Typedefs)
    emitBlock(C);
}

void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_ENUM_BLOCK_ID);
  emitRecord(I.USR, ENUM_USR);
  emitRecord(I.Name, ENUM_NAME);
  for (const auto &N : I.Namespace)
    emitBlock(N, FieldId::F_namespace);
  for (const auto &CI : I.Description)
    emitBlock(CI);
  if (I.DefLoc)
    emitRecord(*I.DefLoc, ENUM_DEFLOCATION);
  for (const auto &L : I.Loc)
    emitRecord(L, ENUM_LOCATION);
  emitRecord(I.Scoped, ENUM_SCOPED);
  if (I.BaseType)
    emitBlock(*I.BaseType);
  for (const auto &N : I.Members)
    emitBlock(N);
}

void ClangDocBitcodeWriter::emitBlock(const EnumValueInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_ENUM_VALUE_BLOCK_ID);
  emitRecord(I.Name, ENUM_VALUE_NAME);
  emitRecord(I.Value, ENUM_VALUE_VALUE);
  emitRecord(I.ValueExpr, ENUM_VALUE_EXPR);
}

void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID);
  emitRecord(I.USR, RECORD_USR);
  emitRecord(I.Name, RECORD_NAME);
  emitRecord(I.Path, RECORD_PATH);
  for (const auto &N : I.Namespace)
    emitBlock(N, FieldId::F_namespace);
  for (const auto &CI : I.Description)
    emitBlock(CI);
  if (I.DefLoc)
    emitRecord(*I.DefLoc, RECORD_DEFLOCATION);
  for (const auto &L : I.Loc)
    emitRecord(L, RECORD_LOCATION);
  emitRecord(llvm::to_underlying(I.TagType), RECORD_TAG_TYPE);
  emitRecord(I.IsTypeDef, RECORD_IS_TYPE_DEF);
  for (const auto &N : I.Members)
    emitBlock(N);
  for (const auto &P : I.Parents)
    emitBlock(P, FieldId::F_parent);
  for (const auto &P : I.VirtualParents)
    emitBlock(P, FieldId::F_vparent);
  for (const auto &PB : I.Bases)
    emitBlock(PB);
  for (const auto &C : I.Children.Records)
    emitBlock(C, FieldId::F_child_record);
  for (const auto &C : I.Children.Functions)
    emitBlock(C);
  for (const auto &C : I.Children.Enums)
    emitBlock(C);
  for (const auto &C : I.Children.Typedefs)
    emitBlock(C);
  if (I.Template)
    emitBlock(*I.Template);
}

void ClangDocBitcodeWriter::emitBlock(const BaseRecordInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_BASE_RECORD_BLOCK_ID);
  emitRecord(I.USR, BASE_RECORD_USR);
  emitRecord(I.Name, BASE_RECORD_NAME);
  emitRecord(I.Path, BASE_RECORD_PATH);
  emitRecord(llvm::to_underlying(I.TagType), BASE_RECORD_TAG_TYPE);
  emitRecord(I.IsVirtual, BASE_RECORD_IS_VIRTUAL);
  emitRecord(I.Access, BASE_RECORD_ACCESS);
  emitRecord(I.IsParent, BASE_RECORD_IS_PARENT);
  for (const auto &M : I.Members)
    emitBlock(M);
  for (const auto &C : I.Children.Functions)
    emitBlock(C);
}

void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
  StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID);
  emitRecord(I.USR, FUNCTION_USR);
  emitRecord(I.Name, FUNCTION_NAME);
  for (const auto &N : I.Namespace)
    emitBlock(N, FieldId::F_namespace);
  for (const auto &CI : I.Description)
    emitBlock(CI);
  emitRecord(I.Access, FUNCTION_ACCESS);
  emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
  if (I.DefLoc)
    emitRecord(*I.DefLoc, FUNCTION_DEFLOCATION);
  for (const auto &L : I.Loc)
    emitRecord(L, FUNCTION_LOCATION);
  emitBlock(I.Parent, FieldId::F_parent);
  emitBlock(I.ReturnType);
  for (const auto &N : I.Params)
    emitBlock(N);
  if (I.Template)
    emitBlock(*I.Template);
}

void ClangDocBitcodeWriter::emitBlock(const TemplateInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID);
  for (const auto &P : T.Params)
    emitBlock(P);
  if (T.Specialization)
    emitBlock(*T.Specialization);
}

void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID);
  emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF);
  for (const auto &P : T.Params)
    emitBlock(P);
}

void ClangDocBitcodeWriter::emitBlock(const TemplateParamInfo &T) {
  StreamSubBlockGuard Block(Stream, BI_TEMPLATE_PARAM_BLOCK_ID);
  emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS);
}

bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
  switch (I->IT) {
  case InfoType::IT_namespace:
    emitBlock(*static_cast<clang::doc::NamespaceInfo *>(I));
    break;
  case InfoType::IT_record:
    emitBlock(*static_cast<clang::doc::RecordInfo *>(I));
    break;
  case InfoType::IT_enum:
    emitBlock(*static_cast<clang::doc::EnumInfo *>(I));
    break;
  case InfoType::IT_function:
    emitBlock(*static_cast<clang::doc::FunctionInfo *>(I));
    break;
  case InfoType::IT_typedef:
    emitBlock(*static_cast<clang::doc::TypedefInfo *>(I));
    break;
  default:
    llvm::errs() << "Unexpected info, unable to write.\n";
    return true;
  }
  return false;
}

} // namespace doc
} // namespace clang
