| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 1 | //===-- Reader.h - Interface To Bytecode Reading ----------------*- 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 Reader which is | 
|  | 11 | //  responsible for correctly interpreting bytecode files (backwards compatible) | 
|  | 12 | //  and materializing a module from the bytecode read. | 
|  | 13 | // | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 |  | 
|  | 16 | #ifndef BYTECODE_PARSER_H | 
|  | 17 | #define BYTECODE_PARSER_H | 
|  | 18 |  | 
|  | 19 | #include "llvm/Constants.h" | 
|  | 20 | #include "llvm/DerivedTypes.h" | 
|  | 21 | #include "llvm/GlobalValue.h" | 
|  | 22 | #include "llvm/Function.h" | 
|  | 23 | #include "llvm/ModuleProvider.h" | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 24 | #include "llvm/Bytecode/Analyzer.h" | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 25 | #include <utility> | 
|  | 26 | #include <map> | 
|  | 27 |  | 
|  | 28 | namespace llvm { | 
|  | 29 |  | 
|  | 30 | class BytecodeHandler; ///< Forward declare the handler interface | 
|  | 31 |  | 
|  | 32 | /// This class defines the interface for parsing a buffer of bytecode. The | 
|  | 33 | /// parser itself takes no action except to call the various functions of | 
|  | 34 | /// the handler interface. The parser's sole responsibility is the correct | 
|  | 35 | /// interpretation of the bytecode buffer. The handler is responsible for | 
|  | 36 | /// instantiating and keeping track of all values. As a convenience, the parser | 
|  | 37 | /// is responsible for materializing types and will pass them through the | 
|  | 38 | /// handler interface as necessary. | 
|  | 39 | /// @see BytecodeHandler | 
|  | 40 | /// @brief Bytecode Reader interface | 
|  | 41 | class BytecodeReader : public ModuleProvider { | 
|  | 42 |  | 
|  | 43 | /// @name Constructors | 
|  | 44 | /// @{ | 
|  | 45 | public: | 
|  | 46 | /// @brief Default constructor. By default, no handler is used. | 
|  | 47 | BytecodeReader( | 
|  | 48 | BytecodeHandler* h = 0 | 
|  | 49 | ) { | 
|  | 50 | Handler = h; | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | ~BytecodeReader() { freeState(); } | 
|  | 54 |  | 
|  | 55 | /// @} | 
|  | 56 | /// @name Types | 
|  | 57 | /// @{ | 
|  | 58 | public: | 
| Reid Spencer | ad89bd6 | 2004-07-25 18:07:36 +0000 | [diff] [blame] | 59 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 60 | /// @brief A convenience type for the buffer pointer | 
|  | 61 | typedef const unsigned char* BufPtr; | 
|  | 62 |  | 
|  | 63 | /// @brief The type used for a vector of potentially abstract types | 
|  | 64 | typedef std::vector<PATypeHolder> TypeListTy; | 
|  | 65 |  | 
|  | 66 | /// This type provides a vector of Value* via the User class for | 
|  | 67 | /// storage of Values that have been constructed when reading the | 
|  | 68 | /// bytecode. Because of forward referencing, constant replacement | 
|  | 69 | /// can occur so we ensure that our list of Value* is updated | 
|  | 70 | /// properly through those transitions. This ensures that the | 
|  | 71 | /// correct Value* is in our list when it comes time to associate | 
|  | 72 | /// constants with global variables at the end of reading the | 
|  | 73 | /// globals section. | 
|  | 74 | /// @brief A list of values as a User of those Values. | 
|  | 75 | struct ValueList : public User { | 
| Reid Spencer | 89fc0e3 | 2004-07-18 00:13:12 +0000 | [diff] [blame] | 76 | ValueList() : User(Type::VoidTy, Value::ValueListVal) {} | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 77 |  | 
|  | 78 | // vector compatibility methods | 
|  | 79 | unsigned size() const { return getNumOperands(); } | 
|  | 80 | void push_back(Value *V) { Operands.push_back(Use(V, this)); } | 
|  | 81 | Value *back() const { return Operands.back(); } | 
|  | 82 | void pop_back() { Operands.pop_back(); } | 
|  | 83 | bool empty() const { return Operands.empty(); } | 
|  | 84 | // must override this | 
|  | 85 | virtual void print(std::ostream& os) const { | 
|  | 86 | for ( unsigned i = 0; i < size(); i++ ) { | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 87 | os << i << " "; | 
|  | 88 | getOperand(i)->print(os); | 
|  | 89 | os << "\n"; | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 90 | } | 
|  | 91 | } | 
|  | 92 | }; | 
|  | 93 |  | 
|  | 94 | /// @brief A 2 dimensional table of values | 
|  | 95 | typedef std::vector<ValueList*> ValueTable; | 
|  | 96 |  | 
|  | 97 | /// This map is needed so that forward references to constants can be looked | 
|  | 98 | /// up by Type and slot number when resolving those references. | 
|  | 99 | /// @brief A mapping of a Type/slot pair to a Constant*. | 
|  | 100 | typedef std::map<std::pair<const Type*,unsigned>, Constant*> ConstantRefsType; | 
|  | 101 |  | 
|  | 102 | /// For lazy read-in of functions, we need to save the location in the | 
|  | 103 | /// data stream where the function is located. This structure provides that | 
|  | 104 | /// information. Lazy read-in is used mostly by the JIT which only wants to | 
|  | 105 | /// resolve functions as it needs them. | 
|  | 106 | /// @brief Keeps pointers to function contents for later use. | 
|  | 107 | struct LazyFunctionInfo { | 
|  | 108 | const unsigned char *Buf, *EndBuf; | 
|  | 109 | LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0) | 
|  | 110 | : Buf(B), EndBuf(EB) {} | 
|  | 111 | }; | 
|  | 112 |  | 
|  | 113 | /// @brief A mapping of functions to their LazyFunctionInfo for lazy reading. | 
|  | 114 | typedef std::map<Function*, LazyFunctionInfo> LazyFunctionMap; | 
|  | 115 |  | 
|  | 116 | /// @brief A list of global variables and the slot number that initializes | 
|  | 117 | /// them. | 
|  | 118 | typedef std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitsList; | 
|  | 119 |  | 
|  | 120 | /// This type maps a typeslot/valueslot pair to the corresponding Value*. | 
|  | 121 | /// It is used for dealing with forward references as values are read in. | 
|  | 122 | /// @brief A map for dealing with forward references of values. | 
|  | 123 | typedef std::map<std::pair<unsigned,unsigned>,Value*> ForwardReferenceMap; | 
|  | 124 |  | 
|  | 125 | /// @} | 
|  | 126 | /// @name Methods | 
|  | 127 | /// @{ | 
|  | 128 | public: | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 129 | /// @brief Main interface to parsing a bytecode buffer. | 
|  | 130 | void ParseBytecode( | 
| Reid Spencer | 5c15fe5 | 2004-07-05 00:57:50 +0000 | [diff] [blame] | 131 | const unsigned char *Buf,    ///< Beginning of the bytecode buffer | 
|  | 132 | unsigned Length,             ///< Length of the bytecode buffer | 
|  | 133 | const std::string &ModuleID, ///< An identifier for the module constructed. | 
|  | 134 | bool processFunctions=false  ///< Process all function bodies fully. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 135 | ); | 
|  | 136 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 137 | /// @brief Parse all function bodies | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 138 | void ParseAllFunctionBodies(); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 139 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 140 | /// @brief Parse the next function of specific type | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 141 | void ParseFunction(Function* Func) ; | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 142 |  | 
|  | 143 | /// This method is abstract in the parent ModuleProvider class. Its | 
|  | 144 | /// implementation is identical to the ParseFunction method. | 
|  | 145 | /// @see ParseFunction | 
|  | 146 | /// @brief Make a specific function materialize. | 
|  | 147 | virtual void materializeFunction(Function *F) { | 
|  | 148 | LazyFunctionMap::iterator Fi = LazyFunctionLoadMap.find(F); | 
|  | 149 | if (Fi == LazyFunctionLoadMap.end()) return; | 
|  | 150 | ParseFunction(F); | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | /// This method is abstract in the parent ModuleProvider class. Its | 
|  | 154 | /// implementation is identical to ParseAllFunctionBodies. | 
|  | 155 | /// @see ParseAllFunctionBodies | 
|  | 156 | /// @brief Make the whole module materialize | 
|  | 157 | virtual Module* materializeModule() { | 
|  | 158 | ParseAllFunctionBodies(); | 
|  | 159 | return TheModule; | 
|  | 160 | } | 
|  | 161 |  | 
|  | 162 | /// This method is provided by the parent ModuleProvde class and overriden | 
|  | 163 | /// here. It simply releases the module from its provided and frees up our | 
|  | 164 | /// state. | 
|  | 165 | /// @brief Release our hold on the generated module | 
|  | 166 | Module* releaseModule() { | 
|  | 167 | // Since we're losing control of this Module, we must hand it back complete | 
|  | 168 | Module *M = ModuleProvider::releaseModule(); | 
|  | 169 | freeState(); | 
|  | 170 | return M; | 
|  | 171 | } | 
|  | 172 |  | 
|  | 173 | /// @} | 
|  | 174 | /// @name Parsing Units For Subclasses | 
|  | 175 | /// @{ | 
|  | 176 | protected: | 
|  | 177 | /// @brief Parse whole module scope | 
|  | 178 | void ParseModule(); | 
|  | 179 |  | 
|  | 180 | /// @brief Parse the version information block | 
|  | 181 | void ParseVersionInfo(); | 
|  | 182 |  | 
|  | 183 | /// @brief Parse the ModuleGlobalInfo block | 
|  | 184 | void ParseModuleGlobalInfo(); | 
|  | 185 |  | 
|  | 186 | /// @brief Parse a symbol table | 
|  | 187 | void ParseSymbolTable( Function* Func, SymbolTable *ST); | 
|  | 188 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 189 | /// @brief Parse functions lazily. | 
|  | 190 | void ParseFunctionLazily(); | 
|  | 191 |  | 
|  | 192 | ///  @brief Parse a function body | 
|  | 193 | void ParseFunctionBody(Function* Func); | 
|  | 194 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 195 | /// @brief Parse the type list portion of a compaction table | 
|  | 196 | void BytecodeReader::ParseCompactionTypes( unsigned NumEntries ); | 
|  | 197 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 198 | /// @brief Parse a compaction table | 
|  | 199 | void ParseCompactionTable(); | 
|  | 200 |  | 
|  | 201 | /// @brief Parse global types | 
|  | 202 | void ParseGlobalTypes(); | 
|  | 203 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 204 | /// @brief Parse a basic block (for LLVM 1.0 basic block blocks) | 
|  | 205 | BasicBlock* ParseBasicBlock(unsigned BlockNo); | 
|  | 206 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 207 | /// @brief parse an instruction list (for post LLVM 1.0 instruction lists | 
|  | 208 | /// with blocks differentiated by terminating instructions. | 
|  | 209 | unsigned ParseInstructionList( | 
|  | 210 | Function* F   ///< The function into which BBs will be inserted | 
|  | 211 | ); | 
|  | 212 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 213 | /// @brief Parse a single instruction. | 
|  | 214 | void ParseInstruction( | 
|  | 215 | std::vector<unsigned>& Args,   ///< The arguments to be filled in | 
|  | 216 | BasicBlock* BB             ///< The BB the instruction goes in | 
|  | 217 | ); | 
|  | 218 |  | 
|  | 219 | /// @brief Parse the whole constant pool | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 220 | void ParseConstantPool(ValueTable& Values, TypeListTy& Types, | 
|  | 221 | bool isFunction); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 222 |  | 
|  | 223 | /// @brief Parse a single constant value | 
|  | 224 | Constant* ParseConstantValue(unsigned TypeID); | 
|  | 225 |  | 
|  | 226 | /// @brief Parse a block of types constants | 
| Reid Spencer | 6690651 | 2004-07-11 17:24:05 +0000 | [diff] [blame] | 227 | void ParseTypes(TypeListTy &Tab, unsigned NumEntries); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 228 |  | 
|  | 229 | /// @brief Parse a single type constant | 
| Reid Spencer | 6690651 | 2004-07-11 17:24:05 +0000 | [diff] [blame] | 230 | const Type *ParseType(); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 231 |  | 
|  | 232 | /// @brief Parse a string constants block | 
|  | 233 | void ParseStringConstants(unsigned NumEntries, ValueTable &Tab); | 
|  | 234 |  | 
|  | 235 | /// @} | 
|  | 236 | /// @name Data | 
|  | 237 | /// @{ | 
|  | 238 | private: | 
|  | 239 | BufPtr MemStart;     ///< Start of the memory buffer | 
|  | 240 | BufPtr MemEnd;       ///< End of the memory buffer | 
|  | 241 | BufPtr BlockStart;   ///< Start of current block being parsed | 
|  | 242 | BufPtr BlockEnd;     ///< End of current block being parsed | 
|  | 243 | BufPtr At;           ///< Where we're currently parsing at | 
|  | 244 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 245 | /// Information about the module, extracted from the bytecode revision number. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 246 | unsigned char RevisionNum;        // The rev # itself | 
|  | 247 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 248 | /// Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0) | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 249 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 250 | /// Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo | 
|  | 251 | /// block.  This was fixed to be like all other blocks in 1.2 | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 252 | bool hasInconsistentModuleGlobalInfo; | 
|  | 253 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 254 | /// Revision #0 also explicitly encoded zero values for primitive types like | 
|  | 255 | /// int/sbyte/etc. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 256 | bool hasExplicitPrimitiveZeros; | 
|  | 257 |  | 
|  | 258 | // Flags to control features specific the LLVM 1.2 and before (revision #1) | 
|  | 259 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 260 | /// LLVM 1.2 and earlier required that getelementptr structure indices were | 
|  | 261 | /// ubyte constants and that sequential type indices were longs. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 262 | bool hasRestrictedGEPTypes; | 
|  | 263 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 264 | /// LLVM 1.2 and earlier had class Type deriving from Value and the Type | 
|  | 265 | /// objects were located in the "Type Type" plane of various lists in read | 
|  | 266 | /// by the bytecode reader. In LLVM 1.3 this is no longer the case. Types are | 
|  | 267 | /// completely distinct from Values. Consequently, Types are written in fixed | 
|  | 268 | /// locations in LLVM 1.3. This flag indicates that the older Type derived | 
|  | 269 | /// from Value style of bytecode file is being read. | 
|  | 270 | bool hasTypeDerivedFromValue; | 
|  | 271 |  | 
| Reid Spencer | ad89bd6 | 2004-07-25 18:07:36 +0000 | [diff] [blame] | 272 | /// LLVM 1.2 and earlier encoded block headers as two uint (8 bytes), one for | 
|  | 273 | /// the size and one for the type. This is a bit wasteful, especially for small | 
|  | 274 | /// files where the 8 bytes per block is a large fraction of the total block | 
|  | 275 | /// size. In LLVM 1.3, the block type and length are encoded into a single | 
|  | 276 | /// uint32 by restricting the number of block types (limit 31) and the maximum | 
|  | 277 | /// size of a block (limit 2^27-1=134,217,727). Note that the module block | 
|  | 278 | /// still uses the 8-byte format so the maximum size of a file can be | 
|  | 279 | /// 2^32-1 bytes long. | 
|  | 280 | bool hasLongBlockHeaders; | 
|  | 281 |  | 
| Reid Spencer | ad89bd6 | 2004-07-25 18:07:36 +0000 | [diff] [blame] | 282 | /// LLVM 1.2 and earlier wrote type slot numbers as vbr_uint32. In LLVM 1.3 | 
|  | 283 | /// this has been reduced to vbr_uint24. It shouldn't make much difference | 
|  | 284 | /// since we haven't run into a module with > 24 million types, but for safety | 
|  | 285 | /// the 24-bit restriction has been enforced in 1.3 to free some bits in | 
|  | 286 | /// various places and to ensure consistency. In particular, global vars are | 
|  | 287 | /// restricted to 24-bits. | 
|  | 288 | bool has32BitTypes; | 
|  | 289 |  | 
|  | 290 | /// LLVM 1.2 and earlier did not provide a target triple nor a list of | 
|  | 291 | /// libraries on which the bytecode is dependent. LLVM 1.3 provides these | 
|  | 292 | /// features, for use in future versions of LLVM. | 
|  | 293 | bool hasNoDependentLibraries; | 
|  | 294 |  | 
|  | 295 | /// LLVM 1.2 and earlier encoded the file version as part of the module block | 
|  | 296 | /// but this information may be needed to | 
|  | 297 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 298 | /// CompactionTable - If a compaction table is active in the current function, | 
|  | 299 | /// this is the mapping that it contains. | 
|  | 300 | std::vector<const Type*> CompactionTypes; | 
|  | 301 |  | 
|  | 302 | /// @brief If a compaction table is active in the current function, | 
|  | 303 | /// this is the mapping that it contains. | 
|  | 304 | std::vector<std::vector<Value*> > CompactionValues; | 
|  | 305 |  | 
|  | 306 | /// @brief This vector is used to deal with forward references to types in | 
|  | 307 | /// a module. | 
|  | 308 | TypeListTy ModuleTypes; | 
|  | 309 |  | 
|  | 310 | /// @brief This vector is used to deal with forward references to types in | 
|  | 311 | /// a function. | 
|  | 312 | TypeListTy FunctionTypes; | 
|  | 313 |  | 
|  | 314 | /// When the ModuleGlobalInfo section is read, we create a Function object | 
|  | 315 | /// for each function in the module. When the function is loaded, after the | 
|  | 316 | /// module global info is read, this Function is populated. Until then, the | 
|  | 317 | /// functions in this vector just hold the function signature. | 
|  | 318 | std::vector<Function*> FunctionSignatureList; | 
|  | 319 |  | 
|  | 320 | /// @brief This is the table of values belonging to the current function | 
|  | 321 | ValueTable FunctionValues; | 
|  | 322 |  | 
|  | 323 | /// @brief This is the table of values belonging to the module (global) | 
|  | 324 | ValueTable ModuleValues; | 
|  | 325 |  | 
|  | 326 | /// @brief This keeps track of function level forward references. | 
|  | 327 | ForwardReferenceMap ForwardReferences; | 
|  | 328 |  | 
|  | 329 | /// @brief The basic blocks we've parsed, while parsing a function. | 
|  | 330 | std::vector<BasicBlock*> ParsedBasicBlocks; | 
|  | 331 |  | 
|  | 332 | /// This maintains a mapping between <Type, Slot #>'s and | 
|  | 333 | /// forward references to constants.  Such values may be referenced before they | 
|  | 334 | /// are defined, and if so, the temporary object that they represent is held | 
|  | 335 | /// here. | 
|  | 336 | /// @brief Temporary place for forward references to constants. | 
|  | 337 | ConstantRefsType ConstantFwdRefs; | 
|  | 338 |  | 
|  | 339 | /// Constant values are read in after global variables.  Because of this, we | 
|  | 340 | /// must defer setting the initializers on global variables until after module | 
|  | 341 | /// level constants have been read.  In the mean time, this list keeps track of | 
|  | 342 | /// what we must do. | 
|  | 343 | GlobalInitsList GlobalInits; | 
|  | 344 |  | 
|  | 345 | // For lazy reading-in of functions, we need to save away several pieces of | 
|  | 346 | // information about each function: its begin and end pointer in the buffer | 
|  | 347 | // and its FunctionSlot. | 
|  | 348 | LazyFunctionMap LazyFunctionLoadMap; | 
|  | 349 |  | 
|  | 350 | /// This stores the parser's handler which is used for handling tasks other | 
|  | 351 | /// just than reading bytecode into the IR. If this is non-null, calls on | 
|  | 352 | /// the (polymorphic) BytecodeHandler interface (see llvm/Bytecode/Handler.h) | 
|  | 353 | /// will be made to report the logical structure of the bytecode file. What | 
|  | 354 | /// the handler does with the events it receives is completely orthogonal to | 
|  | 355 | /// the business of parsing the bytecode and building the IR.  This is used, | 
|  | 356 | /// for example, by the llvm-abcd tool for analysis of byte code. | 
|  | 357 | /// @brief Handler for parsing events. | 
|  | 358 | BytecodeHandler* Handler; | 
|  | 359 |  | 
|  | 360 | /// @} | 
|  | 361 | /// @name Implementation Details | 
|  | 362 | /// @{ | 
|  | 363 | private: | 
|  | 364 | /// @brief Determines if this module has a function or not. | 
|  | 365 | bool hasFunctions() { return ! FunctionSignatureList.empty(); } | 
|  | 366 |  | 
|  | 367 | /// @brief Determines if the type id has an implicit null value. | 
|  | 368 | bool hasImplicitNull(unsigned TyID ); | 
|  | 369 |  | 
|  | 370 | /// @brief Converts a type slot number to its Type* | 
|  | 371 | const Type *getType(unsigned ID); | 
|  | 372 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 373 | /// @brief Converts a pre-sanitized type slot number to its Type* and | 
|  | 374 | /// sanitizes the type id. | 
|  | 375 | inline const Type* getSanitizedType(unsigned& ID ); | 
|  | 376 |  | 
|  | 377 | /// @brief Read in and get a sanitized type id | 
|  | 378 | inline const Type* BytecodeReader::readSanitizedType(); | 
|  | 379 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 380 | /// @brief Converts a Type* to its type slot number | 
|  | 381 | unsigned getTypeSlot(const Type *Ty); | 
|  | 382 |  | 
|  | 383 | /// @brief Converts a normal type slot number to a compacted type slot num. | 
|  | 384 | unsigned getCompactionTypeSlot(unsigned type); | 
|  | 385 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 386 | /// @brief Gets the global type corresponding to the TypeId | 
|  | 387 | const Type *getGlobalTableType(unsigned TypeId); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 388 |  | 
|  | 389 | /// This is just like getTypeSlot, but when a compaction table is in use, | 
|  | 390 | /// it is ignored. | 
|  | 391 | unsigned getGlobalTableTypeSlot(const Type *Ty); | 
|  | 392 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 393 | /// @brief Get a value from its typeid and slot number | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 394 | Value* getValue(unsigned TypeID, unsigned num, bool Create = true); | 
|  | 395 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 396 | /// @brief Get a value from its type and slot number, ignoring compaction tables. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 397 | Value *getGlobalTableValue(const Type *Ty, unsigned SlotNo); | 
|  | 398 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 399 | /// @brief Get a basic block for current function | 
|  | 400 | BasicBlock *getBasicBlock(unsigned ID); | 
|  | 401 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 402 | /// @brief Get a constant value from its typeid and value slot. | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 403 | Constant* getConstantValue(unsigned typeSlot, unsigned valSlot); | 
|  | 404 |  | 
|  | 405 | /// @brief Convenience function for getting a constant value when | 
|  | 406 | /// the Type has already been resolved. | 
|  | 407 | Constant* getConstantValue(const Type *Ty, unsigned valSlot) { | 
|  | 408 | return getConstantValue(getTypeSlot(Ty), valSlot); | 
|  | 409 | } | 
|  | 410 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 411 | /// @brief Insert a newly created value | 
|  | 412 | unsigned insertValue(Value *V, unsigned Type, ValueTable &Table); | 
|  | 413 |  | 
|  | 414 | /// @brief Insert the arguments of a function. | 
|  | 415 | void insertArguments(Function* F ); | 
|  | 416 |  | 
|  | 417 | /// @brief Resolve all references to the placeholder (if any) for the | 
|  | 418 | /// given constant. | 
|  | 419 | void ResolveReferencesToConstant(Constant *C, unsigned Slot); | 
|  | 420 |  | 
|  | 421 | /// @brief Release our memory. | 
|  | 422 | void freeState() { | 
|  | 423 | freeTable(FunctionValues); | 
|  | 424 | freeTable(ModuleValues); | 
|  | 425 | } | 
|  | 426 |  | 
|  | 427 | /// @brief Free a table, making sure to free the ValueList in the table. | 
|  | 428 | void freeTable(ValueTable &Tab) { | 
|  | 429 | while (!Tab.empty()) { | 
|  | 430 | delete Tab.back(); | 
|  | 431 | Tab.pop_back(); | 
|  | 432 | } | 
|  | 433 | } | 
|  | 434 |  | 
| Reid Spencer | 2439972 | 2004-07-09 22:21:33 +0000 | [diff] [blame] | 435 | inline void error(std::string errmsg); | 
|  | 436 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 437 | BytecodeReader(const BytecodeReader &);  // DO NOT IMPLEMENT | 
|  | 438 | void operator=(const BytecodeReader &);  // DO NOT IMPLEMENT | 
|  | 439 |  | 
|  | 440 | /// @} | 
|  | 441 | /// @name Reader Primitives | 
|  | 442 | /// @{ | 
|  | 443 | private: | 
|  | 444 |  | 
|  | 445 | /// @brief Is there more to parse in the current block? | 
|  | 446 | inline bool moreInBlock(); | 
|  | 447 |  | 
|  | 448 | /// @brief Have we read past the end of the block | 
|  | 449 | inline void checkPastBlockEnd(const char * block_name); | 
|  | 450 |  | 
|  | 451 | /// @brief Align to 32 bits | 
|  | 452 | inline void align32(); | 
|  | 453 |  | 
|  | 454 | /// @brief Read an unsigned integer as 32-bits | 
|  | 455 | inline unsigned read_uint(); | 
|  | 456 |  | 
|  | 457 | /// @brief Read an unsigned integer with variable bit rate encoding | 
|  | 458 | inline unsigned read_vbr_uint(); | 
|  | 459 |  | 
| Reid Spencer | ad89bd6 | 2004-07-25 18:07:36 +0000 | [diff] [blame] | 460 | /// @brief Read an unsigned integer of no more than 24-bits with variable | 
|  | 461 | /// bit rate encoding. | 
|  | 462 | inline unsigned read_vbr_uint24(); | 
|  | 463 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 464 | /// @brief Read an unsigned 64-bit integer with variable bit rate encoding. | 
|  | 465 | inline uint64_t read_vbr_uint64(); | 
|  | 466 |  | 
|  | 467 | /// @brief Read a signed 64-bit integer with variable bit rate encoding. | 
|  | 468 | inline int64_t read_vbr_int64(); | 
|  | 469 |  | 
|  | 470 | /// @brief Read a string | 
|  | 471 | inline std::string read_str(); | 
|  | 472 |  | 
| Reid Spencer | 6690651 | 2004-07-11 17:24:05 +0000 | [diff] [blame] | 473 | /// @brief Read a float value | 
|  | 474 | inline void read_float(float& FloatVal); | 
|  | 475 |  | 
|  | 476 | /// @brief Read a double value | 
|  | 477 | inline void read_double(double& DoubleVal); | 
|  | 478 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 479 | /// @brief Read an arbitrary data chunk of fixed length | 
|  | 480 | inline void read_data(void *Ptr, void *End); | 
|  | 481 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 482 | /// @brief Read a bytecode block header | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 483 | inline void read_block(unsigned &Type, unsigned &Size); | 
|  | 484 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 485 | /// @brief Read a type identifier and sanitize it. | 
|  | 486 | inline bool read_typeid(unsigned &TypeId); | 
|  | 487 |  | 
|  | 488 | /// @brief Recalculate type ID for pre 1.3 bytecode files. | 
|  | 489 | inline bool sanitizeTypeId(unsigned &TypeId ); | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 490 | /// @} | 
|  | 491 | }; | 
|  | 492 |  | 
| Reid Spencer | a86159c | 2004-07-04 11:04:56 +0000 | [diff] [blame] | 493 | /// @brief A function for creating a BytecodeAnalzer as a handler | 
|  | 494 | /// for the Bytecode reader. | 
|  | 495 | BytecodeHandler* createBytecodeAnalyzerHandler(BytecodeAnalysis& bca ); | 
|  | 496 |  | 
|  | 497 |  | 
| Reid Spencer | f89143c | 2004-06-29 23:31:01 +0000 | [diff] [blame] | 498 | } // End llvm namespace | 
|  | 499 |  | 
|  | 500 | // vim: sw=2 | 
|  | 501 | #endif |