Fix PR1146: parameter attributes are longer part of
the function type, instead they belong to functions
and function calls.  This is an updated and slightly
corrected version of Reid Spencer's original patch.
The only known problem is that auto-upgrading of
bitcode files doesn't seem to work properly (see
test/Bitcode/AutoUpgradeIntrinsics.ll).  Hopefully
a bitcode guru (who might that be? :) ) will fix it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44359 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index f874a18..852e28d 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -126,12 +126,14 @@
     std::ostream &printType(std::ostream &Out, const Type *Ty, 
                             bool isSigned = false,
                             const std::string &VariableName = "",
-                            bool IgnoreName = false);
+                            bool IgnoreName = false,
+                            const ParamAttrsList *PAL = 0);
     std::ostream &printSimpleType(std::ostream &Out, const Type *Ty, 
                                      bool isSigned, 
                                      const std::string &NameSoFar = "");
 
     void printStructReturnPointerFunctionType(std::ostream &Out,
+                                              const ParamAttrsList *PAL,
                                               const PointerType *Ty);
     
     void writeOperand(Value *Operand);
@@ -353,6 +355,7 @@
 /// return type, except, instead of printing the type as void (*)(Struct*, ...)
 /// print it as "Struct (*)(...)", for struct return functions.
 void CWriter::printStructReturnPointerFunctionType(std::ostream &Out,
+                                                   const ParamAttrsList *PAL,
                                                    const PointerType *TheTy) {
   const FunctionType *FTy = cast<FunctionType>(TheTy->getElementType());
   std::stringstream FunctionInnards;
@@ -362,12 +365,11 @@
   FunctionType::param_iterator I = FTy->param_begin(), E = FTy->param_end();
   const Type *RetTy = cast<PointerType>(I->get())->getElementType();
   unsigned Idx = 1;
-  const ParamAttrsList *Attrs = FTy->getParamAttrs();
   for (++I; I != E; ++I) {
     if (PrintedType)
       FunctionInnards << ", ";
     printType(FunctionInnards, *I, 
-        /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt), "");
+        /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
     PrintedType = true;
   }
   if (FTy->isVarArg()) {
@@ -379,7 +381,7 @@
   FunctionInnards << ')';
   std::string tstr = FunctionInnards.str();
   printType(Out, RetTy, 
-      /*isSigned=*/Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), tstr);
+      /*isSigned=*/PAL && PAL->paramHasAttr(0, ParamAttr::SExt), tstr);
 }
 
 std::ostream &
@@ -422,7 +424,7 @@
 //
 std::ostream &CWriter::printType(std::ostream &Out, const Type *Ty,
                                  bool isSigned, const std::string &NameSoFar,
-                                 bool IgnoreName) {
+                                 bool IgnoreName, const ParamAttrsList* PAL) {
   if (Ty->isPrimitiveType() || Ty->isInteger()) {
     printSimpleType(Out, Ty, isSigned, NameSoFar);
     return Out;
@@ -439,14 +441,13 @@
     const FunctionType *FTy = cast<FunctionType>(Ty);
     std::stringstream FunctionInnards;
     FunctionInnards << " (" << NameSoFar << ") (";
-    const ParamAttrsList *Attrs = FTy->getParamAttrs();
     unsigned Idx = 1;
     for (FunctionType::param_iterator I = FTy->param_begin(),
            E = FTy->param_end(); I != E; ++I) {
       if (I != FTy->param_begin())
         FunctionInnards << ", ";
-      printType(FunctionInnards, *I, 
-         /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt), "");
+      printType(FunctionInnards, *I,
+        /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt), "");
       ++Idx;
     }
     if (FTy->isVarArg()) {
@@ -458,7 +459,7 @@
     FunctionInnards << ')';
     std::string tstr = FunctionInnards.str();
     printType(Out, FTy->getReturnType(), 
-        /*isSigned=*/Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), tstr);
+      /*isSigned=*/PAL && PAL->paramHasAttr(0, ParamAttr::SExt), tstr);
     return Out;
   }
   case Type::StructTyID: {
@@ -1836,7 +1837,7 @@
 
 void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
   /// isStructReturn - Should this function actually return a struct by-value?
-  bool isStructReturn = F->getFunctionType()->isStructReturn();
+  bool isStructReturn = F->isStructReturn();
   
   if (F->hasInternalLinkage()) Out << "static ";
   if (F->hasDLLImportLinkage()) Out << "__declspec(dllimport) ";
@@ -1852,7 +1853,7 @@
   
   // Loop over the arguments, printing them...
   const FunctionType *FT = cast<FunctionType>(F->getFunctionType());
-  const ParamAttrsList *Attrs = FT->getParamAttrs();
+  const ParamAttrsList *PAL = F->getParamAttrs();
 
   std::stringstream FunctionInnards;
 
@@ -1880,7 +1881,7 @@
         else
           ArgName = "";
         printType(FunctionInnards, I->getType(), 
-            /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt), 
+            /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt),
             ArgName);
         PrintedArg = true;
         ++Idx;
@@ -1901,7 +1902,7 @@
     for (; I != E; ++I) {
       if (PrintedArg) FunctionInnards << ", ";
       printType(FunctionInnards, *I,
-             /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt));
+             /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt));
       PrintedArg = true;
       ++Idx;
     }
@@ -1929,7 +1930,7 @@
     
   // Print out the return type and the signature built above.
   printType(Out, RetTy, 
-            /*isSigned=*/ Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), 
+            /*isSigned=*/ PAL && PAL->paramHasAttr(0, ParamAttr::SExt),
             FunctionInnards.str());
 }
 
@@ -1944,7 +1945,7 @@
 
 void CWriter::printFunction(Function &F) {
   /// isStructReturn - Should this function actually return a struct by-value?
-  bool isStructReturn = F.getFunctionType()->isStructReturn();
+  bool isStructReturn = F.isStructReturn();
 
   printFunctionSignature(&F, false);
   Out << " {\n";
@@ -2068,8 +2069,7 @@
 //
 void CWriter::visitReturnInst(ReturnInst &I) {
   // If this is a struct return function, return the temporary struct.
-  bool isStructReturn = I.getParent()->getParent()->
-    getFunctionType()->isStructReturn();
+  bool isStructReturn = I.getParent()->getParent()->isStructReturn();
 
   if (isStructReturn) {
     Out << "  return StructReturn;\n";
@@ -2594,7 +2594,8 @@
 
   // If this is a call to a struct-return function, assign to the first
   // parameter instead of passing it to the call.
-  bool isStructRet = FTy->isStructReturn();
+  const ParamAttrsList *PAL = I.getParamAttrs();
+  bool isStructRet = I.isStructReturn();
   if (isStructRet) {
     Out << "*(";
     writeOperand(I.getOperand(1));
@@ -2633,7 +2634,7 @@
       if (!isStructRet)
         printType(Out, I.getCalledValue()->getType());
       else
-        printStructReturnPointerFunctionType(Out, 
+        printStructReturnPointerFunctionType(Out, PAL,
                              cast<PointerType>(I.getCalledValue()->getType()));
       Out << ")(void*)";
     }
@@ -2652,7 +2653,6 @@
     ++ArgNo;
   }
       
-  const ParamAttrsList *Attrs = FTy->getParamAttrs();
   bool PrintedArg = false;
   unsigned Idx = 1;
   for (; AI != AE; ++AI, ++ArgNo, ++Idx) {
@@ -2661,7 +2661,7 @@
         (*AI)->getType() != FTy->getParamType(ArgNo)) {
       Out << '(';
       printType(Out, FTy->getParamType(ArgNo), 
-            /*isSigned=*/Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt));
+            /*isSigned=*/PAL && PAL->paramHasAttr(Idx, ParamAttr::SExt));
       Out << ')';
     }
     writeOperand(*AI);