aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/NaCl/Reader/NaClBitcodeParser.cpp
blob: 642c8cfd34a6fabe74c278c81ed01c48a1fb5494 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//===- 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.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "NaClBitcodeParser"

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

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

NaClBitcodeParser::~NaClBitcodeParser() {}

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

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

  return ParseBlock(Record.GetEntryID());
}

bool NaClBitcodeParser::ParseThisBlock() {
  if (GetBlockID() == naclbitc::BLOCKINFO_BLOCK_ID) {
    // BLOCKINFO is a special part of the stream. Let the bitstream
    // reader process this block.
    //
    // TODO(kschimpf): Move this out of the bitstream reader, so that
    // we have simplier API's for this class.
    EnterBlockInfo();
    if (Record.GetCursor().ReadBlockInfoBlock())
      return Error("Malformed BlockInfoBlock");
    RemoveBlockBitsFromEnclosingBlock();
    ExitBlockInfo();
    return false;
  }

  // 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: {
      ExitBlock();
      RemoveBlockBitsFromEnclosingBlock();
      return false;
    }
    case NaClBitstreamEntry::SubBlock: {
      if (ParseBlock(Record.GetEntryID())) return true;
      break;
    }
    case NaClBitstreamEntry::Record:
      // The interesting case.
      if (Record.GetEntryID() == naclbitc::DEFINE_ABBREV) {
        //Process any block-local abbreviation definitions.
        Record.GetCursor().ReadAbbrevRecord();
        ProcessRecordAbbrev();
      } else {
        // Read in a record.
        Record.ReadValues();
        ProcessRecord();
      }
      break;
    }
  }
  return false;
}