Move FN_NOTE_AlwaysInline and other out of ParamAttrs namespace.
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index f93fe06d7e148ac77e67fb606808ddf5818d1f79..5de34a722c7b8e793da8b2a0393e049a868bb4d5 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -18,6 +18,7 @@
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/ValueSymbolTable.h"
+#include "llvm/AutoUpgrade.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/ADT/SmallVector.h"
@@ -28,9 +29,6 @@
 #include <list>
 #include <map>
 #include <utility>
-#ifndef NDEBUG
-#define YYDEBUG 1
-#endif
 
 // 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
@@ -50,15 +48,6 @@ static bool TriggerError = false;
 int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
 int yylex();                       // declaration" of xxx warnings.
 int yyparse();
-
-namespace llvm {
-  std::string CurFilename;
-#if YYDEBUG
-static cl::opt<bool>
-Debug("debug-yacc", cl::desc("Print yacc debug state changes"), 
-      cl::Hidden, cl::init(false));
-#endif
-}
 using namespace llvm;
 
 static Module *ParserResult;
@@ -131,6 +120,11 @@ static struct PerModuleInfo {
       return;
     }
 
+    // Look for intrinsic functions and CallInst that need to be upgraded
+    for (Module::iterator FI = CurrentModule->begin(),
+         FE = CurrentModule->end(); FI != FE; )
+      UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
+
     Values.clear();         // Clear out function local definitions
     Types.clear();
     CurrentModule = 0;
@@ -255,10 +249,12 @@ 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
@@ -268,10 +264,11 @@ static void InsertValue(Value *V, ValueList &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) {
@@ -384,7 +381,8 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
   // Check to make sure that "Ty" is an integral type, and that our
   // value will fit into the specified type...
   case ValID::ConstSIntVal:    // Is it a constant pool reference??
-    if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+    if (!isa<IntegerType>(Ty) ||
+        !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
       GenerateError("Signed integral constant '" +
                      itostr(D.ConstPool64) + "' is invalid for type '" +
                      Ty->getDescription() + "'");
@@ -393,24 +391,46 @@ static Value *getExistingVal(const Type *Ty, const ValID &D) {
     return ConstantInt::get(Ty, D.ConstPool64, true);
 
   case ValID::ConstUIntVal:     // Is it an unsigned const pool reference?
-    if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
-      if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
-        GenerateError("Integral constant '" + utostr(D.UConstPool64) +
-                       "' is invalid or out of range");
-        return 0;
-      } else {     // This is really a signed reference.  Transmogrify.
-        return ConstantInt::get(Ty, D.ConstPool64, true);
-      }
-    } else {
+    if (isa<IntegerType>(Ty) &&
+        ConstantInt::isValueValidForType(Ty, D.UConstPool64))
       return ConstantInt::get(Ty, D.UConstPool64);
+
+    if (!isa<IntegerType>(Ty) ||
+        !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+      GenerateError("Integral constant '" + utostr(D.UConstPool64) +
+                    "' is invalid or out of range for type '" +
+                    Ty->getDescription() + "'");
+      return 0;
     }
+    // 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;
+      Tmp.extOrTrunc(Ty->getPrimitiveSizeInBits());
+      return ConstantInt::get(Tmp);
+    }
+      
   case ValID::ConstFPVal:        // Is it a floating point const pool reference?
-    if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) {
+    if (!Ty->isFloatingPoint() ||
+        !ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) {
       GenerateError("FP constant invalid for type");
       return 0;
     }
-    return ConstantFP::get(Ty, D.ConstPoolFP);
+    // 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);
 
   case ValID::ConstNullVal:      // Is it a null value?
     if (!isa<PointerType>(Ty)) {
@@ -472,7 +492,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;
   }
 
@@ -490,9 +510,10 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
    }
    const Type* ElTy = PTy->getElementType();
    if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy))
-     V = new Function(FTy, GlobalValue::ExternalLinkage);
+     V = Function::Create(FTy, GlobalValue::ExternalLinkage);
    else
-     V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage);
+     V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "",
+                            (Module*)0, false, PTy->getAddressSpace());
    break;
   }
   default:
@@ -502,7 +523,7 @@ static Value *getVal(const Type *Ty, const ValID &ID) {
   // 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,
-                                                               llvmAsmlineno)));
+                                                              LLLgetLineNo())));
 
   if (inFunctionScope())
     InsertValue(V, CurFun.LateResolveValues);
@@ -543,21 +564,18 @@ static BasicBlock *defineBBVal(const ValID &ID) {
       assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
       InsertValue(BB);
     }
-
-    ID.destroy();
-    return BB;
-  } 
-  
-  // We haven't seen this BB before and its first mention is a definition. 
-  // Just create it and return it.
-  std::string Name (ID.Type == ValID::LocalName ? ID.getName() : "");
-  BB = new BasicBlock(Name, CurFun.CurrentFunction);
-  if (ID.Type == ValID::LocalID) {
-    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. 
+    // Just create it and return it.
+    std::string Name (ID.Type == ValID::LocalName ? ID.getName() : "");
+    BB = BasicBlock::Create(Name, CurFun.CurrentFunction);
+    if (ID.Type == ValID::LocalID) {
+      assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
+      InsertValue(BB);
+    }
   }
 
-  ID.destroy(); // Free strdup'd memory
+  ID.destroy();
   return BB;
 }
 
@@ -574,12 +592,13 @@ static BasicBlock *getBBVal(const ValID &ID) {
   } if (ID.Type == ValID::LocalName) {
     std::string Name = ID.getName();
     Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name);
-    if (N)
+    if (N) {
       if (N->getType()->getTypeID() == Type::LabelTyID)
         BB = cast<BasicBlock>(N);
       else
         GenerateError("Reference to label '" + Name + "' is actually of type '"+
           N->getType()->getDescription() + "'");
+    }
   } else if (ID.Type == ValID::LocalID) {
     if (ID.Num < CurFun.NextValNum && ID.Num < CurFun.Values.size()) {
       if (CurFun.Values[ID.Num]->getType()->getTypeID() == Type::LabelTyID)
@@ -604,7 +623,7 @@ static BasicBlock *getBBVal(const ValID &ID) {
   std::string Name;
   if (ID.Type == ValID::LocalName)
     Name = ID.getName();
-  BB = new BasicBlock(Name, CurFun.CurrentFunction);
+  BB = BasicBlock::Create(Name, CurFun.CurrentFunction);
 
   // Insert it in the forward refs map.
   CurFun.BBForwardRefs[ID] = BB;
@@ -723,13 +742,18 @@ ParseGlobalVariable(std::string *NameStr,
                     GlobalValue::LinkageTypes Linkage,
                     GlobalValue::VisibilityTypes Visibility,
                     bool isConstantGlobal, const Type *Ty,
-                    Constant *Initializer, bool IsThreadLocal) {
+                    Constant *Initializer, bool IsThreadLocal,
+                    unsigned AddressSpace = 0) {
   if (isa<FunctionType>(Ty)) {
     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);
+  const PointerType *PTy = PointerType::get(Ty, AddressSpace);
 
   std::string Name;
   if (NameStr) {
@@ -781,7 +805,7 @@ ParseGlobalVariable(std::string *NameStr,
   // Otherwise there is no existing GV to use, create one now.
   GlobalVariable *GV =
     new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
-                       CurModule.CurrentModule, IsThreadLocal);
+                       CurModule.CurrentModule, IsThreadLocal, AddressSpace);
   GV->setVisibility(Visibility);
   InsertValue(GV, CurModule.Values);
   return GV;
@@ -934,22 +958,11 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
 //
 static Module* RunParser(Module * M);
 
-Module *llvm::RunVMAsmParser(const std::string &Filename, FILE *F) {
-  set_scan_file(F);
-
-  CurFilename = Filename;
-  return RunParser(new Module(CurFilename));
-}
-
-Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
-  set_scan_string(AsmString);
-
-  CurFilename = "from_memory";
-  if (M == NULL) {
-    return RunParser(new Module (CurFilename));
-  } else {
-    return RunParser(M);
-  }
+Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
+  InitLLLexer(MB);
+  Module *M = RunParser(new Module(LLLgetFilename()));
+  FreeLexer();
+  return M;
 }
 
 %}
@@ -967,10 +980,11 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
   llvm::PATypeHolder                     *TypeVal;
   llvm::Value                            *ValueVal;
   std::vector<llvm::Value*>              *ValueList;
+  std::vector<unsigned>                  *ConstantList;
   llvm::ArgListType                      *ArgList;
   llvm::TypeWithAttrs                     TypeWithAttrs;
   llvm::TypeWithAttrsList                *TypeWithAttrsList;
-  llvm::ValueRefList                     *ValueRefList;
+  llvm::ParamList                        *ParamList;
 
   // Represent the RHS of PHI node
   std::list<std::pair<llvm::Value*,
@@ -980,13 +994,13 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 
   llvm::GlobalValue::LinkageTypes         Linkage;
   llvm::GlobalValue::VisibilityTypes      Visibility;
-  uint16_t                          ParamAttrs;
+  llvm::Attributes                  ParamAttrs;
   llvm::APInt                       *APIntVal;
   int64_t                           SInt64Val;
   uint64_t                          UInt64Val;
   int                               SIntVal;
   unsigned                          UIntVal;
-  double                            FPVal;
+  llvm::APFloat                    *FPVal;
   bool                              BoolVal;
 
   std::string                      *StrVal;   // This memory must be deleted
@@ -1010,8 +1024,9 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %type <ConstVector>   ConstVector
 %type <ArgList>       ArgList ArgListH
 %type <PHIList>       PHIList
-%type <ValueRefList>  ValueRefList      // For call param lists & GEP indices
+%type <ParamList>     ParamList      // For call param lists & GEP indices
 %type <ValueList>     IndexList         // For GEP indices
+%type <ConstantList>  ConstantIndexList // For insertvalue/extractvalue indices
 %type <TypeList>      TypeListI 
 %type <TypeWithAttrsList> ArgTypeList ArgTypeListI
 %type <TypeWithAttrs> ArgType
@@ -1029,6 +1044,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 // ValueRef - Unresolved reference to a definition or BB
 %type <ValIDVal>      ValueRef ConstValueRef SymbolicValueRef
 %type <ValueVal>      ResolvedVal            // <type> <valref> pair
+%type <ValueList>     ReturnedVal
 // Tokens and types for handling constant integer values
 //
 // ESINT64VAL - A negative number within long long range
@@ -1058,21 +1074,24 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %token<StrVal> STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT
 %type <StrVal> LocalName OptLocalName OptLocalAssign
 %type <StrVal> GlobalName OptGlobalAssign GlobalAssign
-%type <StrVal> OptSection SectionString
+%type <StrVal> OptSection SectionString OptGC
 
-%type <UIntVal> OptAlign OptCAlign
+%type <UIntVal> OptAlign OptCAlign OptAddrSpace
 
 %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 OPAQUE EXTERNAL TARGET TRIPLE ALIGN
+%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 X86_SSECALLCC_TOK
 %token DATALAYOUT
-%type <UIntVal> OptCallingConv
+%type <UIntVal> OptCallingConv LocalNumber
 %type <ParamAttrs> OptParamAttrs ParamAttr 
 %type <ParamAttrs> OptFuncAttrs  FuncAttr
+%type <ParamAttrs> OptFuncNotes FuncNote 
+%type <ParamAttrs> FuncNoteList
 
 // Basic Block Terminating Operators
 %token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
@@ -1082,7 +1101,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 %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 
@@ -1099,9 +1118,15 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
 // Other Operators
 %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
+
+// Function Notes
+%token FNNOTE INLINE ALWAYS NEVER OPTIMIZEFORSIZE
 
 // Visibility Styles
 %token DEFAULT HIDDEN PROTECTED
@@ -1146,6 +1171,9 @@ FPType   : FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80;
 LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
 OptLocalName : LocalName | /*empty*/ { $$ = 0; };
 
+OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; }
+             | /*empty*/                    { $$=0; };
+
 /// OptLocalAssign - Value producing statements have an optional assignment
 /// component.
 OptLocalAssign : LocalName '=' {
@@ -1157,6 +1185,12 @@ OptLocalAssign : LocalName '=' {
     CHECK_FOR_ERROR
   };
 
+LocalNumber : LOCALVAL_ID '=' {
+  $$ = $1;
+  CHECK_FOR_ERROR
+};
+
+
 GlobalName : GLOBALVAR | ATSTRINGCONSTANT ;
 
 OptGlobalAssign : GlobalAssign
@@ -1176,6 +1210,7 @@ GVInternalLinkage
   | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; }
   | APPENDING   { $$ = GlobalValue::AppendingLinkage; }
   | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } 
+  | COMMON      { $$ = GlobalValue::CommonLinkage; }
   ;
 
 GVExternalLinkage
@@ -1217,6 +1252,7 @@ OptCallingConv : /*empty*/          { $$ = CallingConv::C; } |
                  COLDCC_TOK         { $$ = CallingConv::Cold; } |
                  X86_STDCALLCC_TOK  { $$ = CallingConv::X86_StdCall; } |
                  X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } |
+                 X86_SSECALLCC_TOK  { $$ = CallingConv::X86_SSECall; } |
                  CC_TOK EUINT64VAL  {
                    if ((unsigned)$2 != $2)
                      GEN_ERROR("Calling conv too large");
@@ -1233,6 +1269,8 @@ ParamAttr     : ZEROEXT { $$ = ParamAttr::ZExt;      }
               | NOALIAS { $$ = ParamAttr::NoAlias;   }
               | BYVAL   { $$ = ParamAttr::ByVal;     }
               | NEST    { $$ = ParamAttr::Nest;      }
+              | ALIGN EUINT64VAL { $$ = 
+                          ParamAttr::constructAlignmentFromInt($2);    }
               ;
 
 OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
@@ -1243,8 +1281,11 @@ OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
 
 FuncAttr      : NORETURN { $$ = ParamAttr::NoReturn; }
               | NOUNWIND { $$ = ParamAttr::NoUnwind; }
+              | INREG    { $$ = ParamAttr::InReg;     }
               | ZEROEXT  { $$ = ParamAttr::ZExt;     }
               | SIGNEXT  { $$ = ParamAttr::SExt;     }
+              | READNONE { $$ = ParamAttr::ReadNone; }
+              | READONLY { $$ = ParamAttr::ReadOnly; }
               ;
 
 OptFuncAttrs  : /* empty */ { $$ = ParamAttr::None; }
@@ -1253,6 +1294,37 @@ OptFuncAttrs  : /* empty */ { $$ = ParamAttr::None; }
               }
               ;
 
+FuncNoteList  : FuncNote { $$ = $1; }
+              | FuncNoteList ',' FuncNote { 
+                unsigned tmp = $1 | $3;
+                if ($3 == FN_NOTE_NoInline 
+                    && ($1 & FN_NOTE_AlwaysInline))
+                  GEN_ERROR("Function Notes may include only one inline notes!")
+                    if ($3 == FN_NOTE_AlwaysInline 
+                        && ($1 & FN_NOTE_NoInline))
+                  GEN_ERROR("Function Notes may include only one inline notes!")
+                $$ = tmp;
+                CHECK_FOR_ERROR 
+              }
+              ;
+
+FuncNote      : INLINE '=' NEVER { $$ = FN_NOTE_NoInline; }
+              | INLINE '=' ALWAYS { $$ = FN_NOTE_AlwaysInline; }
+              | OPTIMIZEFORSIZE { $$ = FN_NOTE_OptimizeForSize; }
+              ;
+
+OptFuncNotes  : /* empty */ { $$ = FN_NOTE_None; }
+              | FNNOTE '(' FuncNoteList  ')' {
+                $$ =  $3;
+              }
+              ;
+
+OptGC         : /* empty */ { $$ = 0; }
+              | GC STRINGCONSTANT {
+                $$ = $2;
+              }
+              ;
+
 // OptAlign/OptCAlign - An optional alignment, and an optional alignment with
 // a comma before it.
 OptAlign : /*empty*/        { $$ = 0; } |
@@ -1271,6 +1343,7 @@ OptCAlign : /*empty*/            { $$ = 0; } |
 };
 
 
+
 SectionString : SECTION STRINGCONSTANT {
   for (unsigned i = 0, e = $2->length(); i != e; ++i)
     if ((*$2)[i] == '"' || (*$2)[i] == '\\')
@@ -1316,10 +1389,10 @@ Types
     $$ = new PATypeHolder($1);
     CHECK_FOR_ERROR
   }
-  | Types '*' {                             // Pointer type?
+  | Types OptAddrSpace '*' {                             // Pointer type?
     if (*$1 == Type::LabelTy)
       GEN_ERROR("Cannot form a pointer to a basic block");
-    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1)));
+    $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2)));
     delete $1;
     CHECK_FOR_ERROR
   }
@@ -1337,68 +1410,61 @@ Types
     CHECK_FOR_ERROR
   }
   | Types '(' ArgTypeListI ')' OptFuncAttrs {
+    // Allow but ignore attributes on function types; this permits auto-upgrade.
+    // FIXME: remove in LLVM 3.0.
+    const Type *RetTy = *$1;
+    if (!FunctionType::isValidReturnType(RetTy))
+      GEN_ERROR("Invalid result type for LLVM function");
+      
     std::vector<const Type*> Params;
-    ParamAttrsVector Attrs;
-    if ($5 != ParamAttr::None) {
-      ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
-      Attrs.push_back(X);
-    }
-    unsigned index = 1;
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
-    for (; I != E; ++I, ++index) {
+    for (; I != E; ++I ) {
       const Type *Ty = I->Ty->get();
       Params.push_back(Ty);
-      if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None) {
-          ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
-          Attrs.push_back(X);
-        }
     }
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    ParamAttrsList *ActualAttrs = 0;
-    if (!Attrs.empty())
-      ActualAttrs = ParamAttrsList::get(Attrs);
-    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
+    for (unsigned i = 0; i != Params.size(); ++i)
+      if (!(Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])))
+        GEN_ERROR("Function arguments must be value 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)); 
     CHECK_FOR_ERROR
   }
   | VOID '(' ArgTypeListI ')' OptFuncAttrs {
+    // Allow but ignore attributes on function types; this permits auto-upgrade.
+    // FIXME: remove in LLVM 3.0.
     std::vector<const Type*> Params;
-    ParamAttrsVector Attrs;
-    if ($5 != ParamAttr::None) {
-      ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
-      Attrs.push_back(X);
-    }
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
-    unsigned index = 1;
-    for ( ; I != E; ++I, ++index) {
+    for ( ; I != E; ++I ) {
       const Type* Ty = I->Ty->get();
       Params.push_back(Ty);
-      if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None) {
-          ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
-          Attrs.push_back(X);
-        }
     }
+
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    ParamAttrsList *ActualAttrs = 0;
-    if (!Attrs.empty())
-      ActualAttrs = ParamAttrsList::get(Attrs);
+    for (unsigned i = 0; i != Params.size(); ++i)
+      if (!(Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])))
+        GEN_ERROR("Function arguments must be value types!");
+
+    CHECK_FOR_ERROR
 
-    FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
+    FunctionType *FT = FunctionType::get($1, Params, isVarArg);
     delete $3;      // Delete the argument list
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     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
   }
@@ -1408,8 +1474,6 @@ Types
         GEN_ERROR("Unsigned result not equal to signed result");
      if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger())
         GEN_ERROR("Element type of a VectorType must be primitive");
-     if (!isPowerOf2_32($2))
-       GEN_ERROR("Vector length should be a power of 2");
      $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4, (unsigned)$2)));
      delete $4;
      CHECK_FOR_ERROR
@@ -1445,9 +1509,11 @@ Types
   ;
 
 ArgType 
-  : Types OptParamAttrs { 
+  : Types OptParamAttrs {
+    // Allow but ignore attributes on function types; this permits auto-upgrade.
+    // FIXME: remove in LLVM 3.0.
     $$.Ty = $1; 
-    $$.Attrs = $2; 
+    $$.Attrs = ParamAttr::None;
   }
   ;
 
@@ -1455,7 +1521,7 @@ ResultTypes
   : Types {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
-    if (!(*$1)->isFirstClassType())
+    if (!(*$1)->isFirstClassType() && !isa<StructType>($1->get()))
       GEN_ERROR("LLVM functions cannot return aggregate types");
     $$ = $1;
   }
@@ -1525,13 +1591,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       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(NumElements) + "");
 
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $3->size(); i++) {
@@ -1553,10 +1619,10 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       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,15 +1635,15 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       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()))
+    if (NumElements != uint64_t(-1) && NumElements != $3->length())
       GEN_ERROR("Can't build string constant of size " + 
-                     itostr((int)($3->length())) +
-                     " when array has size " + itostr(NumElements) + "");
+                     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,13 +1662,13 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       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(NumElements) + "");
 
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $3->size(); i++) {
@@ -1732,7 +1798,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
       GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
     const PointerType *Ty = dyn_cast<PointerType>($1->get());
     if (Ty == 0)
-      GEN_ERROR("Global const reference must be a pointer type");
+      GEN_ERROR("Global const reference must be a pointer type " + (*$1)->getDescription());
 
     // ConstExprs can exist in the body of a function, thus creating
     // GlobalValues whenever they refer to a variable.  Because we are in
@@ -1775,8 +1841,8 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
         GlobalValue *GV;
         if (const FunctionType *FTy = 
                  dyn_cast<FunctionType>(PT->getElementType())) {
-          GV = new Function(FTy, GlobalValue::ExternalWeakLinkage, Name,
-                            CurModule.CurrentModule);
+          GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name,
+                                CurModule.CurrentModule);
         } else {
           GV = new GlobalVariable(PT->getElementType(), false,
                                   GlobalValue::ExternalWeakLinkage, 0,
@@ -1846,19 +1912,26 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
     CHECK_FOR_ERROR
   }
   | INTTYPE TRUETOK {                      // Boolean constants
-    assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+    if (cast<IntegerType>($1)->getBitWidth() != 1)
+      GEN_ERROR("Constant true must have type i1");
     $$ = ConstantInt::getTrue();
     CHECK_FOR_ERROR
   }
   | INTTYPE FALSETOK {                     // Boolean constants
-    assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
+    if (cast<IntegerType>($1)->getBitWidth() != 1)
+      GEN_ERROR("Constant false must have type i1");
     $$ = ConstantInt::getFalse();
     CHECK_FOR_ERROR
   }
-  | FPType FPVAL {                   // Float & Double constants
-    if (!ConstantFP::isValueValidForType($1, $2))
+  | FPType FPVAL {                   // Floating point constants
+    if (!ConstantFP::isValueValidForType($1, *$2))
       GEN_ERROR("Floating point constant invalid for type");
-    $$ = ConstantFP::get($1, $2);
+    // 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);
+    $$ = ConstantFP::get(*$2);
+    delete $2;
     CHECK_FOR_ERROR
   };
 
@@ -1880,8 +1953,7 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
       GEN_ERROR("GetElementPtr requires a pointer operand");
 
     const Type *IdxTy =
-      GetElementPtrInst::getIndexedType($3->getType(), &(*$4)[0], $4->size(),
-                                        true);
+      GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end());
     if (!IdxTy)
       GEN_ERROR("Index list invalid for constant getelementptr");
 
@@ -1915,7 +1987,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");
     }
@@ -1932,6 +2004,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");
@@ -1949,6 +2031,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
   };
 
 
@@ -1974,6 +2072,7 @@ ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; };
 AliaseeRef : ResultTypes SymbolicValueRef {
     const Type* VTy = $1->get();
     Value *V = getVal(VTy, $2);
+    CHECK_FOR_ERROR
     GlobalValue* Aliasee = dyn_cast<GlobalValue>(V);
     if (!Aliasee)
       GEN_ERROR("Aliases can be created only to global values");
@@ -2066,30 +2165,31 @@ Definition
     }
     CHECK_FOR_ERROR
   }
-  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal { 
+  | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal 
+    OptAddrSpace { 
     /* "Externally Visible" Linkage */
     if ($5 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
     CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
-                                $2, $4, $5->getType(), $5, $3);
+                                $2, $4, $5->getType(), $5, $3, $6);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType
-    ConstVal {
+    ConstVal OptAddrSpace {
     if ($6 == 0) 
       GEN_ERROR("Global value initializer is not a constant");
-    CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7);
     CHECK_FOR_ERROR
   } GlobalVarAttributes {
     CurGV = 0;
   }
   | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType
-    Types {
+    Types OptAddrSpace {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
-    CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
+    CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7);
     CHECK_FOR_ERROR
     delete $6;
   } GlobalVarAttributes {
@@ -2113,6 +2213,27 @@ 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.
+      FWGV->replaceAllUsesWith(GA);
+      if (GlobalVariable *GV = dyn_cast<GlobalVariable>(FWGV))
+        GV->eraseFromParent();
+      else
+        cast<Function>(FWGV)->eraseFromParent();
+    }
+    ID.destroy();
+    
     CHECK_FOR_ERROR
   }
   | TARGET TargetDefinition { 
@@ -2167,8 +2288,8 @@ LibList : LibList ',' STRINGCONSTANT {
 ArgListH : ArgListH ',' Types OptParamAttrs 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);
@@ -2177,8 +2298,8 @@ ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
   | Types OptParamAttrs 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);
@@ -2213,7 +2334,7 @@ ArgList : ArgListH {
   };
 
 FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')' 
-                  OptFuncAttrs OptSection OptAlign {
+                  OptFuncAttrs OptSection OptAlign OptGC OptFuncNotes {
   std::string FunctionName(*$3);
   delete $3;  // Free strdup'd memory!
   
@@ -2222,12 +2343,13 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
   if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
     GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
 
+  if (!FunctionType::isValidReturnType(*$2))
+    GEN_ERROR("Invalid result type for LLVM function");
+    
   std::vector<const Type*> ParamTypeList;
-  ParamAttrsVector Attrs;
-  if ($7 != ParamAttr::None) {
-    ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $7;
-    Attrs.push_back(PAWI);
-  }
+  SmallVector<ParamAttrsWithIndex, 8> Attrs;
+  if ($7 != ParamAttr::None)
+    Attrs.push_back(ParamAttrsWithIndex::get(0, $7));
   if ($5) {   // If there are arguments...
     unsigned index = 1;
     for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
@@ -2235,23 +2357,20 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
       if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty))
         GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
       ParamTypeList.push_back(Ty);
-      if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None) {
-          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
-          Attrs.push_back(PAWI);
-        }
+      if (Ty != Type::VoidTy && I->Attrs != ParamAttr::None)
+        Attrs.push_back(ParamAttrsWithIndex::get(index, I->Attrs));
     }
   }
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  ParamAttrsList *PAL = 0;
+  PAListPtr PAL;
   if (!Attrs.empty())
-    PAL = ParamAttrsList::get(Attrs);
+    PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, PAL);
-  const PointerType *PFT = PointerType::get(FT);
+  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
+  const PointerType *PFT = PointerType::getUnqual(FT);
   delete $2;
 
   ValID ID;
@@ -2267,28 +2386,33 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     // Move the function to the end of the list, from whereever it was 
     // previously inserted.
     Fn = cast<Function>(FWRef);
+    assert(Fn->getParamAttrs().isEmpty() &&
+           "Forward reference has parameter attributes!");
     CurModule.CurrentModule->getFunctionList().remove(Fn);
     CurModule.CurrentModule->getFunctionList().push_back(Fn);
   } else if (!FunctionName.empty() &&     // Merge with an earlier prototype?
              (Fn = CurModule.CurrentModule->getFunction(FunctionName))) {
-    if (Fn->getFunctionType() != FT) {
+    if (Fn->getFunctionType() != FT ) {
       // 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) {
+      // The existing function doesn't have the same parameter attributes.
+      // This is an overload error.
+      GEN_ERROR("Overload of function '" + FunctionName + "' not permitted.");
     } else if (!CurFun.isDeclare && !Fn->isDeclaration()) {
       // Neither the existing or the current function is a declaration and they
       // have the same name and same type. Clearly this is a redefinition.
       GEN_ERROR("Redefinition of function '" + FunctionName + "'");
-    } if (Fn->isDeclaration()) {
+    } else if (Fn->isDeclaration()) {
       // Make sure to strip off any argument names so we can't get conflicts.
       for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end();
            AI != AE; ++AI)
         AI->setName("");
     }
   } else  {  // Not already defined?
-    Fn = new Function(FT, GlobalValue::ExternalWeakLinkage, FunctionName,
-                      CurModule.CurrentModule);
-
+    Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName,
+                          CurModule.CurrentModule);
     InsertValue(Fn, CurModule.Values);
   }
 
@@ -2302,11 +2426,19 @@ 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;
   }
+  if ($10) {
+    Fn->setGC($10->c_str());
+    delete $10;
+  }
+  if ($11) {
+    Fn->setNotes($11);
+  }
 
   // Add all of the arguments we parsed to the function...
   if ($5) {                     // Is null if empty...
@@ -2380,6 +2512,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
@@ -2406,16 +2548,13 @@ 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++) {
@@ -2429,6 +2568,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
@@ -2478,6 +2693,16 @@ ResolvedVal : Types ValueRef {
   }
   ;
 
+ReturnedVal : ResolvedVal {
+    $$ = new std::vector<Value *>();
+    $$->push_back($1); 
+    CHECK_FOR_ERROR
+  }
+  | ReturnedVal ',' ResolvedVal {
+    ($$=$1)->push_back($3); 
+    CHECK_FOR_ERROR
+  };
+
 BasicBlockList : BasicBlockList BasicBlock {
     $$ = $1;
     CHECK_FOR_ERROR
@@ -2491,7 +2716,7 @@ BasicBlockList : BasicBlockList BasicBlock {
 // 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);
@@ -2500,6 +2725,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)))
@@ -2520,35 +2758,53 @@ InstructionList : InstructionList Inst {
 
   };
 
-BBTerminatorInst : RET ResolvedVal {              // Return with a result...
-    $$ = new ReturnInst($2);
+BBTerminatorInst : 
+  RET ReturnedVal  { // Return with a result...
+    ValueList &VL = *$2;
+    assert(!VL.empty() && "Invalid ret operands!");
+    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
   }
   | RET VOID {                                    // Return with no result...
-    $$ = new ReturnInst();
+    $$ = ReturnInst::Create();
     CHECK_FOR_ERROR
   }
   | BR LABEL ValueRef {                           // Unconditional Branch...
     BasicBlock* tmpBB = getBBVal($3);
     CHECK_FOR_ERROR
-    $$ = new BranchInst(tmpBB);
+    $$ = BranchInst::Create(tmpBB);
   }                                               // Conditional Branch...
   | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {  
-    assert(cast<IntegerType>($2)->getBitWidth() == 1 && "Not Bool?");
+    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);
     CHECK_FOR_ERROR
     Value* tmpVal = getVal(Type::Int1Ty, $3);
     CHECK_FOR_ERROR
-    $$ = new BranchInst(tmpBBA, tmpBBB, tmpVal);
+    $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal);
   }
   | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
     Value* tmpVal = getVal($2, $3);
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
     CHECK_FOR_ERROR
-    SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size());
+    SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, $8->size());
     $$ = S;
 
     std::vector<std::pair<Constant*,BasicBlock*> >::iterator I = $8->begin(),
@@ -2567,11 +2823,11 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     CHECK_FOR_ERROR
     BasicBlock* tmpBB = getBBVal($6);
     CHECK_FOR_ERROR
-    SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0);
+    SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, 0);
     $$ = S;
     CHECK_FOR_ERROR
   }
-  | INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs
+  | INVOKE OptCallingConv ResultTypes ValueRef '(' ParamList ')' OptFuncAttrs
     TO LABEL ValueRef UNWIND LABEL ValueRef {
 
     // Handle the short syntax
@@ -2581,29 +2837,19 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamAttrsVector Attrs;
-      if ($8 != ParamAttr::None) {
-        ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
-        Attrs.push_back(PAWI);
-      }
-      ValueRefList::iterator I = $6->begin(), E = $6->end();
-      unsigned index = 1;
-      for (; I != E; ++I, ++index) {
+      ParamList::iterator I = $6->begin(), E = $6->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 (I->Attrs != ParamAttr::None) {
-          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
-          Attrs.push_back(PAWI);
-        }
       }
+      
+      if (!FunctionType::isValidReturnType(*$3))
+        GEN_ERROR("Invalid result type for LLVM function");
 
-      ParamAttrsList *PAL = 0;
-      if (!Attrs.empty())
-        PAL = ParamAttrsList::get(Attrs);
-      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
-      PFTy = PointerType::get(Ty);
+      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      PFTy = PointerType::getUnqual(Ty);
     }
 
     delete $3;
@@ -2615,6 +2861,10 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
     BasicBlock *Except = getBBVal($14);
     CHECK_FOR_ERROR
 
+    SmallVector<ParamAttrsWithIndex, 8> Attrs;
+    if ($8 != ParamAttr::None)
+      Attrs.push_back(ParamAttrsWithIndex::get(0, $8));
+
     // Check the arguments
     ValueList Args;
     if ($6->empty()) {                                   // Has no arguments?
@@ -2627,26 +2877,38 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
       // correctly!
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      unsigned index = 1;
 
-      for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+      for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
         if (ArgI->Val->getType() != *I)
           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 (Ty->isVarArg()) {
         if (I == E)
-          for (; ArgI != ArgE; ++ArgI)
+          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));
+          }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
 
+    PAListPtr PAL;
+    if (!Attrs.empty())
+      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+
     // Create the InvokeInst
-    InvokeInst *II = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+    InvokeInst *II = InvokeInst::Create(V, Normal, Except,
+                                        Args.begin(), Args.end());
     II->setCallingConv($2);
+    II->setParamAttrs(PAL);
     $$ = II;
     delete $6;
     CHECK_FOR_ERROR
@@ -2695,6 +2957,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())
@@ -2717,25 +2991,43 @@ PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes
   };
 
 
-ValueRefList : Types ValueRef OptParamAttrs {    
+ParamList : Types OptParamAttrs ValueRef OptParamAttrs {
+    // FIXME: Remove trailing OptParamAttrs 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
-    $$ = new ValueRefList();
-    ValueRefListEntry E; E.Attrs = $3; E.Val = getVal($1->get(), $2);
+    $$ = new ParamList();
+    ParamListEntry E; E.Attrs = $2 | $4; E.Val = getVal($1->get(), $3);
     $$->push_back(E);
     delete $1;
+    CHECK_FOR_ERROR
+  }
+  | LABEL OptParamAttrs ValueRef OptParamAttrs {
+    // FIXME: Remove trailing OptParamAttrs 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
   }
-  | ValueRefList ',' Types ValueRef OptParamAttrs {
+  | ParamList ',' Types OptParamAttrs ValueRef OptParamAttrs {
+    // FIXME: Remove trailing OptParamAttrs in LLVM 3.0, it was a mistake in 2.0
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
     $$ = $1;
-    ValueRefListEntry E; E.Attrs = $5; E.Val = getVal($3->get(), $4);
+    ParamListEntry E; E.Attrs = $4 | $6; E.Val = getVal($3->get(), $5);
     $$->push_back(E);
     delete $3;
     CHECK_FOR_ERROR
   }
-  | /*empty*/ { $$ = new ValueRefList(); };
+  | ParamList ',' LABEL OptParamAttrs ValueRef OptParamAttrs {
+    // FIXME: Remove trailing OptParamAttrs 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);
+    CHECK_FOR_ERROR
+  }
+  | /*empty*/ { $$ = new ParamList(); };
 
 IndexList       // Used for gep instructions and constant expressions
   : /*empty*/ { $$ = new std::vector<Value*>(); }
@@ -2746,6 +3038,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
@@ -2762,16 +3070,11 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         !isa<VectorType>((*$2).get()))
       GEN_ERROR(
         "Arithmetic operator requires integer, FP, or packed operands");
-    if (isa<VectorType>((*$2).get()) && 
-        ($1 == Instruction::URem || 
-         $1 == Instruction::SRem ||
-         $1 == Instruction::FRem))
-      GEN_ERROR("Remainder not supported on vector types");
     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;
@@ -2780,7 +3083,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");
     }
@@ -2788,7 +3091,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;
@@ -2796,13 +3099,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;
@@ -2810,17 +3111,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());
@@ -2830,15 +3157,28 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
       GEN_ERROR("invalid cast opcode for cast from '" +
                 Val->getType()->getDescription() + "' to '" +
                 DestTy->getDescription() + "'"); 
-    $$ = CastInst::create($1, Val, DestTy);
+    $$ = 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");
-    $$ = new SelectInst($2, $4, $6);
+      GEN_ERROR("select value types must match");
+    $$ = SelectInst::Create($2, $4, $6);
     CHECK_FOR_ERROR
   }
   | VAARG ResolvedVal ',' Types {
@@ -2857,7 +3197,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
   | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
     if (!InsertElementInst::isValidOperands($2, $4, $6))
       GEN_ERROR("Invalid insertelement operands");
-    $$ = new InsertElementInst($2, $4, $6);
+    $$ = InsertElementInst::Create($2, $4, $6);
     CHECK_FOR_ERROR
   }
   | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal {
@@ -2870,7 +3210,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     const Type *Ty = $2->front().first->getType();
     if (!Ty->isFirstClassType())
       GEN_ERROR("PHI node operands must be of first class type");
-    $$ = new PHINode(Ty);
+    $$ = PHINode::Create(Ty);
     ((PHINode*)$$)->reserveOperandSpace($2->size());
     while ($2->begin() != $2->end()) {
       if ($2->front().first->getType() != Ty) 
@@ -2881,7 +3221,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     delete $2;  // Free the list...
     CHECK_FOR_ERROR
   }
-  | OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' 
+  | OptTailCall OptCallingConv ResultTypes ValueRef '(' ParamList ')' 
     OptFuncAttrs {
 
     // Handle the short syntax
@@ -2891,30 +3231,19 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamAttrsVector Attrs;
-      if ($8 != ParamAttr::None) {
-        ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
-        Attrs.push_back(PAWI);
-      }
-      unsigned index = 1;
-      ValueRefList::iterator I = $6->begin(), E = $6->end();
-      for (; I != E; ++I, ++index) {
+      ParamList::iterator I = $6->begin(), E = $6->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 (I->Attrs != ParamAttr::None) {
-          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
-          Attrs.push_back(PAWI);
-        }
       }
 
-      ParamAttrsList *PAL = 0;
-      if (!Attrs.empty())
-        PAL = ParamAttrsList::get(Attrs);
+      if (!FunctionType::isValidReturnType(*$3))
+        GEN_ERROR("Invalid result type for LLVM function");
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
-      PFTy = PointerType::get(Ty);
+      Ty = FunctionType::get($3->get(), ParamTypes, false);
+      PFTy = PointerType::getUnqual(Ty);
     }
 
     Value *V = getVal(PFTy, $4);   // Get the function we're calling...
@@ -2929,6 +3258,10 @@ 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 
     ValueList Args;
     if ($6->empty()) {                                   // Has no arguments?
@@ -2938,29 +3271,41 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
                        "expects arguments");
     } else {                                     // Has arguments?
       // Loop through FunctionType's arguments and ensure they are specified
-      // correctly!
-      //
+      // correctly.  Also, gather any parameter attributes.
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
-      ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      ParamList::iterator ArgI = $6->begin(), ArgE = $6->end();
+      unsigned index = 1;
 
-      for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
+      for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) {
         if (ArgI->Val->getType() != *I)
           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 (Ty->isVarArg()) {
         if (I == E)
-          for (; ArgI != ArgE; ++ArgI)
+          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));
+          }
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
+
+    // Finish off the ParamAttrs and check them
+    PAListPtr PAL;
+    if (!Attrs.empty())
+      PAL = PAListPtr::get(Attrs.begin(), Attrs.end());
+
     // Create the call node
-    CallInst *CI = new CallInst(V, Args.begin(), Args.end());
+    CallInst *CI = CallInst::Create(V, Args.begin(), Args.end());
     CI->setTailCall($1);
     CI->setCallingConv($2);
+    CI->setParamAttrs(PAL);
     $$ = CI;
     delete $6;
     delete $3;
@@ -2992,6 +3337,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);
@@ -3007,6 +3354,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);
@@ -3051,20 +3400,66 @@ MemoryInst : MALLOC Types OptCAlign {
     $$ = new StoreInst($3, tmpVal, $1, $7);
     delete $5;
   }
+  | 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())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!isa<PointerType>($2->get()))
       GEN_ERROR("getelementptr insn requires pointer operand");
 
-    if (!GetElementPtrInst::getIndexedType(*$2, &(*$4)[0], $4->size(), 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
-    $$ = new GetElementPtrInst(tmpVal, &(*$4)[0], $4->size());
+    $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end());
     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;
   };
 
 
@@ -3072,13 +3467,7 @@ MemoryInst : MALLOC Types OptCAlign {
 
 // common code from the two 'RunVMAsmParser' functions
 static Module* RunParser(Module * M) {
-
-  llvmAsmlineno = 1;      // Reset the current line number...
   CurModule.CurrentModule = M;
-#if YYDEBUG
-  yydebug = Debug;
-#endif
-
   // Check to make sure the parser succeeded
   if (yyparse()) {
     if (ParserResult)
@@ -3130,21 +3519,21 @@ static Module* RunParser(Module * M) {
 }
 
 void llvm::GenerateError(const std::string &message, int LineNo) {
-  if (LineNo == -1) LineNo = llvmAsmlineno;
+  if (LineNo == -1) LineNo = LLLgetLineNo();
   // TODO: column number in exception
   if (TheParseError)
-    TheParseError->setError(CurFilename, message, LineNo);
+    TheParseError->setError(LLLgetFilename(), message, LineNo);
   TriggerError = 1;
 }
 
 int yyerror(const char *ErrorMsg) {
-  std::string where 
-    = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
-                  + ":" + utostr((unsigned) llvmAsmlineno) + ": ";
+  std::string where = LLLgetFilename() + ":" + utostr(LLLgetLineNo()) + ": ";
   std::string errMsg = where + "error: " + std::string(ErrorMsg);
-  if (yychar != YYEMPTY && yychar != 0)
-    errMsg += " while reading token: '" + std::string(llvmAsmtext, llvmAsmleng)+
-              "'";
+  if (yychar != YYEMPTY && yychar != 0) {
+    errMsg += " while reading token: '";
+    errMsg += std::string(LLLgetTokenStart(), 
+                          LLLgetTokenStart()+LLLgetTokenLength()) + "'";
+  }
   GenerateError(errMsg);
   return 0;
 }