Skip to content

Commit 6e7b3ab

Browse files
authored
Merge pull request #60978 from hyp/eng/rewrite-lowering
[interop][SwiftToCxx] reimplement function lowering to correctly dist…
2 parents 0e49262 + 4c7015a commit 6e7b3ab

37 files changed

+1652
-939
lines changed

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 153 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/AST/Decl.h"
1717
#include "swift/AST/GenericRequirement.h"
1818
#include "swift/AST/Type.h"
19+
#include "swift/AST/Types.h"
1920
#include "clang/AST/CharUnits.h"
2021
#include "llvm/ADT/MapVector.h"
2122
#include "llvm/ADT/Optional.h"
@@ -31,9 +32,157 @@ class ASTContext;
3132
class IRGenOptions;
3233
class ModuleDecl;
3334
class NominalTypeDecl;
35+
class ParamDecl;
3436

3537
class IRABIDetailsProviderImpl;
3638

39+
namespace irgen {
40+
41+
class SignatureExpansionABIDetails;
42+
class TypeInfo;
43+
44+
} // namespace irgen
45+
46+
/// Describes the lowered Swift function signature.
47+
class LoweredFunctionSignature {
48+
public:
49+
class DirectResultType {
50+
public:
51+
/// Enumerates all of the members of the underlying record in terms of
52+
/// their primitive types that needs to be stored in a Clang/LLVM record
53+
/// when this type is passed or returned directly to/from swiftcc
54+
/// function.
55+
///
56+
/// Returns true if an error occurred when a particular member can't be
57+
/// represented with an AST type.
58+
bool enumerateRecordMembers(
59+
llvm::function_ref<void(clang::CharUnits, clang::CharUnits, Type)>
60+
callback) const;
61+
62+
private:
63+
DirectResultType(IRABIDetailsProviderImpl &owner,
64+
const irgen::TypeInfo &typeDetails);
65+
IRABIDetailsProviderImpl &owner;
66+
const irgen::TypeInfo &typeDetails;
67+
friend class LoweredFunctionSignature;
68+
};
69+
70+
/// Represents a result value returned indirectly out of a function.
71+
class IndirectResultValue {
72+
public:
73+
/// Returns true if this indirect result type uses the `sret` LLVM
74+
/// attribute.
75+
inline bool hasSRet() const { return hasSRet_; }
76+
77+
private:
78+
inline IndirectResultValue(bool hasSRet_) : hasSRet_(hasSRet_) {}
79+
bool hasSRet_;
80+
friend class LoweredFunctionSignature;
81+
};
82+
83+
/// Represents a parameter passed directly to the function.
84+
class DirectParameter {
85+
public:
86+
/// Enumerates all of the members of the underlying record in terms of
87+
/// their primitive types that needs to be stored in a Clang/LLVM record
88+
/// when this type is passed or returned directly to/from swiftcc
89+
/// function.
90+
///
91+
/// Returns true if an error occurred when a particular member can't be
92+
/// represented with an AST type.
93+
bool enumerateRecordMembers(
94+
llvm::function_ref<void(clang::CharUnits, clang::CharUnits, Type)>
95+
callback) const;
96+
97+
inline const ParamDecl &getParamDecl() const { return paramDecl; }
98+
99+
private:
100+
DirectParameter(IRABIDetailsProviderImpl &owner,
101+
const irgen::TypeInfo &typeDetails,
102+
const ParamDecl &paramDecl);
103+
IRABIDetailsProviderImpl &owner;
104+
const irgen::TypeInfo &typeDetails;
105+
const ParamDecl &paramDecl;
106+
friend class LoweredFunctionSignature;
107+
};
108+
109+
/// Represents a parameter passed indirectly to the function.
110+
class IndirectParameter {
111+
public:
112+
inline const ParamDecl &getParamDecl() const { return paramDecl; }
113+
114+
private:
115+
IndirectParameter(const ParamDecl &paramDecl);
116+
const ParamDecl &paramDecl;
117+
friend class LoweredFunctionSignature;
118+
};
119+
120+
/// Represents a generic requirement paremeter that must be passed to the
121+
/// function.
122+
class GenericRequirementParameter {
123+
public:
124+
inline GenericRequirement getRequirement() const { return requirement; }
125+
126+
private:
127+
GenericRequirementParameter(const GenericRequirement &requirement);
128+
GenericRequirement requirement;
129+
friend class LoweredFunctionSignature;
130+
};
131+
132+
/// Represents a parameter which is a Swift type pointer sourced from a
133+
/// valid metadata source, like the type of another argument.
134+
class MetadataSourceParameter {
135+
public:
136+
inline CanType getType() const { return type; }
137+
138+
private:
139+
MetadataSourceParameter(const CanType &type);
140+
CanType type;
141+
friend class LoweredFunctionSignature;
142+
};
143+
144+
/// Represents a context parameter passed to the call.
145+
class ContextParameter {};
146+
147+
/// Represents an out error parameter passed indirectly to the call.
148+
class ErrorResultValue {};
149+
150+
/// Returns lowered direct result details, or \c None if direct result is
151+
/// void.
152+
llvm::Optional<DirectResultType> getDirectResultType() const;
153+
154+
/// Returns the number of indirect result values in this function signature.
155+
size_t getNumIndirectResultValues() const;
156+
157+
/// Traverse the entire parameter list of the function signature.
158+
///
159+
/// The parameter list can include actual Swift function parameters, result
160+
/// values returned indirectly, and additional values, like generic
161+
/// requirements for polymorphic calls and the error parameter as well.
162+
void visitParameterList(
163+
llvm::function_ref<void(const IndirectResultValue &)>
164+
indirectResultVisitor,
165+
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
166+
llvm::function_ref<void(const IndirectParameter &)> indirectParamVisitor,
167+
llvm::function_ref<void(const GenericRequirementParameter &)>
168+
genericRequirementVisitor,
169+
llvm::function_ref<void(const MetadataSourceParameter &)>
170+
metadataSourceVisitor,
171+
llvm::function_ref<void(const ContextParameter &)> contextParamVisitor,
172+
llvm::function_ref<void(const ErrorResultValue &)> errorResultVisitor)
173+
const;
174+
175+
private:
176+
LoweredFunctionSignature(
177+
const AbstractFunctionDecl *FD, IRABIDetailsProviderImpl &owner,
178+
const irgen::SignatureExpansionABIDetails &abiDetails);
179+
const AbstractFunctionDecl *FD;
180+
IRABIDetailsProviderImpl &owner;
181+
const irgen::SignatureExpansionABIDetails &abiDetails;
182+
SmallVector<CanType, 1> metadataSourceTypes;
183+
friend class IRABIDetailsProviderImpl;
184+
};
185+
37186
/// Provides access to the IRGen-based queries that can be performed on
38187
/// declarations to get their various ABI details.
39188
class IRABIDetailsProvider {
@@ -48,71 +197,16 @@ class IRABIDetailsProvider {
48197
SizeType alignment;
49198
};
50199

51-
/// Information about any ABI additional parameters.
52-
class ABIAdditionalParam {
53-
public:
54-
enum class ABIParameterRole {
55-
/// A parameter that corresponds to a generic requirement that must be
56-
/// fullfilled by a call to this function.
57-
GenericRequirement,
58-
/// A parameter that corresponds to a Swift type pointer sourced from a
59-
/// valid metadata source, like the type of another argument.
60-
GenericTypeMetadataSource,
61-
/// A parameter that corresponds to the 'self' parameter.
62-
Self,
63-
/// The Swift error parameter.
64-
Error
65-
};
66-
67-
inline ABIParameterRole getRole() const { return role; }
68-
69-
inline GenericRequirement getGenericRequirement() {
70-
assert(role == ABIParameterRole::GenericRequirement);
71-
return *genericRequirement;
72-
}
73-
74-
inline CanType getMetadataSourceType() {
75-
assert(role == ABIParameterRole::GenericTypeMetadataSource);
76-
return canType;
77-
}
78-
79-
private:
80-
inline ABIAdditionalParam(
81-
ABIParameterRole role,
82-
llvm::Optional<GenericRequirement> genericRequirement, CanType canType)
83-
: role(role), genericRequirement(genericRequirement), canType(canType) {
84-
}
85-
86-
ABIParameterRole role;
87-
llvm::Optional<GenericRequirement> genericRequirement;
88-
CanType canType;
89-
90-
friend class IRABIDetailsProviderImpl;
91-
};
200+
/// Returns the function signature lowered to its C / LLVM - like
201+
/// representation, or \c None if such representation could not be computed.
202+
llvm::Optional<LoweredFunctionSignature>
203+
getFunctionLoweredSignature(AbstractFunctionDecl *fd);
92204

93205
/// Returns the size and alignment for the given type, or \c None if the type
94206
/// is not a fixed layout type.
95207
llvm::Optional<SizeAndAlignment>
96208
getTypeSizeAlignment(const NominalTypeDecl *TD);
97209

98-
/// Returns true if the given type should be passed indirectly into a swiftcc
99-
/// function.
100-
bool shouldPassIndirectly(Type t);
101-
102-
/// Returns true if the given type should be returned indirectly from a
103-
/// swiftcc function.
104-
bool shouldReturnIndirectly(Type t);
105-
106-
/// Enumerates all of the members of the underlying record in terms of their
107-
/// primitive types that needs to be stored in a Clang/LLVM record when this
108-
/// type is passed or returned directly to/from swiftcc function.
109-
///
110-
/// Returns true if an error occurred when a particular member can't be
111-
/// represented with an AST type.
112-
bool enumerateDirectPassingRecordMembers(
113-
Type t, llvm::function_ref<void(clang::CharUnits, clang::CharUnits, Type)>
114-
callback);
115-
116210
/// An representation of a single type, or a C struct with multiple members
117211
/// with specified types. The C struct is expected to be passed via swiftcc
118212
/// functions.
@@ -154,10 +248,6 @@ class IRABIDetailsProvider {
154248
llvm::MapVector<EnumElementDecl *, EnumElementInfo>
155249
getEnumTagMapping(const EnumDecl *ED);
156250

157-
/// Returns the additional params if they exist after lowering the function.
158-
SmallVector<ABIAdditionalParam, 1>
159-
getFunctionABIAdditionalParams(AbstractFunctionDecl *fd);
160-
161251
private:
162252
std::unique_ptr<IRABIDetailsProviderImpl> impl;
163253
};

0 commit comments

Comments
 (0)