Skip to content

Commit 431343b

Browse files
authored
Merge pull request swiftlang#24603 from slavapestov/checked-clang-importer-accessors
ClangImporter: Built type-checked expressions in union and indirect field accessors
2 parents d417017 + 3371080 commit 431343b

File tree

2 files changed

+78
-14
lines changed

2 files changed

+78
-14
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -838,16 +838,21 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
838838
auto selfDecl = getterDecl->getImplicitSelfDecl();
839839
Expr *expr = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
840840
/*implicit*/true);
841+
expr->setType(selfDecl->getInterfaceType());
842+
841843
expr = new (C) MemberRefExpr(expr, SourceLoc(), anonymousFieldDecl,
842844
DeclNameLoc(), /*implicit*/true);
845+
expr->setType(anonymousFieldDecl->getInterfaceType());
843846

844847
expr = new (C) MemberRefExpr(expr, SourceLoc(), anonymousInnerFieldDecl,
845848
DeclNameLoc(), /*implicit*/true);
849+
expr->setType(anonymousInnerFieldDecl->getInterfaceType());
846850

847851
auto ret = new (C) ReturnStmt(SourceLoc(), expr);
848852
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(ret), SourceLoc(),
849853
/*implicit*/ true);
850854
getterDecl->setBody(body);
855+
getterDecl->setBodyTypeCheckedIfPresent();
851856
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
852857
Impl.registerExternalDecl(getterDecl);
853858
}
@@ -857,22 +862,29 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
857862
auto selfDecl = setterDecl->getImplicitSelfDecl();
858863
Expr *lhs = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
859864
/*implicit*/true);
865+
lhs->setType(LValueType::get(selfDecl->getInterfaceType()));
866+
860867
lhs = new (C) MemberRefExpr(lhs, SourceLoc(), anonymousFieldDecl,
861-
DeclNameLoc(), /*implicit*/true);
868+
DeclNameLoc(), /*implicit*/true);
869+
lhs->setType(LValueType::get(anonymousFieldDecl->getInterfaceType()));
862870

863871
lhs = new (C) MemberRefExpr(lhs, SourceLoc(), anonymousInnerFieldDecl,
864872
DeclNameLoc(), /*implicit*/true);
873+
lhs->setType(LValueType::get(anonymousInnerFieldDecl->getInterfaceType()));
865874

866875
auto newValueDecl = setterDecl->getParameters()->get(0);
867876

868877
auto rhs = new (C) DeclRefExpr(newValueDecl, DeclNameLoc(),
869878
/*implicit*/ true);
879+
rhs->setType(newValueDecl->getInterfaceType());
870880

871881
auto assign = new (C) AssignExpr(lhs, SourceLoc(), rhs, /*implicit*/true);
882+
assign->setType(TupleType::getEmpty(C));
872883

873884
auto body = BraceStmt::create(C, SourceLoc(), { assign }, SourceLoc(),
874885
/*implicit*/ true);
875886
setterDecl->setBody(body);
887+
setterDecl->setBodyTypeCheckedIfPresent();
876888
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
877889
Impl.registerExternalDecl(setterDecl);
878890
}
@@ -922,18 +934,35 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
922934

923935
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
924936
/*implicit*/ true);
937+
selfRef->setType(selfDecl->getInterfaceType());
938+
925939
auto reinterpretCast = cast<FuncDecl>(getBuiltinValueDecl(
926940
C, C.getIdentifier("reinterpretCast")));
927-
auto reinterpretCastRef
928-
= new (C) DeclRefExpr(reinterpretCast, DeclNameLoc(), /*implicit*/ true);
929-
auto reinterpreted = CallExpr::createImplicit(C, reinterpretCastRef,
941+
942+
ConcreteDeclRef reinterpretCastRef(
943+
reinterpretCast,
944+
SubstitutionMap::get(reinterpretCast->getGenericSignature(),
945+
{selfDecl->getInterfaceType(),
946+
importedFieldDecl->getInterfaceType()},
947+
ArrayRef<ProtocolConformanceRef>()));
948+
auto reinterpretCastRefExpr
949+
= new (C) DeclRefExpr(reinterpretCastRef, DeclNameLoc(),
950+
/*implicit*/ true);
951+
reinterpretCastRefExpr->setType(
952+
FunctionType::get(
953+
AnyFunctionType::Param(selfDecl->getInterfaceType()),
954+
importedFieldDecl->getInterfaceType()));
955+
956+
auto reinterpreted = CallExpr::createImplicit(C, reinterpretCastRefExpr,
930957
{ selfRef },
931958
{ Identifier() });
959+
reinterpreted->setType(importedFieldDecl->getInterfaceType());
932960
reinterpreted->setThrows(false);
933961
auto ret = new (C) ReturnStmt(SourceLoc(), reinterpreted);
934962
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(ret), SourceLoc(),
935963
/*implicit*/ true);
936964
getterDecl->setBody(body);
965+
getterDecl->setBodyTypeCheckedIfPresent();
937966
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
938967
Impl.registerExternalDecl(getterDecl);
939968
}
@@ -944,30 +973,56 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
944973

945974
auto inoutSelfRef = new (C) DeclRefExpr(inoutSelfDecl, DeclNameLoc(),
946975
/*implicit*/ true);
976+
inoutSelfRef->setType(LValueType::get(inoutSelfDecl->getInterfaceType()));
947977
auto inoutSelf = new (C) InOutExpr(SourceLoc(), inoutSelfRef,
948978
importedUnionDecl->getDeclaredType(), /*implicit*/ true);
979+
inoutSelf->setType(InOutType::get(inoutSelfDecl->getInterfaceType()));
949980

950981
auto newValueDecl = setterDecl->getParameters()->get(0);
951982

952983
auto newValueRef = new (C) DeclRefExpr(newValueDecl, DeclNameLoc(),
953984
/*implicit*/ true);
985+
newValueRef->setType(newValueDecl->getInterfaceType());
986+
954987
auto addressofFn = cast<FuncDecl>(getBuiltinValueDecl(
955988
C, C.getIdentifier("addressof")));
956-
auto addressofFnRef
957-
= new (C) DeclRefExpr(addressofFn, DeclNameLoc(), /*implicit*/ true);
958-
auto selfPointer = CallExpr::createImplicit(C, addressofFnRef,
989+
ConcreteDeclRef addressofFnRef(addressofFn,
990+
SubstitutionMap::get(addressofFn->getGenericSignature(),
991+
{inoutSelfDecl->getInterfaceType()},
992+
ArrayRef<ProtocolConformanceRef>()));
993+
auto addressofFnRefExpr
994+
= new (C) DeclRefExpr(addressofFnRef, DeclNameLoc(), /*implicit*/ true);
995+
addressofFnRefExpr->setType(
996+
FunctionType::get(AnyFunctionType::Param(inoutSelfDecl->getInterfaceType(),
997+
Identifier(),
998+
ParameterTypeFlags().withInOut(true)),
999+
C.TheRawPointerType));
1000+
auto selfPointer = CallExpr::createImplicit(C, addressofFnRefExpr,
9591001
{ inoutSelf },
9601002
{ Identifier() });
1003+
selfPointer->setType(C.TheRawPointerType);
1004+
9611005
auto initializeFn = cast<FuncDecl>(getBuiltinValueDecl(
9621006
C, C.getIdentifier("initialize")));
963-
auto initializeFnRef
964-
= new (C) DeclRefExpr(initializeFn, DeclNameLoc(), /*implicit*/ true);
965-
auto initialize = CallExpr::createImplicit(C, initializeFnRef,
1007+
ConcreteDeclRef initializeFnRef(initializeFn,
1008+
SubstitutionMap::get(initializeFn->getGenericSignature(),
1009+
{newValueDecl->getInterfaceType()},
1010+
ArrayRef<ProtocolConformanceRef>()));
1011+
auto initializeFnRefExpr
1012+
= new (C) DeclRefExpr(initializeFnRef, DeclNameLoc(), /*implicit*/ true);
1013+
initializeFnRefExpr->setType(
1014+
FunctionType::get({AnyFunctionType::Param(newValueDecl->getInterfaceType()),
1015+
AnyFunctionType::Param(C.TheRawPointerType)},
1016+
TupleType::getEmpty(C)));
1017+
auto initialize = CallExpr::createImplicit(C, initializeFnRefExpr,
9661018
{ newValueRef, selfPointer },
9671019
{ Identifier(), Identifier() });
1020+
initialize->setType(TupleType::getEmpty(C));
1021+
9681022
auto body = BraceStmt::create(C, SourceLoc(), { initialize }, SourceLoc(),
9691023
/*implicit*/ true);
9701024
setterDecl->setBody(body);
1025+
setterDecl->setBodyTypeCheckedIfPresent();
9711026
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
9721027
Impl.registerExternalDecl(setterDecl);
9731028
}
@@ -1833,6 +1888,8 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
18331888

18341889
DeclRefExpr *domainDeclRef = new (C)
18351890
DeclRefExpr(ConcreteDeclRef(swiftValueDecl), {}, isImplicit);
1891+
domainDeclRef->setType(swiftValueDecl->getInterfaceType());
1892+
18361893
auto *params = ParameterList::createEmpty(C);
18371894

18381895
auto getterDecl = AccessorDecl::create(C,
@@ -1864,6 +1921,8 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
18641921
auto ret = new (C) ReturnStmt(SourceLoc(), domainDeclRef);
18651922
getterDecl->setBody(
18661923
BraceStmt::create(C, SourceLoc(), {ret}, SourceLoc(), isImplicit));
1924+
getterDecl->setBodyTypeCheckedIfPresent();
1925+
18671926
importer.registerExternalDecl(getterDecl);
18681927
return true;
18691928
}

test/ClangImporter/ctypes_parse_union.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir %s
22

33
import ctypes
44

5-
func useStructWithUnion(_ vec: GLKVector4) -> GLKVector4 {
5+
func useStructWithUnion(_ vec: GLKVector4) {
66
var vec = vec
77
_ = vec.v.0
88
_ = vec.v.1
99
_ = vec.v.2
1010
_ = vec.v.3
1111

1212
vec.v = (0, 0, 0, 0)
13+
1314
}
1415

1516
func useUnionIndirectFields(_ vec: GLKVector4) -> GLKVector4 {
@@ -33,7 +34,11 @@ func useUnionIndirectFields(_ vec: GLKVector4) -> GLKVector4 {
3334
let _: CFloat = vec.v.1
3435
let _: CFloat = vec.v.2
3536
let _: CFloat = vec.v.3
36-
return vec
37+
38+
var vec1 = vec
39+
vec1.x = vec.y
40+
41+
return vec1
3742
}
3843

3944
func useStructWithNamedUnion(_ u: NamedUnion) -> NamedUnion {
@@ -53,7 +58,7 @@ func useStructWithAnonymousUnion(_ u: AnonUnion) -> AnonUnion {
5358
return u
5459
}
5560

56-
func useStructWithUnnamedUnion(_ u: UnnamedUnion) -> UnnamedUnion {
61+
func useStructWithUnnamedUnion(_ u: UnnamedUnion) {
5762
var u = u
5863
u.u.i = 100
5964
u.u.f = 1.0

0 commit comments

Comments
 (0)