summaryrefslogtreecommitdiff
path: root/lib/Bytecode/Analyzer/Parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bytecode/Analyzer/Parser.h')
-rw-r--r--lib/Bytecode/Analyzer/Parser.h178
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/Bytecode/Analyzer/Parser.h b/lib/Bytecode/Analyzer/Parser.h
new file mode 100644
index 0000000000..027047b3f8
--- /dev/null
+++ b/lib/Bytecode/Analyzer/Parser.h
@@ -0,0 +1,178 @@
+//===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines the interface to the Bytecode Parser
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BYTECODE_PARSER_H
+#define BYTECODE_PARSER_H
+
+#include "ReaderPrimitives.h"
+#include "BytecodeHandler.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include <utility>
+#include <vector>
+#include <map>
+
+namespace llvm {
+
+struct LazyFunctionInfo {
+ const unsigned char *Buf, *EndBuf;
+ LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0)
+ : Buf(B), EndBuf(EB) {}
+};
+
+typedef std::map<const Type*, LazyFunctionInfo> LazyFunctionMap;
+
+class AbstractBytecodeParser {
+ AbstractBytecodeParser(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
+ void operator=(const AbstractBytecodeParser &); // DO NOT IMPLEMENT
+public:
+ AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; }
+ ~AbstractBytecodeParser() { }
+
+ void ParseBytecode(const unsigned char *Buf, unsigned Length,
+ const std::string &ModuleID);
+
+ void dump() const {
+ std::cerr << "AbstractBytecodeParser instance!\n";
+ }
+
+private:
+ // Information about the module, extracted from the bytecode revision number.
+ unsigned char RevisionNum; // The rev # itself
+
+ // Flags to distinguish LLVM 1.0 & 1.1 bytecode formats (revision #0)
+
+ // Revision #0 had an explicit alignment of data only for the ModuleGlobalInfo
+ // block. This was fixed to be like all other blocks in 1.2
+ bool hasInconsistentModuleGlobalInfo;
+
+ // Revision #0 also explicitly encoded zero values for primitive types like
+ // int/sbyte/etc.
+ bool hasExplicitPrimitiveZeros;
+
+ // Flags to control features specific the LLVM 1.2 and before (revision #1)
+
+ // LLVM 1.2 and earlier required that getelementptr structure indices were
+ // ubyte constants and that sequential type indices were longs.
+ bool hasRestrictedGEPTypes;
+
+
+ /// CompactionTable - If a compaction table is active in the current function,
+ /// this is the mapping that it contains.
+ std::vector<Type*> CompactionTypeTable;
+
+ // ConstantFwdRefs - This maintains a mapping between <Type, Slot #>'s and
+ // forward references to constants. Such values may be referenced before they
+ // are defined, and if so, the temporary object that they represent is held
+ // here.
+ //
+ typedef std::map<std::pair<const Type*,unsigned>, Constant*> ConstantRefsType;
+ ConstantRefsType ConstantFwdRefs;
+
+ // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used
+ // to deal with forward references to types.
+ //
+ typedef std::vector<PATypeHolder> TypeListTy;
+ TypeListTy ModuleTypes;
+ TypeListTy FunctionTypes;
+
+ // When the ModuleGlobalInfo section is read, we create a FunctionType object
+ // for each function in the module. When the function is loaded, this type is
+ // used to instantiate the actual function object.
+ std::vector<const Type*> FunctionSignatureList;
+
+ // Constant values are read in after global variables. Because of this, we
+ // must defer setting the initializers on global variables until after module
+ // level constants have been read. In the mean time, this list keeps track of
+ // what we must do.
+ //
+ std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
+
+ // For lazy reading-in of functions, we need to save away several pieces of
+ // information about each function: its begin and end pointer in the buffer
+ // and its FunctionSlot.
+ //
+ LazyFunctionMap LazyFunctionLoadMap;
+
+ /// The handler for parsing
+ BytecodeHandler* handler;
+
+private:
+ const Type *AbstractBytecodeParser::getType(unsigned ID);
+ /// getGlobalTableType - This is just like getType, but when a compaction
+ /// table is in use, it is ignored. Also, no forward references or other
+ /// fancy features are supported.
+ const Type *getGlobalTableType(unsigned Slot) {
+ if (Slot < Type::FirstDerivedTyID) {
+ const Type *Ty = Type::getPrimitiveType((Type::PrimitiveID)Slot);
+ assert(Ty && "Not a primitive type ID?");
+ return Ty;
+ }
+ Slot -= Type::FirstDerivedTyID;
+ if (Slot >= ModuleTypes.size())
+ throw std::string("Illegal compaction table type reference!");
+ return ModuleTypes[Slot];
+ }
+
+ unsigned getGlobalTableTypeSlot(const Type *Ty) {
+ if (Ty->isPrimitiveType())
+ return Ty->getPrimitiveID();
+ TypeListTy::iterator I = find(ModuleTypes.begin(),
+ ModuleTypes.end(), Ty);
+ if (I == ModuleTypes.end())
+ throw std::string("Didn't find type in ModuleTypes.");
+ return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
+ }
+
+public:
+ typedef const unsigned char* BufPtr;
+ void ParseModule (BufPtr &Buf, BufPtr End);
+ void ParseNextFunction (Type* FType) ;
+ void ParseAllFunctionBodies ();
+
+private:
+ void ParseVersionInfo (BufPtr &Buf, BufPtr End);
+ void ParseModuleGlobalInfo (BufPtr &Buf, BufPtr End);
+ void ParseSymbolTable (BufPtr &Buf, BufPtr End);
+ void ParseFunctionLazily (BufPtr &Buf, BufPtr End);
+ void ParseFunctionBody (const Type* FType, BufPtr &Buf, BufPtr EndBuf);
+ void ParseCompactionTable (BufPtr &Buf, BufPtr End);
+ void ParseGlobalTypes (BufPtr &Buf, BufPtr End);
+
+ void ParseBasicBlock (BufPtr &Buf, BufPtr End, unsigned BlockNo);
+ unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
+
+ bool ParseInstruction (BufPtr &Buf, BufPtr End,
+ std::vector<unsigned>& Args);
+
+ void ParseConstantPool (BufPtr &Buf, BufPtr End, TypeListTy& List);
+ void ParseConstantValue (BufPtr &Buf, BufPtr End, unsigned TypeID);
+ void ParseTypeConstants (BufPtr &Buf, BufPtr End, TypeListTy &Tab,
+ unsigned NumEntries);
+ const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End);
+ void ParseStringConstants (BufPtr &Buf, BufPtr End, unsigned NumEntries);
+
+};
+
+
+static inline void readBlock(const unsigned char *&Buf,
+ const unsigned char *EndBuf,
+ unsigned &Type, unsigned &Size) {
+ Type = read(Buf, EndBuf);
+ Size = read(Buf, EndBuf);
+}
+
+} // End llvm namespace
+
+#endif
+// vim: sw=2