Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 35dad259f6b01ef02703216a3fd5de1ae251be64..af8e3afee3f6213abce006c314634c24dbac03af 100644 (file)
 // The following is a gross hack. In order to rid the libAsmParser library of
 // exceptions, we have to have a way of getting the yyparse function to go into
 // an error situation. So, whenever we want an error to occur, the GenerateError
-// function (see bottom of file) sets TriggerError. Then, at the end of each 
-// production in the grammer we use CHECK_FOR_ERROR which will invoke YYERROR 
-// (a goto) to put YACC in error state. Furthermore, several calls to 
+// function (see bottom of file) sets TriggerError. Then, at the end of each
+// production in the grammer we use CHECK_FOR_ERROR which will invoke YYERROR
+// (a goto) to put YACC in error state. Furthermore, several calls to
 // GenerateError are made from inside productions and they must simulate the
 // previous exception behavior by exiting the production immediately. We have
 // replaced these with the GEN_ERROR macro which calls GeneratError and then
-// immediately invokes YYERROR. This would be so much cleaner if it was a 
+// immediately invokes YYERROR. This would be so much cleaner if it was a
 // recursive descent parser.
 static bool TriggerError = false;
 #define CHECK_FOR_ERROR { if (TriggerError) { TriggerError = false; YYABORT; } }
@@ -72,7 +72,7 @@ static GlobalVariable *CurGV;
 //
 typedef std::vector<Value *> ValueList;           // Numbered defs
 
-static void 
+static void
 ResolveDefinitions(ValueList &LateResolvers, ValueList *FutureLateResolvers=0);
 
 static struct PerModuleInfo {
@@ -140,6 +140,7 @@ static struct PerModuleInfo {
     GlobalValue *Ret = 0;
     if (I != GlobalRefs.end()) {
       Ret = I->second;
+      I->first.second.destroy();
       GlobalRefs.erase(I);
     }
     return Ret;
@@ -151,7 +152,7 @@ static struct PerModuleInfo {
     if (!Ty->isAbstract())
       return false;
     // Traverse the type looking for abstract types. If it isn't abstract then
-    // we don't need to traverse that leg of the type. 
+    // we don't need to traverse that leg of the type.
     std::vector<const Type*> WorkList, SeenList;
     WorkList.push_back(Ty);
     while (!WorkList.empty()) {
@@ -169,7 +170,7 @@ static struct PerModuleInfo {
       } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(Ty)) {
         const Type* TheTy = SeqTy->getElementType();
         if (TheTy->isAbstract() && TheTy != Ty) {
-          std::vector<const Type*>::iterator I = SeenList.begin(), 
+          std::vector<const Type*>::iterator I = SeenList.begin(),
                                              E = SeenList.end();
           for ( ; I != E; ++I)
             if (*I == TheTy)
@@ -181,7 +182,7 @@ static struct PerModuleInfo {
         for (unsigned i = 0; i < StrTy->getNumElements(); ++i) {
           const Type* TheTy = StrTy->getElementType(i);
           if (TheTy->isAbstract() && TheTy != Ty) {
-            std::vector<const Type*>::iterator I = SeenList.begin(), 
+            std::vector<const Type*>::iterator I = SeenList.begin(),
                                                E = SeenList.end();
             for ( ; I != E; ++I)
               if (*I == TheTy)
@@ -249,23 +250,26 @@ static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
 //               Code to handle definitions of all the types
 //===----------------------------------------------------------------------===//
 
-static void InsertValue(Value *V, ValueList &ValueTab = CurFun.Values) {
+/// InsertValue - Insert a value into the value table.  If it is named, this
+/// returns -1, otherwise it returns the slot number for the value.
+static int 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;
+    return -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 
+  // 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;
-  } 
+    return CurFun.NextValNum-1;
+  }
   // For all other lists, its okay to just tack it on the back of the vector.
   ValueTab.push_back(V);
+  return ValueTab.size()-1;
 }
 
 static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
@@ -304,8 +308,10 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
   }
 
   std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
-  if (I != CurModule.LateResolveTypes.end())
+  if (I != CurModule.LateResolveTypes.end()) {
+    D.destroy();
     return I->second;
+  }
 
   Type *Typ = OpaqueType::get();
   CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
@@ -326,47 +332,47 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
   switch (D.Type) {
   case ValID::LocalID: {                 // Is it a numbered definition?
     // Check that the number is within bounds.
-    if (D.Num >= CurFun.Values.size()) 
+    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 " 
+                    Result->getType()->getDescription() + "' does not match "
                     "expected type, '" + Ty->getDescription() + "'");
       return 0;
     }
     return Result;
   }
   case ValID::GlobalID: {                 // Is it a numbered definition?
-    if (D.Num >= CurModule.Values.size()) 
+    if (D.Num >= CurModule.Values.size())
       return 0;
     Value *Result = CurModule.Values[D.Num];
     if (Ty != Result->getType()) {
       GenerateError("Numbered value (@" + utostr(D.Num) + ") of type '" +
-                    Result->getType()->getDescription() + "' does not match " 
+                    Result->getType()->getDescription() + "' does not match "
                     "expected type, '" + Ty->getDescription() + "'");
       return 0;
     }
     return Result;
   }
-    
+
   case ValID::LocalName: {                // Is it a named definition?
-    if (!inFunctionScope()) 
+    if (!inFunctionScope())
       return 0;
     ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
     Value *N = SymTab.lookup(D.getName());
-    if (N == 0) 
+    if (N == 0)
       return 0;
     if (N->getType() != Ty)
       return 0;
-    
+
     D.destroy();  // Free old strdup'd memory...
     return N;
   }
   case ValID::GlobalName: {                // Is it a named definition?
     ValueSymbolTable &SymTab = CurModule.CurrentModule->getValueSymbolTable();
     Value *N = SymTab.lookup(D.getName());
-    if (N == 0) 
+    if (N == 0)
       return 0;
     if (N->getType() != Ty)
       return 0;
@@ -402,18 +408,40 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
     // This is really a signed reference.  Transmogrify.
     return ConstantInt::get(Ty, D.ConstPool64, true);
 
+  case ValID::ConstAPInt:     // Is it an unsigned const pool reference?
+    if (!isa<IntegerType>(Ty)) {
+      GenerateError("Integral constant '" + D.getName() +
+                    "' is invalid or out of range for type '" +
+                    Ty->getDescription() + "'");
+      return 0;
+    }
+
+    {
+      APSInt Tmp = *D.ConstPoolInt;
+      D.destroy();
+      Tmp.extOrTrunc(Ty->getPrimitiveSizeInBits());
+      return ConstantInt::get(Tmp);
+    }
+
   case ValID::ConstFPVal:        // Is it a floating point const pool reference?
     if (!Ty->isFloatingPoint() ||
         !ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) {
       GenerateError("FP constant invalid for type");
       return 0;
     }
-    // Lexer has no type info, so builds all float and double FP constants 
+    // Lexer has no type info, so builds all float and double FP constants
     // as double.  Fix this here.  Long double does not need this.
     if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
-        Ty==Type::FloatTy)
-      D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
-    return ConstantFP::get(*D.ConstPoolFP);
+        Ty==Type::FloatTy) {
+      bool ignored;
+      D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+                             &ignored);
+    }
+    {
+      ConstantFP *tmp = ConstantFP::get(*D.ConstPoolFP);
+      D.destroy();
+      return tmp;
+    }
 
   case ValID::ConstNullVal:      // Is it a null value?
     if (!isa<PointerType>(Ty)) {
@@ -427,7 +455,7 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
 
   case ValID::ConstZeroVal:      // Is it a zero value?
     return Constant::getNullValue(Ty);
-    
+
   case ValID::ConstantVal:       // Fully resolved constant?
     if (D.ConstantValue->getType() != Ty) {
       GenerateError("Constant expression type different from required type");
@@ -475,7 +503,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   if (TriggerError) return 0;
 
   if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
-    GenerateError("Invalid use of a composite type");
+    GenerateError("Invalid use of a non-first-class type");
     return 0;
   }
 
@@ -502,7 +530,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   default:
    V = new Argument(Ty);
   }
-  
+
   // Remember where this forward reference came from.  FIXME, shouldn't we try
   // to recycle these things??
   CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID,
@@ -517,7 +545,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
 
 /// 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, BasicBlock *unwindDest) {
+static BasicBlock *defineBBVal(const ValID &ID) {
   assert(inFunctionScope() && "Can't get basic block at global scope!");
 
   BasicBlock *BB = 0;
@@ -538,7 +566,7 @@ static BasicBlock *defineBBVal(const ValID &ID, BasicBlock *unwindDest) {
     // 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 
+    // 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();
 
@@ -547,8 +575,8 @@ static BasicBlock *defineBBVal(const ValID &ID, BasicBlock *unwindDest) {
       assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
       InsertValue(BB);
     }
-  } else { 
-    // We haven't seen this BB before and its first mention is a definition. 
+  } else {
+    // 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.getName() : "");
     BB = BasicBlock::Create(Name, CurFun.CurrentFunction);
@@ -559,12 +587,11 @@ static BasicBlock *defineBBVal(const ValID &ID, BasicBlock *unwindDest) {
   }
 
   ID.destroy();
-  BB->setUnwindDest(unwindDest);
   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!");
 
@@ -588,8 +615,8 @@ static BasicBlock *getBBVal(const ValID &ID) {
       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 '"+ 
+        GenerateError("Reference to label '%" + utostr(ID.Num) +
+          "' is actually of type '"+
           CurFun.Values[ID.Num]->getType()->getDescription() + "'");
     }
   } else {
@@ -632,7 +659,7 @@ static BasicBlock *getBBVal(const ValID &ID) {
 // time (forward branches, phi functions for loops, etc...) resolve the
 // defs now...
 //
-static void 
+static void
 ResolveDefinitions(ValueList &LateResolvers, ValueList *FutureLateResolvers) {
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
   while (!LateResolvers.empty()) {
@@ -682,15 +709,17 @@ static void ResolveTypeTo(std::string *Name, const Type *ToTy) {
   ValID D;
   if (Name)
     D = ValID::createLocalName(*Name);
-  else      
+  else
     D = ValID::createLocalID(CurModule.Types.size());
 
   std::map<ValID, PATypeHolder>::iterator I =
     CurModule.LateResolveTypes.find(D);
   if (I != CurModule.LateResolveTypes.end()) {
     ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy);
+    I->first.destroy();
     CurModule.LateResolveTypes.erase(I);
   }
+  D.destroy();
 }
 
 // setValueName - Set the specified value to the name given.  The name may be
@@ -732,6 +761,10 @@ ParseGlobalVariable(std::string *NameStr,
     GenerateError("Cannot declare global vars of function type");
     return 0;
   }
+  if (Ty == Type::LabelTy) {
+    GenerateError("Cannot declare global vars of label type");
+    return 0;
+  }
 
   const PointerType *PTy = PointerType::get(Ty, AddressSpace);
 
@@ -762,9 +795,12 @@ ParseGlobalVariable(std::string *NameStr,
     GV->setConstant(isConstantGlobal);
     GV->setThreadLocal(IsThreadLocal);
     InsertValue(GV, CurModule.Values);
+    ID.destroy();
     return GV;
   }
 
+  ID.destroy();
+
   // If this global has a name
   if (!Name.empty()) {
     // if the global we're parsing has an initializer (is a definition) and
@@ -801,7 +837,7 @@ ParseGlobalVariable(std::string *NameStr,
 static bool setTypeName(const Type *T, std::string *NameStr) {
   assert(!inFunctionScope() && "Can't give types function-local names!");
   if (NameStr == 0) return false;
+
   std::string Name(*NameStr);      // Copy string
   delete NameStr;                  // Free old string
 
@@ -884,7 +920,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
   // If Ty isn't abstract, or if there are no up-references in it, then there is
   // nothing to resolve here.
   if (!ty->isAbstract() || UpRefs.empty()) return ty;
-  
+
   PATypeHolder Ty(ty);
   UR_OUT("Type '" << Ty->getDescription() <<
          "' newly formed.  Resolving upreferences.\n" <<
@@ -960,6 +996,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
   llvm::PATypeHolder                     *TypeVal;
   llvm::Value                            *ValueVal;
   std::vector<llvm::Value*>              *ValueList;
+  std::vector<unsigned>                  *ConstantList;
   llvm::ArgListType                      *ArgList;
   llvm::TypeWithAttrs                     TypeWithAttrs;
   llvm::TypeWithAttrsList                *TypeWithAttrsList;
@@ -973,7 +1010,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
   llvm::GlobalValue::LinkageTypes         Linkage;
   llvm::GlobalValue::VisibilityTypes      Visibility;
-  llvm::ParameterAttributes         ParamAttrs;
+  llvm::Attributes                  Attributes;
   llvm::APInt                       *APIntVal;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
@@ -994,7 +1031,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
   llvm::FCmpInst::Predicate         FPredicate;
 }
 
-%type <ModuleVal>     Module 
+%type <ModuleVal>     Module
 %type <FunctionVal>   Function FunctionProto FunctionHeader BasicBlockList
 %type <BasicBlockVal> BasicBlock InstructionList
 %type <TermInstVal>   BBTerminatorInst
@@ -1005,7 +1042,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %type <PHIList>       PHIList
 %type <ParamList>     ParamList      // For call param lists & GEP indices
 %type <ValueList>     IndexList         // For GEP indices
-%type <TypeList>      TypeListI 
+%type <ConstantList>  ConstantIndexList // For insertvalue/extractvalue indices
+%type <TypeList>      TypeListI
 %type <TypeWithAttrsList> ArgTypeList ArgTypeListI
 %type <TypeWithAttrs> ArgType
 %type <JumpTable>     JumpTable
@@ -1031,10 +1069,10 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 // EUINT64VAL - A positive number within uns. long long range
 %token <UInt64Val> EUINT64VAL
 
-// ESAPINTVAL - A negative number with arbitrary precision 
+// ESAPINTVAL - A negative number with arbitrary precision
 %token <APIntVal>  ESAPINTVAL
 
-// EUAPINTVAL - A positive number with arbitrary precision 
+// EUAPINTVAL - A positive number with arbitrary precision
 %token <APIntVal>  EUAPINTVAL
 
 %token  <UIntVal>   LOCALVAL_ID GLOBALVAL_ID  // %123 @123
@@ -1042,13 +1080,13 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 
 // Built in types...
 %type  <TypeVal> Types ResultTypes
-%type  <PrimType> IntType FPType PrimType           // Classifications
-%token <PrimType> VOID INTTYPE 
+%type  <PrimType> PrimType           // Classifications
+%token <PrimType> VOID INTTYPE
 %token <PrimType> FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL
 %token TYPE
 
 
-%token<StrVal> LOCALVAR GLOBALVAR LABELSTR 
+%token<StrVal> LOCALVAR GLOBALVAR LABELSTR
 %token<StrVal> STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT
 %type <StrVal> LocalName OptLocalName OptLocalAssign
 %type <StrVal> GlobalName OptGlobalAssign GlobalAssign
@@ -1059,14 +1097,15 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
 %token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
 %token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
-%token DLLIMPORT DLLEXPORT EXTERN_WEAK
+%token DLLIMPORT DLLEXPORT EXTERN_WEAK COMMON
 %token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
 %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
 %token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
-%token DATALAYOUT UNWINDS
-%type <UIntVal> OptCallingConv
-%type <ParamAttrs> OptParamAttrs ParamAttr 
-%type <ParamAttrs> OptFuncAttrs  FuncAttr
+%token DATALAYOUT
+%type <UIntVal> OptCallingConv LocalNumber
+%type <Attributes> OptAttributes Attribute
+%type <Attributes> OptFuncAttrs  FuncAttr
+%type <Attributes> OptRetAttrs  RetAttr
 
 // Basic Block Terminating Operators
 %token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
@@ -1076,10 +1115,10 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
 %token <BinaryOpVal> SHL LSHR ASHR
 
-%token <OtherOpVal> ICMP FCMP
+%token <OtherOpVal> ICMP FCMP VICMP VFCMP
 %type  <IPredicate> IPredicates
 %type  <FPredicate> FPredicates
-%token  EQ NE SLT SGT SLE SGE ULT UGT ULE UGE 
+%token  EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
 %token  OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE
 
 // Memory Instructions
@@ -1094,10 +1133,11 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %token <OtherOpVal> PHI_TOK SELECT VAARG
 %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
 %token <OtherOpVal> GETRESULT
+%token <OtherOpVal> EXTRACTVALUE INSERTVALUE
 
 // Function Attributes
 %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY GC
+%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ
 
 // Visibility Styles
 %token DEFAULT HIDDEN PROTECTED
@@ -1111,18 +1151,18 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 //
 ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
 LogicalOps   : SHL | LSHR | ASHR | AND | OR | XOR;
-CastOps      : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST | 
+CastOps      : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST |
                UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT;
 
-IPredicates  
+IPredicates
   : EQ   { $$ = ICmpInst::ICMP_EQ; }  | NE   { $$ = ICmpInst::ICMP_NE; }
   | SLT  { $$ = ICmpInst::ICMP_SLT; } | SGT  { $$ = ICmpInst::ICMP_SGT; }
   | SLE  { $$ = ICmpInst::ICMP_SLE; } | SGE  { $$ = ICmpInst::ICMP_SGE; }
   | ULT  { $$ = ICmpInst::ICMP_ULT; } | UGT  { $$ = ICmpInst::ICMP_UGT; }
-  | ULE  { $$ = ICmpInst::ICMP_ULE; } | UGE  { $$ = ICmpInst::ICMP_UGE; } 
+  | ULE  { $$ = ICmpInst::ICMP_ULE; } | UGE  { $$ = ICmpInst::ICMP_UGE; }
   ;
 
-FPredicates  
+FPredicates
   : OEQ  { $$ = FCmpInst::FCMP_OEQ; } | ONE  { $$ = FCmpInst::FCMP_ONE; }
   | OLT  { $$ = FCmpInst::FCMP_OLT; } | OGT  { $$ = FCmpInst::FCMP_OGT; }
   | OLE  { $$ = FCmpInst::FCMP_OLE; } | OGE  { $$ = FCmpInst::FCMP_OGE; }
@@ -1134,11 +1174,6 @@ FPredicates
   | FALSETOK { $$ = FCmpInst::FCMP_FALSE; }
   ;
 
-// These are some types that allow classification if we only want a particular 
-// thing... for example, only a signed, unsigned, or integral type.
-IntType :  INTTYPE;
-FPType   : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80;
-
 LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
 OptLocalName : LocalName | /*empty*/ { $$ = 0; };
 
@@ -1156,6 +1191,12 @@ OptLocalAssign : LocalName '=' {
     CHECK_FOR_ERROR
   };
 
+LocalNumber : LOCALVAL_ID '=' {
+  $$ = $1;
+  CHECK_FOR_ERROR
+};
+
+
 GlobalName : GLOBALVAR | ATSTRINGCONSTANT ;
 
 OptGlobalAssign : GlobalAssign
@@ -1169,12 +1210,13 @@ GlobalAssign : GlobalName '=' {
     CHECK_FOR_ERROR
   };
 
-GVInternalLinkage 
-  : INTERNAL    { $$ = GlobalValue::InternalLinkage; } 
-  | WEAK        { $$ = GlobalValue::WeakLinkage; } 
+GVInternalLinkage
+  : INTERNAL    { $$ = GlobalValue::InternalLinkage; }
+  | WEAK        { $$ = GlobalValue::WeakLinkage; }
   | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; }
   | APPENDING   { $$ = GlobalValue::AppendingLinkage; }
-  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } 
+  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; }
+  | COMMON      { $$ = GlobalValue::CommonLinkage; }
   ;
 
 GVExternalLinkage
@@ -1192,17 +1234,17 @@ GVVisibilityStyle
 
 FunctionDeclareLinkage
   : /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
-  | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } 
+  | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; }
   | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
   ;
-  
+
 FunctionDefineLinkage
   : /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
   | INTERNAL    { $$ = GlobalValue::InternalLinkage; }
   | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; }
   | WEAK        { $$ = GlobalValue::WeakLinkage; }
-  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } 
-  ; 
+  | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; }
+  ;
 
 AliasLinkage
   : /*empty*/   { $$ = GlobalValue::ExternalLinkage; }
@@ -1223,39 +1265,58 @@ OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                   CHECK_FOR_ERROR
                  };
 
-ParamAttr     : ZEROEXT { $$ = ParamAttr::ZExt;      }
-              | ZEXT    { $$ = ParamAttr::ZExt;      }
-              | SIGNEXT { $$ = ParamAttr::SExt;      }
-              | SEXT    { $$ = ParamAttr::SExt;      }
-              | INREG   { $$ = ParamAttr::InReg;     }
-              | SRET    { $$ = ParamAttr::StructRet; }
-              | NOALIAS { $$ = ParamAttr::NoAlias;   }
-              | BYVAL   { $$ = ParamAttr::ByVal;     }
-              | NEST    { $$ = ParamAttr::Nest;      }
-              | ALIGN EUINT64VAL { $$ = 
-                          ParamAttr::constructAlignmentFromInt($2);    }
+Attribute     : ZEROEXT { $$ = Attribute::ZExt;      }
+              | ZEXT    { $$ = Attribute::ZExt;      }
+              | SIGNEXT { $$ = Attribute::SExt;      }
+              | SEXT    { $$ = Attribute::SExt;      }
+              | INREG   { $$ = Attribute::InReg;     }
+              | SRET    { $$ = Attribute::StructRet; }
+              | NOALIAS { $$ = Attribute::NoAlias;   }
+              | BYVAL   { $$ = Attribute::ByVal;     }
+              | NEST    { $$ = Attribute::Nest;      }
+              | ALIGN EUINT64VAL { $$ =
+                          Attribute::constructAlignmentFromInt($2);    }
               ;
 
-OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
-              | OptParamAttrs ParamAttr {
+OptAttributes : /* empty */  { $$ = Attribute::None; }
+              | OptAttributes Attribute {
                 $$ = $1 | $2;
               }
               ;
 
-FuncAttr      : NORETURN { $$ = ParamAttr::NoReturn; }
-              | NOUNWIND { $$ = ParamAttr::NoUnwind; }
-              | ZEROEXT  { $$ = ParamAttr::ZExt;     }
-              | SIGNEXT  { $$ = ParamAttr::SExt;     }
-              | READNONE { $$ = ParamAttr::ReadNone; }
-              | READONLY { $$ = ParamAttr::ReadOnly; }
+RetAttr       : INREG    { $$ = Attribute::InReg;     }
+              | ZEROEXT  { $$ = Attribute::ZExt;     }
+              | SIGNEXT  { $$ = Attribute::SExt;     }
               ;
 
-OptFuncAttrs  : /* empty */ { $$ = ParamAttr::None; }
+OptRetAttrs  : /* empty */ { $$ = Attribute::None; }
+             | OptRetAttrs RetAttr {
+               $$ = $1 | $2;
+             }
+             ;
+
+
+FuncAttr      : NORETURN { $$ = Attribute::NoReturn; }
+              | NOUNWIND { $$ = Attribute::NoUnwind; }
+              | INREG    { $$ = Attribute::InReg;     }
+              | ZEROEXT  { $$ = Attribute::ZExt;     }
+              | SIGNEXT  { $$ = Attribute::SExt;     }
+              | READNONE { $$ = Attribute::ReadNone; }
+              | READONLY { $$ = Attribute::ReadOnly; }
+              | NOINLINE { $$ = Attribute::NoInline; }
+              | ALWAYSINLINE { $$ = Attribute::AlwaysInline; }
+              | OPTSIZE  { $$ = Attribute::OptimizeForSize; }
+              | SSP      { $$ = Attribute::StackProtect; }
+              | SSPREQ   { $$ = Attribute::StackProtectReq; }
+              ;
+
+OptFuncAttrs  : /* empty */ { $$ = Attribute::None; }
               | OptFuncAttrs FuncAttr {
                 $$ = $1 | $2;
               }
               ;
 
+
 OptGC         : /* empty */ { $$ = 0; }
               | GC STRINGCONSTANT {
                 $$ = $2;
@@ -1301,7 +1362,7 @@ GlobalVarAttribute : SectionString {
     CurGV->setSection(*$1);
     delete $1;
     CHECK_FOR_ERROR
-  } 
+  }
   | ALIGN EUINT64VAL {
     if ($2 != 0 && !isPowerOf2_32($2))
       GEN_ERROR("Alignment must be a power of two");
@@ -1311,13 +1372,13 @@ GlobalVarAttribute : SectionString {
 
 //===----------------------------------------------------------------------===//
 // Types includes all predefined types... except void, because it can only be
-// used in specific contexts (function returning void for example).  
+// used in specific contexts (function returning void for example).
 
 // Derived types are added later...
 //
 PrimType : INTTYPE | FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80 | LABEL ;
 
-Types 
+Types
   : OPAQUE {
     $$ = new PATypeHolder(OpaqueType::get());
     CHECK_FOR_ERROR
@@ -1352,7 +1413,7 @@ Types
     const Type *RetTy = *$1;
     if (!FunctionType::isValidReturnType(RetTy))
       GEN_ERROR("Invalid result type for LLVM function");
-      
+
     std::vector<const Type*> Params;
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for (; I != E; ++I ) {
@@ -1370,9 +1431,15 @@ Types
     CHECK_FOR_ERROR
 
     FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
-    delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
-    $$ = new PATypeHolder(HandleUpRefs(FT)); 
+    $$ = new PATypeHolder(HandleUpRefs(FT));
+
+    // Delete the argument list
+    for (I = $3->begin() ; I != E; ++I ) {
+      delete I->Ty;
+    }
+    delete $3;
+
     CHECK_FOR_ERROR
   }
   | VOID '(' ArgTypeListI ')' OptFuncAttrs {
@@ -1395,13 +1462,19 @@ Types
     CHECK_FOR_ERROR
 
     FunctionType *FT = FunctionType::get($1, Params, isVarArg);
-    delete $3;      // Delete the argument list
-    $$ = new PATypeHolder(HandleUpRefs(FT)); 
+    $$ = new PATypeHolder(HandleUpRefs(FT));
+
+    // Delete the argument list
+    for (I = $3->begin() ; I != E; ++I ) {
+      delete I->Ty;
+    }
+    delete $3;
+
     CHECK_FOR_ERROR
   }
 
   | '[' EUINT64VAL 'x' Types ']' {          // Sized array type?
-    $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2)));
+    $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2)));
     delete $4;
     CHECK_FOR_ERROR
   }
@@ -1445,12 +1518,12 @@ Types
   }
   ;
 
-ArgType 
-  : Types OptParamAttrs {
+ArgType
+  : Types OptAttributes {
     // Allow but ignore attributes on function types; this permits auto-upgrade.
     // FIXME: remove in LLVM 3.0.
-    $$.Ty = $1; 
-    $$.Attrs = ParamAttr::None;
+    $$.Ty = $1;
+    $$.Attrs = Attribute::None;
   }
   ;
 
@@ -1478,18 +1551,18 @@ ArgTypeList : ArgType {
   }
   ;
 
-ArgTypeListI 
+ArgTypeListI
   : ArgTypeList
   | ArgTypeList ',' DOTDOTDOT {
     $$=$1;
-    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
+    TypeWithAttrs TWA; TWA.Attrs = Attribute::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
   }
   | DOTDOTDOT {
     $$ = new TypeWithAttrsList;
-    TypeWithAttrs TWA; TWA.Attrs = ParamAttr::None;
+    TypeWithAttrs TWA; TWA.Attrs = Attribute::None;
     TWA.Ty = new PATypeHolder(Type::VoidTy);
     $$->push_back(TWA);
     CHECK_FOR_ERROR
@@ -1499,17 +1572,17 @@ ArgTypeListI
     CHECK_FOR_ERROR
   };
 
-// TypeList - Used for struct declarations and as a basis for function type 
+// TypeList - Used for struct declarations and as a basis for function type
 // declaration type lists
 //
 TypeListI : Types {
     $$ = new std::list<PATypeHolder>();
-    $$->push_back(*$1); 
+    $$->push_back(*$1);
     delete $1;
     CHECK_FOR_ERROR
   }
   | TypeListI ',' Types {
-    ($$=$1)->push_back(*$3); 
+    ($$=$1)->push_back(*$3);
     delete $3;
     CHECK_FOR_ERROR
   };
@@ -1525,21 +1598,21 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const ArrayType *ATy = dyn_cast<ArrayType>($1->get());
     if (ATy == 0)
-      GEN_ERROR("Cannot make array constant with type: '" + 
+      GEN_ERROR("Cannot make array constant with type: '" +
                      (*$1)->getDescription() + "'");
     const Type *ETy = ATy->getElementType();
-    int NumElements = ATy->getNumElements();
+    uint64_t NumElements = ATy->getNumElements();
 
     // Verify that we have the correct size...
-    if (NumElements != -1 && NumElements != (int)$3->size())
+    if (NumElements != uint64_t(-1) && NumElements != $3->size())
       GEN_ERROR("Type mismatch: constant sized array initialized with " +
-                     utostr($3->size()) +  " arguments, but has size of " + 
-                     itostr(NumElements) + "");
+                     utostr($3->size()) +  " arguments, but has size of " +
+                     utostr(NumElements) + "");
 
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $3->size(); i++) {
       if (ETy != (*$3)[i]->getType())
-        GEN_ERROR("Element #" + utostr(i) + " is not of type '" + 
+        GEN_ERROR("Element #" + utostr(i) + " is not of type '" +
                        ETy->getDescription() +"' as required!\nIt is of type '"+
                        (*$3)[i]->getType()->getDescription() + "'.");
     }
@@ -1553,13 +1626,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const ArrayType *ATy = dyn_cast<ArrayType>($1->get());
     if (ATy == 0)
-      GEN_ERROR("Cannot make array constant with type: '" + 
+      GEN_ERROR("Cannot make array constant with type: '" +
                      (*$1)->getDescription() + "'");
 
-    int NumElements = ATy->getNumElements();
-    if (NumElements != -1 && NumElements != 0) 
+    uint64_t NumElements = ATy->getNumElements();
+    if (NumElements != uint64_t(-1) && NumElements != 0)
       GEN_ERROR("Type mismatch: constant sized array initialized with 0"
-                     " arguments, but has size of " + itostr(NumElements) +"");
+                     " arguments, but has size of " + utostr(NumElements) +"");
     $$ = ConstantArray::get(ATy, std::vector<Constant*>());
     delete $1;
     CHECK_FOR_ERROR
@@ -1569,18 +1642,18 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const ArrayType *ATy = dyn_cast<ArrayType>($1->get());
     if (ATy == 0)
-      GEN_ERROR("Cannot make array constant with type: '" + 
+      GEN_ERROR("Cannot make array constant with type: '" +
                      (*$1)->getDescription() + "'");
 
-    int NumElements = ATy->getNumElements();
+    uint64_t NumElements = ATy->getNumElements();
     const Type *ETy = ATy->getElementType();
-    if (NumElements != -1 && NumElements != int($3->length()))
-      GEN_ERROR("Can't build string constant of size " + 
-                     itostr((int)($3->length())) +
-                     " when array has size " + itostr(NumElements) + "");
+    if (NumElements != uint64_t(-1) && NumElements != $3->length())
+      GEN_ERROR("Can't build string constant of size " +
+                     utostr($3->length()) +
+                     " when array has size " + utostr(NumElements) + "");
     std::vector<Constant*> Vals;
     if (ETy == Type::Int8Ty) {
-      for (unsigned i = 0; i < $3->length(); ++i)
+      for (uint64_t i = 0; i < $3->length(); ++i)
         Vals.push_back(ConstantInt::get(ETy, (*$3)[i]));
     } else {
       delete $3;
@@ -1596,21 +1669,21 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const VectorType *PTy = dyn_cast<VectorType>($1->get());
     if (PTy == 0)
-      GEN_ERROR("Cannot make packed constant with type: '" + 
+      GEN_ERROR("Cannot make packed constant with type: '" +
                      (*$1)->getDescription() + "'");
     const Type *ETy = PTy->getElementType();
-    int NumElements = PTy->getNumElements();
+    unsigned NumElements = PTy->getNumElements();
 
     // Verify that we have the correct size...
-    if (NumElements != -1 && NumElements != (int)$3->size())
+    if (NumElements != unsigned(-1) && NumElements != (unsigned)$3->size())
       GEN_ERROR("Type mismatch: constant sized packed initialized with " +
-                     utostr($3->size()) +  " arguments, but has size of " + 
-                     itostr(NumElements) + "");
+                     utostr($3->size()) +  " arguments, but has size of " +
+                     utostr(NumElements) + "");
 
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $3->size(); i++) {
       if (ETy != (*$3)[i]->getType())
-        GEN_ERROR("Element #" + utostr(i) + " is not of type '" + 
+        GEN_ERROR("Element #" + utostr(i) + " is not of type '" +
            ETy->getDescription() +"' as required!\nIt is of type '"+
            (*$3)[i]->getType()->getDescription() + "'.");
     }
@@ -1622,7 +1695,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
   | Types '{' ConstVector '}' {
     const StructType *STy = dyn_cast<StructType>($1->get());
     if (STy == 0)
-      GEN_ERROR("Cannot make struct constant with type: '" + 
+      GEN_ERROR("Cannot make struct constant with type: '" +
                      (*$1)->getDescription() + "'");
 
     if ($3->size() != STy->getNumContainedTypes())
@@ -1650,7 +1723,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const StructType *STy = dyn_cast<StructType>($1->get());
     if (STy == 0)
-      GEN_ERROR("Cannot make struct constant with type: '" + 
+      GEN_ERROR("Cannot make struct constant with type: '" +
                      (*$1)->getDescription() + "'");
 
     if (STy->getNumContainedTypes() != 0)
@@ -1668,7 +1741,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
   | Types '<' '{' ConstVector '}' '>' {
     const StructType *STy = dyn_cast<StructType>($1->get());
     if (STy == 0)
-      GEN_ERROR("Cannot make struct constant with type: '" + 
+      GEN_ERROR("Cannot make struct constant with type: '" +
                      (*$1)->getDescription() + "'");
 
     if ($4->size() != STy->getNumContainedTypes())
@@ -1684,7 +1757,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is packed
     if (!STy->isPacked())
-      GEN_ERROR("Vector initializer to non-vector type '" + 
+      GEN_ERROR("Vector initializer to non-vector type '" +
                 STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, *$4);
@@ -1696,7 +1769,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const StructType *STy = dyn_cast<StructType>($1->get());
     if (STy == 0)
-      GEN_ERROR("Cannot make struct constant with type: '" + 
+      GEN_ERROR("Cannot make struct constant with type: '" +
                      (*$1)->getDescription() + "'");
 
     if (STy->getNumContainedTypes() != 0)
@@ -1704,7 +1777,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
     // Check to ensure that Type is packed
     if (!STy->isPacked())
-      GEN_ERROR("Vector initializer to non-vector type '" + 
+      GEN_ERROR("Vector initializer to non-vector type '" +
                 STy->getDescription() + "'");
 
     $$ = ConstantStruct::get(STy, std::vector<Constant*>());
@@ -1716,7 +1789,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const PointerType *PTy = dyn_cast<PointerType>($1->get());
     if (PTy == 0)
-      GEN_ERROR("Cannot make null pointer constant with type: '" + 
+      GEN_ERROR("Cannot make null pointer constant with type: '" +
                      (*$1)->getDescription() + "'");
 
     $$ = ConstantPointerNull::get(PTy);
@@ -1763,7 +1836,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       // First check to see if the forward references value is already created!
       PerModuleInfo::GlobalRefsType::iterator I =
         CurModule.GlobalRefs.find(std::make_pair(PT, $2));
-    
+
       if (I != CurModule.GlobalRefs.end()) {
         V = I->second;             // Placeholder already exists, use it...
         $2.destroy();
@@ -1776,7 +1849,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
 
         // Create the forward referenced global.
         GlobalValue *GV;
-        if (const FunctionType *FTy = 
+        if (const FunctionType *FTy =
                  dyn_cast<FunctionType>(PT->getElementType())) {
           GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name,
                                 CurModule.CurrentModule);
@@ -1800,7 +1873,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     if ($1->get() != $2->getType())
-      GEN_ERROR("Mismatched types for constant expression: " + 
+      GEN_ERROR("Mismatched types for constant expression: " +
         (*$1)->getDescription() + " and " + $2->getType()->getDescription());
     $$ = $2;
     delete $1;
@@ -1816,56 +1889,82 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     delete $1;
     CHECK_FOR_ERROR
   }
-  | IntType ESINT64VAL {      // integral constants
-    if (!ConstantInt::isValueValidForType($1, $2))
-      GEN_ERROR("Constant value doesn't fit in type");
-    $$ = ConstantInt::get($1, $2, true);
+  | Types ESINT64VAL {      // integral constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if (!ConstantInt::isValueValidForType(IT, $2))
+        GEN_ERROR("Constant value doesn't fit in type");
+      $$ = ConstantInt::get(IT, $2, true);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
+    }
+    delete $1;
     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");
+  | Types ESAPINTVAL {      // arbitrary precision integer constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if ($2->getBitWidth() > IT->getBitWidth())
+        GEN_ERROR("Constant value does not fit in type");
+      $2->sextOrTrunc(IT->getBitWidth());
+      $$ = ConstantInt::get(*$2);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
     }
-    $2->sextOrTrunc(BitWidth);
-    $$ = ConstantInt::get(*$2);
+    delete $1;
     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, false);
+  | Types EUINT64VAL {      // integral constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if (!ConstantInt::isValueValidForType(IT, $2))
+        GEN_ERROR("Constant value doesn't fit in type");
+      $$ = ConstantInt::get(IT, $2, false);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
+    }
+    delete $1;
     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);
+  | Types EUAPINTVAL {      // arbitrary precision integer constants
+    if (IntegerType *IT = dyn_cast<IntegerType>($1->get())) {
+      if ($2->getBitWidth() > IT->getBitWidth())
+        GEN_ERROR("Constant value does not fit in type");
+      $2->zextOrTrunc(IT->getBitWidth());
+      $$ = ConstantInt::get(*$2);
+    } else {
+      GEN_ERROR("integer constant must have integer type");
+    }
+
     delete $2;
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | INTTYPE TRUETOK {                      // Boolean constants
-    assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+  | Types TRUETOK {                      // Boolean constants
+    if ($1->get() != Type::Int1Ty)
+      GEN_ERROR("Constant true must have type i1");
     $$ = ConstantInt::getTrue();
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | INTTYPE FALSETOK {                     // Boolean constants
-    assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+  | Types FALSETOK {                     // Boolean constants
+    if ($1->get() != Type::Int1Ty)
+      GEN_ERROR("Constant false must have type i1");
     $$ = ConstantInt::getFalse();
+    delete $1;
     CHECK_FOR_ERROR
   }
-  | FPType FPVAL {                   // Floating point constants
-    if (!ConstantFP::isValueValidForType($1, *$2))
+  | Types FPVAL {                   // Floating point constants
+    if (!ConstantFP::isValueValidForType($1->get(), *$2))
       GEN_ERROR("Floating point constant invalid for type");
-    // Lexer has no type info, so builds all float and double FP constants 
+      
+    // Lexer has no type info, so builds all float and double FP constants
     // as double.  Fix this here.  Long double is done right.
-    if (&$2->getSemantics()==&APFloat::IEEEdouble && $1==Type::FloatTy)
-      $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven);
+    if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) {
+      bool ignored;
+      $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
+                  &ignored);
+    }
     $$ = ConstantFP::get(*$2);
+    delete $1;
     delete $2;
     CHECK_FOR_ERROR
   };
@@ -1879,7 +1978,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
     if (!CastInst::castIsValid($1, $3, DestTy))
       GEN_ERROR("invalid cast opcode for cast from '" +
                 Val->getType()->getDescription() + "' to '" +
-                DestTy->getDescription() + "'"); 
+                DestTy->getDescription() + "'");
     $$ = ConstantExpr::getCast($1, $3, DestTy);
     delete $5;
   }
@@ -1888,8 +1987,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
       GEN_ERROR("GetElementPtr requires a pointer operand");
 
     const Type *IdxTy =
-      GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end(),
-                                        true);
+      GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end());
     if (!IdxTy)
       GEN_ERROR("Index list invalid for constant getelementptr");
 
@@ -1923,7 +2021,7 @@ 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<VectorType>($3->getType()) || 
+      if (!isa<VectorType>($3->getType()) ||
           !cast<VectorType>($3->getType())->getElementType()->isInteger())
         GEN_ERROR("Logical operator requires integral operands");
     }
@@ -1940,6 +2038,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
       GEN_ERROR("fcmp operand types must match");
     $$ = ConstantExpr::getFCmp($2, $4, $6);
   }
+  | VICMP IPredicates '(' ConstVal ',' ConstVal ')' {
+    if ($4->getType() != $6->getType())
+      GEN_ERROR("vicmp operand types must match");
+    $$ = ConstantExpr::getVICmp($2, $4, $6);
+  }
+  | VFCMP FPredicates '(' ConstVal ',' ConstVal ')' {
+    if ($4->getType() != $6->getType())
+      GEN_ERROR("vfcmp operand types must match");
+    $$ = ConstantExpr::getVFCmp($2, $4, $6);
+  }
   | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
     if (!ExtractElementInst::isValidOperands($3, $5))
       GEN_ERROR("Invalid extractelement operands");
@@ -1957,6 +2065,22 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
       GEN_ERROR("Invalid shufflevector operands");
     $$ = ConstantExpr::getShuffleVector($3, $5, $7);
     CHECK_FOR_ERROR
+  }
+  | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' {
+    if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+      GEN_ERROR("ExtractValue requires an aggregate operand");
+
+    $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size());
+    delete $4;
+    CHECK_FOR_ERROR
+  }
+  | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' {
+    if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
+      GEN_ERROR("InsertValue requires an aggregate operand");
+
+    $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size());
+    delete $6;
+    CHECK_FOR_ERROR
   };
 
 
@@ -1975,7 +2099,7 @@ ConstVector : ConstVector ',' ConstVal {
 // GlobalType - Match either GLOBAL or CONSTANT for global declarations...
 GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
 
-// ThreadLocal 
+// ThreadLocal
 ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
 
 // AliaseeRef - Match either GlobalValue or bitcast to GlobalValue.
@@ -1998,7 +2122,7 @@ AliaseeRef : ResultTypes SymbolicValueRef {
       GEN_ERROR("invalid cast opcode for cast from '" +
                 Val->getType()->getDescription() + "' to '" +
                 DestTy->getDescription() + "'");
-    
+
     $$ = ConstantExpr::getCast($1, $3, DestTy);
     CHECK_FOR_ERROR
     delete $5;
@@ -2011,7 +2135,7 @@ AliaseeRef : ResultTypes SymbolicValueRef {
 // Module rule: Capture the result of parsing the whole file into a result
 // variable...
 //
-Module 
+Module
   : DefinitionList {
     $$ = ParserResult = CurModule.CurrentModule;
     CurModule.ModuleDone();
@@ -2029,7 +2153,7 @@ DefinitionList
   | DefinitionList Definition
   ;
 
-Definition 
+Definition
   : DEFINE { CurFun.isDeclare = false; } Function {
     CurFun.FunctionDone();
     CHECK_FOR_ERROR
@@ -2039,7 +2163,7 @@ Definition
   }
   | MODULE ASM_TOK AsmBlock {
     CHECK_FOR_ERROR
-  }  
+  }
   | OptLocalAssign TYPE Types {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
@@ -2075,10 +2199,10 @@ Definition
     }
     CHECK_FOR_ERROR
   }
-  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal 
-    OptAddrSpace { 
+  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal
+    OptAddrSpace {
     /* "Externally Visible" Linkage */
-    if ($5 == 0) 
+    if ($5 == 0)
       GEN_ERROR("Global value initializer is not a constant");
     CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
                                 $2, $4, $5->getType(), $5, $3, $6);
@@ -2088,7 +2212,7 @@ Definition
   }
   | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType
     ConstVal OptAddrSpace {
-    if ($6 == 0) 
+    if ($6 == 0)
       GEN_ERROR("Global value initializer is not a constant");
     CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7);
     CHECK_FOR_ERROR
@@ -2114,7 +2238,7 @@ Definition
     }
     if (Name.empty())
       GEN_ERROR("Alias name cannot be empty");
-    
+
     Constant* Aliasee = $5;
     if (Aliasee == 0)
       GEN_ERROR(std::string("Invalid aliasee for alias: ") + Name);
@@ -2123,16 +2247,16 @@ Definition
                                       CurModule.CurrentModule);
     GA->setVisibility($2);
     InsertValue(GA, CurModule.Values);
-    
-    
+
+
     // If there was a forward reference of this alias, resolve it now.
-    
+
     ValID ID;
     if (!Name.empty())
       ID = ValID::createGlobalName(Name);
     else
       ID = ValID::createGlobalID(CurModule.Values.size()-1);
-    
+
     if (GlobalValue *FWGV =
           CurModule.GetForwardRefForGlobal(GA->getType(), ID)) {
       // Replace uses of the fwdref with the actual alias.
@@ -2143,10 +2267,10 @@ Definition
         cast<Function>(FWGV)->eraseFromParent();
     }
     ID.destroy();
-    
+
     CHECK_FOR_ERROR
   }
-  | TARGET TargetDefinition { 
+  | TARGET TargetDefinition {
     CHECK_FOR_ERROR
   }
   | DEPLIBS '=' LibrariesDefinition {
@@ -2195,21 +2319,21 @@ LibList : LibList ',' STRINGCONSTANT {
 //                       Rules to match Function Headers
 //===----------------------------------------------------------------------===//
 
-ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
+ArgListH : ArgListH ',' Types OptAttributes OptLocalName {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
-    if (*$3 == Type::VoidTy)
-      GEN_ERROR("void typed arguments are invalid");
+    if (!(*$3)->isFirstClassType())
+      GEN_ERROR("Argument types must be first-class");
     ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5;
     $$ = $1;
     $1->push_back(E);
     CHECK_FOR_ERROR
   }
-  | Types OptParamAttrs OptLocalName {
+  | Types OptAttributes OptLocalName {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
-    if (*$1 == Type::VoidTy)
-      GEN_ERROR("void typed arguments are invalid");
+    if (!(*$1)->isFirstClassType())
+      GEN_ERROR("Argument types must be first-class");
     ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3;
     $$ = new ArgListType;
     $$->push_back(E);
@@ -2225,7 +2349,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = ParamAttr::None;
+    E.Attrs = Attribute::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2234,7 +2358,7 @@ ArgList : ArgListH {
     struct ArgListEntry E;
     E.Ty = new PATypeHolder(Type::VoidTy);
     E.Name = 0;
-    E.Attrs = ParamAttr::None;
+    E.Attrs = Attribute::None;
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
@@ -2243,45 +2367,64 @@ ArgList : ArgListH {
     CHECK_FOR_ERROR
   };
 
-FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' 
+FunctionHeaderH : OptCallingConv OptRetAttrs ResultTypes GlobalName '(' ArgList ')'
                   OptFuncAttrs OptSection OptAlign OptGC {
-  std::string FunctionName(*$3);
-  delete $3;  // Free strdup'd memory!
-  
+  std::string FunctionName(*$4);
+  delete $4;  // Free strdup'd memory!
+
   // Check the function result for abstractness if this is a define. We should
   // have no abstract types at this point
-  if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
-    GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
+  if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($3))
+    GEN_ERROR("Reference to abstract result: "+ $3->get()->getDescription());
 
-  if (!FunctionType::isValidReturnType(*$2))
+  if (!FunctionType::isValidReturnType(*$3))
     GEN_ERROR("Invalid result type for LLVM function");
-    
+
   std::vector<const Type*> ParamTypeList;
-  SmallVector<ParamAttrsWithIndex, 8> Attrs;
-  if ($7 != ParamAttr::None)
-    Attrs.push_back(ParamAttrsWithIndex::get(0, $7));
-  if ($5) {   // If there are arguments...
+  SmallVector<AttributeWithIndex, 8> Attrs;
+  //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+  //attributes.
+  Attributes RetAttrs = $2;
+  if ($8 != Attribute::None) {
+    if ($8 & Attribute::ZExt) {
+      RetAttrs = RetAttrs | Attribute::ZExt;
+      $8 = $8 ^ Attribute::ZExt;
+    }
+    if ($8 & Attribute::SExt) {
+      RetAttrs = RetAttrs | Attribute::SExt;
+      $8 = $8 ^ Attribute::SExt;
+    }
+    if ($8 & Attribute::InReg) {
+      RetAttrs = RetAttrs | Attribute::InReg;
+      $8 = $8 ^ Attribute::InReg;
+    }
+  }
+  if (RetAttrs != Attribute::None)
+    Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+  if ($6) {   // If there are arguments...
     unsigned index = 1;
-    for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
+    for (ArgListType::iterator I = $6->begin(); I != $6->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 && I->Attrs != ParamAttr::None)
-        Attrs.push_back(ParamAttrsWithIndex::get(index, I->Attrs));
+      if (Ty != Type::VoidTy && I->Attrs != Attribute::None)
+        Attrs.push_back(AttributeWithIndex::get(index, I->Attrs));
     }
   }
+  if ($8 != Attribute::None)
+    Attrs.push_back(AttributeWithIndex::get(~0, $8));
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  PAListPtr PAL;
+  AttrListPtr PAL;
   if (!Attrs.empty())
-    PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+    PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
+  FunctionType *FT = FunctionType::get(*$3, ParamTypeList, isVarArg);
   const PointerType *PFT = PointerType::getUnqual(FT);
-  delete $2;
+  delete $3;
 
   ValID ID;
   if (!FunctionName.empty()) {
@@ -2293,10 +2436,10 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
   Function *Fn = 0;
   // See if this function was forward referenced.  If so, recycle the object.
   if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
-    // Move the function to the end of the list, from whereever it was 
+    // Move the function to the end of the list, from whereever it was
     // previously inserted.
     Fn = cast<Function>(FWRef);
-    assert(Fn->getParamAttrs().isEmpty() &&
+    assert(Fn->getAttributes().isEmpty() &&
            "Forward reference has parameter attributes!");
     CurModule.CurrentModule->getFunctionList().remove(Fn);
     CurModule.CurrentModule->getFunctionList().push_back(Fn);
@@ -2306,7 +2449,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
       // The existing function doesn't have the same type. This is an overload
       // error.
       GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
-    } else if (Fn->getParamAttrs() != PAL) {
+    } else if (Fn->getAttributes() != PAL) {
       // The existing function doesn't have the same parameter attributes.
       // This is an overload error.
       GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
@@ -2326,6 +2469,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     InsertValue(Fn, CurModule.Values);
   }
 
+  ID.destroy();
   CurFun.FunctionStart(Fn);
 
   if (CurFun.isDeclare) {
@@ -2336,30 +2480,30 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     Fn->setVisibility(CurFun.Visibility);
   }
   Fn->setCallingConv($1);
-  Fn->setParamAttrs(PAL);
-  Fn->setAlignment($9);
-  if ($8) {
-    Fn->setSection(*$8);
-    delete $8;
+  Fn->setAttributes(PAL);
+  Fn->setAlignment($10);
+  if ($9) {
+    Fn->setSection(*$9);
+    delete $9;
   }
-  if ($10) {
-    Fn->setCollector($10->c_str());
-    delete $10;
+  if ($11) {
+    Fn->setGC($11->c_str());
+    delete $11;
   }
 
   // Add all of the arguments we parsed to the function...
-  if ($5) {                     // Is null if empty...
+  if ($6) {                     // Is null if empty...
     if (isVarArg) {  // Nuke the last entry
-      assert($5->back().Ty->get() == Type::VoidTy && $5->back().Name == 0 &&
+      assert($6->back().Ty->get() == Type::VoidTy && $6->back().Name == 0 &&
              "Not a varargs marker!");
-      delete $5->back().Ty;
-      $5->pop_back();  // Delete the last entry
+      delete $6->back().Ty;
+      $6->pop_back();  // Delete the last entry
     }
     Function::arg_iterator ArgIt = Fn->arg_begin();
     Function::arg_iterator ArgEnd = Fn->arg_end();
     unsigned Idx = 1;
-    for (ArgListType::iterator I = $5->begin(); 
-         I != $5->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
+    for (ArgListType::iterator I = $6->begin();
+         I != $6->end() && ArgIt != ArgEnd; ++I, ++ArgIt) {
       delete I->Ty;                          // Delete the typeholder...
       setValueName(ArgIt, I->Name);       // Insert arg into symtab...
       CHECK_FOR_ERROR
@@ -2367,7 +2511,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
       Idx++;
     }
 
-    delete $5;                     // We're now done with the argument list
+    delete $6;                     // We're now done with the argument list
   }
   CHECK_FOR_ERROR
 };
@@ -2419,6 +2563,16 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
     $$ = ValID::create($1);
     CHECK_FOR_ERROR
   }
+  | ESAPINTVAL {      // arbitrary precision integer constants
+    $$ = ValID::create(*$1, true);
+    delete $1;
+    CHECK_FOR_ERROR
+  }
+  | EUAPINTVAL {      // arbitrary precision integer constants
+    $$ = ValID::create(*$1, false);
+    delete $1;
+    CHECK_FOR_ERROR
+  }
   | FPVAL {                     // Perhaps it's an FP constant?
     $$ = ValID::create($1);
     CHECK_FOR_ERROR
@@ -2426,7 +2580,7 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
   | TRUETOK {
     $$ = ValID::create(ConstantInt::getTrue());
     CHECK_FOR_ERROR
-  } 
+  }
   | FALSETOK {
     $$ = ValID::create(ConstantInt::getFalse());
     CHECK_FOR_ERROR
@@ -2445,21 +2599,18 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
   }
   | '<' ConstVector '>' { // Nonempty unsized packed vector
     const Type *ETy = (*$2)[0]->getType();
-    int NumElements = $2->size(); 
-    
+    unsigned NumElements = $2->size();
+
+    if (!ETy->isInteger() && !ETy->isFloatingPoint())
+      GEN_ERROR("Invalid vector element type: " + ETy->getDescription());
+
     VectorType* pt = VectorType::get(ETy, NumElements);
-    PATypeHolder* PTy = new PATypeHolder(
-                                         HandleUpRefs(
-                                            VectorType::get(
-                                                ETy, 
-                                                NumElements)
-                                            )
-                                         );
-    
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt));
+
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $2->size(); i++) {
       if (ETy != (*$2)[i]->getType())
-        GEN_ERROR("Element #" + utostr(i) + " is not of type '" + 
+        GEN_ERROR("Element #" + utostr(i) + " is not of type '" +
                      ETy->getDescription() +"' as required!\nIt is of type '" +
                      (*$2)[i]->getType()->getDescription() + "'.");
     }
@@ -2468,6 +2619,82 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
     delete PTy; delete $2;
     CHECK_FOR_ERROR
   }
+  | '[' ConstVector ']' { // Nonempty unsized arr
+    const Type *ETy = (*$2)[0]->getType();
+    uint64_t NumElements = $2->size();
+
+    if (!ETy->isFirstClassType())
+      GEN_ERROR("Invalid array element type: " + ETy->getDescription());
+
+    ArrayType *ATy = ArrayType::get(ETy, NumElements);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy));
+
+    // Verify all elements are correct type!
+    for (unsigned i = 0; i < $2->size(); i++) {
+      if (ETy != (*$2)[i]->getType())
+        GEN_ERROR("Element #" + utostr(i) + " is not of type '" +
+                       ETy->getDescription() +"' as required!\nIt is of type '"+
+                       (*$2)[i]->getType()->getDescription() + "'.");
+    }
+
+    $$ = ValID::create(ConstantArray::get(ATy, *$2));
+    delete PTy; delete $2;
+    CHECK_FOR_ERROR
+  }
+  | '[' ']' {
+    // Use undef instead of an array because it's inconvenient to determine
+    // the element type at this point, there being no elements to examine.
+    $$ = ValID::createUndef();
+    CHECK_FOR_ERROR
+  }
+  | 'c' STRINGCONSTANT {
+    uint64_t NumElements = $2->length();
+    const Type *ETy = Type::Int8Ty;
+
+    ArrayType *ATy = ArrayType::get(ETy, NumElements);
+
+    std::vector<Constant*> Vals;
+    for (unsigned i = 0; i < $2->length(); ++i)
+      Vals.push_back(ConstantInt::get(ETy, (*$2)[i]));
+    delete $2;
+    $$ = ValID::create(ConstantArray::get(ATy, Vals));
+    CHECK_FOR_ERROR
+  }
+  | '{' ConstVector '}' {
+    std::vector<const Type*> Elements($2->size());
+    for (unsigned i = 0, e = $2->size(); i != e; ++i)
+      Elements[i] = (*$2)[i]->getType();
+
+    const StructType *STy = StructType::get(Elements);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+    $$ = ValID::create(ConstantStruct::get(STy, *$2));
+    delete PTy; delete $2;
+    CHECK_FOR_ERROR
+  }
+  | '{' '}' {
+    const StructType *STy = StructType::get(std::vector<const Type*>());
+    $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+    CHECK_FOR_ERROR
+  }
+  | '<' '{' ConstVector '}' '>' {
+    std::vector<const Type*> Elements($3->size());
+    for (unsigned i = 0, e = $3->size(); i != e; ++i)
+      Elements[i] = (*$3)[i]->getType();
+
+    const StructType *STy = StructType::get(Elements, /*isPacked=*/true);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+    $$ = ValID::create(ConstantStruct::get(STy, *$3));
+    delete PTy; delete $3;
+    CHECK_FOR_ERROR
+  }
+  | '<' '{' '}' '>' {
+    const StructType *STy = StructType::get(std::vector<const Type*>(),
+                                            /*isPacked=*/true);
+    $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+    CHECK_FOR_ERROR
+  }
   | ConstExpr {
     $$ = ValID::create($1);
     CHECK_FOR_ERROR
@@ -2511,7 +2738,7 @@ ValueRef : SymbolicValueRef | ConstValueRef;
 ResolvedVal : Types ValueRef {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
-    $$ = getVal(*$1, $2); 
+    $$ = getVal(*$1, $2);
     delete $1;
     CHECK_FOR_ERROR
   }
@@ -2519,11 +2746,11 @@ ResolvedVal : Types ValueRef {
 
 ReturnedVal : ResolvedVal {
     $$ = new std::vector<Value *>();
-    $$->push_back($1); 
+    $$->push_back($1);
     CHECK_FOR_ERROR
   }
   | ReturnedVal ',' ResolvedVal {
-    ($$=$1)->push_back($3); 
+    ($$=$1)->push_back($3);
     CHECK_FOR_ERROR
   };
 
@@ -2531,16 +2758,16 @@ BasicBlockList : BasicBlockList BasicBlock {
     $$ = $1;
     CHECK_FOR_ERROR
   }
-  | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks   
+  | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks
     $$ = $1;
     CHECK_FOR_ERROR
   };
 
 
-// Basic blocks are terminated by branching instructions: 
+// Basic blocks are terminated by branching instructions:
 // br, br/cc, switch, ret
 //
-BasicBlock : InstructionList OptLocalAssign BBTerminatorInst  {
+BasicBlock : InstructionList OptLocalAssign BBTerminatorInst {
     setValueName($3, $2);
     CHECK_FOR_ERROR
     InsertValue($3);
@@ -2549,6 +2776,19 @@ BasicBlock : InstructionList OptLocalAssign BBTerminatorInst  {
     CHECK_FOR_ERROR
   };
 
+BasicBlock : InstructionList LocalNumber BBTerminatorInst {
+  CHECK_FOR_ERROR
+  int ValNum = InsertValue($3);
+  if (ValNum != (int)$2)
+    GEN_ERROR("Result value number %" + utostr($2) +
+              " is incorrect, expected %" + utostr((unsigned)ValNum));
+
+  $1->getInstList().push_back($3);
+  $$ = $1;
+  CHECK_FOR_ERROR
+};
+
+
 InstructionList : InstructionList Inst {
     if (CastInst *CI1 = dyn_cast<CastInst>($2))
       if (CastInst *CI2 = dyn_cast<CastInst>(CI1->getOperand(0)))
@@ -2559,29 +2799,34 @@ InstructionList : InstructionList Inst {
     CHECK_FOR_ERROR
   }
   | /* empty */ {          // Empty space between instruction lists
-    $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum), 0);
-    CHECK_FOR_ERROR
-  }
-  | UNWINDS TO ValueRef {   // Only the unwind to block
-    $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum), getBBVal($3));
+    $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum));
     CHECK_FOR_ERROR
   }
   | LABELSTR {             // Labelled (named) basic block
-    $$ = defineBBVal(ValID::createLocalName(*$1), 0);
-    delete $1;
-    CHECK_FOR_ERROR
-  }
-  | LABELSTR UNWINDS TO ValueRef {
-    $$ = defineBBVal(ValID::createLocalName(*$1), getBBVal($4));
+    $$ = defineBBVal(ValID::createLocalName(*$1));
     delete $1;
     CHECK_FOR_ERROR
+
   };
 
-BBTerminatorInst : 
+BBTerminatorInst :
   RET ReturnedVal  { // Return with a result...
     ValueList &VL = *$2;
     assert(!VL.empty() && "Invalid ret operands!");
-    $$ = ReturnInst::Create(&VL[0], VL.size());
+    const Type *ReturnType = CurFun.CurrentFunction->getReturnType();
+    if (VL.size() > 1 ||
+        (isa<StructType>(ReturnType) &&
+         (VL.empty() || VL[0]->getType() != ReturnType))) {
+      Value *RV = UndefValue::get(ReturnType);
+      for (unsigned i = 0, e = VL.size(); i != e; ++i) {
+        Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv");
+        ($<BasicBlockVal>-1)->getInstList().push_back(I);
+        RV = I;
+      }
+      $$ = ReturnInst::Create(RV);
+    } else {
+      $$ = ReturnInst::Create(VL[0]);
+    }
     delete $2;
     CHECK_FOR_ERROR
   }
@@ -2594,8 +2839,9 @@ BBTerminatorInst :
     CHECK_FOR_ERROR
     $$ = BranchInst::Create(tmpBB);
   }                                               // Conditional Branch...
-  | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
-    assert(cast<IntegerType>($2)->getBitWidth() == 1 && "Not Bool?");
+  | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
+    if (cast<IntegerType>($2)->getBitWidth() != 1)
+      GEN_ERROR("Branch condition must have type i1");
     BasicBlock* tmpBBA = getBBVal($6);
     CHECK_FOR_ERROR
     BasicBlock* tmpBBB = getBBVal($9);
@@ -2604,7 +2850,7 @@ BBTerminatorInst :
     CHECK_FOR_ERROR
     $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal);
   }
-  | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
+  | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
     Value* tmpVal = getVal($2, $3);
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
@@ -2623,7 +2869,7 @@ BBTerminatorInst :
     delete $8;
     CHECK_FOR_ERROR
   }
-  | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' {
+  | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' ']' {
     Value* tmpVal = getVal($2, $3);
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
@@ -2632,47 +2878,64 @@ BBTerminatorInst :
     $$ = S;
     CHECK_FOR_ERROR
   }
-  | INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
-    TO LABEL ValueRef UNWIND LABEL ValueRef {
+  | INVOKE OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' 
+    OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef {
 
     // Handle the short syntax
     const PointerType *PFTy = 0;
     const FunctionType *Ty = 0;
-    if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamList::iterator I = $6->begin(), E = $6->end();
+      ParamList::iterator I = $7->begin(), E = $7->end();
       for (; I != E; ++I) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
       }
-      
-      if (!FunctionType::isValidReturnType(*$3))
+
+      if (!FunctionType::isValidReturnType(*$4))
         GEN_ERROR("Invalid result type for LLVM function");
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      Ty = FunctionType::get($4->get(), ParamTypes, false);
       PFTy = PointerType::getUnqual(Ty);
     }
 
-    delete $3;
+    delete $4;
 
-    Value *V = getVal(PFTy, $4);   // Get the function we're calling...
+    Value *V = getVal(PFTy, $5);   // Get the function we're calling...
     CHECK_FOR_ERROR
-    BasicBlock *Normal = getBBVal($11);
+    BasicBlock *Normal = getBBVal($12);
     CHECK_FOR_ERROR
-    BasicBlock *Except = getBBVal($14);
+    BasicBlock *Except = getBBVal($15);
     CHECK_FOR_ERROR
 
-    SmallVector<ParamAttrsWithIndex, 8> Attrs;
-    if ($8 != ParamAttr::None)
-      Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
-
+    SmallVector<AttributeWithIndex, 8> Attrs;
+    //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+    //attributes.
+    Attributes RetAttrs = $3;
+    if ($9 != Attribute::None) {
+      if ($9 & Attribute::ZExt) {
+        RetAttrs = RetAttrs | Attribute::ZExt;
+        $9 = $9 ^ Attribute::ZExt;
+      }
+      if ($9 & Attribute::SExt) {
+        RetAttrs = RetAttrs | Attribute::SExt;
+        $9 = $9 ^ Attribute::SExt;
+      }
+      if ($9 & Attribute::InReg) {
+        RetAttrs = RetAttrs | Attribute::InReg;
+        $9 = $9 ^ Attribute::InReg;
+      }
+    }
+    if (RetAttrs != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+    
     // Check the arguments
     ValueList Args;
-    if ($6->empty()) {                                   // Has no arguments?
+    if ($7->empty()) {                                   // Has no arguments?
       // Make sure no arguments is a good thing!
       if (Ty->getNumParams() != 0)
         GEN_ERROR("No arguments passed to a function that "
@@ -2682,7 +2945,7 @@ BBTerminatorInst :
       // correctly!
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
       unsigned index = 1;
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
@@ -2690,31 +2953,33 @@ BBTerminatorInst :
           GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
                          (*I)->getDescription() + "'");
         Args.push_back(ArgI->Val);
-        if (ArgI->Attrs != ParamAttr::None)
-          Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
+        if (ArgI->Attrs != Attribute::None)
+          Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
       }
 
       if (Ty->isVarArg()) {
         if (I == E)
           for (; ArgI != ArgE; ++ArgI, ++index) {
             Args.push_back(ArgI->Val); // push the remaining varargs
-            if (ArgI->Attrs != ParamAttr::None)
-              Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
+            if (ArgI->Attrs != Attribute::None)
+              Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
           }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
-
-    PAListPtr PAL;
+    if ($9 != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(~0, $9));
+    AttrListPtr PAL;
     if (!Attrs.empty())
-      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+      PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
     // Create the InvokeInst
-    InvokeInst *II = InvokeInst::Create(V, Normal, Except, Args.begin(),Args.end());
+    InvokeInst *II = InvokeInst::Create(V, Normal, Except,
+                                        Args.begin(), Args.end());
     II->setCallingConv($2);
-    II->setParamAttrs(PAL);
+    II->setAttributes(PAL);
     $$ = II;
-    delete $6;
+    delete $7;
     CHECK_FOR_ERROR
   }
   | UNWIND {
@@ -2728,7 +2993,7 @@ BBTerminatorInst :
 
 
 
-JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
+JumpTable : JumpTable INTTYPE ConstValueRef ',' LABEL ValueRef {
     $$ = $1;
     Constant *V = cast<Constant>(getExistingVal($2, $3));
     CHECK_FOR_ERROR
@@ -2739,7 +3004,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
     CHECK_FOR_ERROR
     $$->push_back(std::make_pair(V, tmpBB));
   }
-  | IntType ConstValueRef ',' LABEL ValueRef {
+  | INTTYPE ConstValueRef ',' LABEL ValueRef {
     $$ = new std::vector<std::pair<Constant*, BasicBlock*> >();
     Constant *V = cast<Constant>(getExistingVal($1, $2));
     CHECK_FOR_ERROR
@@ -2749,7 +3014,7 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
 
     BasicBlock* tmpBB = getBBVal($5);
     CHECK_FOR_ERROR
-    $$->push_back(std::make_pair(V, tmpBB)); 
+    $$->push_back(std::make_pair(V, tmpBB));
   };
 
 Inst : OptLocalAssign InstVal {
@@ -2761,6 +3026,18 @@ Inst : OptLocalAssign InstVal {
     CHECK_FOR_ERROR
   };
 
+Inst : LocalNumber InstVal {
+    CHECK_FOR_ERROR
+    int ValNum = InsertValue($2);
+
+    if (ValNum != (int)$1)
+      GEN_ERROR("Result value number %" + utostr($1) +
+                " is incorrect, expected %" + utostr((unsigned)ValNum));
+
+    $$ = $2;
+    CHECK_FOR_ERROR
+  };
+
 
 PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
     if (!UpRefs.empty())
@@ -2783,8 +3060,8 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
   };
 
 
-ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+ParamList : Types OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     // Used for call and invoke instructions
@@ -2794,16 +3071,16 @@ ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
     delete $1;
     CHECK_FOR_ERROR
   }
-  | LABEL OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | LABEL OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     // Labels are only valid in ASMs
     $$ = new ParamList();
     ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3);
     $$->push_back(E);
     CHECK_FOR_ERROR
   }
-  | ParamList ',' Types OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | ParamList ',' Types OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
     $$ = $1;
@@ -2812,8 +3089,8 @@ ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
     delete $3;
     CHECK_FOR_ERROR
   }
-  | ParamList ',' LABEL OptParamAttrs ValueRef OptParamAttrs {
-    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
+  | ParamList ',' LABEL OptAttributes ValueRef OptAttributes {
+    // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0
     $$ = $1;
     ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5);
     $$->push_back(E);
@@ -2830,6 +3107,22 @@ IndexList       // Used for gep instructions and constant expressions
   }
   ;
 
+ConstantIndexList       // Used for insertvalue and extractvalue instructions
+  : ',' EUINT64VAL {
+    $$ = new std::vector<unsigned>();
+    if ((unsigned)$2 != $2)
+      GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue.");
+    $$->push_back($2);
+  }
+  | ConstantIndexList ',' EUINT64VAL {
+    $$ = $1;
+    if ((unsigned)$3 != $3)
+      GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue.");
+    $$->push_back($3);
+    CHECK_FOR_ERROR
+  }
+  ;
+
 OptTailCall : TAIL CALL {
     $$ = true;
     CHECK_FOR_ERROR
@@ -2842,15 +3135,15 @@ OptTailCall : TAIL CALL {
 InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
-    if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && 
+    if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() &&
         !isa<VectorType>((*$2).get()))
       GEN_ERROR(
         "Arithmetic operator requires integer, FP, or packed operands");
-    Value* val1 = getVal(*$2, $3); 
+    Value* val1 = getVal(*$2, $3);
     CHECK_FOR_ERROR
     Value* val2 = getVal(*$2, $5);
     CHECK_FOR_ERROR
-    $$ = BinaryOperator::create($1, val1, val2);
+    $$ = BinaryOperator::Create($1, val1, val2);
     if ($$ == 0)
       GEN_ERROR("binary operator returned null");
     delete $2;
@@ -2859,7 +3152,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!(*$2)->isInteger()) {
-      if (Instruction::isShift($1) || !isa<VectorType>($2->get()) ||
+      if (!isa<VectorType>($2->get()) ||
           !cast<VectorType>($2->get())->getElementType()->isInteger())
         GEN_ERROR("Logical operator requires integral operands");
     }
@@ -2867,7 +3160,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     CHECK_FOR_ERROR
     Value* tmpVal2 = getVal(*$2, $5);
     CHECK_FOR_ERROR
-    $$ = BinaryOperator::create($1, tmpVal1, tmpVal2);
+    $$ = BinaryOperator::Create($1, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("binary operator returned null");
     delete $2;
@@ -2875,13 +3168,11 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
   | ICMP IPredicates Types ValueRef ',' ValueRef  {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
-    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);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("icmp operator returned null");
     delete $3;
@@ -2889,17 +3180,43 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
   | FCMP FPredicates Types ValueRef ',' ValueRef  {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
-    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);
     CHECK_FOR_ERROR
-    $$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
     if ($$ == 0)
       GEN_ERROR("fcmp operator returned null");
     delete $3;
   }
+  | VICMP IPredicates Types ValueRef ',' ValueRef  {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
+    if (!isa<VectorType>((*$3).get()))
+      GEN_ERROR("Scalar types not supported by vicmp instruction");
+    Value* tmpVal1 = getVal(*$3, $4);
+    CHECK_FOR_ERROR
+    Value* tmpVal2 = getVal(*$3, $6);
+    CHECK_FOR_ERROR
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
+    if ($$ == 0)
+      GEN_ERROR("vicmp operator returned null");
+    delete $3;
+  }
+  | VFCMP FPredicates Types ValueRef ',' ValueRef  {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
+    if (!isa<VectorType>((*$3).get()))
+      GEN_ERROR("Scalar types not supported by vfcmp instruction");
+    Value* tmpVal1 = getVal(*$3, $4);
+    CHECK_FOR_ERROR
+    Value* tmpVal2 = getVal(*$3, $6);
+    CHECK_FOR_ERROR
+    $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
+    if ($$ == 0)
+      GEN_ERROR("vfcmp operator returned null");
+    delete $3;
+  }
   | CastOps ResolvedVal TO Types {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());
@@ -2908,15 +3225,28 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     if (!CastInst::castIsValid($1, Val, DestTy))
       GEN_ERROR("invalid cast opcode for cast from '" +
                 Val->getType()->getDescription() + "' to '" +
-                DestTy->getDescription() + "'"); 
-    $$ = CastInst::create($1, Val, DestTy);
+                DestTy->getDescription() + "'");
+    $$ = CastInst::Create($1, Val, DestTy);
     delete $4;
   }
   | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
-    if ($2->getType() != Type::Int1Ty)
-      GEN_ERROR("select condition must be boolean");
+    if (isa<VectorType>($2->getType())) {
+      // vector select
+      if (!isa<VectorType>($4->getType())
+      || !isa<VectorType>($6->getType()) )
+        GEN_ERROR("vector select value types must be vector types");
+      const VectorType* cond_type = cast<VectorType>($2->getType());
+      const VectorType* select_type = cast<VectorType>($4->getType());
+      if (cond_type->getElementType() != Type::Int1Ty)
+        GEN_ERROR("vector select condition element type must be boolean");
+      if (cond_type->getNumElements() != select_type->getNumElements())
+        GEN_ERROR("vector select number of elements must be the same");
+    } else {
+      if ($2->getType() != Type::Int1Ty)
+        GEN_ERROR("select condition must be boolean");
+    }
     if ($4->getType() != $6->getType())
-      GEN_ERROR("select value types should match");
+      GEN_ERROR("select value types must match");
     $$ = SelectInst::Create($2, $4, $6);
     CHECK_FOR_ERROR
   }
@@ -2952,7 +3282,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     $$ = PHINode::Create(Ty);
     ((PHINode*)$$)->reserveOperandSpace($2->size());
     while ($2->begin() != $2->end()) {
-      if ($2->front().first->getType() != Ty) 
+      if ($2->front().first->getType() != Ty)
         GEN_ERROR("All elements of a PHI node must be of the same type");
       cast<PHINode>($$)->addIncoming($2->front().first, $2->front().second);
       $2->pop_front();
@@ -2960,17 +3290,17 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     delete $2;  // Free the list...
     CHECK_FOR_ERROR
   }
-  | OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')' 
+  | OptTailCall OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')'
     OptFuncAttrs {
 
     // Handle the short syntax
     const PointerType *PFTy = 0;
     const FunctionType *Ty = 0;
-    if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
+    if (!(PFTy = dyn_cast<PointerType>($4->get())) ||
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamList::iterator I = $6->begin(), E = $6->end();
+      ParamList::iterator I = $7->begin(), E = $7->end();
       for (; I != E; ++I) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
@@ -2978,14 +3308,14 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         ParamTypes.push_back(Ty);
       }
 
-      if (!FunctionType::isValidReturnType(*$3))
+      if (!FunctionType::isValidReturnType(*$4))
         GEN_ERROR("Invalid result type for LLVM function");
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      Ty = FunctionType::get($4->get(), ParamTypes, false);
       PFTy = PointerType::getUnqual(Ty);
     }
 
-    Value *V = getVal(PFTy, $4);   // Get the function we're calling...
+    Value *V = getVal(PFTy, $5);   // Get the function we're calling...
     CHECK_FOR_ERROR
 
     // Check for call to invalid intrinsic to avoid crashing later.
@@ -2997,13 +3327,31 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
                   theF->getName() + "'");
     }
 
-    // Set up the ParamAttrs for the function
-    SmallVector<ParamAttrsWithIndex, 8> Attrs;
-    if ($8 != ParamAttr::None)
-      Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
-    // Check the arguments 
+    // Set up the Attributes for the function
+    SmallVector<AttributeWithIndex, 8> Attrs;
+    //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function 
+    //attributes.
+    Attributes RetAttrs = $3;
+    if ($9 != Attribute::None) {
+      if ($9 & Attribute::ZExt) {
+        RetAttrs = RetAttrs | Attribute::ZExt;
+        $9 = $9 ^ Attribute::ZExt;
+      }
+      if ($9 & Attribute::SExt) {
+        RetAttrs = RetAttrs | Attribute::SExt;
+        $9 = $9 ^ Attribute::SExt;
+      }
+      if ($9 & Attribute::InReg) {
+        RetAttrs = RetAttrs | Attribute::InReg;
+        $9 = $9 ^ Attribute::InReg;
+      }
+    }
+    if (RetAttrs != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+    
+    // Check the arguments
     ValueList Args;
-    if ($6->empty()) {                                   // Has no arguments?
+    if ($7->empty()) {                                   // Has no arguments?
       // Make sure no arguments is a good thing!
       if (Ty->getNumParams() != 0)
         GEN_ERROR("No arguments passed to a function that "
@@ -3013,7 +3361,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
       // correctly.  Also, gather any parameter attributes.
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $7->begin(), ArgE = $7->end();
       unsigned index = 1;
 
       for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
@@ -3021,33 +3369,35 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
           GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" +
                          (*I)->getDescription() + "'");
         Args.push_back(ArgI->Val);
-        if (ArgI->Attrs != ParamAttr::None)
-          Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
+        if (ArgI->Attrs != Attribute::None)
+          Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
       }
       if (Ty->isVarArg()) {
         if (I == E)
           for (; ArgI != ArgE; ++ArgI, ++index) {
             Args.push_back(ArgI->Val); // push the remaining varargs
-            if (ArgI->Attrs != ParamAttr::None)
-              Attrs.push_back(ParamAttrsWithIndex::get(index, ArgI->Attrs));
+            if (ArgI->Attrs != Attribute::None)
+              Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs));
           }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
+    if ($9 != Attribute::None)
+      Attrs.push_back(AttributeWithIndex::get(~0, $9));
 
-    // Finish off the ParamAttrs and check them
-    PAListPtr PAL;
+    // Finish off the Attributes and check them
+    AttrListPtr PAL;
     if (!Attrs.empty())
-      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+      PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
 
     // Create the call node
     CallInst *CI = CallInst::Create(V, Args.begin(), Args.end());
     CI->setTailCall($1);
     CI->setCallingConv($2);
-    CI->setParamAttrs(PAL);
+    CI->setAttributes(PAL);
     $$ = CI;
-    delete $6;
-    delete $3;
+    delete $7;
+    delete $4;
     CHECK_FOR_ERROR
   }
   | MemoryInst {
@@ -3076,6 +3426,8 @@ MemoryInst : MALLOC Types OptCAlign {
   | MALLOC Types ',' INTTYPE ValueRef OptCAlign {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if ($4 != Type::Int32Ty)
+      GEN_ERROR("Malloc array size is not a 32-bit integer!");
     Value* tmpVal = getVal($4, $5);
     CHECK_FOR_ERROR
     $$ = new MallocInst(*$2, tmpVal, $6);
@@ -3091,6 +3443,8 @@ MemoryInst : MALLOC Types OptCAlign {
   | ALLOCA Types ',' INTTYPE ValueRef OptCAlign {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if ($4 != Type::Int32Ty)
+      GEN_ERROR("Alloca array size is not a 32-bit integer!");
     Value* tmpVal = getVal($4, $5);
     CHECK_FOR_ERROR
     $$ = new AllocaInst(*$2, tmpVal, $6);
@@ -3098,7 +3452,7 @@ MemoryInst : MALLOC Types OptCAlign {
   }
   | FREE ResolvedVal {
     if (!isa<PointerType>($2->getType()))
-      GEN_ERROR("Trying to free nonpointer type " + 
+      GEN_ERROR("Trying to free nonpointer type " +
                      $2->getType()->getDescription() + "");
     $$ = new FreeInst($2);
     CHECK_FOR_ERROR
@@ -3135,13 +3489,19 @@ MemoryInst : MALLOC Types OptCAlign {
     $$ = new StoreInst($3, tmpVal, $1, $7);
     delete $5;
   }
-| GETRESULT Types SymbolicValueRef ',' EUINT64VAL  {
-  Value *TmpVal = getVal($2->get(), $3);
-  if (!GetResultInst::isValidOperands(TmpVal, $5))
-      GEN_ERROR("Invalid getresult operands");
-    $$ = new GetResultInst(TmpVal, $5);
-    delete $2;
+  | GETRESULT Types ValueRef ',' EUINT64VAL  {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("getresult insn requires an aggregate operand");
+    if (!ExtractValueInst::getIndexedType(*$2, $5))
+      GEN_ERROR("Invalid getresult index for type '" +
+                     (*$2)->getDescription()+ "'");
+
+    Value *tmpVal = getVal(*$2, $3);
     CHECK_FOR_ERROR
+    $$ = ExtractValueInst::Create(tmpVal, $5);
+    delete $2;
   }
   | GETELEMENTPTR Types ValueRef IndexList {
     if (!UpRefs.empty())
@@ -3149,14 +3509,46 @@ MemoryInst : MALLOC Types OptCAlign {
     if (!isa<PointerType>($2->get()))
       GEN_ERROR("getelementptr insn requires pointer operand");
 
-    if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end(), true))
+    if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end()))
       GEN_ERROR("Invalid getelementptr indices for type '" +
                      (*$2)->getDescription()+ "'");
     Value* tmpVal = getVal(*$2, $3);
     CHECK_FOR_ERROR
     $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
-    delete $2; 
+    delete $2;
+    delete $4;
+  }
+  | EXTRACTVALUE Types ValueRef ConstantIndexList {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+    if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end()))
+      GEN_ERROR("Invalid extractvalue indices for type '" +
+                     (*$2)->getDescription()+ "'");
+    Value* tmpVal = getVal(*$2, $3);
+    CHECK_FOR_ERROR
+    $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end());
+    delete $2;
     delete $4;
+  }
+  | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList {
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("extractvalue insn requires an aggregate operand");
+
+    if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get())
+      GEN_ERROR("Invalid insertvalue indices for type '" +
+                     (*$2)->getDescription()+ "'");
+    Value* aggVal = getVal(*$2, $3);
+    Value* tmpVal = getVal(*$5, $6);
+    CHECK_FOR_ERROR
+    $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end());
+    delete $2;
+    delete $5;
+    delete $7;
   };
 
 
@@ -3228,7 +3620,7 @@ int yyerror(const char *ErrorMsg) {
   std::string errMsg = where + "error: " + std::string(ErrorMsg);
   if (yychar != YYEMPTY && yychar != 0) {
     errMsg += " while reading token: '";
-    errMsg += std::string(LLLgetTokenStart(), 
+    errMsg += std::string(LLLgetTokenStart(),
                           LLLgetTokenStart()+LLLgetTokenLength()) + "'";
   }
   GenerateError(errMsg);