Implement the "thread_local" keyword.
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y.cvs
index e4a1eacb0198c1069511f5f53a1af5c3f90fd821..9aa81ea8dcc6c8e6ce5247b9bf56f80a13e80874 100644 (file)
@@ -84,13 +84,12 @@ static GlobalVariable *CurGV;
 typedef std::vector<Value *> ValueList;           // Numbered defs
 
 static void 
-ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers,
-                   std::map<const Type *,ValueList> *FutureLateResolvers = 0);
+ResolveDefinitions(ValueList &LateResolvers, ValueList *FutureLateResolvers=0);
 
 static struct PerModuleInfo {
   Module *CurrentModule;
-  std::map<const Type *, ValueList> Values; // Module level numbered definitions
-  std::map<const Type *,ValueList> LateResolveValues;
+  ValueList Values; // Module level numbered definitions
+  ValueList LateResolveValues;
   std::vector<PATypeHolder>    Types;
   std::map<ValID, PATypeHolder> LateResolveTypes;
 
@@ -201,24 +200,21 @@ static struct PerModuleInfo {
     }
     return false;
   }
-
-
 } CurModule;
 
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::map<const Type*, ValueList> Values; // Keep track of #'d definitions
-  std::map<const Type*, ValueList> LateResolveValues;
+  ValueList Values; // Keep track of #'d definitions
+  unsigned NextValNum;
+  ValueList LateResolveValues;
   bool isDeclare;                   // Is this function a forward declararation?
   GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
   GlobalValue::VisibilityTypes Visibility;
 
   /// BBForwardRefs - When we see forward references to basic blocks, keep
   /// track of them here.
-  std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs;
-  std::vector<BasicBlock*> NumberedBlocks;
-  unsigned NextBBNum;
+  std::map<ValID, BasicBlock*> BBForwardRefs;
 
   inline PerFunctionInfo() {
     CurrentFunction = 0;
@@ -229,16 +225,14 @@ static struct PerFunctionInfo {
 
   inline void FunctionStart(Function *M) {
     CurrentFunction = M;
-    NextBBNum = 0;
+    NextValNum = 0;
   }
 
   void FunctionDone() {
-    NumberedBlocks.clear();
-
     // Any forward referenced blocks left?
     if (!BBForwardRefs.empty()) {
       GenerateError("Undefined reference to label " +
-                     BBForwardRefs.begin()->first->getName());
+                     BBForwardRefs.begin()->second->getName());
       return;
     }
 
@@ -246,6 +240,7 @@ static struct PerFunctionInfo {
     ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
 
     Values.clear();         // Clear out function local definitions
+    BBForwardRefs.clear();
     CurrentFunction = 0;
     isDeclare = false;
     Linkage = GlobalValue::ExternalLinkage;
@@ -260,14 +255,23 @@ static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
 //               Code to handle definitions of all the types
 //===----------------------------------------------------------------------===//
 
-static int InsertValue(Value *V,
-                  std::map<const Type*,ValueList> &ValueTab = CurFun.Values) {
-  if (V->hasName()) return -1;           // Is this a numbered definition?
+static void InsertValue(Value *V, ValueList &ValueTab = CurFun.Values) {
+  // Things that have names or are void typed don't get slot numbers
+  if (V->hasName() || (V->getType() == Type::VoidTy))
+    return;
 
-  // Yes, insert the value into the value table...
-  ValueList &List = ValueTab[V->getType()];
-  List.push_back(V);
-  return List.size()-1;
+  // In the case of function values, we have to allow for the forward reference
+  // of basic blocks, which are included in the numbering. Consequently, we keep
+  // track of the next insertion location with NextValNum. When a BB gets 
+  // inserted, it could change the size of the CurFun.Values vector.
+  if (&ValueTab == &CurFun.Values) {
+    if (ValueTab.size() <= CurFun.NextValNum)
+      ValueTab.resize(CurFun.NextValNum+1);
+    ValueTab[CurFun.NextValNum++] = V;
+    return;
+  } 
+  // For all other lists, its okay to just tack it on the back of the vector.
+  ValueTab.push_back(V);
 }
 
 static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
@@ -314,11 +318,11 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   return Typ;
  }
 
-// getValNonImprovising - Look up the value specified by the provided type and
+// getExistingVal - 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) {
+static Value *getExistingVal(const Type *Ty, const ValID &D) {
   if (isa<FunctionType>(Ty)) {
     GenerateError("Functions are not values and "
                    "must be referenced as pointers");
@@ -327,26 +331,29 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
 
   switch (D.Type) {
   case ValID::LocalID: {                 // Is it a numbered definition?
-    // Module constants occupy the lowest numbered slots.
-    std::map<const Type*,ValueList>::iterator VI = CurFun.Values.find(Ty);
-    // Make sure that our type is within bounds.
-    if (VI == CurFun.Values.end()) return 0;
-
     // Check that the number is within bounds.
-    if (D.Num >= VI->second.size()) return 0;
-
-    return VI->second[D.Num];
+    if (D.Num >= CurFun.Values.size()) 
+      return 0;
+    Value *Result = CurFun.Values[D.Num];
+    if (Ty != Result->getType()) {
+      GenerateError("Numbered value (%" + utostr(D.Num) + ") of type '" +
+                    Result->getType()->getDescription() + "' does not match " 
+                    "expected type, '" + Ty->getDescription() + "'");
+      return 0;
+    }
+    return Result;
   }
   case ValID::GlobalID: {                 // Is it a numbered definition?
-    unsigned Num = D.Num;
-    
-    // Module constants occupy the lowest numbered slots...
-    std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty);
-    if (VI == CurModule.Values.end()) 
+    if (D.Num >= CurModule.Values.size()) 
       return 0;
-    if (D.Num >= VI->second.size()) 
+    Value *Result = CurModule.Values[D.Num];
+    if (Ty != Result->getType()) {
+      GenerateError("Numbered value (@" + utostr(D.Num) + ") of type '" +
+                    Result->getType()->getDescription() + "' does not match " 
+                    "expected type, '" + Ty->getDescription() + "'");
       return 0;
-    return VI->second[Num];
+    }
+    return Result;
   }
     
   case ValID::LocalName: {                // Is it a named definition?
@@ -383,7 +390,7 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
                      Ty->getDescription() + "'");
       return 0;
     }
-    return ConstantInt::get(Ty, D.ConstPool64);
+    return ConstantInt::get(Ty, D.ConstPool64, true);
 
   case ValID::ConstUIntVal:     // Is it an unsigned const pool reference?
     if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
@@ -392,7 +399,7 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
                        "' is invalid or out of range");
         return 0;
       } else {     // This is really a signed reference.  Transmogrify.
-        return ConstantInt::get(Ty, D.ConstPool64);
+        return ConstantInt::get(Ty, D.ConstPool64, true);
       }
     } else {
       return ConstantInt::get(Ty, D.UConstPool64);
@@ -447,7 +454,7 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
   return 0;
 }
 
-// getVal - This function is identical to getValNonImprovising, except that if a
+// getVal - This function is identical to getExistingVal, 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
@@ -460,7 +467,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   }
 
   // See if the value has already been defined.
-  Value *V = getValNonImprovising(Ty, ID);
+  Value *V = getExistingVal(Ty, ID);
   if (V) return V;
   if (TriggerError) return 0;
 
@@ -487,69 +494,104 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   return V;
 }
 
-/// getBBVal - This is used for two purposes:
-///  * If isDefinition is true, a new basic block with the specified ID is being
-///    defined.
-///  * If isDefinition is true, this is a reference to a basic block, which may
-///    or may not be a forward reference.
-///
-static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
+/// defineBBVal - This is a definition of a new basic block with the specified
+/// identifier which must be the same as CurFun.NextValNum, if its numeric.
+static BasicBlock *defineBBVal(const ValID &ID) {
   assert(inFunctionScope() && "Can't get basic block at global scope!");
 
-  std::string Name;
   BasicBlock *BB = 0;
-  switch (ID.Type) {
-  default: 
-    GenerateError("Illegal label reference " + ID.getName());
-    return 0;
-  case ValID::LocalID:                // Is it a numbered definition?
-    if (ID.Num >= CurFun.NumberedBlocks.size())
-      CurFun.NumberedBlocks.resize(ID.Num+1);
-    BB = CurFun.NumberedBlocks[ID.Num];
-    break;
-  case ValID::LocalName:                  // Is it a named definition?
-    Name = ID.Name;
-    Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name);
-    if (N && N->getType()->getTypeID() == Type::LabelTyID)
-      BB = cast<BasicBlock>(N);
-    break;
-  }
 
-  // See if the block has already been defined.
-  if (BB) {
-    // If this is the definition of the block, make sure the existing value was
-    // just a forward reference.  If it was a forward reference, there will be
-    // an entry for it in the PlaceHolderInfo map.
-    if (isDefinition && !CurFun.BBForwardRefs.erase(BB)) {
-      // The existing value was a definition, not a forward reference.
-      GenerateError("Redefinition of label " + ID.getName());
-      return 0;
+  // First, see if this was forward referenced
+
+  std::map<ValID, BasicBlock*>::iterator BBI = CurFun.BBForwardRefs.find(ID);
+  if (BBI != CurFun.BBForwardRefs.end()) {
+    BB = BBI->second;
+    // The forward declaration could have been inserted anywhere in the
+    // function: insert it into the correct place now.
+    CurFun.CurrentFunction->getBasicBlockList().remove(BB);
+    CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
+
+    // We're about to erase the entry, save the key so we can clean it up.
+    ValID Tmp = BBI->first;
+
+    // Erase the forward ref from the map as its no longer "forward"
+    CurFun.BBForwardRefs.erase(ID);
+
+    // The key has been removed from the map but so we don't want to leave 
+    // strdup'd memory around so destroy it too.
+    Tmp.destroy();
+
+    // If its a numbered definition, bump the number and set the BB value.
+    if (ID.Type == ValID::LocalID) {
+      assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
+      InsertValue(BB);
     }
 
-    ID.destroy();                       // Free strdup'd memory.
+    ID.destroy();
     return BB;
+  } 
+  
+  // We haven't seen this BB before and its first mention is a definition. 
+  // Just create it and return it.
+  std::string Name (ID.Type == ValID::LocalName ? ID.Name : "");
+  BB = new BasicBlock(Name, CurFun.CurrentFunction);
+  if (ID.Type == ValID::LocalID) {
+    assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
+    InsertValue(BB);
   }
 
-  // Otherwise this block has not been seen before.
-  BB = new BasicBlock("", CurFun.CurrentFunction);
-  if (ID.Type == ValID::LocalName) {
-    BB->setName(ID.Name);
+  ID.destroy(); // Free strdup'd memory
+  return BB;
+}
+
+/// getBBVal - get an existing BB value or create a forward reference for it.
+/// 
+static BasicBlock *getBBVal(const ValID &ID) {
+  assert(inFunctionScope() && "Can't get basic block at global scope!");
+
+  BasicBlock *BB =  0;
+
+  std::map<ValID, BasicBlock*>::iterator BBI = CurFun.BBForwardRefs.find(ID);
+  if (BBI != CurFun.BBForwardRefs.end()) {
+    BB = BBI->second;
+  } if (ID.Type == ValID::LocalName) {
+    std::string Name = ID.Name;
+    Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name);
+    if (N)
+      if (N->getType()->getTypeID() == Type::LabelTyID)
+        BB = cast<BasicBlock>(N);
+      else
+        GenerateError("Reference to label '" + Name + "' is actually of type '"+
+          N->getType()->getDescription() + "'");
+  } else if (ID.Type == ValID::LocalID) {
+    if (ID.Num < CurFun.NextValNum && ID.Num < CurFun.Values.size()) {
+      if (CurFun.Values[ID.Num]->getType()->getTypeID() == Type::LabelTyID)
+        BB = cast<BasicBlock>(CurFun.Values[ID.Num]);
+      else
+        GenerateError("Reference to label '%" + utostr(ID.Num) + 
+          "' is actually of type '"+ 
+          CurFun.Values[ID.Num]->getType()->getDescription() + "'");
+    }
   } else {
-    CurFun.NumberedBlocks[ID.Num] = BB;
+    GenerateError("Illegal label reference " + ID.getName());
+    return 0;
   }
 
-  // If this is not a definition, keep track of it so we can use it as a forward
-  // reference.
-  if (!isDefinition) {
-    // Remember where this forward reference came from.
-    CurFun.BBForwardRefs[BB] = std::make_pair(ID, llvmAsmlineno);
-  } else {
-    // The forward declaration could have been inserted anywhere in the
-    // function: insert it into the correct place now.
-    CurFun.CurrentFunction->getBasicBlockList().remove(BB);
-    CurFun.CurrentFunction->getBasicBlockList().push_back(BB);
+  // If its already been defined, return it now.
+  if (BB) {
+    ID.destroy(); // Free strdup'd memory.
+    return BB;
   }
-  ID.destroy();
+
+  // Otherwise, this block has not been seen before, create it.
+  std::string Name;
+  if (ID.Type == ValID::LocalName)
+    Name = ID.Name;
+  BB = new BasicBlock(Name, CurFun.CurrentFunction);
+
+  // Insert it in the forward refs map.
+  CurFun.BBForwardRefs[ID] = BB;
+
   return BB;
 }
 
@@ -571,50 +613,44 @@ static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) {
 // defs now...
 //
 static void 
-ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers,
-                   std::map<const Type*,ValueList> *FutureLateResolvers) {
+ResolveDefinitions(ValueList &LateResolvers, ValueList *FutureLateResolvers) {
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
-  for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(),
-         E = LateResolvers.end(); LRI != E; ++LRI) {
-    ValueList &List = LRI->second;
-    while (!List.empty()) {
-      Value *V = List.back();
-      List.pop_back();
+  while (!LateResolvers.empty()) {
+    Value *V = LateResolvers.back();
+    LateResolvers.pop_back();
 
-      std::map<Value*, std::pair<ValID, int> >::iterator PHI =
-        CurModule.PlaceHolderInfo.find(V);
-      assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!");
+    std::map<Value*, std::pair<ValID, int> >::iterator PHI =
+      CurModule.PlaceHolderInfo.find(V);
+    assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!");
 
-      ValID &DID = PHI->second.first;
+    ValID &DID = PHI->second.first;
 
-      Value *TheRealValue = getValNonImprovising(LRI->first, DID);
-      if (TriggerError)
+    Value *TheRealValue = getExistingVal(V->getType(), DID);
+    if (TriggerError)
+      return;
+    if (TheRealValue) {
+      V->replaceAllUsesWith(TheRealValue);
+      delete V;
+      CurModule.PlaceHolderInfo.erase(PHI);
+    } else if (FutureLateResolvers) {
+      // Functions have their unresolved items forwarded to the module late
+      // resolver table
+      InsertValue(V, *FutureLateResolvers);
+    } else {
+      if (DID.Type == ValID::LocalName || DID.Type == ValID::GlobalName) {
+        GenerateError("Reference to an invalid definition: '" +DID.getName()+
+                       "' of type '" + V->getType()->getDescription() + "'",
+                       PHI->second.second);
         return;
-      if (TheRealValue) {
-        V->replaceAllUsesWith(TheRealValue);
-        delete V;
-        CurModule.PlaceHolderInfo.erase(PHI);
-      } else if (FutureLateResolvers) {
-        // Functions have their unresolved items forwarded to the module late
-        // resolver table
-        InsertValue(V, *FutureLateResolvers);
       } else {
-        if (DID.Type == ValID::LocalName || DID.Type == ValID::GlobalName) {
-          GenerateError("Reference to an invalid definition: '" +DID.getName()+
-                         "' of type '" + V->getType()->getDescription() + "'",
-                         PHI->second.second);
-          return;
-        } else {
-          GenerateError("Reference to an invalid definition: #" +
-                         itostr(DID.Num) + " of type '" +
-                         V->getType()->getDescription() + "'",
-                         PHI->second.second);
-          return;
-        }
+        GenerateError("Reference to an invalid definition: #" +
+                       itostr(DID.Num) + " of type '" +
+                       V->getType()->getDescription() + "'",
+                       PHI->second.second);
+        return;
       }
     }
   }
-
   LateResolvers.clear();
 }
 
@@ -668,7 +704,7 @@ ParseGlobalVariable(char *NameStr,
                     GlobalValue::LinkageTypes Linkage,
                     GlobalValue::VisibilityTypes Visibility,
                     bool isConstantGlobal, const Type *Ty,
-                    Constant *Initializer) {
+                    Constant *Initializer, bool IsThreadLocal) {
   if (isa<FunctionType>(Ty)) {
     GenerateError("Cannot declare global vars of function type");
     return 0;
@@ -688,7 +724,7 @@ ParseGlobalVariable(char *NameStr,
   if (!Name.empty()) {
     ID = ValID::createGlobalName((char*)Name.c_str());
   } else {
-    ID = ValID::createGlobalID(CurModule.Values[PTy].size());
+    ID = ValID::createGlobalID(CurModule.Values.size());
   }
 
   if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
@@ -701,6 +737,7 @@ ParseGlobalVariable(char *NameStr,
     GV->setLinkage(Linkage);
     GV->setVisibility(Visibility);
     GV->setConstant(isConstantGlobal);
+    GV->setThreadLocal(IsThreadLocal);
     InsertValue(GV, CurModule.Values);
     return GV;
   }
@@ -725,7 +762,7 @@ ParseGlobalVariable(char *NameStr,
   // Otherwise there is no existing GV to use, create one now.
   GlobalVariable *GV =
     new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
-                       CurModule.CurrentModule);
+                       CurModule.CurrentModule, IsThreadLocal);
   GV->setVisibility(Visibility);
   InsertValue(GV, CurModule.Values);
   return GV;
@@ -924,7 +961,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 
   llvm::GlobalValue::LinkageTypes         Linkage;
   llvm::GlobalValue::VisibilityTypes      Visibility;
-  llvm::FunctionType::ParameterAttributes ParamAttrs;
+  uint16_t                          ParamAttrs;
+  llvm::APInt                       *APIntVal;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
   int                               SIntVal;
@@ -960,6 +998,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %type <TypeWithAttrs> ArgType
 %type <JumpTable>     JumpTable
 %type <BoolVal>       GlobalType                  // GLOBAL or CONSTANT?
+%type <BoolVal>       ThreadLocal                 // 'thread_local' or not
 %type <BoolVal>       OptVolatile                 // 'volatile' or not
 %type <BoolVal>       OptTailCall                 // TAIL CALL or plain CALL.
 %type <BoolVal>       OptSideEffect               // 'sideeffect' or not.
@@ -978,6 +1017,12 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 // EUINT64VAL - A positive number within uns. long long range
 %token <UInt64Val> EUINT64VAL
 
+// ESAPINTVAL - A negative number with arbitrary precision 
+%token <APIntVal>  ESAPINTVAL
+
+// EUAPINTVAL - A positive number with arbitrary precision 
+%token <APIntVal>  EUAPINTVAL
+
 %token  <UIntVal>   LOCALVAL_ID GLOBALVAL_ID  // %123 @123
 %token  <FPVal>     FPVAL     // Float or Double constant
 
@@ -994,8 +1039,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %type <UIntVal> OptAlign OptCAlign
 %type <StrVal> OptSection SectionString
 
-%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
-%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE
+%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
+%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE THREAD_LOCAL
 %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
 %token DLLIMPORT DLLEXPORT EXTERN_WEAK
 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
@@ -1033,7 +1078,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
 
 // Function Attributes
-%token NORETURN INREG SRET
+%token NORETURN INREG SRET NOUNWIND
 
 // Visibility Styles
 %token DEFAULT HIDDEN
@@ -1146,25 +1191,26 @@ OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                   CHECK_FOR_ERROR
                  };
 
-ParamAttr     : ZEXT  { $$ = FunctionType::ZExtAttribute;      }
-              | SEXT  { $$ = FunctionType::SExtAttribute;      }
-              | INREG { $$ = FunctionType::InRegAttribute;     }
-              | SRET  { $$ = FunctionType::StructRetAttribute; }
+ParamAttr     : ZEXT  { $$ = ParamAttr::ZExt;      }
+              | SEXT  { $$ = ParamAttr::SExt;      }
+              | INREG { $$ = ParamAttr::InReg;     }
+              | SRET  { $$ = ParamAttr::StructRet; }
               ;
 
-OptParamAttrs : /* empty */  { $$ = FunctionType::NoAttributeSet; }
+OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
               | OptParamAttrs ParamAttr {
-                $$ = FunctionType::ParameterAttributes($1 | $2);
+                $$ = $1 | $2;
               }
               ;
 
-FuncAttr      : NORETURN { $$ = FunctionType::NoReturnAttribute; }
+FuncAttr      : NORETURN { $$ = ParamAttr::NoReturn; }
+              | NOUNWIND { $$ = ParamAttr::NoUnwind; }
               | ParamAttr
               ;
 
-OptFuncAttrs  : /* empty */ { $$ = FunctionType::NoAttributeSet; }
+OptFuncAttrs  : /* empty */ { $$ = ParamAttr::None; }
               | OptFuncAttrs FuncAttr {
-                $$ = FunctionType::ParameterAttributes($1 | $2);
+                $$ = $1 | $2;
               }
               ;
 
@@ -1253,17 +1299,25 @@ Types
   }
   | Types '(' ArgTypeListI ')' OptFuncAttrs {
     std::vector<const Type*> Params;
-    std::vector<FunctionType::ParameterAttributes> Attrs;
-    Attrs.push_back($5);
-    for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) {
-      Params.push_back(I->Ty->get());
-      if (I->Ty->get() != Type::VoidTy)
-        Attrs.push_back(I->Attrs);
+    ParamAttrsList Attrs;
+    if ($5 != ParamAttr::None)
+      Attrs.addAttributes(0, $5);
+    unsigned index = 1;
+    TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
+    for (; I != E; ++I, ++index) {
+      const Type *Ty = I->Ty->get();
+      Params.push_back(Ty);
+      if (Ty != Type::VoidTy)
+        if (I->Attrs != ParamAttr::None)
+          Attrs.addAttributes(index, I->Attrs);
     }
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, Attrs);
+    ParamAttrsList *ActualAttrs = 0;
+    if (!Attrs.empty())
+      ActualAttrs = new ParamAttrsList(Attrs);
+    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
     delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
@@ -1271,17 +1325,26 @@ Types
   }
   | VOID '(' ArgTypeListI ')' OptFuncAttrs {
     std::vector<const Type*> Params;
-    std::vector<FunctionType::ParameterAttributes> Attrs;
-    Attrs.push_back($5);
-    for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) {
-      Params.push_back(I->Ty->get());
-      if (I->Ty->get() != Type::VoidTy)
-        Attrs.push_back(I->Attrs);
+    ParamAttrsList Attrs;
+    if ($5 != ParamAttr::None)
+      Attrs.addAttributes(0, $5);
+    TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
+    unsigned index = 1;
+    for ( ; I != E; ++I, ++index) {
+      const Type* Ty = I->Ty->get();
+      Params.push_back(Ty);
+      if (Ty != Type::VoidTy)
+        if (I->Attrs != ParamAttr::None)
+          Attrs.addAttributes(index, I->Attrs);
     }
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    FunctionType *FT = FunctionType::get($1, Params, isVarArg, Attrs);
+    ParamAttrsList *ActualAttrs = 0;
+    if (!Attrs.empty())
+      ActualAttrs = new ParamAttrsList(Attrs);
+
+    FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
     delete $3;      // Delete the argument list
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     CHECK_FOR_ERROR
@@ -1292,15 +1355,15 @@ Types
     delete $4;
     CHECK_FOR_ERROR
   }
-  | '<' EUINT64VAL 'x' Types '>' {          // Packed array type?
+  | '<' EUINT64VAL 'x' Types '>' {          // Vector type?
      const llvm::Type* ElemTy = $4->get();
      if ((unsigned)$2 != $2)
         GEN_ERROR("Unsigned result not equal to signed result");
      if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger())
-        GEN_ERROR("Element type of a PackedType must be primitive");
+        GEN_ERROR("Element type of a VectorType must be primitive");
      if (!isPowerOf2_32($2))
        GEN_ERROR("Vector length should be a power of 2");
-     $$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2)));
+     $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4, (unsigned)$2)));
      delete $4;
      CHECK_FOR_ERROR
   }
@@ -1369,14 +1432,14 @@ ArgTypeListI
   : ArgTypeList
   | ArgTypeList ',' DOTDOTDOT {
     $$=$1;
-    TypeWithAttrs TWA; TWA.Attrs = FunctionType::NoAttributeSet;
+    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
   }
   | DOTDOTDOT {
     $$ = new TypeWithAttrsList;
-    TypeWithAttrs TWA; TWA.Attrs = FunctionType::NoAttributeSet;
+    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
@@ -1391,11 +1454,13 @@ ArgTypeListI
 //
 TypeListI : Types {
     $$ = new std::list<PATypeHolder>();
-    $$->push_back(*$1); delete $1;
+    $$->push_back(*$1); 
+    delete $1;
     CHECK_FOR_ERROR
   }
   | TypeListI ',' Types {
-    ($$=$1)->push_back(*$3); delete $3;
+    ($$=$1)->push_back(*$3); 
+    delete $3;
     CHECK_FOR_ERROR
   };
 
@@ -1481,7 +1546,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
   | Types '<' ConstVector '>' { // Nonempty unsized arr
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
-    const PackedType *PTy = dyn_cast<PackedType>($1->get());
+    const VectorType *PTy = dyn_cast<VectorType>($1->get());
     if (PTy == 0)
       GEN_ERROR("Cannot make packed constant with type: '" + 
                      (*$1)->getDescription() + "'");
@@ -1502,7 +1567,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
            (*$3)[i]->getType()->getDescription() + "'.");
     }
 
-    $$ = ConstantPacked::get(PTy, *$3);
+    $$ = ConstantVector::get(PTy, *$3);
     delete $1; delete $3;
     CHECK_FOR_ERROR
   }
@@ -1525,7 +1590,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is not packed
     if (STy->isPacked())
-      GEN_ERROR("Unpacked Initializer to packed type '" + STy->getDescription() + "'");
+      GEN_ERROR("Unpacked Initializer to vector type '" + STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, *$3);
     delete $1; delete $3;
@@ -1544,7 +1609,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is not packed
     if (STy->isPacked())
-      GEN_ERROR("Unpacked Initializer to packed type '" + STy->getDescription() + "'");
+      GEN_ERROR("Unpacked Initializer to vector type '" + STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, std::vector<Constant*>());
     delete $1;
@@ -1569,7 +1634,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is packed
     if (!STy->isPacked())
-      GEN_ERROR("Packed Initializer to unpacked type '" + STy->getDescription() + "'");
+      GEN_ERROR("Vector initializer to non-vector type '" + 
+                STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, *$4);
     delete $1; delete $4;
@@ -1588,7 +1654,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is packed
     if (!STy->isPacked())
-      GEN_ERROR("Packed Initializer to unpacked type '" + STy->getDescription() + "'");
+      GEN_ERROR("Vector initializer to non-vector type '" + 
+                STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, std::vector<Constant*>());
     delete $1;
@@ -1622,15 +1689,15 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // ConstExprs can exist in the body of a function, thus creating
     // GlobalValues whenever they refer to a variable.  Because we are in
-    // the context of a function, getValNonImprovising will search the functions
+    // the context of a function, getExistingVal 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.
+    // getExistingVal that we are at global scope here.
     //
     Function *SavedCurFn = CurFun.CurrentFunction;
     CurFun.CurrentFunction = 0;
 
-    Value *V = getValNonImprovising(Ty, $2);
+    Value *V = getExistingVal(Ty, $2);
     CHECK_FOR_ERROR
 
     CurFun.CurrentFunction = SavedCurFn;
@@ -1702,13 +1769,33 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
   | IntType ESINT64VAL {      // integral constants
     if (!ConstantInt::isValueValidForType($1, $2))
       GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2);
+    $$ = ConstantInt::get($1, $2, true);
+    CHECK_FOR_ERROR
+  }
+  | IntType ESAPINTVAL {      // arbitrary precision integer constants
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    if ($2->getBitWidth() > BitWidth) {
+      GEN_ERROR("Constant value does not fit in type");
+    }
+    $2->sextOrTrunc(BitWidth);
+    $$ = ConstantInt::get(*$2);
+    delete $2;
     CHECK_FOR_ERROR
   }
   | IntType EUINT64VAL {      // integral constants
     if (!ConstantInt::isValueValidForType($1, $2))
       GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2);
+    $$ = ConstantInt::get($1, $2, false);
+    CHECK_FOR_ERROR
+  }
+  | IntType EUAPINTVAL {      // arbitrary precision integer constants
+    uint32_t BitWidth = cast<IntegerType>($1)->getBitWidth();
+    if ($2->getBitWidth() > BitWidth) {
+      GEN_ERROR("Constant value does not fit in type");
+    } 
+    $2->zextOrTrunc(BitWidth);
+    $$ = ConstantInt::get(*$2);
+    delete $2;
     CHECK_FOR_ERROR
   }
   | INTTYPE TRUETOK {                      // Boolean constants
@@ -1781,8 +1868,8 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
     if ($3->getType() != $5->getType())
       GEN_ERROR("Logical operator types must match");
     if (!$3->getType()->isInteger()) {
-      if (Instruction::isShift($1) || !isa<PackedType>($3->getType()) || 
-          !cast<PackedType>($3->getType())->getElementType()->isInteger())
+      if (Instruction::isShift($1) || !isa<VectorType>($3->getType()) || 
+          !cast<VectorType>($3->getType())->getElementType()->isInteger())
         GEN_ERROR("Logical operator requires integral operands");
     }
     $$ = ConstantExpr::get($1, $3, $5);
@@ -1833,6 +1920,9 @@ ConstVector : ConstVector ',' ConstVal {
 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
 GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
 
+// ThreadLocal 
+ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
+
 
 //===----------------------------------------------------------------------===//
 //                             Rules to match Modules
@@ -1870,18 +1960,6 @@ Definition
   | MODULE ASM_TOK AsmBlock {
     CHECK_FOR_ERROR
   }  
-  | IMPLEMENTATION {
-    // Emit an error if there are any unresolved types left.
-    if (!CurModule.LateResolveTypes.empty()) {
-      const ValID &DID = CurModule.LateResolveTypes.begin()->first;
-      if (DID.Type == ValID::LocalName) {
-        GEN_ERROR("Reference to an undefined type: '"+DID.getName() + "'");
-      } else {
-        GEN_ERROR("Reference to an undefined type: #" + itostr(DID.Num));
-      }
-    }
-    CHECK_FOR_ERROR
-  }
   | OptLocalAssign TYPE Types {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
@@ -1917,30 +1995,30 @@ Definition
     }
     CHECK_FOR_ERROR
   }
-  | OptGlobalAssign GVVisibilityStyle GlobalType ConstVal { 
+  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal { 
     /* "Externally Visible" Linkage */
-    if ($4 == 0) 
+    if ($5 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
     CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
-                                $2, $3, $4->getType(), $4);
+                                $2, $4, $5->getType(), $5, $3);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
-  | OptGlobalAssign GVInternalLinkage GVVisibilityStyle GlobalType ConstVal {
-    if ($5 == 0) 
+  | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType ConstVal {
+    if ($6 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
-    CurGV = ParseGlobalVariable($1, $2, $3, $4, $5->getType(), $5);
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
-  | OptGlobalAssign GVExternalLinkage GVVisibilityStyle GlobalType Types {
+  | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType Types {
     if (!UpRefs.empty())
-      GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription());
-    CurGV = ParseGlobalVariable($1, $2, $3, $4, *$5, 0);
+      GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
     CHECK_FOR_ERROR
-    delete $5;
+    delete $6;
   } GlobalVarAttributes {
     CurGV = 0;
     CHECK_FOR_ERROR
@@ -2027,7 +2105,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = FunctionType::NoAttributeSet;
+    E.Attrs = ParamAttr::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2036,7 +2114,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = FunctionType::NoAttributeSet;
+    E.Attrs = ParamAttr::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2057,24 +2135,31 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
 
   std::vector<const Type*> ParamTypeList;
-  std::vector<FunctionType::ParameterAttributes> ParamAttrs;
-  ParamAttrs.push_back($7);
+  ParamAttrsList ParamAttrs;
+  if ($7 != ParamAttr::None)
+    ParamAttrs.addAttributes(0, $7);
   if ($5) {   // If there are arguments...
-    for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I) {
+    unsigned index = 1;
+    for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
       const Type* Ty = I->Ty->get();
       if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
         GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
       ParamTypeList.push_back(Ty);
       if (Ty != Type::VoidTy)
-        ParamAttrs.push_back(I->Attrs);
+        if (I->Attrs != ParamAttr::None)
+          ParamAttrs.addAttributes(index, I->Attrs);
     }
   }
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg,
-                                       ParamAttrs);
+  ParamAttrsList *ActualAttrs = 0;
+  if (!ParamAttrs.empty())
+    ActualAttrs = new ParamAttrsList(ParamAttrs);
+
+  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, 
+                                       ActualAttrs);
   const PointerType *PFT = PointerType::get(FT);
   delete $2;
 
@@ -2082,7 +2167,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
   if (!FunctionName.empty()) {
     ID = ValID::createGlobalName((char*)FunctionName.c_str());
   } else {
-    ID = ValID::createGlobalID(CurModule.Values[PFT].size());
+    ID = ValID::createGlobalID(CurModule.Values.size());
   }
 
   Function *Fn = 0;
@@ -2232,10 +2317,10 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
     const Type *ETy = (*$2)[0]->getType();
     int NumElements = $2->size(); 
     
-    PackedType* pt = PackedType::get(ETy, NumElements);
+    VectorType* pt = VectorType::get(ETy, NumElements);
     PATypeHolder* PTy = new PATypeHolder(
                                          HandleUpRefs(
-                                            PackedType::get(
+                                            VectorType::get(
                                                 ETy, 
                                                 NumElements)
                                             )
@@ -2249,7 +2334,7 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
                      (*$2)[i]->getType()->getDescription() + "'.");
     }
 
-    $$ = ValID::create(ConstantPacked::get(pt, *$2));
+    $$ = ValID::create(ConstantVector::get(pt, *$2));
     delete PTy; delete $2;
     CHECK_FOR_ERROR
   }
@@ -2322,7 +2407,6 @@ BasicBlock : InstructionList OptLocalAssign BBTerminatorInst  {
     CHECK_FOR_ERROR
     InsertValue($3);
     $1->getInstList().push_back($3);
-    InsertValue($1);
     $$ = $1;
     CHECK_FOR_ERROR
   };
@@ -2336,28 +2420,12 @@ InstructionList : InstructionList Inst {
     $$ = $1;
     CHECK_FOR_ERROR
   }
-  | /* empty */ {
-    $$ = getBBVal(ValID::createLocalID(CurFun.NextBBNum++), true);
-    CHECK_FOR_ERROR
-
-    // Make sure to move the basic block to the correct location in the
-    // function, instead of leaving it inserted wherever it was first
-    // referenced.
-    Function::BasicBlockListType &BBL = 
-      CurFun.CurrentFunction->getBasicBlockList();
-    BBL.splice(BBL.end(), BBL, $$);
+  | /* empty */ {          // Empty space between instruction lists
+    $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum));
     CHECK_FOR_ERROR
   }
-  | LABELSTR {
-    $$ = getBBVal(ValID::createLocalName($1), true);
-    CHECK_FOR_ERROR
-
-    // Make sure to move the basic block to the correct location in the
-    // function, instead of leaving it inserted wherever it was first
-    // referenced.
-    Function::BasicBlockListType &BBL = 
-      CurFun.CurrentFunction->getBasicBlockList();
-    BBL.splice(BBL.end(), BBL, $$);
+  | LABELSTR {             // Labelled (named) basic block
+    $$ = defineBBVal(ValID::createLocalName($1));
     CHECK_FOR_ERROR
   };
 
@@ -2365,15 +2433,15 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     $$ = new ReturnInst($2);
     CHECK_FOR_ERROR
   }
-  | RET VOID {                                       // Return with no result...
+  | RET VOID {                                    // Return with no result...
     $$ = new ReturnInst();
     CHECK_FOR_ERROR
   }
-  | BR LABEL ValueRef {                         // Unconditional Branch...
+  | BR LABEL ValueRef {                           // Unconditional Branch...
     BasicBlock* tmpBB = getBBVal($3);
     CHECK_FOR_ERROR
     $$ = new BranchInst(tmpBB);
-  }                                                  // Conditional Branch...
+  }                                               // Conditional Branch...
   | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
     assert(cast<IntegerType>($2)->getBitWidth() == 1 && "Not Bool?");
     BasicBlock* tmpBBA = getBBVal($6);
@@ -2422,20 +2490,29 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      FunctionType::ParamAttrsList ParamAttrs;
-      ParamAttrs.push_back($8);
-      for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) {
+      ParamAttrsList ParamAttrs;
+      if ($8 != ParamAttr::None)
+        ParamAttrs.addAttributes(0, $8);
+      ValueRefList::iterator I = $6->begin(), E = $6->end();
+      unsigned index = 1;
+      for (; I != E; ++I, ++index) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
-        ParamAttrs.push_back(I->Attrs);
+        if (I->Attrs != ParamAttr::None)
+          ParamAttrs.addAttributes(index, I->Attrs);
       }
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs);
+      ParamAttrsList *Attrs = 0;
+      if (!ParamAttrs.empty())
+        Attrs = new ParamAttrsList(ParamAttrs);
+      Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
       PFTy = PointerType::get(Ty);
     }
 
+    delete $3;
+
     Value *V = getVal(PFTy, $4);   // Get the function we're calling...
     CHECK_FOR_ERROR
     BasicBlock *Normal = getBBVal($11);
@@ -2492,7 +2569,7 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
 
 JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     $$ = $1;
-    Constant *V = cast<Constant>(getValNonImprovising($2, $3));
+    Constant *V = cast<Constant>(getExistingVal($2, $3));
     CHECK_FOR_ERROR
     if (V == 0)
       GEN_ERROR("May only switch on a constant pool value");
@@ -2503,7 +2580,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
   }
   | IntType ConstValueRef ',' LABEL ValueRef {
     $$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
-    Constant *V = cast<Constant>(getValNonImprovising($1, $2));
+    Constant *V = cast<Constant>(getExistingVal($1, $2));
     CHECK_FOR_ERROR
 
     if (V == 0)
@@ -2552,6 +2629,7 @@ ValueRefList : Types ValueRef OptParamAttrs {
     $$ = new ValueRefList();
     ValueRefListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
     $$->push_back(E);
+    delete $1;
   }
   | ValueRefList ',' Types ValueRef OptParamAttrs {
     if (!UpRefs.empty())
@@ -2559,6 +2637,7 @@ ValueRefList : Types ValueRef OptParamAttrs {
     $$ = $1;
     ValueRefListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
     $$->push_back(E);
+    delete $3;
     CHECK_FOR_ERROR
   }
   | /*empty*/ { $$ = new ValueRefList(); };
@@ -2585,14 +2664,14 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && 
-        !isa<PackedType>((*$2).get()))
+        !isa<VectorType>((*$2).get()))
       GEN_ERROR(
         "Arithmetic operator requires integer, FP, or packed operands");
-    if (isa<PackedType>((*$2).get()) && 
+    if (isa<VectorType>((*$2).get()) && 
         ($1 == Instruction::URem || 
          $1 == Instruction::SRem ||
          $1 == Instruction::FRem))
-      GEN_ERROR("Remainder not supported on packed types");
+      GEN_ERROR("Remainder not supported on vector types");
     Value* val1 = getVal(*$2, $3); 
     CHECK_FOR_ERROR
     Value* val2 = getVal(*$2, $5);
@@ -2606,8 +2685,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!(*$2)->isInteger()) {
-      if (Instruction::isShift($1) || !isa<PackedType>($2->get()) ||
-          !cast<PackedType>($2->get())->getElementType()->isInteger())
+      if (Instruction::isShift($1) || !isa<VectorType>($2->get()) ||
+          !cast<VectorType>($2->get())->getElementType()->isInteger())
         GEN_ERROR("Logical operator requires integral operands");
     }
     Value* tmpVal1 = getVal(*$2, $3);
@@ -2622,8 +2701,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
   | ICMP IPredicates Types ValueRef ',' ValueRef  {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
-    if (isa<PackedType>((*$3).get()))
-      GEN_ERROR("Packed types not supported by icmp instruction");
+    if (isa<VectorType>((*$3).get()))
+      GEN_ERROR("Vector types not supported by icmp instruction");
     Value* tmpVal1 = getVal(*$3, $4);
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
@@ -2631,12 +2710,13 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("icmp operator returned null");
+    delete $3;
   }
   | FCMP FPredicates Types ValueRef ',' ValueRef  {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
-    if (isa<PackedType>((*$3).get()))
-      GEN_ERROR("Packed types not supported by fcmp instruction");
+    if (isa<VectorType>((*$3).get()))
+      GEN_ERROR("Vector types not supported by fcmp instruction");
     Value* tmpVal1 = getVal(*$3, $4);
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$3, $6);
@@ -2644,6 +2724,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("fcmp operator returned null");
+    delete $3;
   }
   | CastOps ResolvedVal TO Types {
     if (!UpRefs.empty())
@@ -2715,17 +2796,25 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      FunctionType::ParamAttrsList ParamAttrs;
-      ParamAttrs.push_back($8);
-      for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) {
+      ParamAttrsList ParamAttrs;
+      if ($8 != ParamAttr::None)
+        ParamAttrs.addAttributes(0, $8);
+      unsigned index = 1;
+      ValueRefList::iterator I = $6->begin(), E = $6->end();
+      for (; I != E; ++I, ++index) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
-        ParamAttrs.push_back(I->Attrs);
+        if (I->Attrs != ParamAttr::None)
+          ParamAttrs.addAttributes(index, I->Attrs);
       }
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs);
+      ParamAttrsList *Attrs = 0;
+      if (!ParamAttrs.empty())
+        Attrs = new ParamAttrsList(ParamAttrs);
+
+      Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
       PFTy = PointerType::get(Ty);
     }
 
@@ -2889,6 +2978,38 @@ static Module* RunParser(Module * M) {
     return 0;
   }
 
+  // Emit an error if there are any unresolved types left.
+  if (!CurModule.LateResolveTypes.empty()) {
+    const ValID &DID = CurModule.LateResolveTypes.begin()->first;
+    if (DID.Type == ValID::LocalName) {
+      GenerateError("Undefined type remains at eof: '"+DID.getName() + "'");
+    } else {
+      GenerateError("Undefined type remains at eof: #" + itostr(DID.Num));
+    }
+    if (ParserResult)
+      delete ParserResult;
+    return 0;
+  }
+
+  // Emit an error if there are any unresolved values left.
+  if (!CurModule.LateResolveValues.empty()) {
+    Value *V = CurModule.LateResolveValues.back();
+    std::map<Value*, std::pair<ValID, int> >::iterator I =
+      CurModule.PlaceHolderInfo.find(V);
+
+    if (I != CurModule.PlaceHolderInfo.end()) {
+      ValID &DID = I->second.first;
+      if (DID.Type == ValID::LocalName) {
+        GenerateError("Undefined value remains at eof: "+DID.getName() + "'");
+      } else {
+        GenerateError("Undefined value remains at eof: #" + itostr(DID.Num));
+      }
+      if (ParserResult)
+        delete ParserResult;
+      return 0;
+    }
+  }
+
   // Check to make sure that parsing produced a result
   if (!ParserResult)
     return 0;