Update InvokeInst to work like CallInst
[oota-llvm.git] / tools / llvm-upgrade / UpgradeParser.y
index 9dabc23d7519928e6317c785a76a5138a8ce3f8e..5893fcd5ccc1de8d972f9c8940e6466890a0a67a 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/ADT/STLExtras.h"
@@ -61,6 +62,7 @@ static bool ObsoleteVarArgs;
 static bool NewVarArgs;
 static BasicBlock *CurBB;
 static GlobalVariable *CurGV;
+static unsigned lastCallingConv;
 
 // This contains info used when building the body of a function.  It is
 // destroyed when the function is completed.
@@ -377,14 +379,20 @@ static Signedness getElementSign(const ConstInfo& CI,
 static bool FuncTysDifferOnlyBySRet(const FunctionType *F1, 
                                     const FunctionType *F2) {
   if (F1->getReturnType() != F2->getReturnType() ||
-      F1->getNumParams() != F2->getNumParams() ||
-      F1->getParamAttrs(0) != F2->getParamAttrs(0))
+      F1->getNumParams() != F2->getNumParams())
     return false;
-  unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute);
+  const ParamAttrsList *PAL1 = F1->getParamAttrs();
+  const ParamAttrsList *PAL2 = F2->getParamAttrs();
+  if (PAL1 && !PAL2 || PAL2 && !PAL1)
+    return false;
+  if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) ||
+      (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0)))) 
+    return false;
+  unsigned SRetMask = ~unsigned(ParamAttr::StructRet);
   for (unsigned i = 0; i < F1->getNumParams(); ++i) {
-    if (F1->getParamType(i) != F2->getParamType(i) ||
-        unsigned(F1->getParamAttrs(i+1)) & SRetMask !=
-        unsigned(F2->getParamAttrs(i+1)) & SRetMask)
+    if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 &&
+        (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask !=
+         unsigned(PAL2->getParamAttrs(i+1)) & SRetMask)))
       return false;
   }
   return true;
@@ -423,13 +431,15 @@ static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) {
   if (PF1 && PF2) {
     const FunctionType *FT1 = dyn_cast<FunctionType>(PF1->getElementType());
     const FunctionType *FT2 = dyn_cast<FunctionType>(PF2->getElementType());
-    if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2))
-      if (FT2->paramHasAttr(1, FunctionType::StructRetAttribute))
+    if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) {
+      const ParamAttrsList *PAL2 = FT2->getParamAttrs();
+      if (PAL2 && PAL2->paramHasAttr(1, ParamAttr::StructRet))
         return V;
       else if (Constant *C = dyn_cast<Constant>(V))
         return ConstantExpr::getBitCast(C, PF1);
       else
         return new BitCastInst(V, PF1, "upgrd.cast", CurBB);
+    }
       
   }
   return 0;
@@ -764,7 +774,8 @@ static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){
     D = ValID::create((int)CurModule.Types.size());
   D.S.copy(Sign);
 
-  CurModule.NamedTypeSigns[Name] = Sign;
+  if (Name)
+    CurModule.NamedTypeSigns[Name] = Sign;
 
   std::map<ValID, PATypeHolder>::iterator I =
     CurModule.LateResolveTypes.find(D);
@@ -923,8 +934,9 @@ ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
   // of this global in the module and emit warnings if there are conflicts.
   if (!Name.empty()) {
     // The global has a name. See if there's an existing one of the same name.
-    if (CurModule.CurrentModule->getNamedGlobal(Name)) {
-      // We found an existing global ov the same name. This isn't allowed 
+    if (CurModule.CurrentModule->getNamedGlobal(Name) ||
+        CurModule.CurrentModule->getFunction(Name)) {
+      // We found an existing global of the same name. This isn't allowed 
       // in LLVM 2.0. Consequently, we must alter the name of the global so it
       // can at least compile. This can happen because of type planes 
       // There is alread a global of the same name which means there is a
@@ -1182,6 +1194,7 @@ void Signedness::destroy() {
   } 
 }
 
+#ifndef NDEBUG
 void Signedness::dump() const {
   if (isComposite()) {
     if (sv->size() == 1) {
@@ -1205,6 +1218,7 @@ void Signedness::dump() const {
   } else
     std::cerr << ".";
 }
+#endif
 
 static inline Instruction::TermOps 
 getTermOp(TermOps op) {
@@ -1446,90 +1460,130 @@ upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
                      std::vector<Value*>& Args) {
 
   std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
-  if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
-    if (Args.size() != 2)
-      error("Invalid prototype for " + Name + " prototype");
-    return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]);
-  } else {
-    const Type* PtrTy = PointerType::get(Type::Int8Ty);
-    std::vector<const Type*> Params;
-    if (Name == "llvm.va_start" || Name == "llvm.va_end") {
-      if (Args.size() != 1)
-        error("Invalid prototype for " + Name + " prototype");
-      Params.push_back(PtrTy);
-      const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false);
-      const PointerType *PFTy = PointerType::get(FTy);
-      Value* Func = getVal(PFTy, ID);
-      Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB);
-      return new CallInst(Func, &Args[0], Args.size());
-    } else if (Name == "llvm.va_copy") {
-      if (Args.size() != 2)
-        error("Invalid prototype for " + Name + " prototype");
-      Params.push_back(PtrTy);
-      Params.push_back(PtrTy);
-      const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false);
-      const PointerType *PFTy = PointerType::get(FTy);
-      Value* Func = getVal(PFTy, ID);
-      std::string InstName0(makeNameUnique("va0"));
-      std::string InstName1(makeNameUnique("va1"));
-      Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB);
-      Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB);
-      return new CallInst(Func, &Args[0], Args.size());
+  if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || 
+      Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+    return 0;
+
+  switch (Name[5]) {
+    case 'i':
+      if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
+        if (Args.size() != 2)
+          error("Invalid prototype for " + Name);
+        return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]);
+      }
+      break;
+
+    case 'v' : {
+      const Type* PtrTy = PointerType::get(Type::Int8Ty);
+      std::vector<const Type*> Params;
+      if (Name == "llvm.va_start" || Name == "llvm.va_end") {
+        if (Args.size() != 1)
+          error("Invalid prototype for " + Name + " prototype");
+        Params.push_back(PtrTy);
+        const FunctionType *FTy = 
+          FunctionType::get(Type::VoidTy, Params, false);
+        const PointerType *PFTy = PointerType::get(FTy);
+        Value* Func = getVal(PFTy, ID);
+        Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB);
+        return new CallInst(Func, Args.begin(), Args.end());
+      } else if (Name == "llvm.va_copy") {
+        if (Args.size() != 2)
+          error("Invalid prototype for " + Name + " prototype");
+        Params.push_back(PtrTy);
+        Params.push_back(PtrTy);
+        const FunctionType *FTy = 
+          FunctionType::get(Type::VoidTy, Params, false);
+        const PointerType *PFTy = PointerType::get(FTy);
+        Value* Func = getVal(PFTy, ID);
+        std::string InstName0(makeNameUnique("va0"));
+        std::string InstName1(makeNameUnique("va1"));
+        Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB);
+        Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB);
+        return new CallInst(Func, Args.begin(), Args.end());
+      }
     }
   }
   return 0;
 }
 
-const Type* upgradeGEPIndices(const Type* PTy, 
-                       std::vector<ValueInfo> *Indices, 
-                       std::vector<Value*>    &VIndices, 
-                       std::vector<Constant*> *CIndices = 0) {
-  // Traverse the indices with a gep_type_iterator so we can build the list
-  // of constant and value indices for use later. Also perform upgrades
-  VIndices.clear();
-  if (CIndices) CIndices->clear();
-  for (unsigned i = 0, e = Indices->size(); i != e; ++i)
-    VIndices.push_back((*Indices)[i].V);
-  generic_gep_type_iterator<std::vector<Value*>::iterator>
-    GTI = gep_type_begin(PTy, VIndices.begin(),  VIndices.end()),
-    GTE = gep_type_end(PTy,  VIndices.begin(),  VIndices.end());
-  for (unsigned i = 0, e = Indices->size(); i != e && GTI != GTE; ++i, ++GTI) {
-    Value *Index = VIndices[i];
-    if (CIndices && !isa<Constant>(Index))
-      error("Indices to constant getelementptr must be constants");
-    // LLVM 1.2 and earlier used ubyte struct indices.  Convert any ubyte 
-    // struct indices to i32 struct indices with ZExt for compatibility.
-    else if (isa<StructType>(*GTI)) {        // Only change struct indices
-      if (ConstantInt *CUI = dyn_cast<ConstantInt>(Index))
-        if (CUI->getType()->getBitWidth() == 8)
-          Index = 
-            ConstantExpr::getCast(Instruction::ZExt, CUI, Type::Int32Ty);
+const Type* upgradeGEPCEIndices(const Type* PTy, 
+                                std::vector<ValueInfo> *Indices, 
+                                std::vector<Constant*> &Result) {
+  const Type *Ty = PTy;
+  Result.clear();
+  for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+    Constant *Index = cast<Constant>((*Indices)[i].V);
+
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+      // LLVM 1.2 and earlier used ubyte struct indices.  Convert any ubyte 
+      // struct indices to i32 struct indices with ZExt for compatibility.
+      if (CI->getBitWidth() < 32)
+        Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+    }
+    
+    if (isa<SequentialType>(Ty)) {
+      // Make sure that unsigned SequentialType indices are zext'd to 
+      // 64-bits if they were smaller than that because LLVM 2.0 will sext 
+      // all indices for SequentialType elements. We must retain the same 
+      // semantic (zext) for unsigned types.
+      if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
+        if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
+          Index = ConstantExpr::getCast(Instruction::ZExt, Index,Type::Int64Ty);
+        }
+      }
+    }
+    Result.push_back(Index);
+    Ty = GetElementPtrInst::getIndexedType(PTy, (Value**)&Result[0], 
+                                           Result.size(),true);
+    if (!Ty)
+      error("Index list invalid for constant getelementptr");
+  }
+  return Ty;
+}
+
+const Type* upgradeGEPInstIndices(const Type* PTy, 
+                                  std::vector<ValueInfo> *Indices, 
+                                  std::vector<Value*>    &Result) {
+  const Type *Ty = PTy;
+  Result.clear();
+  for (unsigned i = 0, e = Indices->size(); i != e ; ++i) {
+    Value *Index = (*Indices)[i].V;
+
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(Index)) {
+      // LLVM 1.2 and earlier used ubyte struct indices.  Convert any ubyte 
+      // struct indices to i32 struct indices with ZExt for compatibility.
+      if (CI->getBitWidth() < 32)
+        Index = ConstantExpr::getCast(Instruction::ZExt, CI, Type::Int32Ty);
+    }
+    
+
+    if (isa<StructType>(Ty)) {        // Only change struct indices
+      if (!isa<Constant>(Index)) {
+        error("Invalid non-constant structure index");
+        return 0;
+      }
     } else {
       // Make sure that unsigned SequentialType indices are zext'd to 
       // 64-bits if they were smaller than that because LLVM 2.0 will sext 
       // all indices for SequentialType elements. We must retain the same 
       // semantic (zext) for unsigned types.
-      if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType()))
+      if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) {
         if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) {
-          if (CIndices)
+          if (isa<Constant>(Index))
             Index = ConstantExpr::getCast(Instruction::ZExt, 
               cast<Constant>(Index), Type::Int64Ty);
           else
             Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty,
               makeNameUnique("gep"), CurBB);
-          VIndices[i] = Index;
         }
+      }
     }
-    // Add to the CIndices list, if requested.
-    if (CIndices)
-      CIndices->push_back(cast<Constant>(Index));
-  }
-
-  const Type *IdxTy =
-    GetElementPtrInst::getIndexedType(PTy, &VIndices[0], VIndices.size(), true);
-    if (!IdxTy)
+    Result.push_back(Index);
+    Ty = GetElementPtrInst::getIndexedType(PTy, &Result[0], Result.size(),true);
+    if (!Ty)
       error("Index list invalid for constant getelementptr");
-  return IdxTy;
+  }
+  return Ty;
 }
 
 unsigned upgradeCallingConv(unsigned CC) {
@@ -1669,11 +1723,13 @@ Module* UpgradeAssembly(const std::string &infile, std::istream& in,
 
       while (!F->use_empty()) {
         CallInst* CI = cast<CallInst>(F->use_back());
-        AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
-        AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
-        new StoreInst(CI->getOperand(1), b, CI);
-        new CallInst(NF, a, b, "", CI);
-        Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
+        Value *Args[2] = {
+          new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI),
+          new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI)         
+        };
+        new StoreInst(CI->getOperand(1), Args[1], CI);
+        new CallInst(NF, Args, Args + 2, "", CI);
+        Value* foo = new LoadInst(Args[0], "vacopy.fix.3", CI);
         CI->replaceAllUsesWith(foo);
         CI->getParent()->getInstList().erase(CI);
       }
@@ -1928,17 +1984,17 @@ OptLinkage
   ;
 
 OptCallingConv 
-  : /*empty*/          { $$ = OldCallingConv::C; } 
-  | CCC_TOK            { $$ = OldCallingConv::C; } 
-  | CSRETCC_TOK        { $$ = OldCallingConv::CSRet; } 
-  | FASTCC_TOK         { $$ = OldCallingConv::Fast; } 
-  | COLDCC_TOK         { $$ = OldCallingConv::Cold; } 
-  | X86_STDCALLCC_TOK  { $$ = OldCallingConv::X86_StdCall; } 
-  | X86_FASTCALLCC_TOK { $$ = OldCallingConv::X86_FastCall; } 
+  : /*empty*/          { $$ = lastCallingConv = OldCallingConv::C; } 
+  | CCC_TOK            { $$ = lastCallingConv = OldCallingConv::C; } 
+  | CSRETCC_TOK        { $$ = lastCallingConv = OldCallingConv::CSRet; } 
+  | FASTCC_TOK         { $$ = lastCallingConv = OldCallingConv::Fast; } 
+  | COLDCC_TOK         { $$ = lastCallingConv = OldCallingConv::Cold; } 
+  | X86_STDCALLCC_TOK  { $$ = lastCallingConv = OldCallingConv::X86_StdCall; } 
+  | X86_FASTCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_FastCall; } 
   | CC_TOK EUINT64VAL  {
     if ((unsigned)$2 != $2)
       error("Calling conv too large");
-    $$ = $2;
+    $$ = lastCallingConv = $2;
   }
   ;
 
@@ -2065,13 +2121,22 @@ UpRTypes
       Params.push_back(I->PAT->get());
       $$.S.add(I->S);
     }
-    FunctionType::ParamAttrsList ParamAttrs;
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
-    $$.PAT = new PATypeHolder(
-      HandleUpRefs(FunctionType::get($1.PAT->get(), Params, isVarArg, 
-                   ParamAttrs), $$.S));
+    ParamAttrsList *PAL = 0;
+    if (lastCallingConv == OldCallingConv::CSRet) {
+      ParamAttrsVector Attrs;
+      ParamAttrsWithIndex PAWI;
+      PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+      Attrs.push_back(PAWI);
+      PAL = ParamAttrsList::get(Attrs);
+    }
+
+    const FunctionType *FTy =
+      FunctionType::get($1.PAT->get(), Params, isVarArg, PAL);
+
+    $$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) );
     delete $1.PAT;  // Delete the return type handle
     delete $3;      // Delete the argument list
   }
@@ -2476,9 +2541,8 @@ ConstExpr
     if (!isa<PointerType>(Ty))
       error("GetElementPtr requires a pointer operand");
 
-    std::vector<Value*> VIndices;
     std::vector<Constant*> CIndices;
-    upgradeGEPIndices($3.C->getType(), $4, VIndices, &CIndices);
+    upgradeGEPCEIndices($3.C->getType(), $4, CIndices);
 
     delete $4;
     $$.C = ConstantExpr::getGetElementPtr($3.C, &CIndices[0], CIndices.size());
@@ -2853,14 +2917,17 @@ FunctionHeaderH
 
     // Convert the CSRet calling convention into the corresponding parameter
     // attribute.
-    FunctionType::ParamAttrsList ParamAttrs;
+    ParamAttrsList *PAL = 0;
     if ($1 == OldCallingConv::CSRet) {
-      ParamAttrs.push_back(FunctionType::NoAttributeSet);     // result
-      ParamAttrs.push_back(FunctionType::StructRetAttribute); // first arg
+      ParamAttrsVector Attrs;
+      ParamAttrsWithIndex PAWI;
+      PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+      Attrs.push_back(PAWI);
+      PAL = ParamAttrsList::get(Attrs);
     }
 
-    const FunctionType *FT = FunctionType::get(RetTy, ParamTyList, isVarArg,
-                                               ParamAttrs);
+    const FunctionType *FT = 
+      FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
     const PointerType *PFT = PointerType::get(FT);
     delete $2.PAT;
 
@@ -2922,7 +2989,7 @@ FunctionHeaderH
               AI->setName("");
         }
       } else if (Conflict) {
-        // We have two globals with the same name and  different types. 
+        // We have two globals with the same name and different types. 
         // Previously, this was permitted because the symbol table had 
         // "type planes" and names only needed to be distinct within a 
         // type plane. After PR411 was fixed, this is no loner the case. 
@@ -2936,32 +3003,33 @@ FunctionHeaderH
           CurModule.RenameMap[Key] = Conflict->getName();
           Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
           InsertValue(Fn, CurModule.Values);
-        } else if (CurFun.Linkage == GlobalValue::InternalLinkage) {
-          // We can safely rename the function we're defining
-          std::string NewName = makeNameUnique(FunctionName);
-          Fn = new Function(FT, CurFun.Linkage, NewName, M);
-          InsertValue(Fn, CurModule.Values);
-          RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S);
-          CurModule.RenameMap[Key] = NewName;
-        } else {
+        } else { 
           // We can't quietly rename either of these things, but we must
-          // rename one of them. Generate a warning about the renaming and
-          // elect to rename the thing we're now defining.
+          // rename one of them. Only if the function's linkage is internal can
+          // we forgo a warning message about the renamed function. 
           std::string NewName = makeNameUnique(FunctionName);
-          warning("Renaming function '" + FunctionName + "' as '" + NewName +
-                  "' may cause linkage errors");
+          if (CurFun.Linkage != GlobalValue::InternalLinkage) {
+            warning("Renaming function '" + FunctionName + "' as '" + NewName +
+                    "' may cause linkage errors");
+          }
+          // Elect to rename the thing we're now defining.
           Fn = new Function(FT, CurFun.Linkage, NewName, M);
           InsertValue(Fn, CurModule.Values);
           RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S);
           CurModule.RenameMap[Key] = NewName;
-        }
+        } 
       } else {
         // There's no conflict, just define the function
         Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
         InsertValue(Fn, CurModule.Values);
       }
+    } else {
+      // There's no conflict, just define the function
+      Fn = new Function(FT, CurFun.Linkage, FunctionName, M);
+      InsertValue(Fn, CurModule.Values);
     }
 
+
     CurFun.FunctionStart(Fn);
 
     if (CurFun.isDeclare) {
@@ -2997,6 +3065,7 @@ FunctionHeaderH
       }
       delete $5;                     // We're now done with the argument list
     }
+    lastCallingConv = OldCallingConv::C;
   }
   ;
 
@@ -3005,7 +3074,7 @@ BEGIN
   ;
 
 FunctionHeader 
-  : OptLinkage FunctionHeaderH BEGIN {
+  : OptLinkage { CurFun.Linkage = $1; } FunctionHeaderH BEGIN {
     $$ = CurFun.CurrentFunction;
 
     // Make sure that we keep track of the linkage type even if there was a
@@ -3245,20 +3314,27 @@ BBTerminatorInst
           FTySign.add(I->S);
         }
       }
-      FunctionType::ParamAttrsList ParamAttrs;
+      ParamAttrsList *PAL = 0;
       if ($2 == OldCallingConv::CSRet) {
-        ParamAttrs.push_back(FunctionType::NoAttributeSet);
-        ParamAttrs.push_back(FunctionType::StructRetAttribute);
+        ParamAttrsVector Attrs;
+        ParamAttrsWithIndex PAWI;
+        PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+        Attrs.push_back(PAWI);
+        PAL = ParamAttrsList::get(Attrs);
       }
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
-      Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, ParamAttrs);
+      Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL);
       PFTy = PointerType::get(Ty);
       $$.S.copy($3.S);
     } else {
       FTySign = $3.S;
-      $$.S.copy($3.S.get(0)); // 0th element of FuncTy sign is result ty
+      // Get the signedness of the result type. $3 is the pointer to the
+      // function type so we get the 0th element to extract the function type,
+      // and then the 0th element again to get the result type.
+      $$.S.copy($3.S.get(0).get(0)); 
     }
+
     $4.S.makeComposite(FTySign);
     Value *V = getVal(PFTy, $4);   // Get the function we're calling...
     BasicBlock *Normal = getBBVal($10);
@@ -3266,7 +3342,8 @@ BBTerminatorInst
 
     // Create the call node...
     if (!$6) {                                   // Has no arguments?
-      $$.TI = new InvokeInst(V, Normal, Except, 0, 0);
+      std::vector<Value*> Args;
+      $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
     } else {                                     // Has arguments?
       // Loop through FunctionType's arguments and ensure they are specified
       // correctly!
@@ -3286,11 +3363,12 @@ BBTerminatorInst
       if (I != E || (ArgI != ArgE && !Ty->isVarArg()))
         error("Invalid number of parameters detected");
 
-      $$.TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
+      $$.TI = new InvokeInst(V, Normal, Except, Args.begin(), Args.end());
     }
     cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
     delete $3.PAT;
     delete $6;
+    lastCallingConv = OldCallingConv::C;
   }
   | Unwind {
     $$.TI = new UnwindInst();
@@ -3619,7 +3697,7 @@ InstVal
     $$.S.copy($2.S);
     delete $2.P;  // Free the list...
   }
-  | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')'  {
+  | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')' {
     // Handle the short call syntax
     const PointerType *PFTy;
     const FunctionType *FTy;
@@ -3637,11 +3715,6 @@ InstVal
         }
       }
 
-      FunctionType::ParamAttrsList ParamAttrs;
-      if ($2 == OldCallingConv::CSRet) {
-        ParamAttrs.push_back(FunctionType::NoAttributeSet);
-        ParamAttrs.push_back(FunctionType::StructRetAttribute);
-      }
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
 
@@ -3649,12 +3722,25 @@ InstVal
       if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy)
         error("Functions cannot return aggregate types");
 
-      FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, ParamAttrs);
+      // Deal with CSRetCC
+      ParamAttrsList *PAL = 0;
+      if ($2 == OldCallingConv::CSRet) {
+        ParamAttrsVector Attrs;
+        ParamAttrsWithIndex PAWI;
+        PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+        Attrs.push_back(PAWI);
+        PAL = ParamAttrsList::get(Attrs);
+      }
+
+      FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
       PFTy = PointerType::get(FTy);
       $$.S.copy($3.S);
     } else {
       FTySign = $3.S;
-      $$.S.copy($3.S.get(0)); // 0th element of FuncTy signedness is result sign
+      // Get the signedness of the result type. $3 is the pointer to the
+      // function type so we get the 0th element to extract the function type,
+      // and then the 0th element again to get the result type.
+      $$.S.copy($3.S.get(0).get(0)); 
     }
     $4.S.makeComposite(FTySign);
 
@@ -3663,7 +3749,7 @@ InstVal
     if ($6)
       for (unsigned i = 0, e = $6->size(); i < e; ++i) 
         Args.push_back((*$6)[i].V);
-    Instruction *Inst = upgradeIntrinsicCall(FTy, $4, Args);
+    Instruction *Inst = upgradeIntrinsicCall(FTy->getReturnType(), $4, Args);
 
     // If we got an upgraded intrinsic
     if (Inst) {
@@ -3695,13 +3781,14 @@ InstVal
       }
 
       // Create the call instruction
-      CallInst *CI = new CallInst(V, &Args[0], Args.size());
+      CallInst *CI = new CallInst(V, Args.begin(), Args.end());
       CI->setTailCall($1);
       CI->setCallingConv(upgradeCallingConv($2));
       $$.I = CI;
     }
     delete $3.PAT;
     delete $6;
+    lastCallingConv = OldCallingConv::C;
   }
   | MemoryInst {
     $$ = $1;
@@ -3800,7 +3887,7 @@ MemoryInst
       error("getelementptr insn requires pointer operand");
 
     std::vector<Value*> VIndices;
-    upgradeGEPIndices(Ty, $4, VIndices);
+    upgradeGEPInstIndices(Ty, $4, VIndices);
 
     Value* tmpVal = getVal(Ty, $3);
     $$.I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size());