Use explicit ctor
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 28e9fae24265d0ed75a6eeb724998b65f61a1521..ee74367d815969f3ee7f13997c6d412024cb1af9 100644 (file)
@@ -6,22 +6,24 @@
 
 %{
 #include "ParserInternals.h"
-#include "llvm/Assembly/Parser.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/Module.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Method.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iMemory.h"
+#include "llvm/iOperators.h"
 #include "llvm/iPHINode.h"
 #include "Support/STLExtras.h"
 #include "Support/DepthFirstIterator.h"
 #include <list>
-#include <utility>            // Get definition of pair class
+#include <utility>
 #include <algorithm>
-#include <stdio.h>            // This embarasment is due to our flex lexer...
+using std::list;
+using std::vector;
+using std::pair;
+using std::map;
+using std::pair;
+using std::make_pair;
+using std::string;
 
 int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
 int yylex();                       // declaration" of xxx warnings.
@@ -35,25 +37,34 @@ string CurFilename;
 //
 //#define DEBUG_UPREFS 1
 #ifdef DEBUG_UPREFS
-#define UR_OUT(X) cerr << X
+#define UR_OUT(X) std::cerr << X
 #else
 #define UR_OUT(X)
 #endif
 
-// This contains info used when building the body of a method.  It is destroyed
-// when the method is completed.
+#define YYERROR_VERBOSE 1
+
+// HACK ALERT: This variable is used to implement the automatic conversion of
+// load/store instructions with indexes into a load/store + getelementptr pair
+// of instructions.  When this compatiblity "Feature" is removed, this should be
+// too.
+//
+static BasicBlock *CurBB;
+
+
+// This contains info used when building the body of a function.  It is
+// destroyed when the function is completed.
 //
 typedef vector<Value *> ValueList;           // Numbered defs
 static void ResolveDefinitions(vector<ValueList> &LateResolvers,
                                vector<ValueList> *FutureLateResolvers = 0);
-static void ResolveTypes      (vector<PATypeHolder<Type> > &LateResolveTypes);
 
 static struct PerModuleInfo {
   Module *CurrentModule;
   vector<ValueList>    Values;     // Module level numbered definitions
   vector<ValueList>    LateResolveValues;
-  vector<PATypeHolder<Type> > Types;
-  map<ValID, PATypeHolder<Type> > LateResolveTypes;
+  vector<PATypeHolder> Types;
+  map<ValID, PATypeHolder> LateResolveTypes;
 
   // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
   // references to global values.  Global values may be referenced before they
@@ -64,9 +75,9 @@ static struct PerModuleInfo {
   GlobalRefsType GlobalRefs;
 
   void ModuleDone() {
-    // If we could not resolve some methods at method compilation time (calls to
-    // methods before they are defined), resolve them now...  Types are resolved
-    // when the constant pool has been completely parsed.
+    // If we could not resolve some functions at function compilation time
+    // (calls to functions before they are defined), resolve them now...  Types
+    // are resolved when the constant pool has been completely parsed.
     //
     ResolveDefinitions(LateResolveValues);
 
@@ -74,19 +85,23 @@ static struct PerModuleInfo {
     // resolved!
     //
     if (!GlobalRefs.empty()) {
-      // TODO: Make this more detailed! Loop over each undef value and print
-      // info
-      ThrowException("TODO: Make better error - Unresolved forward constant "
-                     "references exist!");
+      string UndefinedReferences = "Unresolved global references exist:\n";
+      
+      for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end();
+           I != E; ++I) {
+        UndefinedReferences += "  " + I->first.first->getDescription() + " " +
+                               I->first.second.getName() + "\n";
+      }
+      ThrowException(UndefinedReferences);
     }
 
-    Values.clear();         // Clear out method local definitions
+    Values.clear();         // Clear out function local definitions
     Types.clear();
     CurrentModule = 0;
   }
 
 
-  // DeclareNewGlobalValue - Called every type a new GV has been defined.  This
+  // DeclareNewGlobalValue - Called every time a new GV has been defined.  This
   // is used to remove things from the forward declaration map, resolving them
   // to the correct thing as needed.
   //
@@ -100,22 +115,22 @@ static struct PerModuleInfo {
       I->first.second.destroy();  // Free string memory if neccesary
       
       // Loop over all of the uses of the GlobalValue.  The only thing they are
-      // allowed to be at this point is ConstantPointerRef's.
+      // allowed to be is ConstantPointerRef's.
       assert(OldGV->use_size() == 1 && "Only one reference should exist!");
       while (!OldGV->use_empty()) {
-       User *U = OldGV->use_back();  // Must be a ConstantPointerRef...
-       ConstantPointerRef *CPPR = cast<ConstantPointerRef>(U);
-       assert(CPPR->getValue() == OldGV && "Something isn't happy");
-       
-       // Change the const pool reference to point to the real global variable
-       // now.  This should drop a use from the OldGV.
-       CPPR->mutateReference(GV);
+        User *U = OldGV->use_back();  // Must be a ConstantPointerRef...
+        ConstantPointerRef *CPR = cast<ConstantPointerRef>(U);
+        assert(CPR->getValue() == OldGV && "Something isn't happy");
+        
+        // Change the const pool reference to point to the real global variable
+        // now.  This should drop a use from the OldGV.
+        CPR->mutateReferences(OldGV, GV);
       }
-    
-      // Remove GV from the module...
+      
+      // Remove OldGV from the module...
       CurrentModule->getGlobalList().remove(OldGV);
       delete OldGV;                        // Delete the old placeholder
-
+      
       // Remove the map entry for the global now that it has been created...
       GlobalRefs.erase(I);
     }
@@ -123,39 +138,39 @@ static struct PerModuleInfo {
 
 } CurModule;
 
-static struct PerMethodInfo {
-  Method *CurrentMethod;         // Pointer to current method being created
+static struct PerFunctionInfo {
+  Function *CurrentFunction;     // Pointer to current function being created
 
   vector<ValueList> Values;      // Keep track of numbered definitions
   vector<ValueList> LateResolveValues;
-  vector<PATypeHolder<Type> > Types;
-  map<ValID, PATypeHolder<Type> > LateResolveTypes;
-  bool isDeclare;                // Is this method a forward declararation?
+  vector<PATypeHolder> Types;
+  map<ValID, PATypeHolder> LateResolveTypes;
+  bool isDeclare;                // Is this function a forward declararation?
 
-  inline PerMethodInfo() {
-    CurrentMethod = 0;
+  inline PerFunctionInfo() {
+    CurrentFunction = 0;
     isDeclare = false;
   }
 
-  inline ~PerMethodInfo() {}
+  inline ~PerFunctionInfo() {}
 
-  inline void MethodStart(Method *M) {
-    CurrentMethod = M;
+  inline void FunctionStart(Function *M) {
+    CurrentFunction = M;
   }
 
-  void MethodDone() {
+  void FunctionDone() {
     // If we could not resolve some blocks at parsing time (forward branches)
     // resolve the branches now...
     ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
 
-    Values.clear();         // Clear out method local definitions
+    Values.clear();         // Clear out function local definitions
     Types.clear();
-    CurrentMethod = 0;
+    CurrentFunction = 0;
     isDeclare = false;
   }
-} CurMeth;  // Info for the current method...
+} CurMeth;  // Info for the current function...
 
-static bool inMethodScope() { return CurMeth.CurrentMethod != 0; }
+static bool inFunctionScope() { return CurMeth.CurrentFunction != 0; }
 
 
 //===----------------------------------------------------------------------===//
@@ -175,13 +190,13 @@ static int InsertValue(Value *D, vector<ValueList> &ValueTab = CurMeth.Values) {
 }
 
 // TODO: FIXME when Type are not const
-static void InsertType(const Type *Ty, vector<PATypeHolder<Type> > &Types) {
+static void InsertType(const Type *Ty, vector<PATypeHolder> &Types) {
   Types.push_back(Ty);
 }
 
 static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   switch (D.Type) {
-  case 0: {                 // Is it a numbered definition?
+  case ValID::NumberVal: {                 // Is it a numbered definition?
     unsigned Num = (unsigned)D.Num;
 
     // Module constants occupy the lowest numbered slots...
@@ -195,14 +210,14 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
       return CurMeth.Types[Num];
     break;
   }
-  case 1: {                // Is it a named definition?
+  case ValID::NameVal: {                // Is it a named definition?
     string Name(D.Name);
     SymbolTable *SymTab = 0;
-    if (inMethodScope()) SymTab = CurMeth.CurrentMethod->getSymbolTable();
+    if (inFunctionScope()) SymTab = CurMeth.CurrentFunction->getSymbolTable();
     Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0;
 
     if (N == 0) {
-      // Symbol table doesn't automatically chain yet... because the method
+      // Symbol table doesn't automatically chain yet... because the function
       // hasn't been added to the module...
       //
       SymTab = CurModule.CurrentModule->getSymbolTable();
@@ -215,7 +230,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
     return cast<const Type>(N);
   }
   default:
-    ThrowException("Invalid symbol type reference!");
+    ThrowException("Internal parser error: Invalid symbol type reference!");
   }
 
   // If we reached here, we referenced either a symbol that we don't know about
@@ -224,10 +239,10 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   //
   if (DoNotImprovise) return 0;  // Do we just want a null to be returned?
 
-  map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ? 
+  map<ValID, PATypeHolder> &LateResolver = inFunctionScope() ? 
     CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
   
-  map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+  map<ValID, PATypeHolder>::iterator I = LateResolver.find(D);
   if (I != LateResolver.end()) {
     return I->second;
   }
@@ -239,19 +254,9 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
 
 static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
   SymbolTable *SymTab = 
-    inMethodScope() ? CurMeth.CurrentMethod->getSymbolTable() : 0;
-  Value *N = SymTab ? SymTab->lookup(Ty, Name) : 0;
-
-  if (N == 0) {
-    // Symbol table doesn't automatically chain yet... because the method
-    // hasn't been added to the module...
-    //
-    SymTab = CurModule.CurrentModule->getSymbolTable();
-    if (SymTab)
-      N = SymTab->lookup(Ty, Name);
-  }
-
-  return N;
+    inFunctionScope() ? CurMeth.CurrentFunction->getSymbolTable() :
+                        CurModule.CurrentModule->getSymbolTable();
+  return SymTab ? SymTab->lookup(Ty, Name) : 0;
 }
 
 // getValNonImprovising - Look up the value specified by the provided type and
@@ -259,8 +264,9 @@ static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
 // it.  Otherwise return null.
 //
 static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
-  if (isa<MethodType>(Ty))
-    ThrowException("Methods are not values and must be referenced as pointers");
+  if (isa<FunctionType>(Ty))
+    ThrowException("Functions are not values and "
+                   "must be referenced as pointers");
 
   switch (D.Type) {
   case ValID::NumberVal: {                 // Is it a numbered definition?
@@ -295,20 +301,17 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
   // Check to make sure that "Ty" is an integral type, and that our 
   // value will fit into the specified type...
   case ValID::ConstSIntVal:    // Is it a constant pool reference??
-    if (Ty == Type::BoolTy) {  // Special handling for boolean data
-      return ConstantBool::get(D.ConstPool64 != 0);
-    } else {
-      if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64))
-       ThrowException("Symbolic constant pool value '" +
-                      itostr(D.ConstPool64) + "' is invalid for type '" + 
-                      Ty->getName() + "'!");
-      return ConstantSInt::get(Ty, D.ConstPool64);
-    }
+    if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64))
+      ThrowException("Signed integral constant '" +
+                     itostr(D.ConstPool64) + "' is invalid for type '" + 
+                     Ty->getDescription() + "'!");
+    return ConstantSInt::get(Ty, D.ConstPool64);
 
   case ValID::ConstUIntVal:     // Is it an unsigned const pool reference?
     if (!ConstantUInt::isValueValidForType(Ty, D.UConstPool64)) {
       if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64)) {
-       ThrowException("Integral constant pool reference is invalid!");
+       ThrowException("Integral constant '" + utostr(D.UConstPool64) +
+                       "' is invalid or out of range!");
       } else {     // This is really a signed reference.  Transmogrify.
        return ConstantSInt::get(Ty, D.ConstPool64);
       }
@@ -316,21 +319,21 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
       return ConstantUInt::get(Ty, D.UConstPool64);
     }
 
-  case ValID::ConstStringVal:    // Is it a string const pool reference?
-    cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
-    abort();
-    return 0;
-
   case ValID::ConstFPVal:        // Is it a floating point const pool reference?
     if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP))
       ThrowException("FP constant invalid for type!!");
     return ConstantFP::get(Ty, D.ConstPoolFP);
     
   case ValID::ConstNullVal:      // Is it a null value?
-    if (!Ty->isPointerType())
+    if (!isa<PointerType>(Ty))
       ThrowException("Cannot create a a non pointer null!");
     return ConstantPointerNull::get(cast<PointerType>(Ty));
     
+  case ValID::ConstantVal:       // Fully resolved constant?
+    if (D.ConstantValue->getType() != Ty)
+      ThrowException("Constant expression type different from required type!");
+    return D.ConstantValue;
+
   default:
     assert(0 && "Unhandled case!");
     return 0;
@@ -365,7 +368,7 @@ static Value *getVal(const Type *Ty, const ValID &D) {
   }
 
   assert(d != 0 && "How did we not make something?");
-  if (inMethodScope())
+  if (inFunctionScope())
     InsertValue(d, CurMeth.LateResolveValues);
   else 
     InsertValue(d, CurModule.LateResolveValues);
@@ -390,7 +393,7 @@ static Value *getVal(const Type *Ty, const ValID &D) {
 // defs now...
 //
 static void ResolveDefinitions(vector<ValueList> &LateResolvers,
-                               vector<ValueList> *FutureLateResolvers = 0) {
+                               vector<ValueList> *FutureLateResolvers) {
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
   for (unsigned ty = 0; ty < LateResolvers.size(); ty++) {
     while (!LateResolvers[ty].empty()) {
@@ -405,11 +408,11 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers,
         V->replaceAllUsesWith(TheRealValue);
         delete V;
       } else if (FutureLateResolvers) {
-        // Methods have their unresolved items forwarded to the module late
+        // Functions have their unresolved items forwarded to the module late
         // resolver table
         InsertValue(V, *FutureLateResolvers);
       } else {
-       if (DID.Type == 1)
+       if (DID.Type == ValID::NameVal)
          ThrowException("Reference to an invalid definition: '" +DID.getName()+
                         "' of type '" + V->getType()->getDescription() + "'",
                         getLineNumFromPlaceHolder(V));
@@ -425,40 +428,24 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers,
   LateResolvers.clear();
 }
 
-// ResolveType - Take a specified unresolved type and resolve it.  If there is
-// nothing to resolve it to yet, return true.  Otherwise resolve it and return
-// false.
-//
-static bool ResolveType(PATypeHolder<Type> &T) {
-  const Type *Ty = T;
-  ValID &DID = getValIDFromPlaceHolder(Ty);
-
-  const Type *TheRealType = getTypeVal(DID, true);
-  if (TheRealType == 0 || TheRealType == Ty) return true;
-
-  // Refine the opaque type we had to the new type we are getting.
-  cast<DerivedType>(Ty)->refineAbstractTypeTo(TheRealType);
-  return false;
-}
-
 // ResolveTypeTo - A brand new type was just declared.  This means that (if
 // name is not null) things referencing Name can be resolved.  Otherwise, things
 // refering to the number can be resolved.  Do this now.
 //
 static void ResolveTypeTo(char *Name, const Type *ToTy) {
-  vector<PATypeHolder<Type> > &Types = inMethodScope() ? 
+  vector<PATypeHolder> &Types = inFunctionScope() ? 
      CurMeth.Types : CurModule.Types;
 
    ValID D;
    if (Name) D = ValID::create(Name);
    else      D = ValID::create((int)Types.size());
 
-   map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ? 
+   map<ValID, PATypeHolder> &LateResolver = inFunctionScope() ? 
      CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
   
-   map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+   map<ValID, PATypeHolder>::iterator I = LateResolver.find(D);
    if (I != LateResolver.end()) {
-     cast<DerivedType>(I->second.get())->refineAbstractTypeTo(ToTy);
+     ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy);
      LateResolver.erase(I);
    }
 }
@@ -466,7 +453,7 @@ static void ResolveTypeTo(char *Name, const Type *ToTy) {
 // ResolveTypes - At this point, all types should be resolved.  Any that aren't
 // are errors.
 //
-static void ResolveTypes(map<ValID, PATypeHolder<Type> > &LateResolveTypes) {
+static void ResolveTypes(map<ValID, PATypeHolder> &LateResolveTypes) {
   if (!LateResolveTypes.empty()) {
     const ValID &DID = LateResolveTypes.begin()->first;
 
@@ -496,8 +483,8 @@ static bool setValueName(Value *V, char *NameStr) {
     ThrowException("Can't assign name '" + Name + 
                   "' to a null valued instruction!");
 
-  SymbolTable *ST = inMethodScope() ? 
-    CurMeth.CurrentMethod->getSymbolTableSure() : 
+  SymbolTable *ST = inFunctionScope() ? 
+    CurMeth.CurrentFunction->getSymbolTableSure() : 
     CurModule.CurrentModule->getSymbolTableSure();
 
   Value *Existing = ST->lookup(V->getType(), Name);
@@ -505,9 +492,9 @@ static bool setValueName(Value *V, char *NameStr) {
     // There is only one case where this is allowed: when we are refining an
     // opaque type.  In this case, Existing will be an opaque type.
     if (const Type *Ty = dyn_cast<const Type>(Existing)) {
-      if (OpaqueType *OpTy = dyn_cast<OpaqueType>(Ty)) {
+      if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Ty)) {
        // We ARE replacing an opaque type!
-       OpTy->refineAbstractTypeTo(cast<Type>(V));
+       ((OpaqueType*)OpTy)->refineAbstractTypeTo(cast<Type>(V));
        return true;
       }
     }
@@ -516,7 +503,7 @@ static bool setValueName(Value *V, char *NameStr) {
     // is defined the same as the old one...
     if (const Type *Ty = dyn_cast<const Type>(Existing)) {
       if (Ty == cast<const Type>(V)) return true;  // Yes, it's equal.
-      // cerr << "Type: " << Ty->getDescription() << " != "
+      // std::cerr << "Type: " << Ty->getDescription() << " != "
       //      << cast<const Type>(V)->getDescription() << "!\n";
     } else if (GlobalVariable *EGV = dyn_cast<GlobalVariable>(Existing)) {
       // We are allowed to redefine a global variable in two circumstances:
@@ -561,8 +548,8 @@ static bool TypeContains(const Type *Ty, const Type *E) {
 
 static vector<pair<unsigned, OpaqueType *> > UpRefs;
 
-static PATypeHolder<Type> HandleUpRefs(const Type *ty) {
-  PATypeHolder<Type> Ty(ty);
+static PATypeHolder HandleUpRefs(const Type *ty) {
+  PATypeHolder Ty(ty);
   UR_OUT("Type '" << ty->getDescription() << 
          "' newly formed.  Resolving upreferences.\n" <<
          UpRefs.size() << " upreferences active!\n");
@@ -591,22 +578,6 @@ static PATypeHolder<Type> HandleUpRefs(const Type *ty) {
   return Ty;
 }
 
-template <class TypeTy>
-inline static void TypeDone(PATypeHolder<TypeTy> *Ty) {
-  if (UpRefs.size())
-    ThrowException("Invalid upreference in type: " + (*Ty)->getDescription());
-}
-
-// newTH - Allocate a new type holder for the specified type
-template <class TypeTy>
-inline static PATypeHolder<TypeTy> *newTH(const TypeTy *Ty) {
-  return new PATypeHolder<TypeTy>(Ty);
-}
-template <class TypeTy>
-inline static PATypeHolder<TypeTy> *newTH(const PATypeHolder<TypeTy> &TH) {
-  return new PATypeHolder<TypeTy>(TH);
-}
-
 
 //===----------------------------------------------------------------------===//
 //            RunVMAsmParser - Define an interface to this parser
@@ -630,23 +601,24 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 
 %union {
   Module                           *ModuleVal;
-  Method                           *MethodVal;
-  MethodArgument                   *MethArgVal;
+  Function                         *FunctionVal;
+  std::pair<Argument*, char*>      *ArgVal;
   BasicBlock                       *BasicBlockVal;
   TerminatorInst                   *TermInstVal;
   Instruction                      *InstVal;
   Constant                         *ConstVal;
 
   const Type                       *PrimType;
-  PATypeHolder<Type>               *TypeVal;
+  PATypeHolder                     *TypeVal;
   Value                            *ValueVal;
 
-  list<MethodArgument*>            *MethodArgList;
-  vector<Value*>                   *ValueList;
-  list<PATypeHolder<Type> >        *TypeList;
-  list<pair<Value*, BasicBlock*> > *PHIList;   // Represent the RHS of PHI node
-  list<pair<Constant*, BasicBlock*> > *JumpTable;
-  vector<Constant*>                *ConstVector;
+  std::list<std::pair<Argument*,char*> > *ArgList;
+  std::vector<Value*>              *ValueList;
+  std::list<PATypeHolder>          *TypeList;
+  std::list<std::pair<Value*,
+                      BasicBlock*> > *PHIList; // Represent the RHS of PHI node
+  std::vector<std::pair<Constant*, BasicBlock*> > *JumpTable;
+  std::vector<Constant*>           *ConstVector;
 
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
@@ -658,22 +630,21 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
   char                             *StrVal;   // This memory is strdup'd!
   ValID                             ValIDVal; // strdup'd memory maybe!
 
-  Instruction::UnaryOps             UnaryOpVal;
   Instruction::BinaryOps            BinaryOpVal;
   Instruction::TermOps              TermOpVal;
   Instruction::MemoryOps            MemOpVal;
   Instruction::OtherOps             OtherOpVal;
 }
 
-%type <ModuleVal>     Module MethodList
-%type <MethodVal>     Method MethodProto MethodHeader BasicBlockList
+%type <ModuleVal>     Module FunctionList
+%type <FunctionVal>   Function FunctionProto FunctionHeader BasicBlockList
 %type <BasicBlockVal> BasicBlock InstructionList
 %type <TermInstVal>   BBTerminatorInst
 %type <InstVal>       Inst InstVal MemoryInst
-%type <ConstVal>      ConstVal
+%type <ConstVal>      ConstVal ConstExpr
 %type <ConstVector>   ConstVector
-%type <MethodArgList> ArgList ArgListH
-%type <MethArgVal>    ArgVal
+%type <ArgList>       ArgList ArgListH
+%type <ArgVal>        ArgVal
 %type <PHIList>       PHIList
 %type <ValueList>     ValueRefList ValueRefListE  // For call param lists
 %type <ValueList>     IndexList                   // For GEP derived indices
@@ -701,31 +672,27 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 // Built in types...
 %type  <TypeVal> Types TypesV UpRTypes UpRTypesV
 %type  <PrimType> SIntType UIntType IntType FPType PrimType   // Classifications
-%token <TypeVal>  OPAQUE
 %token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
 %token <PrimType> FLOAT DOUBLE TYPE LABEL
 
 %token <StrVal>     VAR_ID LABELSTR STRINGCONSTANT
-%type  <StrVal>  OptVAR_ID OptAssign
+%type  <StrVal>  OptVAR_ID OptAssign FuncName
 
 
-%token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE GLOBAL CONSTANT UNINIT
-%token TO EXCEPT DOTDOTDOT STRING NULL_TOK CONST INTERNAL
+%token IMPLEMENTATION TRUE FALSE BEGINTOK ENDTOK DECLARE GLOBAL CONSTANT UNINIT
+%token TO EXCEPT DOTDOTDOT NULL_TOK CONST INTERNAL OPAQUE NOT
 
 // Basic Block Terminating Operators 
 %token <TermOpVal> RET BR SWITCH
 
-// Unary Operators 
-%type  <UnaryOpVal> UnaryOps  // all the unary operators
-%token <UnaryOpVal> NOT
-
 // Binary Operators 
 %type  <BinaryOpVal> BinaryOps  // all the binary operators
+%type  <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories
 %token <BinaryOpVal> ADD SUB MUL DIV REM AND OR XOR
 %token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE  // Binary Comarators
 
 // Memory Instructions
-%token <MemoryOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
+%token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR
 
 // Other Operators
 %type  <OtherOpVal> ShiftOps
@@ -737,35 +704,37 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 // Handle constant integer size restriction and conversion...
 //
 
-INTVAL : SINTVAL
+INTVAL : SINTVAL;
 INTVAL : UINTVAL {
   if ($1 > (uint32_t)INT32_MAX)     // Outside of my range!
     ThrowException("Value too large for type!");
   $$ = (int32_t)$1;
-}
+};
 
 
-EINT64VAL : ESINT64VAL       // These have same type and can't cause problems...
+EINT64VAL : ESINT64VAL;      // These have same type and can't cause problems...
 EINT64VAL : EUINT64VAL {
   if ($1 > (uint64_t)INT64_MAX)     // Outside of my range!
     ThrowException("Value too large for type!");
   $$ = (int64_t)$1;
-}
+};
 
 // Operations that are notably excluded from this list include: 
 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
 //
-UnaryOps  : NOT
-BinaryOps : ADD | SUB | MUL | DIV | REM | AND | OR | XOR
-BinaryOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE
-ShiftOps  : SHL | SHR
+ArithmeticOps: ADD | SUB | MUL | DIV | REM;
+LogicalOps   : AND | OR | XOR;
+SetCondOps   : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
+BinaryOps : ArithmeticOps | LogicalOps | SetCondOps;
+
+ShiftOps  : SHL | SHR;
 
 // These are some types that allow classification if we only want a particular 
 // thing... for example, only a signed, unsigned, or integral type.
-SIntType :  LONG |  INT |  SHORT | SBYTE
-UIntType : ULONG | UINT | USHORT | UBYTE
-IntType  : SIntType | UIntType
-FPType   : FLOAT | DOUBLE
+SIntType :  LONG |  INT |  SHORT | SBYTE;
+UIntType : ULONG | UINT | USHORT | UBYTE;
+IntType  : SIntType | UIntType;
+FPType   : FLOAT | DOUBLE;
 
 // OptAssign - Value producing statements have an optional assignment component
 OptAssign : VAR_ID '=' {
@@ -773,33 +742,40 @@ OptAssign : VAR_ID '=' {
   }
   | /*empty*/ { 
     $$ = 0; 
-  }
+  };
 
-OptInternal : INTERNAL { $$ = true; } | /*empty*/ { $$ = false; }
+OptInternal : INTERNAL { $$ = true; } | /*empty*/ { $$ = false; };
 
 //===----------------------------------------------------------------------===//
 // Types includes all predefined types... except void, because it can only be
-// used in specific contexts (method returning void for example).  To have
+// used in specific contexts (function returning void for example).  To have
 // access to it, a user must explicitly use TypesV.
 //
 
 // TypesV includes all of 'Types', but it also includes the void type.
-TypesV    : Types    | VOID { $$ = newTH($1); }
-UpRTypesV : UpRTypes | VOID { $$ = newTH($1); }
+TypesV    : Types    | VOID { $$ = new PATypeHolder($1); };
+UpRTypesV : UpRTypes | VOID { $$ = new PATypeHolder($1); };
 
 Types     : UpRTypes {
-    TypeDone($$ = $1);
-  }
+    if (UpRefs.size())
+      ThrowException("Invalid upreference in type: " + (*$1)->getDescription());
+    $$ = $1;
+  };
 
 
 // Derived types are added later...
 //
-PrimType : BOOL | SBYTE | UBYTE | SHORT  | USHORT | INT   | UINT 
-PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE   | LABEL
-UpRTypes : OPAQUE | PrimType { $$ = newTH($1); }
-UpRTypes : ValueRef {                    // Named types are also simple types...
-  $$ = newTH(getTypeVal($1));
-}
+PrimType : BOOL | SBYTE | UBYTE | SHORT  | USHORT | INT   | UINT ;
+PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE   | LABEL;
+UpRTypes : OPAQUE {
+    $$ = new PATypeHolder(OpaqueType::get());
+  }
+  | PrimType {
+    $$ = new PATypeHolder($1);
+  };
+UpRTypes : SymbolicValueRef {            // Named types are also simple types...
+  $$ = new PATypeHolder(getTypeVal($1));
+};
 
 // Include derived types in the Types production.
 //
@@ -807,70 +783,68 @@ UpRTypes : '\\' EUINT64VAL {                   // Type UpReference
     if ($2 > (uint64_t)INT64_MAX) ThrowException("Value out of range!");
     OpaqueType *OT = OpaqueType::get();        // Use temporary placeholder
     UpRefs.push_back(make_pair((unsigned)$2, OT));  // Add to vector...
-    $$ = newTH<Type>(OT);
+    $$ = new PATypeHolder(OT);
     UR_OUT("New Upreference!\n");
   }
-  | UpRTypesV '(' ArgTypeListI ')' {           // Method derived type?
+  | UpRTypesV '(' ArgTypeListI ')' {           // Function derived type?
     vector<const Type*> Params;
-    mapto($3->begin(), $3->end(), back_inserter(Params), 
-         mem_fun_ref(&PATypeHandle<Type>::get));
+    mapto($3->begin(), $3->end(), std::back_inserter(Params), 
+         std::mem_fun_ref(&PATypeHandle<Type>::get));
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    $$ = newTH(HandleUpRefs(MethodType::get(*$1, Params, isVarArg)));
+    $$ = new PATypeHolder(HandleUpRefs(FunctionType::get(*$1,Params,isVarArg)));
     delete $3;      // Delete the argument list
     delete $1;      // Delete the old type handle
   }
-  | '[' UpRTypesV ']' {                        // Unsized array type?
-    $$ = newTH<Type>(HandleUpRefs(ArrayType::get(*$2)));
-    delete $2;
-  }
   | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type?
-    $$ = newTH<Type>(HandleUpRefs(ArrayType::get(*$4, (int)$2)));
+    $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2)));
     delete $4;
   }
   | '{' TypeListI '}' {                        // Structure type?
     vector<const Type*> Elements;
-    mapto($2->begin(), $2->end(), back_inserter(Elements), 
-       mem_fun_ref(&PATypeHandle<Type>::get));
+    mapto($2->begin(), $2->end(), std::back_inserter(Elements), 
+       std::mem_fun_ref(&PATypeHandle<Type>::get));
 
-    $$ = newTH<Type>(HandleUpRefs(StructType::get(Elements)));
+    $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
     delete $2;
   }
   | '{' '}' {                                  // Empty structure type?
-    $$ = newTH<Type>(StructType::get(vector<const Type*>()));
+    $$ = new PATypeHolder(StructType::get(vector<const Type*>()));
   }
   | UpRTypes '*' {                             // Pointer type?
-    $$ = newTH<Type>(HandleUpRefs(PointerType::get(*$1)));
+    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1)));
     delete $1;
-  }
+  };
 
-// TypeList - Used for struct declarations and as a basis for method type 
+// TypeList - Used for struct declarations and as a basis for function type 
 // declaration type lists
 //
 TypeListI : UpRTypes {
-    $$ = new list<PATypeHolder<Type> >();
+    $$ = new list<PATypeHolder>();
     $$->push_back(*$1); delete $1;
   }
   | TypeListI ',' UpRTypes {
     ($$=$1)->push_back(*$3); delete $3;
-  }
+  };
 
-// ArgTypeList - List of types for a method type declaration...
+// ArgTypeList - List of types for a function type declaration...
 ArgTypeListI : TypeListI
   | TypeListI ',' DOTDOTDOT {
     ($$=$1)->push_back(Type::VoidTy);
   }
   | DOTDOTDOT {
-    ($$ = new list<PATypeHolder<Type> >())->push_back(Type::VoidTy);
+    ($$ = new list<PATypeHolder>())->push_back(Type::VoidTy);
   }
   | /*empty*/ {
-    $$ = new list<PATypeHolder<Type> >();
-  }
-
+    $$ = new list<PATypeHolder>();
+  };
 
 // ConstVal - The various declarations that go into the constant pool.  This
-// includes all forward declarations of types, constants, and functions.
+// production is used ONLY to represent constants that show up AFTER a 'const',
+// 'constant' or 'global' token at global scope.  Constants that can be inlined
+// into other expressions (such as integers and constexprs) are handled by the
+// ResolvedVal, ValueRef and ConstValueRef productions.
 //
 ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     const ArrayType *ATy = dyn_cast<const ArrayType>($1->get());
@@ -890,8 +864,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     for (unsigned i = 0; i < $3->size(); i++) {
       if (ETy != (*$3)[i]->getType())
        ThrowException("Element #" + utostr(i) + " is not of type '" + 
-                      ETy->getName() + "' as required!\nIt is of type '" +
-                      (*$3)[i]->getType()->getName() + "'.");
+                      ETy->getDescription() +"' as required!\nIt is of type '"+
+                      (*$3)[i]->getType()->getDescription() + "'.");
     }
 
     $$ = ConstantArray::get(ATy, *$3);
@@ -962,8 +936,21 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     if (Ty == 0)
       ThrowException("Global const reference must be a pointer type!");
 
+    // ConstExprs can exist in the body of a function, thus creating
+    // ConstantPointerRefs whenever they refer to a variable.  Because we are in
+    // the context of a function, getValNonImprovising will search the functions
+    // symbol table instead of the module symbol table for the global symbol,
+    // which throws things all off.  To get around this, we just tell
+    // getValNonImprovising that we are at global scope here.
+    //
+    Function *SavedCurFn = CurMeth.CurrentFunction;
+    CurMeth.CurrentFunction = 0;
+
     Value *V = getValNonImprovising(Ty, $2);
 
+    CurMeth.CurrentFunction = SavedCurFn;
+
+
     // If this is an initializer for a constant pointer, which is referencing a
     // (currently) undefined variable, create a stub now that shall be replaced
     // in the future with the right type of variable.
@@ -998,7 +985,12 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     $$ = ConstantPointerRef::get(GV);
     delete $1;            // Free the type handle
   }
-
+  | Types ConstExpr {
+    if ($1->get() != $2->getType())
+      ThrowException("Mismatched types for constant expression!");
+    $$ = $2;
+    delete $1;
+  };
 
 ConstVal : SIntType EINT64VAL {     // integral constants
     if (!ConstantSInt::isValueValidForType($1, $2))
@@ -1018,7 +1010,44 @@ ConstVal : SIntType EINT64VAL {     // integral constants
   }
   | FPType FPVAL {                   // Float & Double constants
     $$ = ConstantFP::get($1, $2);
+  };
+
+
+ConstExpr: CAST '(' ConstVal TO Types ')' {
+    $$ = ConstantExpr::getCast($3, $5->get());
+    delete $5;
   }
+  | GETELEMENTPTR '(' ConstVal IndexList ')' {
+    if (!isa<PointerType>($3->getType()))
+      ThrowException("GetElementPtr requires a pointer operand!");
+
+    const Type *IdxTy =
+      GetElementPtrInst::getIndexedType($3->getType(), *$4, true);
+    if (!IdxTy)
+      ThrowException("Index list invalid for constant getelementptr!");
+
+    vector<Constant*> IdxVec;
+    for (unsigned i = 0, e = $4->size(); i != e; ++i)
+      if (Constant *C = dyn_cast<Constant>((*$4)[i]))
+        IdxVec.push_back(C);
+      else
+        ThrowException("Indices to constant getelementptr must be constants!");
+
+    delete $4;
+
+    $$ = ConstantExpr::getGetElementPtr($3, IdxVec);
+  }
+  | BinaryOps '(' ConstVal ',' ConstVal ')' {
+    if ($3->getType() != $5->getType())
+      ThrowException("Binary operator types must match!");
+    $$ = ConstantExpr::get($1, $3, $5);
+  }
+  | ShiftOps '(' ConstVal ',' ConstVal ')' {
+    if ($5->getType() != Type::UByteTy)
+      ThrowException("Shift count for shift constant must be unsigned byte!");
+    $$ = ConstantExpr::get($1, $3, $5);
+  };
+
 
 // ConstVector - A list of comma seperated constants.
 ConstVector : ConstVector ',' ConstVal {
@@ -1027,12 +1056,44 @@ ConstVector : ConstVector ',' ConstVal {
   | ConstVal {
     $$ = new vector<Constant*>();
     $$->push_back($1);
-  }
+  };
 
 
 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
-GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }
+GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
+
+
+//===----------------------------------------------------------------------===//
+//                             Rules to match Modules
+//===----------------------------------------------------------------------===//
 
+// Module rule: Capture the result of parsing the whole file into a result
+// variable...
+//
+Module : FunctionList {
+  $$ = ParserResult = $1;
+  CurModule.ModuleDone();
+};
+
+// FunctionList - A list of functions, preceeded by a constant pool.
+//
+FunctionList : FunctionList Function {
+    $$ = $1;
+    assert($2->getParent() == 0 && "Function already in module!");
+    $1->getFunctionList().push_back($2);
+    CurMeth.FunctionDone();
+  } 
+  | FunctionList FunctionProto {
+    $$ = $1;
+  }
+  | FunctionList IMPLEMENTATION {
+    $$ = $1;
+  }
+  | ConstPool {
+    $$ = CurModule.CurrentModule;
+    // Resolve circular types before we parse the body of the module
+    ResolveTypes(CurModule.LateResolveTypes);
+  };
 
 // ConstPool - Constants with optional names assigned to them.
 ConstPool : ConstPool OptAssign CONST ConstVal { 
@@ -1056,13 +1117,13 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
       // If this is not a redefinition of a type...
       if (!$2) {
         InsertType($4->get(),
-                   inMethodScope() ? CurMeth.Types : CurModule.Types);
+                   inFunctionScope() ? CurMeth.Types : CurModule.Types);
       }
     }
 
     delete $4;
   }
-  | ConstPool MethodProto {            // Method prototypes can be in const pool
+  | ConstPool FunctionProto {       // Function prototypes can be in const pool
   }
   | ConstPool OptAssign OptInternal GlobalType ConstVal {
     const Type *Ty = $5->getType();
@@ -1070,7 +1131,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
     Constant *Initializer = $5;
     if (Initializer == 0)
       ThrowException("Global value initializer is not a constant!");
-        
+    
     GlobalVariable *GV = new GlobalVariable(Ty, $4, $3, Initializer);
     if (!setValueName(GV, $2)) {   // If not redefining...
       CurModule.CurrentModule->getGlobalList().push_back(GV);
@@ -1100,138 +1161,141 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
                                                (char*)GV->getName().c_str()));
       }
     }
+    delete $6;
   }
   | /* empty: end of list */ { 
-  }
+  };
 
 
 //===----------------------------------------------------------------------===//
-//                             Rules to match Modules
+//                       Rules to match Function Headers
 //===----------------------------------------------------------------------===//
 
-// Module rule: Capture the result of parsing the whole file into a result
-// variable...
-//
-Module : MethodList {
-  $$ = ParserResult = $1;
-  CurModule.ModuleDone();
-}
-
-// MethodList - A list of methods, preceeded by a constant pool.
-//
-MethodList : MethodList Method {
-    $$ = $1;
-    if (!$2->getParent())
-      $1->getMethodList().push_back($2);
-    CurMeth.MethodDone();
-  } 
-  | MethodList MethodProto {
-    $$ = $1;
-  }
-  | ConstPool IMPLEMENTATION {
-    $$ = CurModule.CurrentModule;
-    // Resolve circular types before we parse the body of the module
-    ResolveTypes(CurModule.LateResolveTypes);
-  }
-
-
-//===----------------------------------------------------------------------===//
-//                       Rules to match Method Headers
-//===----------------------------------------------------------------------===//
-
-OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; }
+OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; };
 
 ArgVal : Types OptVAR_ID {
-  $$ = new MethodArgument(*$1); delete $1;
-  if (setValueName($$, $2)) { assert(0 && "No arg redef allowed!"); }
-}
+  $$ = new pair<Argument*, char*>(new Argument(*$1), $2);
+  delete $1;  // Delete the type handle..
+};
 
 ArgListH : ArgVal ',' ArgListH {
     $$ = $3;
-    $3->push_front($1);
+    $3->push_front(*$1);
+    delete $1;
   }
   | ArgVal {
-    $$ = new list<MethodArgument*>();
-    $$->push_front($1);
+    $$ = new list<pair<Argument*,char*> >();
+    $$->push_front(*$1);
+    delete $1;
   }
   | DOTDOTDOT {
-    $$ = new list<MethodArgument*>();
-    $$->push_front(new MethodArgument(Type::VoidTy));
-  }
+    $$ = new list<pair<Argument*, char*> >();
+    $$->push_front(pair<Argument*,char*>(new Argument(Type::VoidTy), 0));
+  };
 
 ArgList : ArgListH {
     $$ = $1;
   }
   | /* empty */ {
     $$ = 0;
-  }
+  };
+
+FuncName : VAR_ID | STRINGCONSTANT;
 
-MethodHeaderH : OptInternal TypesV STRINGCONSTANT '(' ArgList ')' {
+FunctionHeaderH : OptInternal TypesV FuncName '(' ArgList ')' {
   UnEscapeLexed($3);
-  string MethodName($3);
+  string FunctionName($3);
   
   vector<const Type*> ParamTypeList;
   if ($5)
-    for (list<MethodArgument*>::iterator I = $5->begin(); I != $5->end(); ++I)
-      ParamTypeList.push_back((*I)->getType());
+    for (list<pair<Argument*,char*> >::iterator I = $5->begin();
+         I != $5->end(); ++I)
+      ParamTypeList.push_back(I->first->getType());
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  const MethodType  *MT  = MethodType::get(*$2, ParamTypeList, isVarArg);
+  const FunctionType *MT = FunctionType::get(*$2, ParamTypeList, isVarArg);
   const PointerType *PMT = PointerType::get(MT);
   delete $2;
 
-  Method *M = 0;
+  Function *M = 0;
   if (SymbolTable *ST = CurModule.CurrentModule->getSymbolTable()) {
-    if (Value *V = ST->lookup(PMT, MethodName)) {  // Method already in symtab?
-      M = cast<Method>(V);
+    // Is the function already in symtab?
+    if (Value *V = ST->lookup(PMT, FunctionName)) {
+      M = cast<Function>(V);
 
       // Yes it is.  If this is the case, either we need to be a forward decl,
       // or it needs to be.
       if (!CurMeth.isDeclare && !M->isExternal())
-       ThrowException("Redefinition of method '" + MethodName + "'!");      
+       ThrowException("Redefinition of function '" + FunctionName + "'!");
+
+      // Make sure that we keep track of the internal marker, even if there was
+      // a previous "declare".
+      if ($1)
+        M->setInternalLinkage(true);
+
+      // If we found a preexisting function prototype, remove it from the
+      // module, so that we don't get spurious conflicts with global & local
+      // variables.
+      //
+      CurModule.CurrentModule->getFunctionList().remove(M);
     }
   }
 
   if (M == 0) {  // Not already defined?
-    M = new Method(MT, $1, MethodName);
+    M = new Function(MT, $1, FunctionName);
     InsertValue(M, CurModule.Values);
     CurModule.DeclareNewGlobalValue(M, ValID::create($3));
   }
   free($3);  // Free strdup'd memory!
 
-  CurMeth.MethodStart(M);
+  CurMeth.FunctionStart(M);
 
-  // Add all of the arguments we parsed to the method...
+  // Add all of the arguments we parsed to the function...
   if ($5 && !CurMeth.isDeclare) {        // Is null if empty...
-    Method::ArgumentListType &ArgList = M->getArgumentList();
-
-    for (list<MethodArgument*>::iterator I = $5->begin(); I != $5->end(); ++I) {
-      InsertValue(*I);
-      ArgList.push_back(*I);
+    for (list<pair<Argument*, char*> >::iterator I = $5->begin();
+         I != $5->end(); ++I) {
+      if (setValueName(I->first, I->second)) {  // Insert into symtab...
+        assert(0 && "No arg redef allowed!");
+      }
+      
+      InsertValue(I->first);
+      M->getArgumentList().push_back(I->first);
     }
     delete $5;                     // We're now done with the argument list
+  } else if ($5) {
+    // If we are a declaration, we should free the memory for the argument list!
+    for (list<pair<Argument*, char*> >::iterator I = $5->begin(), E = $5->end();
+         I != E; ++I) {
+      if (I->second) free(I->second);   // Free the memory for the name...
+      delete I->first;                  // Free the unused function argument
+    }
+    delete $5;                          // Free the memory for the list itself
   }
-}
+};
+
+BEGIN : BEGINTOK | '{';                // Allow BEGIN or '{' to start a function
 
-MethodHeader : MethodHeaderH ConstPool BEGINTOK {
-  $$ = CurMeth.CurrentMethod;
+FunctionHeader : FunctionHeaderH BEGIN {
+  $$ = CurMeth.CurrentFunction;
 
-  // Resolve circular types before we parse the body of the method.
+  // Resolve circular types before we parse the body of the function.
   ResolveTypes(CurMeth.LateResolveTypes);
-}
+};
 
-Method : BasicBlockList END {
+END : ENDTOK | '}';                    // Allow end of '}' to end a function
+
+Function : BasicBlockList END {
   $$ = $1;
-}
+};
 
-MethodProto : DECLARE { CurMeth.isDeclare = true; } MethodHeaderH {
-  $$ = CurMeth.CurrentMethod;
-  if (!$$->getParent())
-    CurModule.CurrentModule->getMethodList().push_back($$);
-  CurMeth.MethodDone();
-}
+FunctionProto : DECLARE { CurMeth.isDeclare = true; } FunctionHeaderH {
+  $$ = CurMeth.CurrentFunction;
+  assert($$->getParent() == 0 && "Function already in module!");
+  CurModule.CurrentModule->getFunctionList().push_back($$);
+  CurMeth.FunctionDone();
+};
 
 //===----------------------------------------------------------------------===//
 //                        Rules to match Basic Blocks
@@ -1247,20 +1311,17 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
     $$ = ValID::create($1);
   }
   | TRUE {
-    $$ = ValID::create((int64_t)1);
+    $$ = ValID::create(ConstantBool::True);
   } 
   | FALSE {
-    $$ = ValID::create((int64_t)0);
+    $$ = ValID::create(ConstantBool::False);
   }
   | NULL_TOK {
     $$ = ValID::createNull();
   }
-
-/*
-  | STRINGCONSTANT {        // Quoted strings work too... especially for methods
-    $$ = ValID::create_conststr($1);
-  }
-*/
+  | ConstExpr {
+    $$ = ValID::create($1);
+  };
 
 // SymbolicValueRef - Reference to one of two ways of symbolically refering to
 // another value.
@@ -1270,10 +1331,10 @@ SymbolicValueRef : INTVAL {  // Is it an integer reference...?
   }
   | VAR_ID {                 // Is it a named reference...?
     $$ = ValID::create($1);
-  }
+  };
 
 // ValueRef - A reference to a definition... either constant or symbolic
-ValueRef : SymbolicValueRef | ConstValueRef
+ValueRef : SymbolicValueRef | ConstValueRef;
 
 
 // ResolvedVal - a <type> <value> pair.  This is used only in cases where the
@@ -1281,15 +1342,14 @@ ValueRef : SymbolicValueRef | ConstValueRef
 // pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
 ResolvedVal : Types ValueRef {
     $$ = getVal(*$1, $2); delete $1;
-  }
-
+  };
 
 BasicBlockList : BasicBlockList BasicBlock {
-    ($$ = $1)->getBasicBlocks().push_back($2);
-  }
-  | MethodHeader BasicBlock { // Do not allow methods with 0 basic blocks   
-    ($$ = $1)->getBasicBlocks().push_back($2);
+    ($$ = $1)->getBasicBlockList().push_back($2);
   }
+  | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks   
+    ($$ = $1)->getBasicBlockList().push_back($2);
+  };
 
 
 // Basic blocks are terminated by branching instructions: 
@@ -1312,15 +1372,15 @@ BasicBlock : InstructionList OptAssign BBTerminatorInst  {
 
     InsertValue($2);
     $$ = $2;
-  }
+  };
 
 InstructionList : InstructionList Inst {
     $1->getInstList().push_back($2);
     $$ = $1;
   }
   | /* empty */ {
-    $$ = new BasicBlock();
-  }
+    $$ = CurBB = new BasicBlock();
+  };
 
 BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     $$ = new ReturnInst($2);
@@ -1341,18 +1401,18 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
                                    cast<BasicBlock>(getVal(Type::LabelTy, $6)));
     $$ = S;
 
-    list<pair<Constant*, BasicBlock*> >::iterator I = $8->begin(), 
-                                                      end = $8->end();
-    for (; I != end; ++I)
+    vector<pair<Constant*,BasicBlock*> >::iterator I = $8->begin(),
+      E = $8->end();
+    for (; I != E; ++I)
       S->dest_push_back(I->first, I->second);
   }
   | INVOKE TypesV ValueRef '(' ValueRefListE ')' TO ResolvedVal 
     EXCEPT ResolvedVal {
     const PointerType *PMTy;
-    const MethodType *Ty;
+    const FunctionType *Ty;
 
     if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
-        !(Ty = dyn_cast<MethodType>(PMTy->getElementType()))) {
+        !(Ty = dyn_cast<FunctionType>(PMTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       vector<const Type*> ParamTypes;
       if ($5) {
@@ -1363,12 +1423,12 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
 
-      Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
+      Ty = FunctionType::get($2->get(), ParamTypes, isVarArg);
       PMTy = PointerType::get(Ty);
     }
     delete $2;
 
-    Value *V = getVal(PMTy, $3);   // Get the method we're calling...
+    Value *V = getVal(PMTy, $3);   // Get the function we're calling...
 
     BasicBlock *Normal = dyn_cast<BasicBlock>($8);
     BasicBlock *Except = dyn_cast<BasicBlock>($10);
@@ -1380,17 +1440,17 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     if (!$5) {                                   // Has no arguments?
       $$ = new InvokeInst(V, Normal, Except, vector<Value*>());
     } else {                                     // Has arguments?
-      // Loop through MethodType's arguments and ensure they are specified
+      // Loop through FunctionType's arguments and ensure they are specified
       // correctly!
       //
-      MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
-      MethodType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
+      FunctionType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
+      FunctionType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
       vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I)
        if ((*ArgI)->getType() != *I)
          ThrowException("Parameter " +(*ArgI)->getName()+ " is not of type '" +
-                        (*I)->getName() + "'!");
+                        (*I)->getDescription() + "'!");
 
       if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
        ThrowException("Invalid number of parameters detected!");
@@ -1398,7 +1458,7 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
       $$ = new InvokeInst(V, Normal, Except, *$5);
     }
     delete $5;
-  }
+  };
 
 
 
@@ -1411,21 +1471,21 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     $$->push_back(make_pair(V, cast<BasicBlock>(getVal($5, $6))));
   }
   | IntType ConstValueRef ',' LABEL ValueRef {
-    $$ = new list<pair<Constant*, BasicBlock*> >();
+    $$ = new vector<pair<Constant*, BasicBlock*> >();
     Constant *V = cast<Constant>(getValNonImprovising($1, $2));
 
     if (V == 0)
       ThrowException("May only switch on a constant pool value!");
 
     $$->push_back(make_pair(V, cast<BasicBlock>(getVal($4, $5))));
-  }
+  };
 
 Inst : OptAssign InstVal {
   // Is this definition named?? if so, assign the name...
   if (setValueName($2, $1)) { assert(0 && "No redefin allowed!"); }
   InsertValue($2);
   $$ = $2;
-}
+};
 
 PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
     $$ = new list<pair<Value*, BasicBlock*> >();
@@ -1437,7 +1497,7 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
     $$ = $1;
     $1->push_back(make_pair(getVal($1->front().first->getType(), $4),
                             cast<BasicBlock>(getVal(Type::LabelTy, $6))));
-  }
+  };
 
 
 ValueRefList : ResolvedVal {    // Used for call statements, and memory insts...
@@ -1447,21 +1507,44 @@ ValueRefList : ResolvedVal {    // Used for call statements, and memory insts...
   | ValueRefList ',' ResolvedVal {
     $$ = $1;
     $1->push_back($3);
-  }
+  };
 
 // ValueRefListE - Just like ValueRefList, except that it may also be empty!
-ValueRefListE : ValueRefList | /*empty*/ { $$ = 0; }
+ValueRefListE : ValueRefList | /*empty*/ { $$ = 0; };
 
-InstVal : BinaryOps Types ValueRef ',' ValueRef {
+InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
+    if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint())
+      ThrowException("Arithmetic operator requires integer or FP operands!");
     $$ = BinaryOperator::create($1, getVal(*$2, $3), getVal(*$2, $5));
     if ($$ == 0)
       ThrowException("binary operator returned null!");
     delete $2;
   }
-  | UnaryOps ResolvedVal {
-    $$ = UnaryOperator::create($1, $2);
+  | LogicalOps Types ValueRef ',' ValueRef {
+    if (!(*$2)->isIntegral())
+      ThrowException("Logical operator requires integral operands!");
+    $$ = BinaryOperator::create($1, getVal(*$2, $3), getVal(*$2, $5));
     if ($$ == 0)
-      ThrowException("unary operator returned null!");
+      ThrowException("binary operator returned null!");
+    delete $2;
+  }
+  | SetCondOps Types ValueRef ',' ValueRef {
+    $$ = new SetCondInst($1, getVal(*$2, $3), getVal(*$2, $5));
+    if ($$ == 0)
+      ThrowException("binary operator returned null!");
+    delete $2;
+  }
+  | NOT ResolvedVal {
+    std::cerr << "WARNING: Use of eliminated 'not' instruction:"
+              << " Replacing with 'xor'.\n";
+
+    Value *Ones = ConstantIntegral::getAllOnesValue($2->getType());
+    if (Ones == 0)
+      ThrowException("Expected integral type for not instruction!");
+
+    $$ = BinaryOperator::create(Instruction::Xor, $2, Ones);
+    if ($$ == 0)
+      ThrowException("Could not create a xor instruction!");
   }
   | ShiftOps ResolvedVal ',' ResolvedVal {
     if ($4->getType() != Type::UByteTy)
@@ -1485,10 +1568,10 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
   } 
   | CALL TypesV ValueRef '(' ValueRefListE ')' {
     const PointerType *PMTy;
-    const MethodType *Ty;
+    const FunctionType *Ty;
 
     if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
-        !(Ty = dyn_cast<MethodType>(PMTy->getElementType()))) {
+        !(Ty = dyn_cast<FunctionType>(PMTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       vector<const Type*> ParamTypes;
       if ($5) {
@@ -1499,28 +1582,33 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
 
-      Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
+      Ty = FunctionType::get($2->get(), ParamTypes, isVarArg);
       PMTy = PointerType::get(Ty);
     }
     delete $2;
 
-    Value *V = getVal(PMTy, $3);   // Get the method we're calling...
+    Value *V = getVal(PMTy, $3);   // Get the function we're calling...
 
     // Create the call node...
     if (!$5) {                                   // Has no arguments?
+      // Make sure no arguments is a good thing!
+      if (Ty->getNumParams() != 0)
+        ThrowException("No arguments passed to a function that "
+                       "expects arguments!");
+
       $$ = new CallInst(V, vector<Value*>());
     } else {                                     // Has arguments?
-      // Loop through MethodType's arguments and ensure they are specified
+      // Loop through FunctionType's arguments and ensure they are specified
       // correctly!
       //
-      MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
-      MethodType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
+      FunctionType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
+      FunctionType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
       vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I)
        if ((*ArgI)->getType() != *I)
          ThrowException("Parameter " +(*ArgI)->getName()+ " is not of type '" +
-                        (*I)->getName() + "'!");
+                        (*I)->getDescription() + "'!");
 
       if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
        ThrowException("Invalid number of parameters detected!");
@@ -1531,7 +1619,7 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
   }
   | MemoryInst {
     $$ = $1;
-  }
+  };
 
 
 // IndexList - List of indices for GEP based instructions...
@@ -1539,16 +1627,13 @@ IndexList : ',' ValueRefList {
   $$ = $2; 
 } | /* empty */ { 
   $$ = new vector<Value*>(); 
-}
+};
 
 MemoryInst : MALLOC Types {
     $$ = new MallocInst(PointerType::get(*$2));
     delete $2;
   }
   | MALLOC Types ',' UINT ValueRef {
-    if (!(*$2)->isArrayType() || cast<const ArrayType>($2->get())->isSized())
-      ThrowException("Trying to allocate " + (*$2)->getName() + 
-                    " as unsized array!");
     const Type *Ty = PointerType::get(*$2);
     $$ = new MallocInst(Ty, getVal($4, $5));
     delete $2;
@@ -1558,55 +1643,85 @@ MemoryInst : MALLOC Types {
     delete $2;
   }
   | ALLOCA Types ',' UINT ValueRef {
-    if (!(*$2)->isArrayType() || cast<const ArrayType>($2->get())->isSized())
-      ThrowException("Trying to allocate " + (*$2)->getName() + 
-                    " as unsized array!");
     const Type *Ty = PointerType::get(*$2);
     Value *ArrSize = getVal($4, $5);
     $$ = new AllocaInst(Ty, ArrSize);
     delete $2;
   }
   | FREE ResolvedVal {
-    if (!$2->getType()->isPointerType())
+    if (!isa<PointerType>($2->getType()))
       ThrowException("Trying to free nonpointer type " + 
-                     $2->getType()->getName() + "!");
+                     $2->getType()->getDescription() + "!");
     $$ = new FreeInst($2);
   }
 
   | LOAD Types ValueRef IndexList {
-    if (!(*$2)->isPointerType())
+    if (!isa<PointerType>($2->get()))
       ThrowException("Can't load from nonpointer type: " +
                     (*$2)->getDescription());
-    if (LoadInst::getIndexedType(*$2, *$4) == 0)
+    if (GetElementPtrInst::getIndexedType(*$2, *$4) == 0)
       ThrowException("Invalid indices for load instruction!");
 
-    $$ = new LoadInst(getVal(*$2, $3), *$4);
+    Value *Src = getVal(*$2, $3);
+    if (!$4->empty()) {
+      std::cerr << "WARNING: Use of index load instruction:"
+                << " replacing with getelementptr/load pair.\n";
+      // Create a getelementptr hack instruction to do the right thing for
+      // compatibility.
+      //
+      Instruction *I = new GetElementPtrInst(Src, *$4);
+      CurBB->getInstList().push_back(I);
+      Src = I;
+    }
+
+    $$ = new LoadInst(Src);
     delete $4;   // Free the vector...
     delete $2;
   }
   | STORE ResolvedVal ',' Types ValueRef IndexList {
-    if (!(*$4)->isPointerType())
-      ThrowException("Can't store to a nonpointer type: " + (*$4)->getName());
-    const Type *ElTy = StoreInst::getIndexedType(*$4, *$6);
+    if (!isa<PointerType>($4->get()))
+      ThrowException("Can't store to a nonpointer type: " +
+                     (*$4)->getDescription());
+    const Type *ElTy = GetElementPtrInst::getIndexedType(*$4, *$6);
     if (ElTy == 0)
       ThrowException("Can't store into that field list!");
     if (ElTy != $2->getType())
-      ThrowException("Can't store '" + $2->getType()->getName() +
-                     "' into space of type '" + ElTy->getName() + "'!");
-    $$ = new StoreInst($2, getVal(*$4, $5), *$6);
+      ThrowException("Can't store '" + $2->getType()->getDescription() +
+                     "' into space of type '" + ElTy->getDescription() + "'!");
+
+    Value *Ptr = getVal(*$4, $5);
+    if (!$6->empty()) {
+      std::cerr << "WARNING: Use of index store instruction:"
+                << " replacing with getelementptr/store pair.\n";
+      // Create a getelementptr hack instruction to do the right thing for
+      // compatibility.
+      //
+      Instruction *I = new GetElementPtrInst(Ptr, *$6);
+      CurBB->getInstList().push_back(I);
+      Ptr = I;
+    }
+
+    $$ = new StoreInst($2, Ptr);
     delete $4; delete $6;
   }
   | GETELEMENTPTR Types ValueRef IndexList {
-    if (!(*$2)->isPointerType())
+    if (!isa<PointerType>($2->get()))
       ThrowException("getelementptr insn requires pointer operand!");
     if (!GetElementPtrInst::getIndexedType(*$2, *$4, true))
-      ThrowException("Can't get element ptr '" + (*$2)->getName() + "'!");
+      ThrowException("Can't get element ptr '" + (*$2)->getDescription()+ "'!");
     $$ = new GetElementPtrInst(getVal(*$2, $3), *$4);
     delete $2; delete $4;
-  }
+  };
 
 %%
 int yyerror(const char *ErrorMsg) {
-  ThrowException(string("Parse error: ") + ErrorMsg);
+  string where  = string((CurFilename == "-")? string("<stdin>") : CurFilename)
+                  + ":" + utostr((unsigned) llvmAsmlineno) + ": ";
+  string errMsg = string(ErrorMsg) + string("\n") + where + " while reading ";
+  if (yychar == YYEMPTY)
+    errMsg += "end-of-file.";
+  else
+    errMsg += "token: '" + string(llvmAsmtext, llvmAsmleng) + "'";
+  ThrowException(errMsg);
   return 0;
 }