1515#include " GenType.h"
1616#include " IRGen.h"
1717#include " IRGenModule.h"
18+ #include " NativeConventionSchema.h"
1819
1920#include " swift/AST/ASTContext.h"
2021#include " swift/AST/IRGenOptions.h"
2122#include " swift/AST/Types.h"
2223#include " swift/SIL/SILModule.h"
24+ #include " clang/CodeGen/ModuleBuilder.h"
25+ #include " clang/CodeGen/SwiftCallingConv.h"
26+ #include " llvm/IR/DerivedTypes.h"
2327
2428using namespace swift ;
2529using namespace irgen ;
2630
31+ static Optional<Type> getPrimitiveTypeFromLLVMType (ASTContext &ctx,
32+ const llvm::Type *type) {
33+ if (const auto *intType = dyn_cast<llvm::IntegerType>(type)) {
34+ switch (intType->getBitWidth ()) {
35+ case 8 :
36+ return ctx.getUInt8Type ();
37+ case 16 :
38+ return ctx.getUInt16Type ();
39+ case 32 :
40+ return ctx.getUInt32Type ();
41+ case 64 :
42+ return ctx.getUInt64Type ();
43+ default :
44+ return None;
45+ }
46+ } else if (type->isFloatTy ()) {
47+ return ctx.getFloatType ();
48+ } else if (type->isDoubleTy ()) {
49+ return ctx.getDoubleType ();
50+ } else if (type->isPointerTy ()) {
51+ return ctx.getOpaquePointerType ();
52+ }
53+ // FIXME: Handle vector type.
54+ return None;
55+ }
56+
2757namespace swift {
2858
2959class IRABIDetailsProviderImpl {
@@ -44,6 +74,39 @@ class IRABIDetailsProviderImpl {
4474 fixedTI->getFixedAlignment ().getValue ()};
4575 }
4676
77+ bool shouldPassIndirectly (Type type) {
78+ auto *TI = &IGM.getTypeInfoForUnlowered (type);
79+ NativeConventionSchema schema (IGM, TI, /* isResult=*/ false );
80+ return schema.requiresIndirect ();
81+ }
82+
83+ bool shouldReturnIndirectly (Type type) {
84+ if (type->isVoid ())
85+ return false ;
86+ auto *TI = &IGM.getTypeInfoForUnlowered (type);
87+ NativeConventionSchema schema (IGM, TI, /* isResult=*/ true );
88+ return schema.requiresIndirect ();
89+ }
90+
91+ bool enumerateDirectPassingRecordMembers (
92+ Type t, llvm::function_ref<void (clang::CharUnits, clang::CharUnits, Type)>
93+ callback) {
94+ auto *TI = &IGM.getTypeInfoForUnlowered (t);
95+ NativeConventionSchema schema (IGM, TI, /* isResult=*/ false );
96+ bool hasError = false ;
97+ schema.enumerateComponents (
98+ [&](clang::CharUnits offset, clang::CharUnits end, llvm::Type *type) {
99+ auto primitiveType = getPrimitiveTypeFromLLVMType (
100+ IGM.getSwiftModule ()->getASTContext (), type);
101+ if (!primitiveType) {
102+ hasError = true ;
103+ return ;
104+ }
105+ callback (offset, end, *primitiveType);
106+ });
107+ return hasError;
108+ }
109+
47110private:
48111 Lowering::TypeConverter typeConverter;
49112 // Default silOptions are sufficient, as we don't need to generated SIL.
@@ -65,3 +128,17 @@ llvm::Optional<IRABIDetailsProvider::SizeAndAlignment>
65128IRABIDetailsProvider::getTypeSizeAlignment (const NominalTypeDecl *TD) {
66129 return impl->getTypeSizeAlignment (TD);
67130}
131+
132+ bool IRABIDetailsProvider::shouldPassIndirectly (Type t) {
133+ return impl->shouldPassIndirectly (t);
134+ }
135+
136+ bool IRABIDetailsProvider::shouldReturnIndirectly (Type t) {
137+ return impl->shouldReturnIndirectly (t);
138+ }
139+
140+ bool IRABIDetailsProvider::enumerateDirectPassingRecordMembers (
141+ Type t, llvm::function_ref<void (clang::CharUnits, clang::CharUnits, Type)>
142+ callback) {
143+ return impl->enumerateDirectPassingRecordMembers (t, callback);
144+ }
0 commit comments