Merged BytecodeHandler.h into Parser.h since the parser and the handler
authorReid Spencer <rspencer@reidspencer.com>
Tue, 8 Jun 2004 05:51:18 +0000 (05:51 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Tue, 8 Jun 2004 05:51:18 +0000 (05:51 +0000)
must always coexist. Cleaned up the documentation on these interfaces
significantly. This is in preparation for moving Parser.h to the include
directories to make it a public interface.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14054 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Analyzer/BytecodeHandler.h [deleted file]
lib/Bytecode/Analyzer/Parser.h
lib/Bytecode/Reader/Parser.h

diff --git a/lib/Bytecode/Analyzer/BytecodeHandler.h b/lib/Bytecode/Analyzer/BytecodeHandler.h
deleted file mode 100644 (file)
index 2b03e2d..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-//===-- BytecodeHandler.h - Parsing Handler ---------------------*- 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 BytecodeHandler class that gets called by the
-//  AbstractBytecodeParser when parsing events occur.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BYTECODE_HANDLER_H
-#define BYTECODE_HANDLER_H
-
-#include "llvm/Module.h"
-#include "llvm/GlobalValue.h"
-#include <vector>
-
-namespace llvm {
-
-class ArrayType;
-class StructType;
-class PointerType;
-class ConstantArray;
-
-/// This class provides the interface for the handling bytecode events during
-/// parsing. The methods on this interface are invoked by the 
-/// AbstractBytecodeParser as it discovers the content of a bytecode stream. 
-/// This class provides a a clear separation of concerns between recognizing 
-/// the semantic units of a bytecode file and deciding what to do with them. 
-/// The AbstractBytecodeParser recognizes the content of the bytecode file and
-/// calls the BytecodeHandler methods to determine what should be done. This
-/// arrangement allows Bytecode files to be read and handled for a number of
-/// purposes simply by creating a subclass of BytecodeHandler. None of the
-/// parsing details need to be understood, only the meaning of the calls
-/// made on this interface.
-/// 
-/// Another paradigm that uses this design pattern is the XML SAX Parser. The
-/// ContentHandler for SAX plays the same role as the BytecodeHandler here.
-/// @brief Handle Bytecode Parsing Events
-class BytecodeHandler {
-
-/// @name Constructors And Operators
-/// @{
-public:
-  /// @brief Default constructor (empty)
-  BytecodeHandler() {}
-  /// @brief Virtual destructor (empty)
-  virtual ~BytecodeHandler() {}
-
-private:
-  BytecodeHandler(const BytecodeHandler &);  // DO NOT IMPLEMENT
-  void operator=(const BytecodeHandler &);  // DO NOT IMPLEMENT
-
-/// @}
-/// @name Handler Methods
-/// @{
-public:
-
-  /// This method is called whenever the parser detects an error in the
-  /// bytecode formatting. Returning true will cause the parser to keep 
-  /// going, however this is inadvisable in most cases. Returning false will
-  /// cause the parser to throw the message as a std::string.
-  /// @brief Handle parsing errors.
-  virtual bool handleError(const std::string& str );
-
-  /// This method is called at the beginning of a parse before anything is
-  /// read in order to give the handler a chance to initialize.
-  /// @brief Handle the start of a bytecode parse
-  virtual void handleStart();
-
-  /// This method is called at the end of a parse after everything has been
-  /// read in order to give the handler a chance to terminate.
-  /// @brief Handle the end of a bytecode parse
-  virtual void handleFinish();
-
-  /// This method is called at the start of a module to indicate that a
-  /// module is being parsed.
-  /// @brief Handle the start of a module.
-  virtual void handleModuleBegin(const std::string& id);
-
-  /// This method is called at the end of a module to indicate that the module
-  /// previously being parsed has concluded.
-  /// @brief Handle the end of a module.
-  virtual void handleModuleEnd(const std::string& id);
-
-  /// This method is called once the version information has been parsed. It 
-  /// provides the information about the version of the bytecode file being 
-  /// read.
-  /// @brief Handle the bytecode prolog
-  virtual void handleVersionInfo(
-    unsigned char RevisionNum,        ///< Byte code revision number
-    Module::Endianness Endianness,    ///< Endianness indicator
-    Module::PointerSize PointerSize   ///< PointerSize indicator
-  );
-
-  /// This method is called at the start of a module globals block which
-  /// contains the global variables and the function placeholders
-  virtual void handleModuleGlobalsBegin();
-
-  /// This method is called when a non-initialized global variable is 
-  /// recognized. Its type, constness, and linkage type are provided.
-  /// @brief Handle a non-initialized global variable
-  virtual void handleGlobalVariable( 
-    const Type* ElemType,     ///< The type of the global variable
-    bool isConstant,          ///< Whether the GV is constant or not
-    GlobalValue::LinkageTypes ///< The linkage type of the GV
-  );
-
-  /// This method is called when an initialized global variable is recognized.
-  /// Its type constness, linkage type, and the slot number of the initializer
-  /// are provided.
-  /// @brief Handle an intialized global variable.
-  virtual void handleInitializedGV( 
-    const Type* ElemType,     ///< The type of the global variable
-    bool isConstant,          ///< Whether the GV is constant or not
-    GlobalValue::LinkageTypes,///< The linkage type of the GV
-    unsigned initSlot         ///< Slot number of GV's initializer
-  );
-
-  /// This method is called when a new type is recognized. The type is 
-  /// converted from the bytecode and passed to this method.
-  /// @brief Handle a type
-  virtual void handleType( const Type* Ty );
-
-  /// This method is called when the function prototype for a function is
-  /// encountered in the module globals block.
-  virtual void handleFunctionDeclaration( 
-    const Type* FuncType      ///< The type of the function
-  );
-
-  /// This method is called at the end of the module globals block.
-  /// @brief Handle end of module globals block.
-  virtual void handleModuleGlobalsEnd();
-
-  /// This method is called at the beginning of a compaction table.
-  /// @brief Handle start of compaction table.
-  virtual void handleCompactionTableBegin();
-  virtual void handleCompactionTablePlane( 
-    unsigned Ty, 
-    unsigned NumEntries
-  );
-
-  virtual void handleCompactionTableType( 
-    unsigned i, 
-    unsigned TypSlot, 
-    const Type* 
-  );
-
-  virtual void handleCompactionTableValue( 
-    unsigned i, 
-    unsigned ValSlot, 
-    const Type* 
-  );
-
-  virtual void handleCompactionTableEnd();
-
-  virtual void handleSymbolTableBegin();
-
-  virtual void handleSymbolTablePlane( 
-    unsigned Ty, 
-    unsigned NumEntries, 
-    const Type* Ty 
-  );
-
-  virtual void handleSymbolTableType( 
-    unsigned i, 
-    unsigned slot, 
-    const std::string& name 
-  );
-
-  virtual void handleSymbolTableValue( 
-    unsigned i, 
-    unsigned slot, 
-    const std::string& name 
-  );
-
-  virtual void handleSymbolTableEnd();
-
-  virtual void handleFunctionBegin(
-    const Type* FType, 
-    GlobalValue::LinkageTypes linkage 
-  );
-
-  virtual void handleFunctionEnd(
-    const Type* FType
-  );
-
-  virtual void handleBasicBlockBegin(
-    unsigned blocknum
-  );
-
-  /// This method is called for each instruction that is parsed. 
-  /// @returns true if the instruction is a block terminating instruction
-  /// @brief Handle an instruction
-  virtual bool handleInstruction(
-    unsigned Opcode, 
-    const Type* iType, 
-    std::vector<unsigned>& Operands
-  );
-
-  /// This method is called for each block that is parsed.
-  virtual void handleBasicBlockEnd(unsigned blocknum);
-  /// This method is called at the start of the global constants block.
-  /// @brief Handle start of global constants block.
-  virtual void handleGlobalConstantsBegin();
-
-  virtual void handleConstantExpression( 
-    unsigned Opcode, 
-    const Type* Typ, 
-    std::vector<std::pair<const Type*,unsigned> > ArgVec 
-  );
-
-  virtual void handleConstantArray( 
-    const ArrayType* AT, 
-    std::vector<unsigned>& ElementSlots
-  );
-
-  virtual void handleConstantStruct(
-    const StructType* ST,
-    std::vector<unsigned>& ElementSlots
-  );
-
-  virtual void handleConstantPointer(
-    const PointerType* PT,
-    unsigned Slot
-  );
-
-  virtual void handleConstantString(
-    const ConstantArray* CA
-  );
-
-  virtual void handleConstantValue( Constant * c );
-  virtual void handleGlobalConstantsEnd();
-
-/// @}
-
-};
-
-} // End llvm namespace
-
-#endif
-
-// vim: sw=2
index 027047b3f8d6b2ffd1650077db1ce8128bc92a50..38a14717d5e87b3a51969595ed6bf4f9be0f9b3d 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===//
+//===-- Parser.h - Abstract Interface To Bytecode Parsing -------*- C++ -*-===//
 // 
 //                     The LLVM Compiler Infrastructure
 //
 // 
 //===----------------------------------------------------------------------===//
 //
-//  This header file defines the interface to the Bytecode Parser
+//  This header file defines the interface to the Bytecode Parser and the
+//  Bytecode Handler interface that it calls.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef BYTECODE_PARSER_H
 #define BYTECODE_PARSER_H
 
-#include "ReaderPrimitives.h"
-#include "BytecodeHandler.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Module.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 BytecodeHandler; ///< Forward declare the handler interface
+
+/// This class defines the interface for parsing a buffer of bytecode. The
+/// parser itself takes no action except to call the various functions of
+/// the handler interface. The parser's sole responsibility is the correct
+/// interpretation of the bytecode buffer. The handler is responsible for 
+/// instantiating and keeping track of all values. As a convenience, the parser 
+/// is responsible for materializing types and will pass them through the
+/// handler interface as necessary.
+/// @see BytecodeHandler
+/// @brief Abstract Bytecode Parser interface
 class AbstractBytecodeParser {
-  AbstractBytecodeParser(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
-  void operator=(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+
+/// @name Constructors
+/// @{
 public:
   AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; }
   ~AbstractBytecodeParser() { }
 
+/// @}
+/// @name Types
+/// @{
+public:
+  /// @brief A convenience type for the buffer pointer
+  typedef const unsigned char* BufPtr;
+
+  /// @brief The type used for vector of potentially abstract types
+  typedef std::vector<PATypeHolder> TypeListTy;
+
+  /// @brief 
+
+/// @}
+/// @name Methods
+/// @{
+public:
+
+  /// @brief Main interface to parsing a bytecode buffer.
   void ParseBytecode(const unsigned char *Buf, unsigned Length,
                      const std::string &ModuleID);
 
-  void dump() const {
-    std::cerr << "AbstractBytecodeParser instance!\n";
-  }
+  /// The ParseBytecode method lazily parses functions. Use this
+  /// method to cause the parser to actually parse all the function bodies
+  /// in the bytecode buffer.
+  /// @see ParseBytecode
+  /// @brief Parse all function bodies
+  void ParseAllFunctionBodies  ();
+
+  /// The Parsebytecode method lazily parses functions. Use this
+  /// method to casue the parser to parse the next function of a given
+  /// types. Note that this will remove the function from what is to be
+  /// included by ParseAllFunctionBodies.
+  /// @see ParseAllFunctionBodies
+  /// @see ParseBytecode
+  /// @brief Parse the next function of specific type
+  void ParseNextFunction       (Type* FType) ;
+
+/// @}
+/// @name Parsing Units For Subclasses
+/// @{
+protected:
+  /// @brief Parse whole module scope
+  void ParseModule             (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse the version information block
+  void ParseVersionInfo        (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse the ModuleGlobalInfo block
+  void ParseModuleGlobalInfo   (BufPtr &Buf, BufPtr End);
 
+  /// @brief Parse a symbol table
+  void ParseSymbolTable        (BufPtr &Buf, BufPtr End);
+
+  /// This function parses LLVM functions lazily. It obtains the type of the
+  /// function and records where the body of the function is in the bytecode
+  /// buffer. The caller can then use the ParseNextFunction and 
+  /// ParseAllFunctionBodies to get handler events for the functions.
+  /// @brief Parse functions lazily.
+  void ParseFunctionLazily     (BufPtr &Buf, BufPtr End);
+
+  ///  @brief Parse a function body
+  void ParseFunctionBody       (const Type* FType, BufPtr &Buf, BufPtr EndBuf);
+
+  /// @brief Parse a compaction table
+  void ParseCompactionTable    (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse global types
+  void ParseGlobalTypes        (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse a basic block (for LLVM 1.0 basic block blocks)
+  void ParseBasicBlock         (BufPtr &Buf, BufPtr End, unsigned BlockNo);
+
+  /// @brief parse an instruction list (for post LLVM 1.0 instruction lists
+  /// with blocks differentiated by terminating instructions.
+  unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
+  
+  /// @brief Parse an instruction.
+  bool ParseInstruction        (BufPtr &Buf, BufPtr End, 
+                               std::vector<unsigned>& Args);
+
+  /// @brief Parse a constant pool
+  void ParseConstantPool       (BufPtr &Buf, BufPtr End, TypeListTy& List);
+
+  /// @brief Parse a constant value
+  void ParseConstantValue      (BufPtr &Buf, BufPtr End, unsigned TypeID);
+
+  /// @brief Parse a block of types.
+  void ParseTypeConstants      (BufPtr &Buf, BufPtr End, TypeListTy &Tab,
+                                       unsigned NumEntries);
+
+  /// @brief Parse a single type.
+  const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse a string constants block
+  void ParseStringConstants    (BufPtr &Buf, BufPtr End, unsigned NumEntries);
+
+/// @}
+/// @name Data
+/// @{
 private:
   // Information about the module, extracted from the bytecode revision number.
   unsigned char RevisionNum;        // The rev # itself
@@ -82,13 +179,13 @@ private:
   // 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
@@ -98,16 +195,34 @@ private:
   //
   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
+/// @}
+/// @name Implementation Details
+/// @{
+private:
+  /// This stores the parser's handler. It makes virtual function calls through
+  /// the BytecodeHandler to notify the handler of parsing events. What the
+  /// handler does with the events is completely orthogonal to the business of
+  /// parsing the bytecode.
+  /// @brief The handler of bytecode parsing events.
   BytecodeHandler* handler;
   
+  /// 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.
+  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;
+  LazyFunctionMap LazyFunctionLoadMap;
+
 private:
+
+  static inline void readBlock(const unsigned char *&Buf,
+                              const unsigned char *EndBuf, 
+                              unsigned &Type, unsigned &Size) ;
+
   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
@@ -134,45 +249,250 @@ private:
     return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
   }
 
+  AbstractBytecodeParser(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+  void operator=(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+
+/// @}
+};
+
+/// This class provides the interface for the handling bytecode events during
+/// parsing. The methods on this interface are invoked by the 
+/// AbstractBytecodeParser as it discovers the content of a bytecode stream. 
+/// This class provides a a clear separation of concerns between recognizing 
+/// the semantic units of a bytecode file and deciding what to do with them. 
+/// The AbstractBytecodeParser recognizes the content of the bytecode file and
+/// calls the BytecodeHandler methods to determine what should be done. This
+/// arrangement allows Bytecode files to be read and handled for a number of
+/// purposes simply by creating a subclass of BytecodeHandler. None of the
+/// parsing details need to be understood, only the meaning of the calls
+/// made on this interface.
+/// 
+/// Another paradigm that uses this design pattern is the XML SAX Parser. The
+/// ContentHandler for SAX plays the same role as the BytecodeHandler here.
+/// @see AbstractbytecodeParser
+/// @brief Handle Bytecode Parsing Events
+class BytecodeHandler {
+
+/// @name Constructors And Operators
+/// @{
 public:
-  typedef const unsigned char* BufPtr;
-  void ParseModule             (BufPtr &Buf, BufPtr End);
-  void ParseNextFunction       (Type* FType) ;
-  void ParseAllFunctionBodies  ();
+  /// @brief Default constructor (empty)
+  BytecodeHandler() {}
+  /// @brief Virtual destructor (empty)
+  virtual ~BytecodeHandler() {}
 
 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);
+  BytecodeHandler(const BytecodeHandler &);  // DO NOT IMPLEMENT
+  void operator=(const BytecodeHandler &);  // DO NOT IMPLEMENT
 
-  void ParseBasicBlock         (BufPtr &Buf, BufPtr End, unsigned BlockNo);
-  unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
-  
-  bool ParseInstruction        (BufPtr &Buf, BufPtr End, 
-                               std::vector<unsigned>& Args);
+/// @}
+/// @name Handler Methods
+/// @{
+public:
 
-  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);
+  /// This method is called whenever the parser detects an error in the
+  /// bytecode formatting. Returning true will cause the parser to keep 
+  /// going, however this is inadvisable in most cases. Returning false will
+  /// cause the parser to throw the message as a std::string.
+  /// @brief Handle parsing errors.
+  virtual bool handleError(const std::string& str );
+
+  /// This method is called at the beginning of a parse before anything is
+  /// read in order to give the handler a chance to initialize.
+  /// @brief Handle the start of a bytecode parse
+  virtual void handleStart();
+
+  /// This method is called at the end of a parse after everything has been
+  /// read in order to give the handler a chance to terminate.
+  /// @brief Handle the end of a bytecode parse
+  virtual void handleFinish();
+
+  /// This method is called at the start of a module to indicate that a
+  /// module is being parsed.
+  /// @brief Handle the start of a module.
+  virtual void handleModuleBegin(const std::string& id);
+
+  /// This method is called at the end of a module to indicate that the module
+  /// previously being parsed has concluded.
+  /// @brief Handle the end of a module.
+  virtual void handleModuleEnd(const std::string& id);
+
+  /// This method is called once the version information has been parsed. It 
+  /// provides the information about the version of the bytecode file being 
+  /// read.
+  /// @brief Handle the bytecode prolog
+  virtual void handleVersionInfo(
+    unsigned char RevisionNum,        ///< Byte code revision number
+    Module::Endianness Endianness,    ///< Endianness indicator
+    Module::PointerSize PointerSize   ///< PointerSize indicator
+  );
+
+  /// This method is called at the start of a module globals block which
+  /// contains the global variables and the function placeholders
+  virtual void handleModuleGlobalsBegin();
+
+  /// This method is called when a non-initialized global variable is 
+  /// recognized. Its type, constness, and linkage type are provided.
+  /// @brief Handle a non-initialized global variable
+  virtual void handleGlobalVariable( 
+    const Type* ElemType,     ///< The type of the global variable
+    bool isConstant,          ///< Whether the GV is constant or not
+    GlobalValue::LinkageTypes ///< The linkage type of the GV
+  );
+
+  /// This method is called when an initialized global variable is recognized.
+  /// Its type constness, linkage type, and the slot number of the initializer
+  /// are provided.
+  /// @brief Handle an intialized global variable.
+  virtual void handleInitializedGV( 
+    const Type* ElemType,     ///< The type of the global variable
+    bool isConstant,          ///< Whether the GV is constant or not
+    GlobalValue::LinkageTypes,///< The linkage type of the GV
+    unsigned initSlot         ///< Slot number of GV's initializer
+  );
+
+  /// This method is called when a new type is recognized. The type is 
+  /// converted from the bytecode and passed to this method.
+  /// @brief Handle a type
+  virtual void handleType( const Type* Ty );
+
+  /// This method is called when the function prototype for a function is
+  /// encountered in the module globals block.
+  virtual void handleFunctionDeclaration( 
+    const Type* FuncType      ///< The type of the function
+  );
+
+  /// This method is called at the end of the module globals block.
+  /// @brief Handle end of module globals block.
+  virtual void handleModuleGlobalsEnd();
+
+  /// This method is called at the beginning of a compaction table.
+  /// @brief Handle start of compaction table.
+  virtual void handleCompactionTableBegin();
+
+  /// @brief Handle start of a compaction table plane
+  virtual void handleCompactionTablePlane( 
+    unsigned Ty, 
+    unsigned NumEntries
+  );
+
+
+  /// @brief Handle a type entry in the compaction table
+  virtual void handleCompactionTableType( 
+    unsigned i, 
+    unsigned TypSlot, 
+    const Type* 
+  );
+
+  /// @brief Handle a value entry in the compaction table
+  virtual void handleCompactionTableValue( 
+    unsigned i, 
+    unsigned ValSlot, 
+    const Type* 
+  );
+
+  /// @brief Handle end of a compaction table
+  virtual void handleCompactionTableEnd();
+
+  /// @brief Handle start of a symbol table
+  virtual void handleSymbolTableBegin();
+
+  /// @brief Handle start of a symbol table plane
+  virtual void handleSymbolTablePlane( 
+    unsigned Ty, 
+    unsigned NumEntries, 
+    const Type* Ty 
+  );
+
+  /// @brief Handle a named type in the symbol table
+  virtual void handleSymbolTableType( 
+    unsigned i, 
+    unsigned slot, 
+    const std::string& name 
+  );
+
+  /// @brief Handle a named value in the symbol table
+  virtual void handleSymbolTableValue( 
+    unsigned i, 
+    unsigned slot, 
+    const std::string& name 
+  );
+
+  /// @brief Handle the end of a symbol table
+  virtual void handleSymbolTableEnd();
+
+  /// @brief Handle the beginning of a function body
+  virtual void handleFunctionBegin(
+    const Type* FType, 
+    GlobalValue::LinkageTypes linkage 
+  );
+
+  /// @brief Handle the end of a function body
+  virtual void handleFunctionEnd(
+    const Type* FType
+  );
+
+  /// @brief Handle the beginning of a basic block
+  virtual void handleBasicBlockBegin(
+    unsigned blocknum
+  );
+
+  /// This method is called for each instruction that is parsed. 
+  /// @returns true if the instruction is a block terminating instruction
+  /// @brief Handle an instruction
+  virtual bool handleInstruction(
+    unsigned Opcode, 
+    const Type* iType, 
+    std::vector<unsigned>& Operands
+  );
+
+  /// @brief Handle the end of a basic block
+  virtual void handleBasicBlockEnd(unsigned blocknum);
+
+  /// @brief Handle start of global constants block.
+  virtual void handleGlobalConstantsBegin();
+
+  /// @brief Handle a constant expression
+  virtual void handleConstantExpression( 
+    unsigned Opcode, 
+    const Type* Typ, 
+    std::vector<std::pair<const Type*,unsigned> > ArgVec 
+  );
+
+  /// @brief Handle a constant array
+  virtual void handleConstantArray( 
+    const ArrayType* AT, 
+    std::vector<unsigned>& ElementSlots
+  );
+
+  /// @brief Handle a constant structure
+  virtual void handleConstantStruct(
+    const StructType* ST,
+    std::vector<unsigned>& ElementSlots
+  );
+
+  /// @brief Handle a constant pointer
+  virtual void handleConstantPointer(
+    const PointerType* PT,
+    unsigned Slot
+  );
+
+  /// @brief Handle a constant strings (array special case)
+  virtual void handleConstantString(
+    const ConstantArray* CA
+  );
+
+  /// @brief Handle a primitive constant value
+  virtual void handleConstantValue( Constant * c );
+
+  /// @brief Handle the end of the global constants
+  virtual void handleGlobalConstantsEnd();
+
+/// @}
 
 };
 
-
-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
+#endif
index 027047b3f8d6b2ffd1650077db1ce8128bc92a50..38a14717d5e87b3a51969595ed6bf4f9be0f9b3d 100644 (file)
@@ -1,4 +1,4 @@
-//===-- Parser.h - Definitions internal to the reader -----------*- C++ -*-===//
+//===-- Parser.h - Abstract Interface To Bytecode Parsing -------*- C++ -*-===//
 // 
 //                     The LLVM Compiler Infrastructure
 //
 // 
 //===----------------------------------------------------------------------===//
 //
-//  This header file defines the interface to the Bytecode Parser
+//  This header file defines the interface to the Bytecode Parser and the
+//  Bytecode Handler interface that it calls.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef BYTECODE_PARSER_H
 #define BYTECODE_PARSER_H
 
-#include "ReaderPrimitives.h"
-#include "BytecodeHandler.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Module.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 BytecodeHandler; ///< Forward declare the handler interface
+
+/// This class defines the interface for parsing a buffer of bytecode. The
+/// parser itself takes no action except to call the various functions of
+/// the handler interface. The parser's sole responsibility is the correct
+/// interpretation of the bytecode buffer. The handler is responsible for 
+/// instantiating and keeping track of all values. As a convenience, the parser 
+/// is responsible for materializing types and will pass them through the
+/// handler interface as necessary.
+/// @see BytecodeHandler
+/// @brief Abstract Bytecode Parser interface
 class AbstractBytecodeParser {
-  AbstractBytecodeParser(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
-  void operator=(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+
+/// @name Constructors
+/// @{
 public:
   AbstractBytecodeParser( BytecodeHandler* h ) { handler = h; }
   ~AbstractBytecodeParser() { }
 
+/// @}
+/// @name Types
+/// @{
+public:
+  /// @brief A convenience type for the buffer pointer
+  typedef const unsigned char* BufPtr;
+
+  /// @brief The type used for vector of potentially abstract types
+  typedef std::vector<PATypeHolder> TypeListTy;
+
+  /// @brief 
+
+/// @}
+/// @name Methods
+/// @{
+public:
+
+  /// @brief Main interface to parsing a bytecode buffer.
   void ParseBytecode(const unsigned char *Buf, unsigned Length,
                      const std::string &ModuleID);
 
-  void dump() const {
-    std::cerr << "AbstractBytecodeParser instance!\n";
-  }
+  /// The ParseBytecode method lazily parses functions. Use this
+  /// method to cause the parser to actually parse all the function bodies
+  /// in the bytecode buffer.
+  /// @see ParseBytecode
+  /// @brief Parse all function bodies
+  void ParseAllFunctionBodies  ();
+
+  /// The Parsebytecode method lazily parses functions. Use this
+  /// method to casue the parser to parse the next function of a given
+  /// types. Note that this will remove the function from what is to be
+  /// included by ParseAllFunctionBodies.
+  /// @see ParseAllFunctionBodies
+  /// @see ParseBytecode
+  /// @brief Parse the next function of specific type
+  void ParseNextFunction       (Type* FType) ;
+
+/// @}
+/// @name Parsing Units For Subclasses
+/// @{
+protected:
+  /// @brief Parse whole module scope
+  void ParseModule             (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse the version information block
+  void ParseVersionInfo        (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse the ModuleGlobalInfo block
+  void ParseModuleGlobalInfo   (BufPtr &Buf, BufPtr End);
 
+  /// @brief Parse a symbol table
+  void ParseSymbolTable        (BufPtr &Buf, BufPtr End);
+
+  /// This function parses LLVM functions lazily. It obtains the type of the
+  /// function and records where the body of the function is in the bytecode
+  /// buffer. The caller can then use the ParseNextFunction and 
+  /// ParseAllFunctionBodies to get handler events for the functions.
+  /// @brief Parse functions lazily.
+  void ParseFunctionLazily     (BufPtr &Buf, BufPtr End);
+
+  ///  @brief Parse a function body
+  void ParseFunctionBody       (const Type* FType, BufPtr &Buf, BufPtr EndBuf);
+
+  /// @brief Parse a compaction table
+  void ParseCompactionTable    (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse global types
+  void ParseGlobalTypes        (BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse a basic block (for LLVM 1.0 basic block blocks)
+  void ParseBasicBlock         (BufPtr &Buf, BufPtr End, unsigned BlockNo);
+
+  /// @brief parse an instruction list (for post LLVM 1.0 instruction lists
+  /// with blocks differentiated by terminating instructions.
+  unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
+  
+  /// @brief Parse an instruction.
+  bool ParseInstruction        (BufPtr &Buf, BufPtr End, 
+                               std::vector<unsigned>& Args);
+
+  /// @brief Parse a constant pool
+  void ParseConstantPool       (BufPtr &Buf, BufPtr End, TypeListTy& List);
+
+  /// @brief Parse a constant value
+  void ParseConstantValue      (BufPtr &Buf, BufPtr End, unsigned TypeID);
+
+  /// @brief Parse a block of types.
+  void ParseTypeConstants      (BufPtr &Buf, BufPtr End, TypeListTy &Tab,
+                                       unsigned NumEntries);
+
+  /// @brief Parse a single type.
+  const Type *ParseTypeConstant(BufPtr &Buf, BufPtr End);
+
+  /// @brief Parse a string constants block
+  void ParseStringConstants    (BufPtr &Buf, BufPtr End, unsigned NumEntries);
+
+/// @}
+/// @name Data
+/// @{
 private:
   // Information about the module, extracted from the bytecode revision number.
   unsigned char RevisionNum;        // The rev # itself
@@ -82,13 +179,13 @@ private:
   // 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
@@ -98,16 +195,34 @@ private:
   //
   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
+/// @}
+/// @name Implementation Details
+/// @{
+private:
+  /// This stores the parser's handler. It makes virtual function calls through
+  /// the BytecodeHandler to notify the handler of parsing events. What the
+  /// handler does with the events is completely orthogonal to the business of
+  /// parsing the bytecode.
+  /// @brief The handler of bytecode parsing events.
   BytecodeHandler* handler;
   
+  /// 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.
+  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;
+  LazyFunctionMap LazyFunctionLoadMap;
+
 private:
+
+  static inline void readBlock(const unsigned char *&Buf,
+                              const unsigned char *EndBuf, 
+                              unsigned &Type, unsigned &Size) ;
+
   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
@@ -134,45 +249,250 @@ private:
     return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
   }
 
+  AbstractBytecodeParser(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+  void operator=(const AbstractBytecodeParser &);  // DO NOT IMPLEMENT
+
+/// @}
+};
+
+/// This class provides the interface for the handling bytecode events during
+/// parsing. The methods on this interface are invoked by the 
+/// AbstractBytecodeParser as it discovers the content of a bytecode stream. 
+/// This class provides a a clear separation of concerns between recognizing 
+/// the semantic units of a bytecode file and deciding what to do with them. 
+/// The AbstractBytecodeParser recognizes the content of the bytecode file and
+/// calls the BytecodeHandler methods to determine what should be done. This
+/// arrangement allows Bytecode files to be read and handled for a number of
+/// purposes simply by creating a subclass of BytecodeHandler. None of the
+/// parsing details need to be understood, only the meaning of the calls
+/// made on this interface.
+/// 
+/// Another paradigm that uses this design pattern is the XML SAX Parser. The
+/// ContentHandler for SAX plays the same role as the BytecodeHandler here.
+/// @see AbstractbytecodeParser
+/// @brief Handle Bytecode Parsing Events
+class BytecodeHandler {
+
+/// @name Constructors And Operators
+/// @{
 public:
-  typedef const unsigned char* BufPtr;
-  void ParseModule             (BufPtr &Buf, BufPtr End);
-  void ParseNextFunction       (Type* FType) ;
-  void ParseAllFunctionBodies  ();
+  /// @brief Default constructor (empty)
+  BytecodeHandler() {}
+  /// @brief Virtual destructor (empty)
+  virtual ~BytecodeHandler() {}
 
 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);
+  BytecodeHandler(const BytecodeHandler &);  // DO NOT IMPLEMENT
+  void operator=(const BytecodeHandler &);  // DO NOT IMPLEMENT
 
-  void ParseBasicBlock         (BufPtr &Buf, BufPtr End, unsigned BlockNo);
-  unsigned ParseInstructionList(BufPtr &Buf, BufPtr End);
-  
-  bool ParseInstruction        (BufPtr &Buf, BufPtr End, 
-                               std::vector<unsigned>& Args);
+/// @}
+/// @name Handler Methods
+/// @{
+public:
 
-  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);
+  /// This method is called whenever the parser detects an error in the
+  /// bytecode formatting. Returning true will cause the parser to keep 
+  /// going, however this is inadvisable in most cases. Returning false will
+  /// cause the parser to throw the message as a std::string.
+  /// @brief Handle parsing errors.
+  virtual bool handleError(const std::string& str );
+
+  /// This method is called at the beginning of a parse before anything is
+  /// read in order to give the handler a chance to initialize.
+  /// @brief Handle the start of a bytecode parse
+  virtual void handleStart();
+
+  /// This method is called at the end of a parse after everything has been
+  /// read in order to give the handler a chance to terminate.
+  /// @brief Handle the end of a bytecode parse
+  virtual void handleFinish();
+
+  /// This method is called at the start of a module to indicate that a
+  /// module is being parsed.
+  /// @brief Handle the start of a module.
+  virtual void handleModuleBegin(const std::string& id);
+
+  /// This method is called at the end of a module to indicate that the module
+  /// previously being parsed has concluded.
+  /// @brief Handle the end of a module.
+  virtual void handleModuleEnd(const std::string& id);
+
+  /// This method is called once the version information has been parsed. It 
+  /// provides the information about the version of the bytecode file being 
+  /// read.
+  /// @brief Handle the bytecode prolog
+  virtual void handleVersionInfo(
+    unsigned char RevisionNum,        ///< Byte code revision number
+    Module::Endianness Endianness,    ///< Endianness indicator
+    Module::PointerSize PointerSize   ///< PointerSize indicator
+  );
+
+  /// This method is called at the start of a module globals block which
+  /// contains the global variables and the function placeholders
+  virtual void handleModuleGlobalsBegin();
+
+  /// This method is called when a non-initialized global variable is 
+  /// recognized. Its type, constness, and linkage type are provided.
+  /// @brief Handle a non-initialized global variable
+  virtual void handleGlobalVariable( 
+    const Type* ElemType,     ///< The type of the global variable
+    bool isConstant,          ///< Whether the GV is constant or not
+    GlobalValue::LinkageTypes ///< The linkage type of the GV
+  );
+
+  /// This method is called when an initialized global variable is recognized.
+  /// Its type constness, linkage type, and the slot number of the initializer
+  /// are provided.
+  /// @brief Handle an intialized global variable.
+  virtual void handleInitializedGV( 
+    const Type* ElemType,     ///< The type of the global variable
+    bool isConstant,          ///< Whether the GV is constant or not
+    GlobalValue::LinkageTypes,///< The linkage type of the GV
+    unsigned initSlot         ///< Slot number of GV's initializer
+  );
+
+  /// This method is called when a new type is recognized. The type is 
+  /// converted from the bytecode and passed to this method.
+  /// @brief Handle a type
+  virtual void handleType( const Type* Ty );
+
+  /// This method is called when the function prototype for a function is
+  /// encountered in the module globals block.
+  virtual void handleFunctionDeclaration( 
+    const Type* FuncType      ///< The type of the function
+  );
+
+  /// This method is called at the end of the module globals block.
+  /// @brief Handle end of module globals block.
+  virtual void handleModuleGlobalsEnd();
+
+  /// This method is called at the beginning of a compaction table.
+  /// @brief Handle start of compaction table.
+  virtual void handleCompactionTableBegin();
+
+  /// @brief Handle start of a compaction table plane
+  virtual void handleCompactionTablePlane( 
+    unsigned Ty, 
+    unsigned NumEntries
+  );
+
+
+  /// @brief Handle a type entry in the compaction table
+  virtual void handleCompactionTableType( 
+    unsigned i, 
+    unsigned TypSlot, 
+    const Type* 
+  );
+
+  /// @brief Handle a value entry in the compaction table
+  virtual void handleCompactionTableValue( 
+    unsigned i, 
+    unsigned ValSlot, 
+    const Type* 
+  );
+
+  /// @brief Handle end of a compaction table
+  virtual void handleCompactionTableEnd();
+
+  /// @brief Handle start of a symbol table
+  virtual void handleSymbolTableBegin();
+
+  /// @brief Handle start of a symbol table plane
+  virtual void handleSymbolTablePlane( 
+    unsigned Ty, 
+    unsigned NumEntries, 
+    const Type* Ty 
+  );
+
+  /// @brief Handle a named type in the symbol table
+  virtual void handleSymbolTableType( 
+    unsigned i, 
+    unsigned slot, 
+    const std::string& name 
+  );
+
+  /// @brief Handle a named value in the symbol table
+  virtual void handleSymbolTableValue( 
+    unsigned i, 
+    unsigned slot, 
+    const std::string& name 
+  );
+
+  /// @brief Handle the end of a symbol table
+  virtual void handleSymbolTableEnd();
+
+  /// @brief Handle the beginning of a function body
+  virtual void handleFunctionBegin(
+    const Type* FType, 
+    GlobalValue::LinkageTypes linkage 
+  );
+
+  /// @brief Handle the end of a function body
+  virtual void handleFunctionEnd(
+    const Type* FType
+  );
+
+  /// @brief Handle the beginning of a basic block
+  virtual void handleBasicBlockBegin(
+    unsigned blocknum
+  );
+
+  /// This method is called for each instruction that is parsed. 
+  /// @returns true if the instruction is a block terminating instruction
+  /// @brief Handle an instruction
+  virtual bool handleInstruction(
+    unsigned Opcode, 
+    const Type* iType, 
+    std::vector<unsigned>& Operands
+  );
+
+  /// @brief Handle the end of a basic block
+  virtual void handleBasicBlockEnd(unsigned blocknum);
+
+  /// @brief Handle start of global constants block.
+  virtual void handleGlobalConstantsBegin();
+
+  /// @brief Handle a constant expression
+  virtual void handleConstantExpression( 
+    unsigned Opcode, 
+    const Type* Typ, 
+    std::vector<std::pair<const Type*,unsigned> > ArgVec 
+  );
+
+  /// @brief Handle a constant array
+  virtual void handleConstantArray( 
+    const ArrayType* AT, 
+    std::vector<unsigned>& ElementSlots
+  );
+
+  /// @brief Handle a constant structure
+  virtual void handleConstantStruct(
+    const StructType* ST,
+    std::vector<unsigned>& ElementSlots
+  );
+
+  /// @brief Handle a constant pointer
+  virtual void handleConstantPointer(
+    const PointerType* PT,
+    unsigned Slot
+  );
+
+  /// @brief Handle a constant strings (array special case)
+  virtual void handleConstantString(
+    const ConstantArray* CA
+  );
+
+  /// @brief Handle a primitive constant value
+  virtual void handleConstantValue( Constant * c );
+
+  /// @brief Handle the end of the global constants
+  virtual void handleGlobalConstantsEnd();
+
+/// @}
 
 };
 
-
-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
+#endif