Skip to content

Commit 557e377

Browse files
author
Gabor Horvath
committed
Revert "Revert "[SILGen] Fix the type of closure thunks that are passed const reference structs (#76903)" (#77309)"
This reverts commit f73c2e5.
1 parent 8c84ee2 commit 557e377

File tree

16 files changed

+243
-64
lines changed

16 files changed

+243
-64
lines changed

include/swift/AST/Expr.h

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/AST/FunctionRefInfo.h"
3030
#include "swift/AST/ProtocolConformanceRef.h"
3131
#include "swift/AST/ThrownErrorDestination.h"
32+
#include "swift/AST/Type.h"
3233
#include "swift/AST/TypeAlignments.h"
3334
#include "swift/Basic/Debug.h"
3435
#include "swift/Basic/InlineBitfield.h"
@@ -3367,9 +3368,8 @@ class UnresolvedTypeConversionExpr : public ImplicitConversionExpr {
33673368
/// FIXME: This should be a CapturingExpr.
33683369
class FunctionConversionExpr : public ImplicitConversionExpr {
33693370
public:
3370-
FunctionConversionExpr(Expr *subExpr, Type type)
3371-
: ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {}
3372-
3371+
FunctionConversionExpr(Expr *subExpr, Type type);
3372+
33733373
static bool classof(const Expr *E) {
33743374
return E->getKind() == ExprKind::FunctionConversion;
33753375
}
@@ -4290,6 +4290,12 @@ class ClosureExpr : public AbstractClosureExpr {
42904290
/// The body of the closure.
42914291
BraceStmt *Body;
42924292

4293+
/// Used when lowering ClosureExprs to C function pointers.
4294+
/// This is required to access the ClangType from SILDeclRef.
4295+
/// TODO: this will be redundant after we preserve ClangTypes
4296+
/// in the canonical types.
4297+
FunctionConversionExpr *ConvertedTo;
4298+
42934299
friend class GlobalActorAttributeRequest;
42944300

42954301
bool hasNoGlobalActorAttribute() const {
@@ -4301,19 +4307,19 @@ class ClosureExpr : public AbstractClosureExpr {
43014307
}
43024308

43034309
public:
4304-
ClosureExpr(const DeclAttributes &attributes,
4305-
SourceRange bracketRange, VarDecl *capturedSelfDecl,
4306-
ParameterList *params, SourceLoc asyncLoc, SourceLoc throwsLoc,
4307-
TypeExpr *thrownType, SourceLoc arrowLoc, SourceLoc inLoc,
4308-
TypeExpr *explicitResultType, DeclContext *parent)
4309-
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
4310-
parent),
4311-
Attributes(attributes), BracketRange(bracketRange),
4312-
CapturedSelfDecl(capturedSelfDecl),
4313-
AsyncLoc(asyncLoc), ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc),
4314-
InLoc(inLoc), ThrownType(thrownType),
4315-
ExplicitResultTypeAndBodyState(explicitResultType, BodyState::Parsed),
4316-
Body(nullptr) {
4310+
ClosureExpr(const DeclAttributes &attributes, SourceRange bracketRange,
4311+
VarDecl *capturedSelfDecl, ParameterList *params,
4312+
SourceLoc asyncLoc, SourceLoc throwsLoc, TypeExpr *thrownType,
4313+
SourceLoc arrowLoc, SourceLoc inLoc, TypeExpr *explicitResultType,
4314+
DeclContext *parent)
4315+
: AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false,
4316+
parent),
4317+
Attributes(attributes), BracketRange(bracketRange),
4318+
CapturedSelfDecl(capturedSelfDecl), AsyncLoc(asyncLoc),
4319+
ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc),
4320+
ThrownType(thrownType),
4321+
ExplicitResultTypeAndBodyState(explicitResultType, BodyState::Parsed),
4322+
Body(nullptr), ConvertedTo(nullptr) {
43174323
setParameterList(params);
43184324
Bits.ClosureExpr.HasAnonymousClosureVars = false;
43194325
Bits.ClosureExpr.ImplicitSelfCapture = false;
@@ -4506,6 +4512,9 @@ class ClosureExpr : public AbstractClosureExpr {
45064512
ExplicitResultTypeAndBodyState.setInt(v);
45074513
}
45084514

4515+
const FunctionConversionExpr *getConvertedTo() const { return ConvertedTo; }
4516+
void setConvertedTo(FunctionConversionExpr *e) { ConvertedTo = e; }
4517+
45094518
static bool classof(const Expr *E) {
45104519
return E->getKind() == ExprKind::Closure;
45114520
}

include/swift/SIL/SILBridging.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ struct BridgedSuccessorArray {
957957
};
958958

959959
struct BridgedDeclRef {
960-
uint64_t storage[3];
960+
uint64_t storage[4];
961961

962962
BRIDGED_INLINE BridgedDeclRef(swift::SILDeclRef declRef);
963963
BRIDGED_INLINE swift::SILDeclRef unbridged() const;
@@ -970,7 +970,7 @@ struct BridgedDeclRef {
970970
};
971971

972972
struct BridgedVTableEntry {
973-
uint64_t storage[5];
973+
uint64_t storage[6];
974974

975975
enum class Kind {
976976
Normal,
@@ -1038,7 +1038,7 @@ struct BridgedConstExprFunctionState {
10381038
};
10391039

10401040
struct BridgedWitnessTableEntry {
1041-
uint64_t storage[5];
1041+
uint64_t storage[6];
10421042

10431043
enum class Kind {
10441044
invalid,

include/swift/SIL/SILDeclRef.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ namespace llvm {
3434
class raw_ostream;
3535
}
3636

37+
namespace clang {
38+
class Type;
39+
}
40+
3741
namespace swift {
3842
enum class EffectsKind : uint8_t;
3943
class AbstractFunctionDecl;
@@ -208,6 +212,9 @@ struct SILDeclRef {
208212
const GenericSignatureImpl *, CustomAttr *>
209213
pointer;
210214

215+
// Type of closure thunk.
216+
const clang::Type *thunkType = nullptr;
217+
211218
/// Returns the type of AST node location being stored by the SILDeclRef.
212219
LocKind getLocKind() const {
213220
if (loc.is<ValueDecl *>())
@@ -261,11 +268,10 @@ struct SILDeclRef {
261268
/// for the containing ClassDecl.
262269
/// - If 'loc' is a global VarDecl, this returns its GlobalAccessor
263270
/// SILDeclRef.
264-
explicit SILDeclRef(
265-
Loc loc,
266-
bool isForeign = false,
267-
bool isDistributed = false,
268-
bool isDistributedLocal = false);
271+
explicit SILDeclRef(Loc loc, bool isForeign = false,
272+
bool isDistributed = false,
273+
bool isDistributedLocal = false,
274+
const clang::Type *thunkType = nullptr);
269275

270276
/// See above put produces a prespecialization according to the signature.
271277
explicit SILDeclRef(Loc loc, GenericSignature prespecializationSig);

lib/AST/Expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,13 @@ DestructureTupleExpr::create(ASTContext &ctx,
14521452
srcExpr, dstExpr, ty);
14531453
}
14541454

1455+
FunctionConversionExpr::FunctionConversionExpr(Expr *subExpr, Type type)
1456+
: ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {
1457+
if (auto *CE = dyn_cast<ClosureExpr>(subExpr)) {
1458+
CE->setConvertedTo(this);
1459+
}
1460+
}
1461+
14551462
SourceRange TupleExpr::getSourceRange() const {
14561463
auto start = LParenLoc;
14571464
if (start.isInvalid()) {

lib/ClangImporter/Serializability.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,19 +302,25 @@ namespace {
302302
void writeUInt64(uint64_t value) {}
303303
void writeIdentifier(const clang::IdentifierInfo *ident) {}
304304
void writeStmtRef(const clang::Stmt *stmt) {
305-
if (stmt != nullptr)
305+
if (stmt != nullptr) {
306306
IsSerializable = false;
307+
llvm::errs() << "Foo\n";
308+
}
307309
}
308310
void writeDeclRef(const clang::Decl *decl) {
309-
if (decl && !Impl.findStableSerializationPath(decl))
311+
if (decl && !Impl.findStableSerializationPath(decl)) {
310312
IsSerializable = false;
313+
llvm::errs() << "Foo\n";
314+
}
311315
}
312316
void writeSourceLocation(clang::SourceLocation loc) {
313317
// If a source location is written into a type, it's likely to be
314318
// something like the location of a VLA which we shouldn't simply
315319
// replace with a meaningless location.
316-
if (loc.isValid())
320+
if (loc.isValid()) {
317321
IsSerializable = false;
322+
llvm::errs() << "Foo\n";
323+
}
318324
}
319325

320326
void writeAttr(const clang::Attr *attr) {}

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,13 @@ SILDeclRef::SILDeclRef(ValueDecl *vd, SILDeclRef::Kind kind, bool isForeign,
135135
isAsyncLetClosure(0), pointer(derivativeId) {}
136136

137137
SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, bool asForeign,
138-
bool asDistributed, bool asDistributedKnownToBeLocal)
138+
bool asDistributed, bool asDistributedKnownToBeLocal,
139+
const clang::Type *thunkType)
139140
: isRuntimeAccessible(false),
140141
backDeploymentKind(SILDeclRef::BackDeploymentKind::None),
141142
defaultArgIndex(0), isAsyncLetClosure(0),
142-
pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr) {
143+
pointer((AutoDiffDerivativeFunctionIdentifier *)nullptr),
144+
thunkType(thunkType) {
143145
if (auto *vd = baseLoc.dyn_cast<ValueDecl*>()) {
144146
if (auto *fd = dyn_cast<FuncDecl>(vd)) {
145147
// Map FuncDecls directly to Func SILDeclRefs.

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
//
1717
//===----------------------------------------------------------------------===//
1818

19+
#include "swift/AST/Expr.h"
20+
#include "swift/AST/Type.h"
1921
#define DEBUG_TYPE "libsil"
2022

2123
#include "swift/AST/AnyFunctionRef.h"
@@ -4296,12 +4298,10 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
42964298
// The type of the native-to-foreign thunk for a swift closure.
42974299
if (constant.isForeign && constant.hasClosureExpr() &&
42984300
shouldStoreClangType(TC.getDeclRefRepresentation(constant))) {
4299-
auto clangType = TC.Context.getClangFunctionType(
4300-
origLoweredInterfaceType->getParams(),
4301-
origLoweredInterfaceType->getResult(),
4302-
FunctionTypeRepresentation::CFunctionPointer);
4303-
AbstractionPattern pattern =
4304-
AbstractionPattern(origLoweredInterfaceType, clangType);
4301+
assert(!extInfoBuilder.getClangTypeInfo().empty() &&
4302+
"clang type not found");
4303+
AbstractionPattern pattern = AbstractionPattern(
4304+
origLoweredInterfaceType, extInfoBuilder.getClangTypeInfo().getType());
43054305
return getSILFunctionTypeForAbstractCFunction(
43064306
TC, pattern, origLoweredInterfaceType, extInfoBuilder, constant);
43074307
}
@@ -4809,9 +4809,25 @@ getAbstractionPatternForConstant(ASTContext &ctx, SILDeclRef constant,
48094809
if (!constant.isForeign)
48104810
return AbstractionPattern(fnType);
48114811

4812+
if (const auto *closure = dyn_cast_or_null<ClosureExpr>(
4813+
constant.loc.dyn_cast<AbstractClosureExpr *>())) {
4814+
if (const auto *convertedTo = closure->getConvertedTo()) {
4815+
auto clangInfo = convertedTo->getType()
4816+
->castTo<AnyFunctionType>()
4817+
->getExtInfo()
4818+
.getClangTypeInfo();
4819+
if (!clangInfo.empty())
4820+
return AbstractionPattern(fnType, clangInfo.getType());
4821+
}
4822+
}
4823+
4824+
if (constant.thunkType)
4825+
return AbstractionPattern(fnType, constant.thunkType);
4826+
48124827
auto bridgedFn = getBridgedFunction(constant);
48134828
if (!bridgedFn)
48144829
return AbstractionPattern(fnType);
4830+
48154831
const clang::Decl *clangDecl = bridgedFn->getClangDecl();
48164832
if (!clangDecl)
48174833
return AbstractionPattern(fnType);

lib/SILGen/SILGenBridging.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,8 +1315,9 @@ static SILValue emitObjCUnconsumedArgument(SILGenFunction &SGF,
13151315
SILLocation loc,
13161316
SILValue arg) {
13171317
auto &lowering = SGF.getTypeLowering(arg->getType());
1318-
// If address-only, make a +1 copy and operate on that.
1319-
if (lowering.isAddressOnly() && SGF.useLoweredAddresses()) {
1318+
// If arg is non-trivial and has an address type, make a +1 copy and operate
1319+
// on that.
1320+
if (!lowering.isTrivial() && arg->getType().isAddress()) {
13201321
auto tmp = SGF.emitTemporaryAllocation(loc, arg->getType().getObjectType());
13211322
SGF.B.createCopyAddr(loc, arg, tmp, IsNotTake, IsInitialization);
13221323
return tmp;
@@ -1453,6 +1454,11 @@ emitObjCThunkArguments(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
14531454
auto buf = SGF.emitTemporaryAllocation(loc, native.getType());
14541455
native.forwardInto(SGF, loc, buf);
14551456
native = SGF.emitManagedBufferWithCleanup(buf);
1457+
} else if (!fnConv.isSILIndirect(nativeInputs[i]) &&
1458+
native.getType().isAddress()) {
1459+
// Load the value if the argument has an address type and the native
1460+
// function expects the argument to be passed directly.
1461+
native = SGF.emitManagedLoadCopy(loc, native.getValue());
14561462
}
14571463

14581464
if (nativeInputs[i].isConsumedInCaller()) {

lib/SILGen/SILGenExpr.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,7 +1735,19 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
17351735
FunctionConversionExpr *e,
17361736
SILType loweredResultTy,
17371737
llvm::function_ref<ManagedValue ()> fnEmitter) {
1738-
SILType loweredDestTy = SGF.getLoweredType(e->getType());
1738+
SILType loweredDestTy;
1739+
auto destTy = e->getType();
1740+
auto clangInfo =
1741+
destTy->castTo<AnyFunctionType>()->getExtInfo().getClangTypeInfo();
1742+
if (clangInfo.empty())
1743+
loweredDestTy = SGF.getLoweredType(destTy);
1744+
else
1745+
// This won't be necessary after we stop dropping clang types when
1746+
// canonicalizing function types.
1747+
loweredDestTy = SGF.getLoweredType(
1748+
AbstractionPattern(destTy->getCanonicalType(), clangInfo.getType()),
1749+
destTy);
1750+
17391751
ManagedValue result;
17401752

17411753
// We're converting between C function pointer types. They better be
@@ -1806,20 +1818,20 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
18061818
#endif
18071819
semanticExpr = conv->getSubExpr()->getSemanticsProvidingExpr();
18081820
}
1809-
1821+
18101822
if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
18111823
setLocFromConcreteDeclRef(declRef->getDeclRef());
18121824
} else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
18131825
setLocFromConcreteDeclRef(memberRef->getMember());
18141826
} else if (isAnyClosureExpr(semanticExpr)) {
1815-
(void) emitAnyClosureExpr(SGF, semanticExpr,
1816-
[&](AbstractClosureExpr *closure) {
1817-
// Emit the closure body.
1818-
SGF.SGM.emitClosure(closure, SGF.getClosureTypeInfo(closure));
1827+
(void)emitAnyClosureExpr(
1828+
SGF, semanticExpr, [&](AbstractClosureExpr *closure) {
1829+
// Emit the closure body.
1830+
SGF.SGM.emitClosure(closure, SGF.getClosureTypeInfo(closure));
18191831

1820-
loc = closure;
1821-
return ManagedValue();
1822-
});
1832+
loc = closure;
1833+
return ManagedValue();
1834+
});
18231835
} else {
18241836
llvm_unreachable("c function pointer converted from a non-concrete decl ref");
18251837
}

lib/Serialization/Deserialization.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8446,9 +8446,6 @@ class SwiftToClangBasicReader :
84468446

84478447
llvm::Expected<const clang::Type *>
84488448
ModuleFile::getClangType(ClangTypeID TID) {
8449-
if (!getContext().LangOpts.UseClangFunctionTypes)
8450-
return nullptr;
8451-
84528449
if (TID == 0)
84538450
return nullptr;
84548451

0 commit comments

Comments
 (0)