Standardize the parsing of function type attributes in a way that
follows (as conservatively as possible) gcc's current behavior:  attributes
written on return types that don't apply there are applied to the function
instead, etc.  Only parse CC attributes as type attributes, not as decl attributes;
don't accepet noreturn as a decl attribute on ValueDecls, either (it still
needs to apply to other decls, like blocks).  Consistently consume CC/noreturn
information throughout codegen;  enforce this by removing their default values
in CodeGenTypes::getFunctionInfo().



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95436 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 5da6187..05d138b 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -496,10 +496,12 @@
   // Load the function.
   llvm::Value *Func = Builder.CreateLoad(FuncPtr, "tmp");
 
-  QualType ResultType = FnType->getAs<FunctionType>()->getResultType();
+  const FunctionType *FuncTy = FnType->getAs<FunctionType>();
+  QualType ResultType = FuncTy->getResultType();
 
   const CGFunctionInfo &FnInfo =
-    CGM.getTypes().getFunctionInfo(ResultType, Args);
+    CGM.getTypes().getFunctionInfo(ResultType, Args, FuncTy->getCallConv(),
+                                   FuncTy->getNoReturnAttr());
 
   // Cast the function pointer to the right type.
   const llvm::Type *BlockFTy =
@@ -704,6 +706,8 @@
 
   const FunctionType *BlockFunctionType = BExpr->getFunctionType();
   QualType ResultType;
+  CallingConv CC = BlockFunctionType->getCallConv();
+  bool NoReturn = BlockFunctionType->getNoReturnAttr();
   bool IsVariadic;
   if (const FunctionProtoType *FTy =
       dyn_cast<FunctionProtoType>(BlockFunctionType)) {
@@ -742,7 +746,7 @@
     Args.push_back(std::make_pair(*i, (*i)->getType()));
 
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(ResultType, Args);
+    CGM.getTypes().getFunctionInfo(ResultType, Args, CC, NoReturn);
 
   CodeGenTypes &Types = CGM.getTypes();
   const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
@@ -867,7 +871,7 @@
   Args.push_back(std::make_pair(Src, Src->getType()));
 
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(R, Args);
+    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.
@@ -948,7 +952,7 @@
   Args.push_back(std::make_pair(Src, Src->getType()));
 
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(R, Args);
+    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.
@@ -1032,7 +1036,7 @@
   Args.push_back(std::make_pair(Src, Src->getType()));
 
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(R, Args);
+    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
 
   CodeGenTypes &Types = CGM.getTypes();
   const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
@@ -1095,7 +1099,7 @@
   Args.push_back(std::make_pair(Src, Src->getType()));
 
   const CGFunctionInfo &FI =
-    CGM.getTypes().getFunctionInfo(R, Args);
+    CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
 
   CodeGenTypes &Types = CGM.getTypes();
   const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 4323f84..28c4c6b 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -165,7 +165,8 @@
                                    GlobalDecl GD, bool Extern,
                                    const CovariantThunkAdjustment &Adjustment) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
-  QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType();
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  QualType ResultType = FPT->getResultType();
 
   FunctionArgList Args;
   ImplicitParamDecl *ThisDecl =
@@ -190,7 +191,6 @@
   StartFunction(FD, ResultType, Fn, Args, SourceLocation());
 
   // generate body
-  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
   const llvm::Type *Ty =
     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
                                    FPT->isVariadic());
@@ -232,7 +232,9 @@
     CallArgs.push_back(std::make_pair(EmitCallArg(Arg, ArgType), ArgType));
   }
 
-  RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+  RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs,
+                                                      FPT->getCallConv(),
+                                                      FPT->getNoReturnAttr()),
                        Callee, ReturnValueSlot(), CallArgs, MD);
   if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) {
     bool CanBeZero = !(ResultType->isReferenceType()
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index ce361f0..7a47d5b 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -33,12 +33,19 @@
 
 // FIXME: Use iterator and sidestep silly type array creation.
 
+static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
+  switch (CC) {
+  default: return llvm::CallingConv::C;
+  case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
+  case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
+  }
+}
+
 const
 CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
-  // FIXME: Set calling convention correctly, it needs to be associated with the
-  // type somehow.
   return getFunctionInfo(FTNP->getResultType(),
-                         llvm::SmallVector<QualType, 16>(), 0);
+                         llvm::SmallVector<QualType, 16>(),
+                         FTNP->getCallConv(), FTNP->getNoReturnAttr());
 }
 
 const
@@ -47,20 +54,19 @@
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FTP->getArgType(i));
-  // FIXME: Set calling convention correctly, it needs to be associated with the
-  // type somehow.
-  return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
+  return getFunctionInfo(FTP->getResultType(), ArgTys,
+                         FTP->getCallConv(), FTP->getNoReturnAttr());
 }
 
-static unsigned getCallingConventionForDecl(const Decl *D) {
+static CallingConv getCallingConventionForDecl(const Decl *D) {
   // Set the appropriate calling convention for the Function.
   if (D->hasAttr<StdCallAttr>())
-    return llvm::CallingConv::X86_StdCall;
+    return CC_X86StdCall;
 
   if (D->hasAttr<FastCallAttr>())
-    return llvm::CallingConv::X86_FastCall;
+    return CC_X86FastCall;
 
-  return llvm::CallingConv::C;
+  return CC_C;
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD,
@@ -75,7 +81,8 @@
   
   // FIXME: Set calling convention correctly, it needs to be associated with the
   // type somehow.
-  return getFunctionInfo(FTP->getResultType(), ArgTys, 0);
+  return getFunctionInfo(FTP->getResultType(), ArgTys,
+                         FTP->getCallConv(), FTP->getNoReturnAttr());
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) {
@@ -87,8 +94,8 @@
   const FunctionProtoType *FTP = MD->getType()->getAs<FunctionProtoType>();
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys,
-                         getCallingConventionForDecl(MD));
+  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+                         FTP->getNoReturnAttr());
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, 
@@ -105,8 +112,8 @@
   const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys,
-                         getCallingConventionForDecl(D));
+  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+                         FTP->getNoReturnAttr());
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D,
@@ -123,8 +130,8 @@
   const FunctionProtoType *FTP = D->getType()->getAs<FunctionProtoType>();
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FTP->getArgType(i));
-  return getFunctionInfo(FTP->getResultType(), ArgTys,
-                         getCallingConventionForDecl(D));
+  return getFunctionInfo(FTP->getResultType(), ArgTys, FTP->getCallConv(),
+                         FTP->getNoReturnAttr());
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
@@ -132,19 +139,19 @@
     if (MD->isInstance())
       return getFunctionInfo(MD);
 
-  unsigned CallingConvention = getCallingConventionForDecl(FD);
   const FunctionType *FTy = FD->getType()->getAs<FunctionType>();
   if (const FunctionNoProtoType *FNTP = dyn_cast<FunctionNoProtoType>(FTy))
     return getFunctionInfo(FNTP->getResultType(), 
                            llvm::SmallVector<QualType, 16>(),
-                           CallingConvention);
+                           FNTP->getCallConv(), FNTP->getNoReturnAttr());
   
   const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
   llvm::SmallVector<QualType, 16> ArgTys;
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
     ArgTys.push_back(FPT->getArgType(i));
-  return getFunctionInfo(FPT->getResultType(), ArgTys, CallingConvention);
+  return getFunctionInfo(FPT->getResultType(), ArgTys,
+                         FPT->getCallConv(), FPT->getNoReturnAttr());
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {
@@ -156,37 +163,43 @@
          e = MD->param_end(); i != e; ++i)
     ArgTys.push_back((*i)->getType());
   return getFunctionInfo(MD->getResultType(), ArgTys,
-                         getCallingConventionForDecl(MD));
+                         getCallingConventionForDecl(MD),
+                         /*NoReturn*/ false);
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
                                                     const CallArgList &Args,
-                                                    unsigned CallingConvention){
+                                                    CallingConv CC,
+                                                    bool NoReturn) {
   // FIXME: Kill copy.
   llvm::SmallVector<QualType, 16> ArgTys;
   for (CallArgList::const_iterator i = Args.begin(), e = Args.end();
        i != e; ++i)
     ArgTys.push_back(i->second);
-  return getFunctionInfo(ResTy, ArgTys, CallingConvention);
+  return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
                                                     const FunctionArgList &Args,
-                                                    unsigned CallingConvention){
+                                                    CallingConv CC,
+                                                    bool NoReturn) {
   // FIXME: Kill copy.
   llvm::SmallVector<QualType, 16> ArgTys;
   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
        i != e; ++i)
     ArgTys.push_back(i->second);
-  return getFunctionInfo(ResTy, ArgTys, CallingConvention);
+  return getFunctionInfo(ResTy, ArgTys, CC, NoReturn);
 }
 
 const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
                                   const llvm::SmallVector<QualType, 16> &ArgTys,
-                                                    unsigned CallingConvention){
+                                                    CallingConv CallConv,
+                                                    bool NoReturn) {
+  unsigned CC = ClangCallConvToLLVMCallConv(CallConv);
+
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID ID;
-  CGFunctionInfo::Profile(ID, CallingConvention, ResTy,
+  CGFunctionInfo::Profile(ID, CC, NoReturn, ResTy,
                           ArgTys.begin(), ArgTys.end());
 
   void *InsertPos = 0;
@@ -195,7 +208,7 @@
     return *FI;
 
   // Construct the function info.
-  FI = new CGFunctionInfo(CallingConvention, ResTy, ArgTys);
+  FI = new CGFunctionInfo(CC, NoReturn, ResTy, ArgTys);
   FunctionInfos.InsertNode(FI, InsertPos);
 
   // Compute ABI information.
@@ -205,10 +218,12 @@
 }
 
 CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention,
+                               bool _NoReturn,
                                QualType ResTy,
                                const llvm::SmallVector<QualType, 16> &ArgTys) 
   : CallingConvention(_CallingConvention),
-    EffectiveCallingConvention(_CallingConvention)
+    EffectiveCallingConvention(_CallingConvention),
+    NoReturn(_NoReturn)
 {
   NumArgs = ArgTys.size();
   Args = new ArgInfo[1 + NumArgs];
@@ -490,6 +505,9 @@
 
   CallingConv = FI.getEffectiveCallingConvention();
 
+  if (FI.isNoReturn())
+    FuncAttrs |= llvm::Attribute::NoReturn;
+
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
     if (TargetDecl->hasAttr<NoThrowAttr>())
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
index 427ab5f..9601e9a 100644
--- a/lib/CodeGen/CGCall.h
+++ b/lib/CodeGen/CGCall.h
@@ -69,6 +69,9 @@
     /// depend on the ABI.
     unsigned EffectiveCallingConvention;
 
+    /// Whether this function is noreturn.
+    bool NoReturn;
+
     unsigned NumArgs;
     ArgInfo *Args;
 
@@ -77,6 +80,7 @@
     typedef ArgInfo *arg_iterator;
 
     CGFunctionInfo(unsigned CallingConvention,
+                   bool NoReturn,
                    QualType ResTy,
                    const llvm::SmallVector<QualType, 16> &ArgTys);
     ~CGFunctionInfo() { delete[] Args; }
@@ -88,6 +92,8 @@
 
     unsigned  arg_size() const { return NumArgs; }
 
+    bool isNoReturn() const { return NoReturn; }
+
     /// getCallingConvention - Return the user specified calling
     /// convention.
     unsigned getCallingConvention() const { return CallingConvention; }
@@ -108,6 +114,7 @@
 
     void Profile(llvm::FoldingSetNodeID &ID) {
       ID.AddInteger(getCallingConvention());
+      ID.AddBoolean(NoReturn);
       getReturnType().Profile(ID);
       for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
         it->type.Profile(ID);
@@ -115,10 +122,12 @@
     template<class Iterator>
     static void Profile(llvm::FoldingSetNodeID &ID,
                         unsigned CallingConvention,
+                        bool NoReturn,
                         QualType ResTy,
                         Iterator begin,
                         Iterator end) {
       ID.AddInteger(CallingConvention);
+      ID.AddBoolean(NoReturn);
       ResTy.Profile(ID);
       for (; begin != end; ++begin)
         begin->Profile(ID);
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 70973a4..c3901a5 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -327,9 +327,9 @@
     // Push the Src ptr.
     CallArgs.push_back(std::make_pair(RValue::get(Src),
                                      BaseCopyCtor->getParamDecl(0)->getType()));
-    QualType ResultType =
-      BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType();
-    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+    const FunctionProtoType *FPT
+      = BaseCopyCtor->getType()->getAs<FunctionProtoType>();
+    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
              Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
   }
   EmitBlock(ContinueBlock);
@@ -412,8 +412,7 @@
     RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
                                                  RValue::getAggregate(Src);
     CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
-    QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType();
-    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
              Callee, ReturnValueSlot(), CallArgs, MD);
   }
   EmitBlock(ContinueBlock);
@@ -503,9 +502,9 @@
     // Push the Src ptr.
     CallArgs.push_back(std::make_pair(RValue::get(Src),
                        BaseCopyCtor->getParamDecl(0)->getType()));
-    QualType ResultType =
-    BaseCopyCtor->getType()->getAs<FunctionType>()->getResultType();
-    EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+    const FunctionProtoType *FPT =
+      BaseCopyCtor->getType()->getAs<FunctionProtoType>();
+    EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
              Callee, ReturnValueSlot(), CallArgs, BaseCopyCtor);
   }
 }
@@ -550,9 +549,7 @@
   RValue SrcValue = SrcTy->isReferenceType() ? RValue::get(Src) :
                                                RValue::getAggregate(Src);
   CallArgs.push_back(std::make_pair(SrcValue, SrcTy));
-  QualType ResultType =
-    MD->getType()->getAs<FunctionType>()->getResultType();
-  EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+  EmitCall(CGM.getTypes().getFunctionInfo(CallArgs, FPT),
            Callee, ReturnValueSlot(), CallArgs, MD);
 }
 
@@ -1197,7 +1194,8 @@
   llvm::SmallString<16> Name;
   llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount);
   QualType R = getContext().VoidTy;
-  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(R, Args);
+  const CGFunctionInfo &FI
+    = CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false);
   const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false);
   llvm::Function *Fn =
     llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index bd0461f..a992b45 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -194,9 +194,9 @@
       // Push the Src ptr.
       CallArgs.push_back(std::make_pair(RValue::get(Src),
                                         CopyCtor->getParamDecl(0)->getType()));
-      QualType ResultType =
-        CopyCtor->getType()->getAs<FunctionType>()->getResultType();
-      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+      const FunctionProtoType *FPT
+        = CopyCtor->getType()->getAs<FunctionProtoType>();
+      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
                    Callee, ReturnValueSlot(), CallArgs, CopyCtor);
       CGF.setInvokeDest(PrevLandingPad);
     } else
@@ -244,9 +244,10 @@
       // Push the Src ptr.
       CallArgs.push_back(std::make_pair(RValue::get(Src),
                                         CopyCtor->getParamDecl(0)->getType()));
-      QualType ResultType =
-        CopyCtor->getType()->getAs<FunctionType>()->getResultType();
-      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
+
+      const FunctionProtoType *FPT
+        = CopyCtor->getType()->getAs<FunctionProtoType>();
+      CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
                    Callee, ReturnValueSlot(), CallArgs, CopyCtor);
     } else
       llvm_unreachable("uncopyable object");
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 7fb79e9..d258945 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1853,14 +1853,6 @@
   return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
 }
 
-static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) {
-  switch (CC) {
-  default: return llvm::CallingConv::C;
-  case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
-  case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
-  }
-}
-
 RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
                                  ReturnValueSlot ReturnValue,
                                  CallExpr::const_arg_iterator ArgBeg,
@@ -1873,16 +1865,14 @@
 
   CalleeType = getContext().getCanonicalType(CalleeType);
 
-  QualType FnType = cast<PointerType>(CalleeType)->getPointeeType();
-  QualType ResultType = cast<FunctionType>(FnType)->getResultType();
+  const FunctionType *FnType
+    = cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
+  QualType ResultType = FnType->getResultType();
 
   CallArgList Args;
   EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
 
-  unsigned CallingConvention =
-    ClangCallConvToLLVMCallConv(FnType->getAs<FunctionType>()->getCallConv());
-  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
-                                                 CallingConvention),
+  return EmitCall(CGM.getTypes().getFunctionInfo(Args, FnType),
                   Callee, ReturnValue, Args, TargetDecl);
 }
 
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 2dbeaec..7af90b7 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -42,8 +42,10 @@
   // And the rest of the call args
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
-  QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType();
-  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, 
+  QualType ResultType = FPT->getResultType();
+  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
+                                                 FPT->getCallConv(),
+                                                 FPT->getNoReturnAttr()), Callee, 
                   ReturnValue, Args, MD);
 }
 
@@ -244,8 +246,8 @@
   
   // And the rest of the call args
   EmitCallArgs(Args, FPT, E->arg_begin(), E->arg_end());
-  QualType ResultType = BO->getType()->getAs<FunctionType>()->getResultType();
-  return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, 
+  const FunctionType *BO_FPT = BO->getType()->getAs<FunctionProtoType>();
+  return EmitCall(CGM.getTypes().getFunctionInfo(Args, BO_FPT), Callee, 
                   ReturnValue, Args);
 }
 
@@ -542,7 +544,7 @@
 
   // Emit the call to new.
   RValue RV =
-    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
+    EmitCall(CGM.getTypes().getFunctionInfo(NewArgs, NewFTy),
              CGM.GetAddrOfFunction(NewFD), ReturnValueSlot(), NewArgs, NewFD);
 
   // If an allocation function is declared with an empty exception specification
@@ -686,8 +688,7 @@
     DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
 
   // Emit the call to delete.
-  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
-                                          DeleteArgs),
+  EmitCall(CGM.getTypes().getFunctionInfo(DeleteArgs, DeleteFTy),
            CGM.GetAddrOfFunction(DeleteFD), ReturnValueSlot(), 
            DeleteArgs, DeleteFD);
 }
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index e03d760..fedf16c 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -190,7 +190,8 @@
     Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
     // FIXME: We shouldn't need to get the function info here, the
     // runtime already should have computed it to build the function.
-    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args),
+    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
+                                               CC_Default, false),
                          GetPropertyFn, ReturnValueSlot(), Args);
     // We need to fix the type here. Ivars with copy & retain are
     // always objects so we don't need to worry about complex or
@@ -278,7 +279,8 @@
                                   getContext().BoolTy));
     // FIXME: We shouldn't need to get the function info here, the runtime
     // already should have computed it to build the function.
-    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args), SetPropertyFn, 
+    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
+                                   CC_Default, false), SetPropertyFn,
              ReturnValueSlot(), Args);
   } else {
     // FIXME: Find a clean way to avoid AST node creation.
@@ -554,7 +556,8 @@
                                 getContext().getObjCIdType()));
   // FIXME: We shouldn't need to get the function info here, the runtime already
   // should have computed it to build the function.
-  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2),
+  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
+                                          CC_Default, false),
            EnumerationMutationFn, ReturnValueSlot(), Args2);
 
   EmitBlock(WasNotMutated);
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index ace3896..d14f954 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -464,7 +464,8 @@
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 
   CodeGenTypes &Types = CGM.getTypes();
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       CC_Default, false);
   const llvm::FunctionType *impType =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
@@ -571,7 +572,8 @@
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 
   CodeGenTypes &Types = CGM.getTypes();
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       CC_Default, false);
   const llvm::FunctionType *impType =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
@@ -1686,7 +1688,8 @@
   llvm::SmallVector<QualType,16> Params;
   Params.push_back(ASTIdTy);
   const llvm::FunctionType *FTy =
-    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
+    Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                CC_Default, false), false);
   return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
 }
 
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 0dcbe82..2f931bd 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -305,7 +305,8 @@
     Params.push_back(Ctx.LongTy);
     Params.push_back(Ctx.BoolTy);
     const llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(IdType, Params), false);
+      Types.GetFunctionType(Types.getFunctionInfo(IdType, Params,
+                                                  CC_Default, false), false);
     return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
   }
 
@@ -323,7 +324,8 @@
     Params.push_back(Ctx.BoolTy);
     Params.push_back(Ctx.BoolTy);
     const llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
+      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                  CC_Default, false), false);
     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
   }
 
@@ -334,7 +336,8 @@
     llvm::SmallVector<QualType,16> Params;
     Params.push_back(Ctx.getObjCIdType());
     const llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
+      Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params,
+                                                  CC_Default, false), false);
     return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
   }
 
@@ -1554,7 +1557,8 @@
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
 
   CodeGenTypes &Types = CGM.getTypes();
-  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
+  const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                       CC_Default, false);
   const llvm::FunctionType *FTy =
     Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false);
 
@@ -5089,7 +5093,8 @@
   // FIXME. This is too much work to get the ABI-specific result type needed to
   // find the message name.
   const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType,
-                                                       llvm::SmallVector<QualType, 16>());
+                                                       llvm::SmallVector<QualType, 16>(),
+                                                       CC_Default, false);
   llvm::Constant *Fn = 0;
   std::string Name("\01l_");
   if (CGM.ReturnTypeUsesSret(FnInfo)) {
@@ -5163,7 +5168,8 @@
   ActualArgs.push_back(std::make_pair(RValue::get(Arg1),
                                       ObjCTypes.MessageRefCPtrTy));
   ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
-  const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs);
+  const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs,
+                                                        CC_Default, false);
   llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0);
   Callee = CGF.Builder.CreateLoad(Callee);
   const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true);
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 520742e..44ed9db 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -196,7 +196,9 @@
   }
 
   // FIXME: Leaked.
-  CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args);
+  // CC info is ignored, hopefully?
+  CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args,
+                                              CC_Default, false);
 
   if (RetTy->isVoidType()) {
     // Void type; nothing to return.
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index aa1880b..49da15d 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -198,6 +198,12 @@
   const CGFunctionInfo &getFunctionInfo(const CXXDestructorDecl *D,
                                         CXXDtorType Type);
 
+  const CGFunctionInfo &getFunctionInfo(const CallArgList &Args,
+                                        const FunctionType *Ty) {
+    return getFunctionInfo(Ty->getResultType(), Args,
+                           Ty->getCallConv(), Ty->getNoReturnAttr());
+  }
+
   // getFunctionInfo - Get the function info for a member function.
   const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD,
                                         const FunctionProtoType *FTP);
@@ -207,13 +213,16 @@
   /// specified, the "C" calling convention will be used.
   const CGFunctionInfo &getFunctionInfo(QualType ResTy,
                                         const CallArgList &Args,
-                                        unsigned CallingConvention = 0);
+                                        CallingConv CC,
+                                        bool NoReturn);
   const CGFunctionInfo &getFunctionInfo(QualType ResTy,
                                         const FunctionArgList &Args,
-                                        unsigned CallingConvention = 0);
+                                        CallingConv CC,
+                                        bool NoReturn);
   const CGFunctionInfo &getFunctionInfo(QualType RetTy,
                                   const llvm::SmallVector<QualType, 16> &ArgTys,
-                                        unsigned CallingConvention = 0);
+                                        CallingConv CC,
+                                        bool NoReturn);
 
 public:  // These are internal details of CGT that shouldn't be used externally.
   /// addFieldInfo - Assign field number to field FD.