Skip to content

Commit 2593294

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 a28515e commit 2593294

File tree

15 files changed

+277
-54
lines changed

15 files changed

+277
-54
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;
@@ -4528,6 +4534,9 @@ class ClosureExpr : public AbstractClosureExpr {
45284534
ExplicitResultTypeAndBodyState.setInt(v);
45294535
}
45304536

4537+
const FunctionConversionExpr *getConvertedTo() const { return ConvertedTo; }
4538+
void setConvertedTo(FunctionConversionExpr *e) { ConvertedTo = e; }
4539+
45314540
static bool classof(const Expr *E) {
45324541
return E->getKind() == ExprKind::Closure;
45334542
}

include/swift/SIL/SILDeclRef.h

Lines changed: 7 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;
@@ -261,11 +265,9 @@ struct SILDeclRef {
261265
/// for the containing ClassDecl.
262266
/// - If 'loc' is a global VarDecl, this returns its GlobalAccessor
263267
/// SILDeclRef.
264-
explicit SILDeclRef(
265-
Loc loc,
266-
bool isForeign = false,
267-
bool isDistributed = false,
268-
bool isDistributedLocal = false);
268+
explicit SILDeclRef(Loc loc, bool isForeign = false,
269+
bool isDistributed = false,
270+
bool isDistributedLocal = false);
269271

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

lib/AST/Expr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,13 @@ DestructureTupleExpr::create(ASTContext &ctx,
14561456
srcExpr, dstExpr, ty);
14571457
}
14581458

1459+
FunctionConversionExpr::FunctionConversionExpr(Expr *subExpr, Type type)
1460+
: ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {
1461+
if (auto *CE = dyn_cast<ClosureExpr>(subExpr)) {
1462+
CE->setConvertedTo(this);
1463+
}
1464+
}
1465+
14591466
SourceRange TupleExpr::getSourceRange() const {
14601467
auto start = LParenLoc;
14611468
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/SILFunctionType.cpp

Lines changed: 19 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"
@@ -4321,12 +4323,10 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
43214323
// The type of the native-to-foreign thunk for a swift closure.
43224324
if (constant.isForeign && constant.hasClosureExpr() &&
43234325
shouldStoreClangType(TC.getDeclRefRepresentation(constant))) {
4324-
auto clangType = TC.Context.getClangFunctionType(
4325-
origLoweredInterfaceType->getParams(),
4326-
origLoweredInterfaceType->getResult(),
4327-
FunctionTypeRepresentation::CFunctionPointer);
4328-
AbstractionPattern pattern =
4329-
AbstractionPattern(origLoweredInterfaceType, clangType);
4326+
assert(!extInfoBuilder.getClangTypeInfo().empty() &&
4327+
"clang type not found");
4328+
AbstractionPattern pattern = AbstractionPattern(
4329+
origLoweredInterfaceType, extInfoBuilder.getClangTypeInfo().getType());
43304330
return getSILFunctionTypeForAbstractCFunction(
43314331
TC, pattern, origLoweredInterfaceType, extInfoBuilder, constant);
43324332
}
@@ -4834,9 +4834,22 @@ getAbstractionPatternForConstant(ASTContext &ctx, SILDeclRef constant,
48344834
if (!constant.isForeign)
48354835
return AbstractionPattern(fnType);
48364836

4837+
if (const auto *closure = dyn_cast_or_null<ClosureExpr>(
4838+
constant.loc.dyn_cast<AbstractClosureExpr *>())) {
4839+
if (const auto *convertedTo = closure->getConvertedTo()) {
4840+
auto clangInfo = convertedTo->getType()
4841+
->castTo<AnyFunctionType>()
4842+
->getExtInfo()
4843+
.getClangTypeInfo();
4844+
if (!clangInfo.empty())
4845+
return AbstractionPattern(fnType, clangInfo.getType());
4846+
}
4847+
}
4848+
48374849
auto bridgedFn = getBridgedFunction(constant);
48384850
if (!bridgedFn)
48394851
return AbstractionPattern(fnType);
4852+
48404853
const clang::Decl *clangDecl = bridgedFn->getClangDecl();
48414854
if (!clangDecl)
48424855
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
@@ -1733,7 +1733,19 @@ static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
17331733
FunctionConversionExpr *e,
17341734
SILType loweredResultTy,
17351735
llvm::function_ref<ManagedValue ()> fnEmitter) {
1736-
SILType loweredDestTy = SGF.getLoweredType(e->getType());
1736+
SILType loweredDestTy;
1737+
auto destTy = e->getType();
1738+
auto clangInfo =
1739+
destTy->castTo<AnyFunctionType>()->getExtInfo().getClangTypeInfo();
1740+
if (clangInfo.empty())
1741+
loweredDestTy = SGF.getLoweredType(destTy);
1742+
else
1743+
// This won't be necessary after we stop dropping clang types when
1744+
// canonicalizing function types.
1745+
loweredDestTy = SGF.getLoweredType(
1746+
AbstractionPattern(destTy->getCanonicalType(), clangInfo.getType()),
1747+
destTy);
1748+
17371749
ManagedValue result;
17381750

17391751
// We're converting between C function pointer types. They better be
@@ -1804,20 +1816,20 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
18041816
#endif
18051817
semanticExpr = conv->getSubExpr()->getSemanticsProvidingExpr();
18061818
}
1807-
1819+
18081820
if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
18091821
setLocFromConcreteDeclRef(declRef->getDeclRef());
18101822
} else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
18111823
setLocFromConcreteDeclRef(memberRef->getMember());
18121824
} else if (isAnyClosureExpr(semanticExpr)) {
1813-
(void) emitAnyClosureExpr(SGF, semanticExpr,
1814-
[&](AbstractClosureExpr *closure) {
1815-
// Emit the closure body.
1816-
SGF.SGM.emitClosure(closure, SGF.getClosureTypeInfo(closure));
1825+
(void)emitAnyClosureExpr(
1826+
SGF, semanticExpr, [&](AbstractClosureExpr *closure) {
1827+
// Emit the closure body.
1828+
SGF.SGM.emitClosure(closure, SGF.getClosureTypeInfo(closure));
18171829

1818-
loc = closure;
1819-
return ManagedValue();
1820-
});
1830+
loc = closure;
1831+
return ManagedValue();
1832+
});
18211833
} else {
18221834
llvm_unreachable("c function pointer converted from a non-concrete decl ref");
18231835
}

lib/Serialization/Deserialization.cpp

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

84968496
llvm::Expected<const clang::Type *>
84978497
ModuleFile::getClangType(ClangTypeID TID) {
8498-
if (!getContext().LangOpts.UseClangFunctionTypes)
8499-
return nullptr;
8500-
85018498
if (TID == 0)
85028499
return nullptr;
85038500

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5899,10 +5899,7 @@ class Serializer::TypeSerializer : public TypeVisitor<TypeSerializer> {
58995899
using namespace decls_block;
59005900

59015901
auto resultType = S.addTypeRef(fnTy->getResult());
5902-
auto clangType =
5903-
S.getASTContext().LangOpts.UseClangFunctionTypes
5904-
? S.addClangTypeRef(fnTy->getClangTypeInfo().getType())
5905-
: ClangTypeID(0);
5902+
auto clangType = S.addClangTypeRef(fnTy->getClangTypeInfo().getType());
59065903

59075904
auto isolation = encodeIsolation(fnTy->getIsolation());
59085905

test/Interop/Cxx/class/Inputs/closure.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ struct NonTrivial {
1010
int *p;
1111
};
1212

13+
struct Trivial {
14+
int i;
15+
};
16+
1317
void cfunc(void (^ _Nonnull block)(NonTrivial)) noexcept {
1418
block(NonTrivial());
1519
}
@@ -75,4 +79,13 @@ inline void releaseSharedRef(SharedRef *_Nonnull x) {
7579
}
7680
}
7781

82+
void cfuncConstRefNonTrivial(void (*_Nonnull)(const NonTrivial &));
83+
void cfuncConstRefTrivial(void (*_Nonnull)(const Trivial &));
84+
void blockConstRefNonTrivial(void (^_Nonnull)(const NonTrivial &));
85+
void blockConstRefTrivial(void (^_Nonnull)(const Trivial &));
86+
#if __OBJC__
87+
void cfuncConstRefStrong(void (*_Nonnull)(const ARCStrong &));
88+
void blockConstRefStrong(void (^_Nonnull)(const ARCStrong &));
89+
#endif
90+
7891
#endif // __CLOSURE__

0 commit comments

Comments
 (0)