//===- NaClBitcodeParser.cpp ----------------------------------------------===//
//     Low-level bitcode driver to parse PNaCl bitcode files.
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h"

using namespace llvm;

void NaClBitcodeRecordData::Print(raw_ostream &os) const {
  os << "[" << Code;
  for (NaClRecordVector::const_iterator
           Iter = Values.begin(), IterEnd = Values.end();
       Iter != IterEnd; ++Iter) {
    os << ", " << *Iter;
  }
  os << "]";
}

void NaClBitcodeRecord::Print(raw_ostream& os) const {
  Block.Print(os);
  os << ", Code " << Data.Code << ", EntryID " << Entry.ID << ", <";
  for (unsigned i = 0, e = Data.Values.size(); i != e; ++i) {
    if (i > 0) os << " ";
    os << Data.Values[i];
  }
  os << ">";
}

NaClBitcodeBlock::NaClBitcodeBlock(unsigned BlockID,
                                   const NaClBitcodeRecord &Record)
    : NaClBitcodeData(Record),
      BlockID(BlockID),
      EnclosingBlock(&Record.GetBlock()),
      LocalStartBit(Record.GetStartBit())
{}

void NaClBitcodeBlock::Print(raw_ostream &os) const {
  os << "Block " << BlockID;
}

void NaClBitcodeParserListener::BeginBlockInfoBlock(unsigned NumWords) {
  Parser->EnterBlock(NumWords);
}

void NaClBitcodeParserListener::SetBID() {
  Parser->Record.SetStartBit(StartBit);
  Parser->Record.Entry.Kind = NaClBitstreamEntry::Record;
  Parser->Record.Entry.ID = naclbitc::UNABBREV_RECORD;
  Parser->Record.Data.Code = naclbitc::BLOCKINFO_CODE_SETBID;
  Parser->Record.Data.Values = Values;
  GlobalBlockID = Values[0];
  Parser->SetBID();
  Values.clear();
}

void NaClBitcodeParserListener::EndBlockInfoBlock() {
  Parser->Record.SetStartBit(StartBit);
  Parser->Record.Entry.Kind = NaClBitstreamEntry::EndBlock;
  Parser->Record.Entry.ID = naclbitc::END_BLOCK;
  Parser->Record.Data.Code = naclbitc::END_BLOCK;
  Parser->Record.Data.Values.clear();
  GlobalBlockID = naclbitc::BLOCKINFO_BLOCK_ID;
  Parser->ExitBlock();
}

void NaClBitcodeParserListener::
ProcessAbbreviation(NaClBitCodeAbbrev *Abbrev, bool IsLocal) {
  Parser->Record.SetStartBit(StartBit);
  Parser->Record.Entry.Kind = NaClBitstreamEntry::Record;
  Parser->Record.Entry.ID = naclbitc::DEFINE_ABBREV;
  Parser->Record.Data.Code = naclbitc::BLK_CODE_DEFINE_ABBREV;
  Parser->Record.Data.Values = Values;
  Parser->ProcessAbbreviation(IsLocal ? Parser->GetBlockID() : GlobalBlockID,
                              Abbrev, IsLocal);
}

NaClBitcodeParser::~NaClBitcodeParser() {
  if (EnclosingParser) {
    EnclosingParser->Block.LocalStartBit += Block.GetNumBits();
  }
}

bool NaClBitcodeParser::ErrorAt(
    naclbitc::ErrorLevel Level, uint64_t BitPosition,
    const std::string &Message) {
  naclbitc::ErrorAt(*ErrStream, Level, BitPosition) << Message << "\n";
  if (Level == naclbitc::Fatal)
    report_fatal_error("Unable to continue");
  return true;
}

bool NaClBitcodeParser::Parse() {
  Record.ReadEntry();

  if (Record.GetEntryKind() != NaClBitstreamEntry::SubBlock)
    return Error("Expected block, but not found");

  return ParseBlock(Record.GetEntryID());
}

bool NaClBitcodeParser::ParseBlockInfoInternal() {
  // BLOCKINFO is a special part of the stream. Let the bitstream
  // reader process this block.
  bool Result = Record.GetCursor().ReadBlockInfoBlock(Listener);
  if (Result) return Error("Malformed BlockInfoBlock");
  return Result;
}

bool NaClBitcodeParser::ParseBlockInternal() {
  // Regular block. Enter subblock.
  unsigned NumWords;
  if (Record.GetCursor().EnterSubBlock(GetBlockID(), &NumWords)) {
    return Error("Malformed block record");
  }

  EnterBlock(NumWords);

  // Process records.
  while (1) {
    if (Record.GetCursor().AtEndOfStream())
      return Error("Premature end of bitstream");

    // Read entry defining type of entry.
    Record.ReadEntry();

    switch (Record.GetEntryKind()) {
    case NaClBitstreamEntry::Error:
      return Error("malformed bitcode file");
    case NaClBitstreamEntry::EndBlock: {
      return false;
    }
    case NaClBitstreamEntry::SubBlock: {
      if (ParseBlock(Record.GetEntryID())) return true;
      break;
    }
    case NaClBitstreamEntry::Record:
      // The interesting case.
      if (Record.GetEntryID() == naclbitc::DEFINE_ABBREV) {
        // Since this abbreviation is local, the listener doesn't
        // have the start bit set (it is only set when processing
        // the BlockInfo block). Fix this by setting it here.
        if (Listener) Listener->StartBit = Record.GetStartBit();
        Record.GetCursor().ReadAbbrevRecord(true, Listener);
      } else {
        // Read in a record.
        Record.ReadValues();
        ProcessRecord();
      }
      break;
    }
  }
  return false;
}
