Skip to content

Commit bb58bdd

Browse files
committed
[clang codegen] Add CreateRuntimeFunction overload that takes a clang type.
Correctly computing the LLVM types/attributes is complicated in general, so add a variant which does that for you.
1 parent e78f53d commit bb58bdd

File tree

3 files changed

+59
-22
lines changed

3 files changed

+59
-22
lines changed

clang/lib/CodeGen/CGBlocks.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,10 +2839,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
28392839
if (BlockObjectDispose)
28402840
return BlockObjectDispose;
28412841

2842-
llvm::Type *args[] = { Int8PtrTy, Int32Ty };
2843-
llvm::FunctionType *fty
2844-
= llvm::FunctionType::get(VoidTy, args, false);
2845-
BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
2842+
QualType args[] = {Context.VoidPtrTy, Context.IntTy};
2843+
BlockObjectDispose =
2844+
CreateRuntimeFunction(Context.VoidTy, args, "_Block_object_dispose");
28462845
configureBlocksRuntimeObject(
28472846
*this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
28482847
return BlockObjectDispose;
@@ -2852,10 +2851,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
28522851
if (BlockObjectAssign)
28532852
return BlockObjectAssign;
28542853

2855-
llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
2856-
llvm::FunctionType *fty
2857-
= llvm::FunctionType::get(VoidTy, args, false);
2858-
BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");
2854+
QualType args[] = {Context.VoidPtrTy, Context.VoidPtrTy, Context.IntTy};
2855+
BlockObjectAssign =
2856+
CreateRuntimeFunction(Context.VoidTy, args, "_Block_object_assign");
28592857
configureBlocksRuntimeObject(
28602858
*this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
28612859
return BlockObjectAssign;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4903,6 +4903,52 @@ GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
49034903
return nullptr;
49044904
}
49054905

4906+
static void setWindowsItaniumDLLImport(CodeGenModule &CGM, bool Local,
4907+
llvm::Function *F, StringRef Name) {
4908+
// In Windows Itanium environments, try to mark runtime functions
4909+
// dllimport. For Mingw and MSVC, don't. We don't really know if the user
4910+
// will link their standard library statically or dynamically. Marking
4911+
// functions imported when they are not imported can cause linker errors
4912+
// and warnings.
4913+
if (!Local && CGM.getTriple().isWindowsItaniumEnvironment() &&
4914+
!CGM.getCodeGenOpts().LTOVisibilityPublicStd) {
4915+
const FunctionDecl *FD = GetRuntimeFunctionDecl(CGM.getContext(), Name);
4916+
if (!FD || FD->hasAttr<DLLImportAttr>()) {
4917+
F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
4918+
F->setLinkage(llvm::GlobalValue::ExternalLinkage);
4919+
}
4920+
}
4921+
}
4922+
4923+
llvm::FunctionCallee CodeGenModule::CreateRuntimeFunction(
4924+
QualType ReturnTy, ArrayRef<QualType> ArgTys, StringRef Name,
4925+
llvm::AttributeList ExtraAttrs, bool Local, bool AssumeConvergent) {
4926+
if (AssumeConvergent) {
4927+
ExtraAttrs =
4928+
ExtraAttrs.addFnAttribute(VMContext, llvm::Attribute::Convergent);
4929+
}
4930+
4931+
QualType FTy = Context.getFunctionType(ReturnTy, ArgTys,
4932+
FunctionProtoType::ExtProtoInfo());
4933+
const CGFunctionInfo &Info = getTypes().arrangeFreeFunctionType(
4934+
Context.getCanonicalType(FTy).castAs<FunctionProtoType>());
4935+
auto *ConvTy = getTypes().GetFunctionType(Info);
4936+
llvm::Constant *C = GetOrCreateLLVMFunction(
4937+
Name, ConvTy, GlobalDecl(), /*ForVTable=*/false,
4938+
/*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs);
4939+
4940+
if (auto *F = dyn_cast<llvm::Function>(C)) {
4941+
if (F->empty()) {
4942+
SetLLVMFunctionAttributes(GlobalDecl(), Info, F, /*IsThunk*/ false);
4943+
// FIXME: Set calling-conv properly in ExtProtoInfo
4944+
F->setCallingConv(getRuntimeCC());
4945+
setWindowsItaniumDLLImport(*this, Local, F, Name);
4946+
setDSOLocal(F);
4947+
}
4948+
}
4949+
return {ConvTy, C};
4950+
}
4951+
49064952
/// CreateRuntimeFunction - Create a new runtime function with the specified
49074953
/// type and name.
49084954
llvm::FunctionCallee
@@ -4922,20 +4968,7 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
49224968
if (auto *F = dyn_cast<llvm::Function>(C)) {
49234969
if (F->empty()) {
49244970
F->setCallingConv(getRuntimeCC());
4925-
4926-
// In Windows Itanium environments, try to mark runtime functions
4927-
// dllimport. For Mingw and MSVC, don't. We don't really know if the user
4928-
// will link their standard library statically or dynamically. Marking
4929-
// functions imported when they are not imported can cause linker errors
4930-
// and warnings.
4931-
if (!Local && getTriple().isWindowsItaniumEnvironment() &&
4932-
!getCodeGenOpts().LTOVisibilityPublicStd) {
4933-
const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name);
4934-
if (!FD || FD->hasAttr<DLLImportAttr>()) {
4935-
F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
4936-
F->setLinkage(llvm::GlobalValue::ExternalLinkage);
4937-
}
4938-
}
4971+
setWindowsItaniumDLLImport(*this, Local, F, Name);
49394972
setDSOLocal(F);
49404973
// FIXME: We should use CodeGenModule::SetLLVMFunctionAttributes() instead
49414974
// of trying to approximate the attributes using the LLVM function

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,12 @@ class CodeGenModule : public CodeGenTypeCache {
12541254
llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
12551255
bool Local = false, bool AssumeConvergent = false);
12561256

1257+
llvm::FunctionCallee
1258+
CreateRuntimeFunction(QualType ReturnTy, ArrayRef<QualType> ArgTys,
1259+
StringRef Name,
1260+
llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
1261+
bool Local = false, bool AssumeConvergent = false);
1262+
12571263
/// Create a new runtime global variable with the specified type and name.
12581264
llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
12591265
StringRef Name);

0 commit comments

Comments
 (0)