diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c7b2a5dc895f..7e2592206e0b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -31,50 +31,70 @@ using namespace CodeGen; // FIXME: Use iterator and sidestep silly type array creation. -CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP) { - ArgTypes.push_back(FTNP->getResultType()); +const +CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeNoProto *FTNP) { + return getFunctionInfo(FTNP->getResultType(), + llvm::SmallVector()); } -CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP) { - ArgTypes.push_back(FTP->getResultType()); +const +CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeProto *FTP) { + llvm::SmallVector ArgTys; + // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) - ArgTypes.push_back(FTP->getArgType(i)); + ArgTys.push_back(FTP->getArgType(i)); + return getFunctionInfo(FTP->getResultType(), ArgTys); } -// FIXME: Is there really any reason to have this still? -CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) { +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { const FunctionType *FTy = FD->getType()->getAsFunctionType(); - const FunctionTypeProto *FTP = dyn_cast(FTy); - - ArgTypes.push_back(FTy->getResultType()); - if (FTP) { - for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) - ArgTypes.push_back(FTP->getArgType(i)); - } + if (const FunctionTypeProto *FTP = dyn_cast(FTy)) + return getFunctionInfo(FTP); + return getFunctionInfo(cast(FTy)); } -CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, - const ASTContext &Context) { - ArgTypes.push_back(MD->getResultType()); - ArgTypes.push_back(MD->getSelfDecl()->getType()); - ArgTypes.push_back(Context.getObjCSelType()); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { + llvm::SmallVector ArgTys; + ArgTys.push_back(MD->getSelfDecl()->getType()); + ArgTys.push_back(Context.getObjCSelType()); + // FIXME: Kill copy? for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(), e = MD->param_end(); i != e; ++i) - ArgTypes.push_back((*i)->getType()); + ArgTys.push_back((*i)->getType()); + return getFunctionInfo(MD->getResultType(), ArgTys); } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args) { - ArgTypes.push_back(ResTy); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const CallArgList &Args) { + // FIXME: Kill copy. + llvm::SmallVector ArgTys; for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) - ArgTypes.push_back(i->second); + ArgTys.push_back(i->second); + return getFunctionInfo(ResTy, ArgTys); } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, const FunctionArgList &Args) { - ArgTypes.push_back(ResTy); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const FunctionArgList &Args) { + // FIXME: Kill copy. + llvm::SmallVector ArgTys; for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) - ArgTypes.push_back(i->second); + ArgTys.push_back(i->second); + return getFunctionInfo(ResTy, ArgTys); +} + +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys) { + return *new CGFunctionInfo(ResTy, ArgTys); +} + +/***/ + +CGFunctionInfo::CGFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys) { + ArgTypes.push_back(ResTy); + ArgTypes.insert(ArgTypes.end(), ArgTys.begin(), ArgTys.end()); } ArgTypeIterator CGFunctionInfo::argtypes_begin() const { diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 7ca5f26a8f8c..f8fb32b15a4e 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -57,12 +57,8 @@ namespace CodeGen { llvm::SmallVector ArgTypes; public: - CGFunctionInfo(const FunctionTypeNoProto *FTNP); - CGFunctionInfo(const FunctionTypeProto *FTP); - CGFunctionInfo(const FunctionDecl *FD); - CGFunctionInfo(const ObjCMethodDecl *MD, const ASTContext &Context); - CGFunctionInfo(QualType ResTy, const CallArgList &Args); - CGFunctionInfo(QualType ResTy, const FunctionArgList &Args); + CGFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys); ArgTypeIterator argtypes_begin() const; ArgTypeIterator argtypes_end() const; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5ed215164b7e..2c16c1940b55 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1102,5 +1102,6 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType, Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); - return EmitCall(CGFunctionInfo(ResultType, Args), Callee, Args); + return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), + Callee, Args); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index cf37886e6d37..9dc45efc6872 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -183,7 +183,7 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); - RValue RV = EmitCall(CGFunctionInfo(PD->getType(), Args), + RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args), GetPropertyFn, 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 @@ -268,7 +268,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, getContext().BoolTy)); Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), getContext().BoolTy)); - EmitCall(CGFunctionInfo(PD->getType(), Args), SetPropertyFn, Args); + EmitCall(Types.getFunctionInfo(PD->getType(), Args), + SetPropertyFn, Args); } else { SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index e6ae6f36b4e1..1ce28bf91d40 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -311,7 +311,8 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); + return CGF.EmitCall(CGM.getTypes().getFunctionInfo(ResultType, ActualArgs), + imp, ActualArgs); } /// Generate code for a message send expression. @@ -358,7 +359,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); + return CGF.EmitCall(CGM.getTypes().getFunctionInfo(ResultType, ActualArgs), + imp, ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and @@ -969,9 +971,9 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, std::string MethodName = OMD->getSelector().getAsString(); bool isClassMethod = !OMD->isInstanceMethod(); + CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), - OMD->isVariadic()); + Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, MethodName, isClassMethod); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index d8e873b84592..a577bd03cb26 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -806,8 +806,9 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - CGFunctionInfo FnInfo(ResultType, ActualArgs); - const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo, false); + CodeGenTypes &Types = CGM.getTypes(); + const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); + const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo, false); llvm::Constant *Fn; if (CGM.ReturnTypeUsesSret(FnInfo)) { @@ -1668,9 +1669,9 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, std::string Name; GetNameForMethod(OMD, CD, Name); + CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), - OMD->isVariadic()); + Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); llvm::Function *Method = llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fe28b3aeccdd..866b8826241c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -172,7 +172,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, } // FIXME: Leaked. - CurFnInfo = new CGFunctionInfo(FnRetTy, Args); + CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args); EmitFunctionProlog(*CurFnInfo, CurFn, Args); // If any of the arguments have a variably modified type, make sure to diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d02812ac5d9c..18870722fa28 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -299,14 +299,14 @@ void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D, void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD, llvm::Function *F) { - SetFunctionAttributes(MD, CGFunctionInfo(MD, Context), F); + SetFunctionAttributes(MD, getTypes().getFunctionInfo(MD), F); SetFunctionAttributesForDefinition(MD, F); } void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, llvm::Function *F) { - SetFunctionAttributes(FD, CGFunctionInfo(FD), F); + SetFunctionAttributes(FD, getTypes().getFunctionInfo(FD), F); SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static, FD->isInline(), F, false); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index bcb3cc559158..0b74e1e636fb 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -256,11 +256,11 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { VT.getNumElements()); } case Type::FunctionNoProto: - return GetFunctionType(CGFunctionInfo(cast(&Ty)), + return GetFunctionType(getFunctionInfo(cast(&Ty)), true); case Type::FunctionProto: { const FunctionTypeProto *FTP = cast(&Ty); - return GetFunctionType(CGFunctionInfo(FTP), FTP->isVariadic()); + return GetFunctionType(getFunctionInfo(FTP), FTP->isVariadic()); } case Type::ASQual: diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 60c2946f131f..d41c23d37476 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -158,6 +158,20 @@ public: /// UpdateCompletedType - When we find the full definition for a TagDecl, /// replace the 'opaque' type we previously made for it if applicable. void UpdateCompletedType(const TagDecl *TD); + + /// getFunctionInfo - Get the CGFunctionInfo for this function signature. + const CGFunctionInfo &getFunctionInfo(QualType RetTy, + const llvm::SmallVector + &ArgTys); + + const CGFunctionInfo &getFunctionInfo(const FunctionTypeNoProto *FTNP); + const CGFunctionInfo &getFunctionInfo(const FunctionTypeProto *FTP); + const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD); + const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD); + const CGFunctionInfo &getFunctionInfo(QualType ResTy, + const CallArgList &Args); + const CGFunctionInfo &getFunctionInfo(QualType ResTy, + const FunctionArgList &Args); public: // These are internal details of CGT that shouldn't be used externally. /// addFieldInfo - Assign field number to field FD.