Create a new #include "Support/..." directory structure to move things
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 6852df7dc6b93d8dc87fc5c7b54d47798f080732..0f5c11e1eae514ad55b904a0ba05884722b78e36 100644 (file)
 #include "llvm/DerivedTypes.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iMemory.h"
-#include "llvm/Support/STLExtras.h"
-#include "llvm/Support/DepthFirstIterator.h"
+#include "Support/STLExtras.h"
+#include "Support/DepthFirstIterator.h"
 #include <list>
 #include <utility>            // Get definition of pair class
 #include <algorithm>
 #include <stdio.h>            // This embarasment is due to our flex lexer...
 
-int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit 
+int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
 int yylex();                       // declaration" of xxx warnings.
 int yyparse();
 
@@ -49,14 +49,24 @@ string CurFilename;
 // when the method is completed.
 //
 typedef vector<Value *> ValueList;           // Numbered defs
-static void ResolveDefinitions(vector<ValueList> &LateResolvers);
+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, LateResolveTypes;
+  vector<PATypeHolder<Type> > Types;
+  map<ValID, PATypeHolder<Type> > LateResolveTypes;
+
+  // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
+  // references to global values.  Global values may be referenced before they
+  // are defined, and if so, the temporary object that they represent is held
+  // here.  This is used for forward references of ConstPoolPointerRefs.
+  //
+  typedef map<pair<const PointerType *, ValID>, GlobalVariable*> GlobalRefsType;
+  GlobalRefsType GlobalRefs;
 
   void ModuleDone() {
     // If we could not resolve some methods at method compilation time (calls to
@@ -65,10 +75,57 @@ static struct PerModuleInfo {
     //
     ResolveDefinitions(LateResolveValues);
 
+    // Check to make sure that all global value forward references have been
+    // 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!");
+    }
+
     Values.clear();         // Clear out method local definitions
     Types.clear();
     CurrentModule = 0;
   }
+
+
+  // DeclareNewGlobalValue - Called every type 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.
+  //
+  void DeclareNewGlobalValue(GlobalValue *GV, ValID D) {
+    // Check to see if there is a forward reference to this global variable...
+    // if there is, eliminate it and patch the reference to use the new def'n.
+    GlobalRefsType::iterator I = GlobalRefs.find(make_pair(GV->getType(), D));
+
+    if (I != GlobalRefs.end()) {
+      GlobalVariable *OldGV = I->second;   // Get the placeholder...
+      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 ConstPoolPointerRef's.
+      assert(OldGV->use_size() == 1 && "Only one reference should exist!");
+      while (!OldGV->use_empty()) {
+       User *U = OldGV->use_back();  // Must be a ConstPoolPointerRef...
+       ConstPoolPointerRef *CPPR = cast<ConstPoolPointerRef>(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);
+      }
+    
+      // Remove GV 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);
+    }
+  }
+
 } CurModule;
 
 static struct PerMethodInfo {
@@ -76,7 +133,8 @@ static struct PerMethodInfo {
 
   vector<ValueList> Values;      // Keep track of numbered definitions
   vector<ValueList> LateResolveValues;
-  vector<PATypeHolder<Type> > Types, LateResolveTypes;
+  vector<PATypeHolder<Type> > Types;
+  map<ValID, PATypeHolder<Type> > LateResolveTypes;
   bool isDeclare;                // Is this method a forward declararation?
 
   inline PerMethodInfo() {
@@ -93,7 +151,7 @@ static struct PerMethodInfo {
   void MethodDone() {
     // If we could not resolve some blocks at parsing time (forward branches)
     // resolve the branches now...
-    ResolveDefinitions(LateResolveValues);
+    ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
 
     Values.clear();         // Clear out method local definitions
     Types.clear();
@@ -102,19 +160,23 @@ static struct PerMethodInfo {
   }
 } CurMeth;  // Info for the current method...
 
+static bool inMethodScope() { return CurMeth.CurrentMethod != 0; }
+
 
 //===----------------------------------------------------------------------===//
 //               Code to handle definitions of all the types
 //===----------------------------------------------------------------------===//
 
-static void InsertValue(Value *D, vector<ValueList> &ValueTab = CurMeth.Values){
-  if (!D->hasName()) {             // Is this a numbered definition?
-    unsigned type = D->getType()->getUniqueID();
-    if (ValueTab.size() <= type)
-      ValueTab.resize(type+1, ValueList());
-    //printf("Values[%d][%d] = %d\n", type, ValueTab[type].size(), D);
-    ValueTab[type].push_back(D);
-  }
+static int InsertValue(Value *D, vector<ValueList> &ValueTab = CurMeth.Values) {
+  if (D->hasName()) return -1;           // Is this a numbered definition?
+
+  // Yes, insert the value into the value table...
+  unsigned type = D->getType()->getUniqueID();
+  if (ValueTab.size() <= type)
+    ValueTab.resize(type+1, ValueList());
+  //printf("Values[%d][%d] = %d\n", type, ValueTab[type].size(), D);
+  ValueTab[type].push_back(D);
+  return ValueTab[type].size()-1;
 }
 
 // TODO: FIXME when Type are not const
@@ -136,12 +198,12 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
     // Check that the number is within bounds...
     if (Num <= CurMeth.Types.size())
       return CurMeth.Types[Num];
+    break;
   }
   case 1: {                // Is it a named definition?
     string Name(D.Name);
     SymbolTable *SymTab = 0;
-    if (CurMeth.CurrentMethod) 
-      SymTab = CurMeth.CurrentMethod->getSymbolTable();
+    if (inMethodScope()) SymTab = CurMeth.CurrentMethod->getSymbolTable();
     Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0;
 
     if (N == 0) {
@@ -167,17 +229,22 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   //
   if (DoNotImprovise) return 0;  // Do we just want a null to be returned?
 
-  vector<PATypeHolder<Type> > *LateResolver = CurMeth.CurrentMethod ? 
-    &CurMeth.LateResolveTypes : &CurModule.LateResolveTypes;
+  map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ? 
+    CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
+  
+  map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+  if (I != LateResolver.end()) {
+    return I->second;
+  }
 
-  Type *Typ = new TypePlaceHolder(Type::TypeTy, D);
-  InsertType(Typ, *LateResolver);
+  Type *Typ = OpaqueType::get();
+  LateResolver.insert(make_pair(D, Typ));
   return Typ;
 }
 
 static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
   SymbolTable *SymTab = 
-    CurMeth.CurrentMethod ? CurMeth.CurrentMethod->getSymbolTable() : 0;
+    inMethodScope() ? CurMeth.CurrentMethod->getSymbolTable() : 0;
   Value *N = SymTab ? SymTab->lookup(Ty, Name) : 0;
 
   if (N == 0) {
@@ -192,9 +259,13 @@ static Value *lookupInSymbolTable(const Type *Ty, const string &Name) {
   return N;
 }
 
-static Value *getVal(const Type *Ty, const ValID &D, 
-                     bool DoNotImprovise = false) {
-  assert(Ty != Type::TypeTy && "Should use getTypeVal for types!");
+// getValNonImprovising - Look up the value specified by the provided type and
+// the provided ValID.  If the value exists and has already been defined, return
+// 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");
 
   switch (D.Type) {
   case ValID::NumberVal: {                 // Is it a numbered definition?
@@ -210,100 +281,99 @@ static Value *getVal(const Type *Ty, const ValID &D,
     }
 
     // Make sure that our type is within bounds
-    if (CurMeth.Values.size() <= type)
-      break;
+    if (CurMeth.Values.size() <= type) return 0;
 
     // Check that the number is within bounds...
-    if (CurMeth.Values[type].size() <= Num)
-      break;
+    if (CurMeth.Values[type].size() <= Num) return 0;
   
     return CurMeth.Values[type][Num];
   }
+
   case ValID::NameVal: {                // Is it a named definition?
-    string Name(D.Name);
-    Value *N = lookupInSymbolTable(Ty, Name);
-    if (N == 0) break;
+    Value *N = lookupInSymbolTable(Ty, string(D.Name));
+    if (N == 0) return 0;
 
     D.destroy();  // Free old strdup'd memory...
     return N;
   }
 
-  case ValID::ConstSIntVal:     // Is it a constant pool reference??
+  // 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 ConstPoolBool::get(D.ConstPool64 != 0);
+    } else {
+      if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64))
+       ThrowException("Symbolic constant pool value '" +
+                      itostr(D.ConstPool64) + "' is invalid for type '" + 
+                      Ty->getName() + "'!");
+      return ConstPoolSInt::get(Ty, D.ConstPool64);
+    }
+
   case ValID::ConstUIntVal:     // Is it an unsigned const pool reference?
-  case ValID::ConstStringVal:   // Is it a string const pool reference?
-  case ValID::ConstFPVal:       // Is it a floating point const pool reference?
-  case ValID::ConstNullVal: {   // Is it a null value?
-    ConstPoolVal *CPV = 0;
-
-    // Check to make sure that "Ty" is an integral type, and that our 
-    // value will fit into the specified type...
-    switch (D.Type) {
-    case ValID::ConstSIntVal:
-      if (Ty == Type::BoolTy) {  // Special handling for boolean data
-        CPV = ConstPoolBool::get(D.ConstPool64 != 0);
-      } else {
-        if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64))
-          ThrowException("Symbolic constant pool value '" +
-                        itostr(D.ConstPool64) + "' is invalid for type '" + 
-                        Ty->getName() + "'!");
-        CPV = ConstPoolSInt::get(Ty, D.ConstPool64);
+    if (!ConstPoolUInt::isValueValidForType(Ty, D.UConstPool64)) {
+      if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64)) {
+       ThrowException("Integral constant pool reference is invalid!");
+      } else {     // This is really a signed reference.  Transmogrify.
+       return ConstPoolSInt::get(Ty, D.ConstPool64);
       }
-      break;
-    case ValID::ConstUIntVal:
-      if (!ConstPoolUInt::isValueValidForType(Ty, D.UConstPool64)) {
-        if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64)) {
-          ThrowException("Integral constant pool reference is invalid!");
-        } else {     // This is really a signed reference.  Transmogrify.
-          CPV = ConstPoolSInt::get(Ty, D.ConstPool64);
-        }
-      } else {
-        CPV = ConstPoolUInt::get(Ty, D.UConstPool64);
-      }
-      break;
-    case ValID::ConstStringVal:
-      cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
-      abort();
-      break;
-    case ValID::ConstFPVal:
-      if (!ConstPoolFP::isValueValidForType(Ty, D.ConstPoolFP))
-       ThrowException("FP constant invalid for type!!");
-      CPV = ConstPoolFP::get(Ty, D.ConstPoolFP);
-      break;
-    case ValID::ConstNullVal:
-      if (!Ty->isPointerType())
-        ThrowException("Cannot create a a non pointer null!");
-      CPV = ConstPoolPointer::getNullPointer(cast<PointerType>(Ty));
-      break;
-    default:
-      assert(0 && "Unhandled case!");
+    } else {
+      return ConstPoolUInt::get(Ty, D.UConstPool64);
     }
-    assert(CPV && "How did we escape creating a constant??");
-    return CPV;
-  }   // End of case 2,3,4
+
+  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 (!ConstPoolFP::isValueValidForType(Ty, D.ConstPoolFP))
+      ThrowException("FP constant invalid for type!!");
+    return ConstPoolFP::get(Ty, D.ConstPoolFP);
+    
+  case ValID::ConstNullVal:      // Is it a null value?
+    if (!Ty->isPointerType())
+      ThrowException("Cannot create a a non pointer null!");
+    return ConstPoolPointerNull::get(cast<PointerType>(Ty));
+    
   default:
     assert(0 && "Unhandled case!");
+    return 0;
   }   // End of switch
 
+  assert(0 && "Unhandled case!");
+  return 0;
+}
+
+
+// getVal - This function is identical to getValNonImprovising, except that if a
+// value is not already defined, it "improvises" by creating a placeholder var
+// that looks and acts just like the requested variable.  When the value is
+// defined later, all uses of the placeholder variable are replaced with the
+// real thing.
+//
+static Value *getVal(const Type *Ty, const ValID &D) {
+  assert(Ty != Type::TypeTy && "Should use getTypeVal for types!");
+
+  // See if the value has already been defined...
+  Value *V = getValNonImprovising(Ty, D);
+  if (V) return V;
 
   // If we reached here, we referenced either a symbol that we don't know about
   // or an id number that hasn't been read yet.  We may be referencing something
   // forward, so just create an entry to be resolved later and get to it...
   //
-  if (DoNotImprovise) return 0;  // Do we just want a null to be returned?
-
   Value *d = 0;
-  vector<ValueList> *LateResolver =  (CurMeth.CurrentMethod) ? 
-    &CurMeth.LateResolveValues : &CurModule.LateResolveValues;
-
   switch (Ty->getPrimitiveID()) {
   case Type::LabelTyID:  d = new   BBPlaceHolder(Ty, D); break;
-  case Type::MethodTyID: d = new MethPlaceHolder(Ty, D); 
-                         LateResolver = &CurModule.LateResolveValues; break;
   default:               d = new ValuePlaceHolder(Ty, D); break;
   }
 
   assert(d != 0 && "How did we not make something?");
-  InsertValue(d, *LateResolver);
+  if (inMethodScope())
+    InsertValue(d, CurMeth.LateResolveValues);
+  else 
+    InsertValue(d, CurModule.LateResolveValues);
   return d;
 }
 
@@ -324,17 +394,26 @@ static Value *getVal(const Type *Ty, const ValID &D,
 // time (forward branches, phi functions for loops, etc...) resolve the 
 // defs now...
 //
-static void ResolveDefinitions(vector<ValueList> &LateResolvers) {
+static void ResolveDefinitions(vector<ValueList> &LateResolvers,
+                               vector<ValueList> *FutureLateResolvers = 0) {
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
   for (unsigned ty = 0; ty < LateResolvers.size(); ty++) {
     while (!LateResolvers[ty].empty()) {
       Value *V = LateResolvers[ty].back();
+      assert(!isa<Type>(V) && "Types should be in LateResolveTypes!");
+
       LateResolvers[ty].pop_back();
       ValID &DID = getValIDFromPlaceHolder(V);
 
-      Value *TheRealValue = getVal(Type::getUniqueIDType(ty), DID, true);
-
-      if (TheRealValue == 0) {
+      Value *TheRealValue = getValNonImprovising(Type::getUniqueIDType(ty),DID);
+      if (TheRealValue) {
+        V->replaceAllUsesWith(TheRealValue);
+        delete V;
+      } else if (FutureLateResolvers) {
+        // Methods have their unresolved items forwarded to the module late
+        // resolver table
+        InsertValue(V, *FutureLateResolvers);
+      } else {
        if (DID.Type == 1)
          ThrowException("Reference to an invalid definition: '" +DID.getName()+
                         "' of type '" + V->getType()->getDescription() + "'",
@@ -345,11 +424,6 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers) {
                         V->getType()->getDescription() + "'",
                         getLineNumFromPlaceHolder(V));
       }
-
-      assert(!isa<Type>(V) && "Types should be in LateResolveTypes!");
-
-      V->replaceAllUsesWith(TheRealValue);
-      delete V;
     }
   }
 
@@ -365,49 +439,46 @@ static bool ResolveType(PATypeHolder<Type> &T) {
   ValID &DID = getValIDFromPlaceHolder(Ty);
 
   const Type *TheRealType = getTypeVal(DID, true);
-  if (TheRealType == 0) return 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;
 }
 
-
-// ResolveTypes - This goes through the forward referenced type table and makes
-// sure that all type references are complete.  This code is executed after the
-// constant pool of a method or module is completely parsed.
+// 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 ResolveTypes(vector<PATypeHolder<Type> > &LateResolveTypes) {
-  while (!LateResolveTypes.empty()) {
-    if (ResolveType(LateResolveTypes.back())) {
-      const Type *Ty = LateResolveTypes.back();
-      ValID &DID = getValIDFromPlaceHolder(Ty);
-
-      if (DID.Type == ValID::NameVal)
-       ThrowException("Reference to an invalid type: '" +DID.getName(),
-                      getLineNumFromPlaceHolder(Ty));
-      else
-       ThrowException("Reference to an invalid type: #" + itostr(DID.Num),
-                      getLineNumFromPlaceHolder(Ty));
-    }
+static void ResolveTypeTo(char *Name, const Type *ToTy) {
+  vector<PATypeHolder<Type> > &Types = inMethodScope() ? 
+     CurMeth.Types : CurModule.Types;
 
-    // No need to delete type, refine does that for us.
-    LateResolveTypes.pop_back();
-  }
-}
+   ValID D;
+   if (Name) D = ValID::create(Name);
+   else      D = ValID::create((int)Types.size());
 
+   map<ValID, PATypeHolder<Type> > &LateResolver = inMethodScope() ? 
+     CurMeth.LateResolveTypes : CurModule.LateResolveTypes;
+  
+   map<ValID, PATypeHolder<Type> >::iterator I = LateResolver.find(D);
+   if (I != LateResolver.end()) {
+     cast<DerivedType>(I->second.get())->refineAbstractTypeTo(ToTy);
+     LateResolver.erase(I);
+   }
+}
 
-// ResolveSomeTypes - This goes through the forward referenced type table and
-// completes references that are now done.  This is so that types are
-// immediately resolved to be as concrete as possible.  This does not cause
-// thrown exceptions if not everything is resolved.
+// ResolveTypes - At this point, all types should be resolved.  Any that aren't
+// are errors.
 //
-static void ResolveSomeTypes(vector<PATypeHolder<Type> > &LateResolveTypes) {
-  for (unsigned i = 0; i < LateResolveTypes.size(); ) {
-    if (ResolveType(LateResolveTypes[i]))
-      ++i;                                                // Type didn't resolve
+static void ResolveTypes(map<ValID, PATypeHolder<Type> > &LateResolveTypes) {
+  if (!LateResolveTypes.empty()) {
+    const ValID &DID = LateResolveTypes.begin()->first;
+
+    if (DID.Type == ValID::NameVal)
+      ThrowException("Reference to an invalid type: '" +DID.getName() + "'");
     else
-      LateResolveTypes.erase(LateResolveTypes.begin()+i); // Type resolved!
+      ThrowException("Reference to an invalid type: #" + itostr(DID.Num));
   }
 }
 
@@ -416,12 +487,21 @@ static void ResolveSomeTypes(vector<PATypeHolder<Type> > &LateResolveTypes) {
 // null potentially, in which case this is a noop.  The string passed in is
 // assumed to be a malloc'd string buffer, and is freed by this function.
 //
-static void setValueName(Value *V, char *NameStr) {
-  if (NameStr == 0) return;
+// This function returns true if the value has already been defined, but is
+// allowed to be redefined in the specified context.  If the name is a new name
+// for the typeplane, false is returned.
+//
+static bool setValueName(Value *V, char *NameStr) {
+  if (NameStr == 0) return false;
+  
   string Name(NameStr);           // Copy string
   free(NameStr);                  // Free old string
 
-  SymbolTable *ST = CurMeth.CurrentMethod ? 
+  if (V->getType() == Type::VoidTy) 
+    ThrowException("Can't assign name '" + Name + 
+                  "' to a null valued instruction!");
+
+  SymbolTable *ST = inMethodScope() ? 
     CurMeth.CurrentMethod->getSymbolTableSure() : 
     CurModule.CurrentModule->getSymbolTableSure();
 
@@ -433,24 +513,43 @@ static void setValueName(Value *V, char *NameStr) {
       if (OpaqueType *OpTy = dyn_cast<OpaqueType>(Ty)) {
        // We ARE replacing an opaque type!
        OpTy->refineAbstractTypeTo(cast<Type>(V));
-       return;
+       return true;
       }
     }
 
     // Otherwise, we are a simple redefinition of a value, check to see if it
     // is defined the same as the old one...
     if (const Type *Ty = dyn_cast<const Type>(Existing)) {
-      if (Ty == cast<const Type>(V)) return;  // Yes, it's equal.
-      cerr << "Type: " << Ty->getDescription() << " != "
-           << cast<const Type>(V)->getDescription() << "!\n";
-    } else {
-      
+      if (Ty == cast<const Type>(V)) return true;  // Yes, it's equal.
+      // 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:
+      // 1. If at least one of the globals is uninitialized or 
+      // 2. If both initializers have the same value.
+      //
+      // This can only be done if the const'ness of the vars is the same.
+      //
+      if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
+        if (EGV->isConstant() == GV->isConstant() &&
+            (!EGV->hasInitializer() || !GV->hasInitializer() ||
+             EGV->getInitializer() == GV->getInitializer())) {
+
+          // Make sure the existing global version gets the initializer!
+          if (GV->hasInitializer() && !EGV->hasInitializer())
+            EGV->setInitializer(GV->getInitializer());
+          
+         delete GV;     // Destroy the duplicate!
+          return true;   // They are equivalent!
+        }
+      }
     }
-    ThrowException("Redefinition of value name '" + Name + "' in the '" +
+    ThrowException("Redefinition of value named '" + Name + "' in the '" +
                   V->getType()->getDescription() + "' type plane!");
   }
 
   V->setName(Name, ST);
+  return false;
 }
 
 
@@ -469,20 +568,23 @@ static vector<pair<unsigned, OpaqueType *> > UpRefs;
 
 static PATypeHolder<Type> HandleUpRefs(const Type *ty) {
   PATypeHolder<Type> Ty(ty);
-  UR_OUT(UpRefs.size() << " upreferences active!\n");
+  UR_OUT("Type '" << ty->getDescription() << 
+         "' newly formed.  Resolving upreferences.\n" <<
+         UpRefs.size() << " upreferences active!\n");
   for (unsigned i = 0; i < UpRefs.size(); ) {
-    UR_OUT("TypeContains(" << Ty->getDescription() << ", " 
+    UR_OUT("  UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " 
           << UpRefs[i].second->getDescription() << ") = " 
-          << TypeContains(Ty, UpRefs[i].second) << endl);
+          << (TypeContains(Ty, UpRefs[i].second) ? "true" : "false") << endl);
     if (TypeContains(Ty, UpRefs[i].second)) {
       unsigned Level = --UpRefs[i].first;   // Decrement level of upreference
-      UR_OUT("Uplevel Ref Level = " << Level << endl);
+      UR_OUT("  Uplevel Ref Level = " << Level << endl);
       if (Level == 0) {                     // Upreference should be resolved! 
-       UR_OUT("About to resolve upreference!\n";
+       UR_OUT("  * Resolving upreference for "
+               << UpRefs[i].second->getDescription() << endl;
               string OldName = UpRefs[i].second->getDescription());
        UpRefs[i].second->refineAbstractTypeTo(Ty);
        UpRefs.erase(UpRefs.begin()+i);     // Remove from upreference list...
-       UR_OUT("Type '" << OldName << "' refined upreference to: "
+       UR_OUT("  * Type '" << OldName << "' refined upreference to: "
               << (const void*)Ty << ", " << Ty->getDescription() << endl);
        continue;
       }
@@ -545,7 +647,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
   Value                            *ValueVal;
 
   list<MethodArgument*>            *MethodArgList;
-  list<Value*>                     *ValueList;
+  vector<Value*>                   *ValueList;
   list<PATypeHolder<Type> >        *TypeList;
   list<pair<Value*, BasicBlock*> > *PHIList;   // Represent the RHS of PHI node
   list<pair<ConstPoolVal*, BasicBlock*> > *JumpTable;
@@ -574,16 +676,18 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 %type <TermInstVal>   BBTerminatorInst
 %type <InstVal>       Inst InstVal MemoryInst
 %type <ConstVal>      ConstVal
-%type <ConstVector>   ConstVector UByteList
+%type <ConstVector>   ConstVector
 %type <MethodArgList> ArgList ArgListH
 %type <MethArgVal>    ArgVal
 %type <PHIList>       PHIList
 %type <ValueList>     ValueRefList ValueRefListE  // For call param lists
+%type <ValueList>     IndexList                   // For GEP derived indices
 %type <TypeList>      TypeListI ArgTypeListI
 %type <JumpTable>     JumpTable
-%type <BoolVal>       GlobalType                  // GLOBAL or CONSTANT?
+%type <BoolVal>       GlobalType OptInternal      // GLOBAL or CONSTANT? Intern?
 
-%type <ValIDVal>      ValueRef ConstValueRef // Reference to a definition or BB
+// ValueRef - Unresolved reference to a definition or BB
+%type <ValIDVal>      ValueRef ConstValueRef SymbolicValueRef
 %type <ValueVal>      ResolvedVal            // <type> <valref> pair
 // Tokens and types for handling constant integer values
 //
@@ -611,7 +715,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 
 
 %token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE GLOBAL CONSTANT UNINIT
-%token TO DOTDOTDOT STRING NULL_TOK CONST
+%token TO EXCEPT DOTDOTDOT STRING NULL_TOK CONST INTERNAL
 
 // Basic Block Terminating Operators 
 %token <TermOpVal> RET BR SWITCH
@@ -622,7 +726,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 
 // Binary Operators 
 %type  <BinaryOpVal> BinaryOps  // all the binary operators
-%token <BinaryOpVal> ADD SUB MUL DIV REM
+%token <BinaryOpVal> ADD SUB MUL DIV REM AND OR XOR
 %token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE  // Binary Comarators
 
 // Memory Instructions
@@ -630,7 +734,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 
 // Other Operators
 %type  <OtherOpVal> ShiftOps
-%token <OtherOpVal> PHI CALL CAST SHL SHR
+%token <OtherOpVal> PHI CALL INVOKE CAST SHL SHR
 
 %start Module
 %%
@@ -657,7 +761,7 @@ EINT64VAL : EUINT64VAL {
 // RET, BR, & SWITCH because they end basic blocks and are treated specially.
 //
 UnaryOps  : NOT
-BinaryOps : ADD | SUB | MUL | DIV | REM
+BinaryOps : ADD | SUB | MUL | DIV | REM | AND | OR | XOR
 BinaryOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE
 ShiftOps  : SHL | SHR
 
@@ -676,6 +780,7 @@ OptAssign : VAR_ID '=' {
     $$ = 0; 
   }
 
+OptInternal : INTERNAL { $$ = true; } | /*empty*/ { $$ = false; }
 
 //===----------------------------------------------------------------------===//
 // Types includes all predefined types... except void, because it can only be
@@ -714,7 +819,10 @@ UpRTypes : '\\' EUINT64VAL {                   // Type UpReference
     vector<const Type*> Params;
     mapto($3->begin(), $3->end(), back_inserter(Params), 
          mem_fun_ref(&PATypeHandle<Type>::get));
-    $$ = newTH(HandleUpRefs(MethodType::get(*$1, Params)));
+    bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
+    if (isVarArg) Params.pop_back();
+
+    $$ = newTH(HandleUpRefs(MethodType::get(*$1, Params, isVarArg)));
     delete $3;      // Delete the argument list
     delete $1;      // Delete the old type handle
   }
@@ -851,29 +959,48 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       ThrowException("Cannot make null pointer constant with type: '" + 
                      (*$1)->getDescription() + "'!");
 
-    $$ = ConstPoolPointer::getNullPointer(PTy);
+    $$ = ConstPoolPointerNull::get(PTy);
     delete $1;
   }
-  | Types VAR_ID {
-    string Name($2); free($2);  // Change to a responsible mem manager
+  | Types SymbolicValueRef {
     const PointerType *Ty = dyn_cast<const PointerType>($1->get());
     if (Ty == 0)
       ThrowException("Global const reference must be a pointer type!");
 
-    Value *N = lookupInSymbolTable(Ty, Name);
-    if (N == 0)
-      ThrowException("Global pointer reference '%" + Name +
-                     "' must be defined before use!");    
+    Value *V = getValNonImprovising(Ty, $2);
 
-    // TODO FIXME: This should also allow methods... when common baseclass
-    // exists
-    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(N)) {
-      $$ = ConstPoolPointerReference::get(GV);
-    } else {
-      ThrowException("'%" + Name + "' is not a global value reference!");
+    // 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.
+    //
+    if (V == 0) {
+      assert(isa<PointerType>(Ty) && "Globals may only be used as pointers!");
+      const PointerType *PT = cast<PointerType>(Ty);
+
+      // First check to see if the forward references value is already created!
+      PerModuleInfo::GlobalRefsType::iterator I =
+       CurModule.GlobalRefs.find(make_pair(PT, $2));
+    
+      if (I != CurModule.GlobalRefs.end()) {
+       V = I->second;             // Placeholder already exists, use it...
+      } else {
+       // TODO: Include line number info by creating a subclass of
+       // TODO: GlobalVariable here that includes the said information!
+       
+       // Create a placeholder for the global variable reference...
+       GlobalVariable *GV = new GlobalVariable(PT->getValueType(), false,true);
+       // Keep track of the fact that we have a forward ref to recycle it
+       CurModule.GlobalRefs.insert(make_pair(make_pair(PT, $2), GV));
+
+       // Must temporarily push this value into the module table...
+       CurModule.CurrentModule->getGlobalList().push_back(GV);
+       V = GV;
+      }
     }
 
-    delete $1;
+    GlobalValue *GV = cast<GlobalValue>(V);
+    $$ = ConstPoolPointerRef::get(GV);
+    delete $1;            // Free the type handle
   }
 
 
@@ -913,51 +1040,70 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }
 
 // ConstPool - Constants with optional names assigned to them.
 ConstPool : ConstPool OptAssign CONST ConstVal { 
-    setValueName($4, $2);
+    if (setValueName($4, $2)) { assert(0 && "No redefinitions allowed!"); }
     InsertValue($4);
   }
   | ConstPool OptAssign TYPE TypesV {  // Types can be defined in the const pool
-    // TODO: FIXME when Type are not const
-    setValueName(const_cast<Type*>($4->get()), $2);
+    // Eagerly resolve types.  This is not an optimization, this is a
+    // requirement that is due to the fact that we could have this:
+    //
+    // %list = type { %list * }
+    // %list = type { %list * }    ; repeated type decl
+    //
+    // If types are not resolved eagerly, then the two types will not be
+    // determined to be the same type!
+    //
+    ResolveTypeTo($2, $4->get());
 
-    if (!$2) {
-      InsertType($4->get(),
-                CurMeth.CurrentMethod ? CurMeth.Types : CurModule.Types);
+    // TODO: FIXME when Type are not const
+    if (!setValueName(const_cast<Type*>($4->get()), $2)) {
+      // If this is not a redefinition of a type...
+      if (!$2) {
+        InsertType($4->get(),
+                   inMethodScope() ? CurMeth.Types : CurModule.Types);
+      }
     }
-    delete $4;
 
-    ResolveSomeTypes(CurMeth.CurrentMethod ? CurMeth.LateResolveTypes :
-                     CurModule.LateResolveTypes);
+    delete $4;
   }
   | ConstPool MethodProto {            // Method prototypes can be in const pool
   }
-  | ConstPool OptAssign GlobalType ConstVal {
-    const Type *Ty = $4->getType();
+  | ConstPool OptAssign OptInternal GlobalType ConstVal {
+    const Type *Ty = $5->getType();
     // Global declarations appear in Constant Pool
-    ConstPoolVal *Initializer = $4;
+    ConstPoolVal *Initializer = $5;
     if (Initializer == 0)
       ThrowException("Global value initializer is not a constant!");
         
-    GlobalVariable *GV = new GlobalVariable(PointerType::get(Ty), $3,
-                                           Initializer);
-    setValueName(GV, $2);
+    GlobalVariable *GV = new GlobalVariable(Ty, $4, $3, Initializer);
+    if (!setValueName(GV, $2)) {   // If not redefining...
+      CurModule.CurrentModule->getGlobalList().push_back(GV);
+      int Slot = InsertValue(GV, CurModule.Values);
 
-    CurModule.CurrentModule->getGlobalList().push_back(GV);
-    InsertValue(GV, CurModule.Values);
+      if (Slot != -1) {
+       CurModule.DeclareNewGlobalValue(GV, ValID::create(Slot));
+      } else {
+       CurModule.DeclareNewGlobalValue(GV, ValID::create(
+                                               (char*)GV->getName().c_str()));
+      }
+    }
   }
-  | ConstPool OptAssign UNINIT GlobalType Types {
-    const Type *Ty = *$5;
+  | ConstPool OptAssign OptInternal UNINIT GlobalType Types {
+    const Type *Ty = *$6;
     // Global declarations appear in Constant Pool
-    if (isa<ArrayType>(Ty) && cast<ArrayType>(Ty)->isUnsized()) {
-      ThrowException("Type '" + Ty->getDescription() +
-                    "' is not a sized type!");
-    }
+    GlobalVariable *GV = new GlobalVariable(Ty, $5, $3);
+    if (!setValueName(GV, $2)) {   // If not redefining...
+      CurModule.CurrentModule->getGlobalList().push_back(GV);
+      int Slot = InsertValue(GV, CurModule.Values);
 
-    GlobalVariable *GV = new GlobalVariable(PointerType::get(Ty), $4);
-    setValueName(GV, $2);
-
-    CurModule.CurrentModule->getGlobalList().push_back(GV);
-    InsertValue(GV, CurModule.Values);
+      if (Slot != -1) {
+       CurModule.DeclareNewGlobalValue(GV, ValID::create(Slot));
+      } else {
+       assert(GV->hasName() && "Not named and not numbered!?");
+       CurModule.DeclareNewGlobalValue(GV, ValID::create(
+                                               (char*)GV->getName().c_str()));
+      }
+    }
   }
   | /* empty: end of list */ { 
   }
@@ -1001,7 +1147,7 @@ OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; }
 
 ArgVal : Types OptVAR_ID {
   $$ = new MethodArgument(*$1); delete $1;
-  setValueName($$, $2);
+  if (setValueName($$, $2)) { assert(0 && "No arg redef allowed!"); }
 }
 
 ArgListH : ArgVal ',' ArgListH {
@@ -1014,7 +1160,7 @@ ArgListH : ArgVal ',' ArgListH {
   }
   | DOTDOTDOT {
     $$ = new list<MethodArgument*>();
-    $$->push_back(new MethodArgument(Type::VoidTy));
+    $$->push_front(new MethodArgument(Type::VoidTy));
   }
 
 ArgList : ArgListH {
@@ -1024,46 +1170,52 @@ ArgList : ArgListH {
     $$ = 0;
   }
 
-MethodHeaderH : TypesV STRINGCONSTANT '(' ArgList ')' {
-  UnEscapeLexed($2);
+MethodHeaderH : OptInternal TypesV STRINGCONSTANT '(' ArgList ')' {
+  UnEscapeLexed($3);
+  string MethodName($3);
+  
   vector<const Type*> ParamTypeList;
-  if ($4)
-    for (list<MethodArgument*>::iterator I = $4->begin(); I != $4->end(); ++I)
+  if ($5)
+    for (list<MethodArgument*>::iterator I = $5->begin(); I != $5->end(); ++I)
       ParamTypeList.push_back((*I)->getType());
 
-  const MethodType *MT = MethodType::get(*$1, ParamTypeList);
-  delete $1;
+  bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
+  if (isVarArg) ParamTypeList.pop_back();
+
+  const MethodType  *MT  = MethodType::get(*$2, ParamTypeList, isVarArg);
+  const PointerType *PMT = PointerType::get(MT);
+  delete $2;
 
   Method *M = 0;
   if (SymbolTable *ST = CurModule.CurrentModule->getSymbolTable()) {
-    if (Value *V = ST->lookup(MT, $2)) {  // Method already in symtab?
-      M =  cast<Method>(V);
+    if (Value *V = ST->lookup(PMT, MethodName)) {  // Method already in symtab?
+      M = cast<Method>(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 '" + string($2) + "'!");      
+       ThrowException("Redefinition of method '" + MethodName + "'!");      
     }
   }
 
   if (M == 0) {  // Not already defined?
-    M = new Method(MT, $2);
+    M = new Method(MT, $1, MethodName);
     InsertValue(M, CurModule.Values);
+    CurModule.DeclareNewGlobalValue(M, ValID::create($3));
   }
-
-  free($2);  // Free strdup'd memory!
+  free($3);  // Free strdup'd memory!
 
   CurMeth.MethodStart(M);
 
   // Add all of the arguments we parsed to the method...
-  if ($4 && !CurMeth.isDeclare) {        // Is null if empty...
+  if ($5 && !CurMeth.isDeclare) {        // Is null if empty...
     Method::ArgumentListType &ArgList = M->getArgumentList();
 
-    for (list<MethodArgument*>::iterator I = $4->begin(); I != $4->end(); ++I) {
+    for (list<MethodArgument*>::iterator I = $5->begin(); I != $5->end(); ++I) {
       InsertValue(*I);
       ArgList.push_back(*I);
     }
-    delete $4;                     // We're now done with the argument list
+    delete $5;                     // We're now done with the argument list
   }
 }
 
@@ -1114,16 +1266,19 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
   }
 */
 
-// ValueRef - A reference to a definition... 
-ValueRef : INTVAL {           // Is it an integer reference...?
+// SymbolicValueRef - Reference to one of two ways of symbolically refering to
+// another value.
+//
+SymbolicValueRef : INTVAL {  // Is it an integer reference...?
     $$ = ValID::create($1);
   }
   | VAR_ID {                 // Is it a named reference...?
     $$ = ValID::create($1);
   }
-  | ConstValueRef {
-    $$ = $1;
-  }
+
+// ValueRef - A reference to a definition... either constant or symbolic
+ValueRef : SymbolicValueRef | ConstValueRef
+
 
 // ResolvedVal - a <type> <value> pair.  This is used only in cases where the
 // type immediately preceeds the value reference, and allows complex constant
@@ -1134,26 +1289,30 @@ ResolvedVal : Types ValueRef {
 
 
 BasicBlockList : BasicBlockList BasicBlock {
-    $1->getBasicBlocks().push_back($2);
-    $$ = $1;
+    ($$ = $1)->getBasicBlocks().push_back($2);
   }
   | MethodHeader BasicBlock { // Do not allow methods with 0 basic blocks   
-    $$ = $1;                  // in them...
-    $1->getBasicBlocks().push_back($2);
+    ($$ = $1)->getBasicBlocks().push_back($2);
   }
 
 
 // Basic blocks are terminated by branching instructions: 
 // br, br/cc, switch, ret
 //
-BasicBlock : InstructionList BBTerminatorInst  {
-    $1->getInstList().push_back($2);
+BasicBlock : InstructionList OptAssign BBTerminatorInst  {
+    if (setValueName($3, $2)) { assert(0 && "No redefn allowed!"); }
+    InsertValue($3);
+
+    $1->getInstList().push_back($3);
     InsertValue($1);
     $$ = $1;
   }
-  | LABELSTR InstructionList BBTerminatorInst  {
-    $2->getInstList().push_back($3);
-    setValueName($2, $1);
+  | LABELSTR InstructionList OptAssign BBTerminatorInst  {
+    if (setValueName($4, $3)) { assert(0 && "No redefn allowed!"); }
+    InsertValue($4);
+
+    $2->getInstList().push_back($4);
+    if (setValueName($2, $1)) { assert(0 && "No label redef allowed!"); }
 
     InsertValue($2);
     $$ = $2;
@@ -1191,10 +1350,65 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     for (; I != end; ++I)
       S->dest_push_back(I->first, I->second);
   }
+  | INVOKE TypesV ValueRef '(' ValueRefListE ')' TO ResolvedVal 
+    EXCEPT ResolvedVal {
+    const PointerType *PMTy;
+    const MethodType *Ty;
+
+    if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
+        !(Ty = dyn_cast<MethodType>(PMTy->getValueType()))) {
+      // Pull out the types of all of the arguments...
+      vector<const Type*> ParamTypes;
+      if ($5) {
+        for (vector<Value*>::iterator I = $5->begin(), E = $5->end(); I!=E; ++I)
+          ParamTypes.push_back((*I)->getType());
+      }
+
+      bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+      if (isVarArg) ParamTypes.pop_back();
+
+      Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
+      PMTy = PointerType::get(Ty);
+    }
+    delete $2;
+
+    Value *V = getVal(PMTy, $3);   // Get the method we're calling...
+
+    BasicBlock *Normal = dyn_cast<BasicBlock>($8);
+    BasicBlock *Except = dyn_cast<BasicBlock>($10);
+
+    if (Normal == 0 || Except == 0)
+      ThrowException("Invoke instruction without label destinations!");
+
+    // Create the call node...
+    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
+      // correctly!
+      //
+      MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
+      MethodType::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() + "'!");
+
+      if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
+       ThrowException("Invalid number of parameters detected!");
+
+      $$ = new InvokeInst(V, Normal, Except, *$5);
+    }
+    delete $5;
+  }
+
+
 
 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     $$ = $1;
-    ConstPoolVal *V = cast<ConstPoolVal>(getVal($2, $3, true));
+    ConstPoolVal *V = cast<ConstPoolVal>(getValNonImprovising($2, $3));
     if (V == 0)
       ThrowException("May only switch on a constant pool value!");
 
@@ -1202,7 +1416,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
   }
   | IntType ConstValueRef ',' LABEL ValueRef {
     $$ = new list<pair<ConstPoolVal*, BasicBlock*> >();
-    ConstPoolVal *V = cast<ConstPoolVal>(getVal($1, $2, true));
+    ConstPoolVal *V = cast<ConstPoolVal>(getValNonImprovising($1, $2));
 
     if (V == 0)
       ThrowException("May only switch on a constant pool value!");
@@ -1211,8 +1425,8 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
   }
 
 Inst : OptAssign InstVal {
-  setValueName($2, $1);  // Is this definition named?? if so, assign the name...
-
+  // Is this definition named?? if so, assign the name...
+  if (setValueName($2, $1)) { assert(0 && "No redefin allowed!"); }
   InsertValue($2);
   $$ = $2;
 }
@@ -1231,7 +1445,7 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
 
 
 ValueRefList : ResolvedVal {    // Used for call statements, and memory insts...
-    $$ = new list<Value*>();
+    $$ = new vector<Value*>();
     $$->push_back($1);
   }
   | ValueRefList ',' ResolvedVal {
@@ -1274,29 +1488,38 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
     delete $2;  // Free the list...
   } 
   | CALL TypesV ValueRef '(' ValueRefListE ')' {
+    const PointerType *PMTy;
     const MethodType *Ty;
 
-    if (!(Ty = dyn_cast<MethodType>($2->get()))) {
+    if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
+        !(Ty = dyn_cast<MethodType>(PMTy->getValueType()))) {
       // Pull out the types of all of the arguments...
       vector<const Type*> ParamTypes;
-      for (list<Value*>::iterator I = $5->begin(), E = $5->end(); I != E; ++I)
-       ParamTypes.push_back((*I)->getType());
-      Ty = MethodType::get(*$2, ParamTypes);
+      if ($5) {
+        for (vector<Value*>::iterator I = $5->begin(), E = $5->end(); I!=E; ++I)
+          ParamTypes.push_back((*I)->getType());
+      }
+
+      bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
+      if (isVarArg) ParamTypes.pop_back();
+
+      Ty = MethodType::get($2->get(), ParamTypes, isVarArg);
+      PMTy = PointerType::get(Ty);
     }
     delete $2;
 
-    Value *V = getVal(Ty, $3);   // Get the method we're calling...
+    Value *V = getVal(PMTy, $3);   // Get the method we're calling...
 
     // Create the call node...
     if (!$5) {                                   // Has no arguments?
-      $$ = new CallInst(cast<Method>(V), vector<Value*>());
+      $$ = new CallInst(V, vector<Value*>());
     } else {                                     // Has arguments?
       // Loop through MethodType's arguments and ensure they are specified
       // correctly!
       //
       MethodType::ParamTypes::const_iterator I = Ty->getParamTypes().begin();
       MethodType::ParamTypes::const_iterator E = Ty->getParamTypes().end();
-      list<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
+      vector<Value*>::iterator ArgI = $5->begin(), ArgE = $5->end();
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I)
        if ((*ArgI)->getType() != *I)
@@ -1306,8 +1529,7 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
       if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
        ThrowException("Invalid number of parameters detected!");
 
-      $$ = new CallInst(cast<Method>(V),
-                       vector<Value*>($5->begin(), $5->end()));
+      $$ = new CallInst(V, *$5);
     }
     delete $5;
   }
@@ -1315,11 +1537,12 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
     $$ = $1;
   }
 
-// UByteList - List of ubyte values for load and store instructions
-UByteList : ',' ConstVector { 
+
+// IndexList - List of indices for GEP based instructions...
+IndexList : ',' ValueRefList { 
   $$ = $2; 
 } | /* empty */ { 
-  $$ = new vector<ConstPoolVal*>(); 
+  $$ = new vector<Value*>(); 
 }
 
 MemoryInst : MALLOC Types {
@@ -1354,9 +1577,10 @@ MemoryInst : MALLOC Types {
     $$ = new FreeInst($2);
   }
 
-  | LOAD Types ValueRef UByteList {
+  | LOAD Types ValueRef IndexList {
     if (!(*$2)->isPointerType())
-      ThrowException("Can't load from nonpointer type: " + (*$2)->getName());
+      ThrowException("Can't load from nonpointer type: " +
+                    (*$2)->getDescription());
     if (LoadInst::getIndexedType(*$2, *$4) == 0)
       ThrowException("Invalid indices for load instruction!");
 
@@ -1364,7 +1588,7 @@ MemoryInst : MALLOC Types {
     delete $4;   // Free the vector...
     delete $2;
   }
-  | STORE ResolvedVal ',' Types ValueRef UByteList {
+  | 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);
@@ -1376,7 +1600,7 @@ MemoryInst : MALLOC Types {
     $$ = new StoreInst($2, getVal(*$4, $5), *$6);
     delete $4; delete $6;
   }
-  | GETELEMENTPTR Types ValueRef UByteList {
+  | GETELEMENTPTR Types ValueRef IndexList {
     if (!(*$2)->isPointerType())
       ThrowException("getelementptr insn requires pointer operand!");
     if (!GetElementPtrInst::getIndexedType(*$2, *$4, true))