diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index e6222b6..c47b6fc 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -139,18 +139,14 @@
   // GetForwardRefForGlobal - Check to see if there is a forward reference
   // for this global.  If so, remove it from the GlobalRefs map and return it.
   // If not, just return null.
-  GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ParamAttrsList *PAL, 
-                                      ValID ID) {
+  GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) {
     // Check to see if there is a forward reference to this global variable...
     // if there is, eliminate it and patch the reference to use the new def'n.
     GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID));
     GlobalValue *Ret = 0;
     if (I != GlobalRefs.end()) {
       Ret = I->second;
-      if (PAL && isa<Function>(Ret)) 
-        Ret = cast<Function>(Ret)->getParamAttrs() == PAL ? Ret : 0;
-      if (Ret)
-        GlobalRefs.erase(I);
+      GlobalRefs.erase(I);
     }
     return Ret;
   }
@@ -748,7 +744,7 @@
     ID = ValID::createGlobalID(CurModule.Values.size());
   }
 
-  if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, 0, ID)) {
+  if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) {
     // Move the global to the end of the list, from whereever it was
     // previously inserted.
     GlobalVariable *GV = cast<GlobalVariable>(FWGV);
@@ -1328,35 +1324,62 @@
     UR_OUT("New Upreference!\n");
     CHECK_FOR_ERROR
   }
-  | Types '(' ArgTypeListI ')' {
+  | Types '(' ArgTypeListI ')' OptFuncAttrs {
     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) {
       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();
 
-    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg);
+    ParamAttrsList *ActualAttrs = 0;
+    if (!Attrs.empty())
+      ActualAttrs = ParamAttrsList::get(Attrs);
+    FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
     delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     CHECK_FOR_ERROR
   }
-  | VOID '(' ArgTypeListI ')' {
+  | VOID '(' ArgTypeListI ')' OptFuncAttrs {
     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) {
       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();
 
-    FunctionType *FT = FunctionType::get($1, Params, isVarArg);
+    ParamAttrsList *ActualAttrs = 0;
+    if (!Attrs.empty())
+      ActualAttrs = ParamAttrsList::get(Attrs);
+
+    FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
     delete $3;      // Delete the argument list
     $$ = new PATypeHolder(HandleUpRefs(FT)); 
     CHECK_FOR_ERROR
@@ -1410,9 +1433,9 @@
   ;
 
 ArgType 
-  : Types { 
+  : Types OptParamAttrs { 
     $$.Ty = $1; 
-    $$.Attrs = ParamAttr::None;
+    $$.Attrs = $2; 
   }
   ;
 
@@ -2217,7 +2240,7 @@
   if (!Attrs.empty())
     PAL = ParamAttrsList::get(Attrs);
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
+  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, PAL);
   const PointerType *PFT = PointerType::get(FT);
   delete $2;
 
@@ -2230,7 +2253,7 @@
 
   Function *Fn = 0;
   // See if this function was forward referenced.  If so, recycle the object.
-  if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, PAL, ID)) {
+  if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) {
     // Move the function to the end of the list, from whereever it was 
     // previously inserted.
     Fn = cast<Function>(FWRef);
@@ -2238,7 +2261,7 @@
     CurModule.CurrentModule->getFunctionList().push_back(Fn);
   } else if (!FunctionName.empty() &&     // Merge with an earlier prototype?
              (Fn = CurModule.CurrentModule->getFunction(FunctionName))) {
-    if (Fn->getFunctionType() != FT || PAL != Fn->getParamAttrs()) {
+    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.");
@@ -2255,7 +2278,6 @@
   } else  {  // Not already defined?
     Fn = new Function(FT, GlobalValue::ExternalWeakLinkage, FunctionName,
                       CurModule.CurrentModule);
-    Fn->setParamAttrs(PAL);
 
     InsertValue(Fn, CurModule.Values);
   }
@@ -2549,14 +2571,28 @@
         !(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();
-      for (; I != E; ++I) {
+      unsigned index = 1;
+      for (; I != E; ++I, ++index) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+          Attrs.push_back(PAWI);
+        }
       }
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+
+      ParamAttrsList *PAL = 0;
+      if (!Attrs.empty())
+        PAL = ParamAttrsList::get(Attrs);
+      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
       PFTy = PointerType::get(Ty);
     }
 
@@ -2569,12 +2605,6 @@
     BasicBlock *Except = getBBVal($14);
     CHECK_FOR_ERROR
 
-    ParamAttrsVector Attrs;
-    if ($8 != ParamAttr::None) {
-      ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = 8;
-      Attrs.push_back(PAWI);
-    }
-
     // Check the arguments
     ValueList Args;
     if ($6->empty()) {                                   // Has no arguments?
@@ -2588,16 +2618,12 @@
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
       ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
-      unsigned index = 1;
+
       for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
         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) {
-          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = ArgI->Attrs;
-          Attrs.push_back(PAWI);
-        }
       }
 
       if (Ty->isVarArg()) {
@@ -2608,17 +2634,9 @@
         GEN_ERROR("Invalid number of parameters detected");
     }
 
-    ParamAttrsList *PAL = 0;
-    if (!Attrs.empty())
-      PAL = ParamAttrsList::get(Attrs);
-    if (isa<Function>(V))
-      if (PAL != cast<Function>(V)->getParamAttrs())
-        GEN_ERROR("Invalid parameter attributes for function invoked");
-
     // Create the InvokeInst
     InvokeInst *II = new InvokeInst(V, Normal, Except, &Args[0], Args.size());
     II->setCallingConv($2);
-    II->setParamAttrs(PAL);
     $$ = II;
     delete $6;
     CHECK_FOR_ERROR
@@ -2863,14 +2881,29 @@
         !(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) {
+      for (; I != E; ++I, ++index) {
         const Type *Ty = I->Val->getType();
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+          Attrs.push_back(PAWI);
+        }
       }
-      Ty = FunctionType::get($3->get(), ParamTypes, false);
+
+      ParamAttrsList *PAL = 0;
+      if (!Attrs.empty())
+        PAL = ParamAttrsList::get(Attrs);
+
+      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
       PFTy = PointerType::get(Ty);
     }
 
@@ -2886,12 +2919,6 @@
                   theF->getName() + "'");
     }
 
-    // Set up the ParamAttrs for the function
-    ParamAttrsVector Attrs;
-    if ($8 != ParamAttr::None) {
-      ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
-      Attrs.push_back(PAWI);
-    }
     // Check the arguments 
     ValueList Args;
     if ($6->empty()) {                                   // Has no arguments?
@@ -2901,20 +2928,17 @@
                        "expects arguments");
     } else {                                     // Has arguments?
       // Loop through FunctionType's arguments and ensure they are specified
-      // correctly. Also, gather any parameter attributes.
+      // correctly!
+      //
       FunctionType::param_iterator I = Ty->param_begin();
       FunctionType::param_iterator E = Ty->param_end();
       ValueRefList::iterator ArgI = $6->begin(), ArgE = $6->end();
-      unsigned index = 1;
+
       for (; ArgI != ArgE && I != E; ++ArgI, ++I) {
         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) {
-          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = ArgI->Attrs;
-          Attrs.push_back(PAWI);
-        }
       }
       if (Ty->isVarArg()) {
         if (I == E)
@@ -2923,20 +2947,10 @@
       } else if (I != E || ArgI != ArgE)
         GEN_ERROR("Invalid number of parameters detected");
     }
-
-    // Finish off the ParamAttrs and check them
-    ParamAttrsList *PAL = 0;
-    if (!Attrs.empty())
-      PAL = ParamAttrsList::get(Attrs);
-    if (isa<Function>(V))
-      if (PAL != cast<Function>(V)->getParamAttrs())
-        GEN_ERROR("Invalid parameter attributes for function called");
-
     // Create the call node
     CallInst *CI = new CallInst(V, &Args[0], Args.size());
     CI->setTailCall($1);
     CI->setCallingConv($2);
-    CI->setParamAttrs(PAL);
     $$ = CI;
     delete $6;
     delete $3;
