diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 23 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 31 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 65 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 5 |
4 files changed, 90 insertions, 34 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 8c867d9437f..d960503e57e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -711,6 +711,29 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); + + // Note that there is parallel code in SetFunctionAttributes in CodeGenModule + llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList; + if (hasAggregateLLVMType(ResultType)) + ParamAttrList.push_back( + llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet)); + unsigned increment = hasAggregateLLVMType(ResultType) ? 2 : 1; + for (unsigned i = 0; i < NumArgs; i++) { + QualType ParamType = ArgExprs[i]->getType(); + unsigned ParamAttrs = 0; + if (ParamType->isRecordType()) + ParamAttrs |= llvm::ParamAttr::ByVal; + if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::SExt; + if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::ZExt; + if (ParamAttrs) + ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment, + ParamAttrs)); + } + CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), + ParamAttrList.size())); + if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee)) CI->setCallingConv(F->getCallingConv()); if (CI->getType() != llvm::Type::VoidTy) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 26a0cfbafbb..1557738ed1c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -167,37 +167,6 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { CurFn = cast<llvm::Function>(CGM.GetAddrOfFunctionDecl(FD, true)); assert(CurFn->isDeclaration() && "Function already has body?"); - - // TODO: Set up linkage and many other things. Note, this is a simple - // approximation of what we really want. - if (FD->getStorageClass() == FunctionDecl::Static) - CurFn->setLinkage(llvm::Function::InternalLinkage); - else if (FD->getAttr<DLLImportAttr>()) - CurFn->setLinkage(llvm::Function::DLLImportLinkage); - else if (FD->getAttr<DLLExportAttr>()) - CurFn->setLinkage(llvm::Function::DLLExportLinkage); - else if (FD->getAttr<WeakAttr>() || FD->isInline()) - CurFn->setLinkage(llvm::Function::WeakLinkage); - - if (FD->getAttr<FastCallAttr>()) - CurFn->setCallingConv(llvm::CallingConv::Fast); - - if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>()) - CodeGenModule::setVisibility(CurFn, attr->getVisibility()); - // FIXME: else handle -fvisibility - - - unsigned FuncAttrs = 0; - if (FD->getAttr<NoThrowAttr>()) - FuncAttrs |= llvm::ParamAttr::NoUnwind; - if (FD->getAttr<NoReturnAttr>()) - FuncAttrs |= llvm::ParamAttr::NoReturn; - - if (FuncAttrs) { - llvm::ParamAttrsWithIndex PAWI = - llvm::ParamAttrsWithIndex::get(0, FuncAttrs); - CurFn->setParamAttrs(llvm::PAListPtr::get(&PAWI, 1)); - } llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6b9e69e13dd..764186daf37 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -183,6 +183,66 @@ void CodeGenModule::ReplaceMapValuesWith(llvm::Constant *OldVal, if (I->second == OldVal) I->second = NewVal; } +bool hasAggregateLLVMType(QualType T) { + return !T->isRealType() && !T->isPointerLikeType() && + !T->isVoidType() && !T->isVectorType() && !T->isFunctionType(); +} + +void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, + llvm::Function *F, + const llvm::FunctionType *FTy) { + unsigned FuncAttrs = 0; + if (FD->getAttr<NoThrowAttr>()) + FuncAttrs |= llvm::ParamAttr::NoUnwind; + if (FD->getAttr<NoReturnAttr>()) + FuncAttrs |= llvm::ParamAttr::NoReturn; + + llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList; + if (FuncAttrs) + ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs)); + // Note that there is parallel code in CodeGenFunction::EmitCallExpr + bool AggregateReturn = hasAggregateLLVMType(FD->getResultType()); + if (AggregateReturn) + ParamAttrList.push_back( + llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet)); + unsigned increment = AggregateReturn ? 2 : 1; + for (unsigned i = 0; i < FD->getNumParams(); i++) { + QualType ParamType = FD->getParamDecl(i)->getType(); + unsigned ParamAttrs = 0; + if (ParamType->isRecordType()) + ParamAttrs |= llvm::ParamAttr::ByVal; + if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::SExt; + if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType()) + ParamAttrs |= llvm::ParamAttr::ZExt; + if (ParamAttrs) + ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment, + ParamAttrs)); + } + F->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), + ParamAttrList.size())); + + // Set the appropriate calling convention for the Function. + if (FD->getAttr<FastCallAttr>()) + F->setCallingConv(llvm::CallingConv::Fast); + + // TODO: Set up linkage and many other things. Note, this is a simple + // approximation of what we really want. + if (FD->getStorageClass() == FunctionDecl::Static) + F->setLinkage(llvm::Function::InternalLinkage); + else if (FD->getAttr<DLLImportAttr>()) + F->setLinkage(llvm::Function::DLLImportLinkage); + else if (FD->getAttr<DLLExportAttr>()) + F->setLinkage(llvm::Function::DLLExportLinkage); + else if (FD->getAttr<WeakAttr>() || FD->isInline()) + F->setLinkage(llvm::Function::WeakLinkage); + + if (const VisibilityAttr *attr = FD->getAttr<VisibilityAttr>()) + CodeGenModule::setVisibility(F, attr->getVisibility()); + // FIXME: else handle -fvisibility +} + + llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D, bool isDefinition) { @@ -202,9 +262,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D, F = llvm::Function::Create(FTy, llvm::Function::ExternalLinkage, D->getName(), &getModule()); - // Set the appropriate calling convention for the Function. - if (D->getAttr<FastCallAttr>()) - F->setCallingConv(llvm::CallingConv::Fast); + SetFunctionAttributes(D, F, FTy); return Entry = F; } @@ -243,6 +301,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunctionDecl(const FunctionDecl *D, assert(F->isDeclaration() && "Shouldn't replace non-declaration"); F->eraseFromParent(); + SetFunctionAttributes(D, NewFn, FTy); // Return the new function which has the right type. return Entry = NewFn; } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 3e775260676..de2995f6a8c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -26,6 +26,7 @@ namespace llvm { class Function; class GlobalValue; class TargetData; + class FunctionType; } namespace clang { @@ -149,6 +150,10 @@ private: /// searches for any entries in GlobalDeclMap that point to OldVal, changing /// them to point to NewVal. This is badbadbad, FIXME! void ReplaceMapValuesWith(llvm::Constant *OldVal, llvm::Constant *NewVal); + + void SetFunctionAttributes(const FunctionDecl *FD, + llvm::Function *F, + const llvm::FunctionType *FTy); }; } // end namespace CodeGen |