blob: 027047b3f8d6b2ffd1650077db1ce8128bc92a50 [file] [log] [blame]
Reid Spencerdac69c82004-06-07 17:53:43 +00001//===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This header file defines the interface to the Bytecode Parser
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef BYTECODE_PARSER_H
15#define BYTECODE_PARSER_H
16
17#include "ReaderPrimitives.h"
18#include "BytecodeHandler.h"
19#include "llvm/Constants.h"
20#include "llvm/DerivedTypes.h"
21#include <utility>
22#include <vector>
23#include <map>
24
25namespace llvm {
26
27struct LazyFunctionInfo {
28 const unsigned char *Buf, *EndBuf;
29 LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0)
30 : Buf(B), EndBuf(EB) {}
31};
32
33typedef std::map<const Type*, LazyFunctionInfo> LazyFunctionMap;
34
35class AbstractBytecodeParser {
36 AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
37 void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
38public:
39 AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; }
40 ~AbstractBytecodeParser() { }
41
42 void ParseBytecode(const unsigned char *Buf, unsigned Length,
43 const std::string &ModuleID);
44
45 void dump() const {
46 std::cerr << "AbstractBytecodeParser instance!\n";
47 }
48
49private:
50 // Information about the module, extracted from the bytecode revision number.
51 unsigned char RevisionNum; // The rev # itself
52
53 // Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0)
54
55 // Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo
56 // block. This was fixed to be like all other blocks in 1.2
57 bool hasInconsistentModuleGlobalInfo;
58
59 // Revision #0 also explicitly encoded zero values for primitive types like
60 // int/sbyte/etc.
61 bool hasExplicitPrimitiveZeros;
62
63 // Flags to control features specific the LLVM 1.2 and before (revision #1)
64
65 // LLVM 1.2 and earlier required that getelementptr structure indices were
66 // ubyte constants and that sequential type indices were longs.
67 bool hasRestrictedGEPTypes;
68
69
70 /// CompactionTable - If a compaction table is active in the current function,
71 /// this is the mapping that it contains.
72 std::vector<Type*> CompactionTypeTable;
73
74 // ConstantFwdRefs - This maintains a mapping between <Type, Slot #>'s and
75 // forward references to constants. Such values may be referenced before they
76 // are defined, and if so, the temporary object that they represent is held
77 // here.
78 //
79 typedef std::map<std::pair<const Type*,unsigned>, Constant*> ConstantRefsType;
80 ConstantRefsType ConstantFwdRefs;
81
82 // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used
83 // to deal with forward references to types.
84 //
85 typedef std::vector<PATypeHolder> TypeListTy;
86 TypeListTy ModuleTypes;
87 TypeListTy FunctionTypes;
88
89 // When the ModuleGlobalInfo section is read, we create a FunctionType object
90 // for each function in the module. When the function is loaded, this type is
91 // used to instantiate the actual function object.
92 std::vector<const Type*> FunctionSignatureList;
93
94 // Constant values are read in after global variables. Because of this, we
95 // must defer setting the initializers on global variables until after module
96 // level constants have been read. In the mean time, this list keeps track of
97 // what we must do.
98 //
99 std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
100
101 // For lazy reading-in of functions, we need to save away several pieces of
102 // information about each function: its begin and end pointer in the buffer
103 // and its FunctionSlot.
104 //
105 LazyFunctionMap LazyFunctionLoadMap;
106
107 /// The handler for parsing
108 BytecodeHandler* handler;
109
110private:
111 const Type *AbstractBytecodeParser::getType(unsigned ID);
112 /// getGlobalTableType - This is just like getType, but when a compaction
113 /// table is in use, it is ignored. Also, no forward references or other
114 /// fancy features are supported.
115 const Type *getGlobalTableType(unsigned Slot) {
116 if (Slot < Type::FirstDerivedTyID) {
117 const Type *Ty = Type::getPrimitiveType((Type::PrimitiveID)Slot);
118 assert(Ty && "Not a primitive type ID?");
119 return Ty;
120 }
121 Slot -= Type::FirstDerivedTyID;
122 if (Slot >= ModuleTypes.size())
123 throw std::string("Illegal compaction table type reference!");
124 return ModuleTypes[Slot];
125 }
126
127 unsigned getGlobalTableTypeSlot(const Type *Ty) {
128 if (Ty->isPrimitiveType())
129 return Ty->getPrimitiveID();
130 TypeListTy::iterator I = find(ModuleTypes.begin(),
131 ModuleTypes.end(), Ty);
132 if (I == ModuleTypes.end())
133 throw std::string("Didn't find type in ModuleTypes.");
134 return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
135 }
136
137public:
138 typedef const unsigned char* BufPtr;
139 void ParseModule (BufPtr &Buf, BufPtr End);
140 void ParseNextFunction (Type* FType) ;
141 void ParseAllFunctionBodies ();
142
143private:
144 void ParseVersionInfo (BufPtr &Buf, BufPtr End);
145 void ParseModuleGlobalInfo (BufPtr &Buf, BufPtr End);
146 void ParseSymbolTable (BufPtr &Buf, BufPtr End);
147 void ParseFunctionLazily (BufPtr &Buf, BufPtr End);
148 void ParseFunctionBody (const Type* FType, BufPtr &Buf, BufPtr EndBuf);
149 void ParseCompactionTable (BufPtr &Buf, BufPtr End);
150 void ParseGlobalTypes (BufPtr &Buf, BufPtr End);
151
152 void ParseBasicBlock (BufPtr &Buf, BufPtr End, unsigned BlockNo);
153 unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
154
155 bool ParseInstruction (BufPtr &Buf, BufPtr End,
156 std::vector<unsigned>& Args);
157
158 void ParseConstantPool (BufPtr &Buf, BufPtr End, TypeListTy& List);
159 void ParseConstantValue (BufPtr &Buf, BufPtr End, unsigned TypeID);
160 void ParseTypeConstants (BufPtr &Buf, BufPtr End, TypeListTy &Tab,
161 unsigned NumEntries);
162 const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End);
163 void ParseStringConstants (BufPtr &Buf, BufPtr End, unsigned NumEntries);
164
165};
166
167
168static inline void readBlock(const unsigned char *&Buf,
169 const unsigned char *EndBuf,
170 unsigned &Type, unsigned &Size) {
171 Type = read(Buf, EndBuf);
172 Size = read(Buf, EndBuf);
173}
174
175} // End llvm namespace
176
177#endif
178// vim: sw=2