Skip to content

Commit 1696f94

Browse files
committed
[interop][SwiftToCxx] reimplement function lowering to correctly distinguish between direct/indirect return values and parameters
1 parent 965a966 commit 1696f94

32 files changed

+1384
-660
lines changed

include/swift/IRGen/IRABIDetailsProvider.h

Lines changed: 124 additions & 4 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,17 @@ 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+
3746
/// Provides access to the IRGen-based queries that can be performed on
3847
/// declarations to get their various ABI details.
3948
class IRABIDetailsProvider {
@@ -90,6 +99,121 @@ class IRABIDetailsProvider {
9099
friend class IRABIDetailsProviderImpl;
91100
};
92101

102+
/// Describes the lowered Swift function signature.
103+
class LoweredFunctionSignature {
104+
public:
105+
class DirectResultType {
106+
public:
107+
/// Enumerates all of the members of the underlying record in terms of
108+
/// their primitive types that needs to be stored in a Clang/LLVM record
109+
/// when this type is passed or returned directly to/from swiftcc
110+
/// function.
111+
///
112+
/// Returns true if an error occurred when a particular member can't be
113+
/// represented with an AST type.
114+
bool enumerateRecordMembers(
115+
llvm::function_ref<void(clang::CharUnits, clang::CharUnits, Type)>
116+
callback) const;
117+
118+
private:
119+
DirectResultType(IRABIDetailsProviderImpl &owner,
120+
const irgen::TypeInfo &typeDetails);
121+
IRABIDetailsProviderImpl &owner;
122+
const irgen::TypeInfo &typeDetails;
123+
friend class LoweredFunctionSignature;
124+
};
125+
126+
class IndirectResultType {
127+
public:
128+
/// Returns true if this indirect result type uses the `sret` LLVM
129+
/// attribute.
130+
inline bool hasSRet() const { return hasSRet_; }
131+
132+
private:
133+
inline IndirectResultType(bool hasSRet_) : hasSRet_(hasSRet_) {}
134+
bool hasSRet_;
135+
friend class LoweredFunctionSignature;
136+
};
137+
138+
/// Represents a parameter passed directly to the function.
139+
class DirectParameter {
140+
public:
141+
/// Enumerates all of the members of the underlying record in terms of
142+
/// their primitive types that needs to be stored in a Clang/LLVM record
143+
/// when this type is passed or returned directly to/from swiftcc
144+
/// function.
145+
///
146+
/// Returns true if an error occurred when a particular member can't be
147+
/// represented with an AST type.
148+
bool enumerateRecordMembers(
149+
llvm::function_ref<void(clang::CharUnits, clang::CharUnits, Type)>
150+
callback) const;
151+
152+
inline const ParamDecl &getParamDecl() const { return paramDecl; }
153+
154+
private:
155+
DirectParameter(IRABIDetailsProviderImpl &owner,
156+
const irgen::TypeInfo &typeDetails,
157+
const ParamDecl &paramDecl);
158+
IRABIDetailsProviderImpl &owner;
159+
const irgen::TypeInfo &typeDetails;
160+
const ParamDecl &paramDecl;
161+
friend class LoweredFunctionSignature;
162+
};
163+
164+
/// Represents a parameter passed indirectly to the function.
165+
class IndirectParameter {
166+
public:
167+
inline const ParamDecl &getParamDecl() const { return paramDecl; }
168+
169+
private:
170+
IndirectParameter(const ParamDecl &paramDecl);
171+
const ParamDecl &paramDecl;
172+
friend class LoweredFunctionSignature;
173+
};
174+
175+
/// Returns lowered direct result details, or \c None if direct result is
176+
/// void.
177+
llvm::Optional<DirectResultType> getDirectResultType() const;
178+
179+
/// Returns the number of indirect result values in this function signature.
180+
size_t getNumIndirectResults() const;
181+
182+
/// Returns lowered indirect result details.
183+
llvm::SmallVector<IndirectResultType, 1> getIndirectResultTypes() const;
184+
185+
/// Traverse the entire parameter list of the function signature.
186+
///
187+
/// The parameter list can include actual Swift function parameters, result
188+
/// values returned indirectly, and additional values, like generic
189+
/// requirements for polymorphic calls and the error parameter as well.
190+
void visitParameterList(
191+
llvm::function_ref<void(const DirectParameter &)> directParamVisitor,
192+
llvm::function_ref<void(const IndirectParameter &)>
193+
indirectParamVisitor);
194+
195+
/// FIXME: make private.
196+
SmallVector<ABIAdditionalParam, 1> additionalParams;
197+
198+
private:
199+
LoweredFunctionSignature(
200+
const AbstractFunctionDecl *FD, IRABIDetailsProviderImpl &owner,
201+
const irgen::SignatureExpansionABIDetails &abiDetails);
202+
const AbstractFunctionDecl *FD;
203+
IRABIDetailsProviderImpl &owner;
204+
const irgen::SignatureExpansionABIDetails &abiDetails;
205+
friend class IRABIDetailsProviderImpl;
206+
};
207+
208+
/// Returns the function signature lowered to its C / LLVM - like
209+
/// representation, or \c None if such representation could not be computed.
210+
llvm::Optional<LoweredFunctionSignature>
211+
getFunctionLoweredSignature(AbstractFunctionDecl *fd);
212+
213+
/// Returns the additional params if they exist after lowering the function.
214+
SmallVector<ABIAdditionalParam, 1>
215+
getFunctionABIAdditionalParams(AbstractFunctionDecl *fd);
216+
93217
/// Returns the size and alignment for the given type, or \c None if the type
94218
/// is not a fixed layout type.
95219
llvm::Optional<SizeAndAlignment>
@@ -154,10 +278,6 @@ class IRABIDetailsProvider {
154278
llvm::MapVector<EnumElementDecl *, EnumElementInfo>
155279
getEnumTagMapping(const EnumDecl *ED);
156280

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

0 commit comments

Comments
 (0)