Skip to content

Commit e1f839e

Browse files
committed
---
yaml --- r: 341710 b: refs/heads/rxwei-patch-1 c: 4d4059e h: refs/heads/master
1 parent eec6cfe commit e1f839e

File tree

2 files changed

+90
-75
lines changed

2 files changed

+90
-75
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a: b10b1fce14385faa6d44f6b933e95
10151015
refs/heads/rdar-43033749-fix-batch-mode-no-diags-swift-5.0-branch: a14e64eaad30de89f0f5f0b2a782eed7ecdcb255
10161016
refs/heads/revert-19006-error-bridging-integer-type: 8a9065a3696535305ea53fe9b71f91cbe6702019
10171017
refs/heads/revert-19050-revert-19006-error-bridging-integer-type: ecf752d54b05dd0a20f510f0bfa54a3fec3bcaca
1018-
refs/heads/rxwei-patch-1: 9c17bb1ffe0ba17eae40eb87454b84f685bdb091
1018+
refs/heads/rxwei-patch-1: 4d4059e20255bfa137bf7a197cd8d48fe94179cb
10191019
refs/heads/shahmishal-patch-1: e58ec0f7488258d42bef51bc3e6d7b3dc74d7b2a
10201020
refs/heads/typelist-existential: 4046359efd541fb5c72d69a92eefc0a784df8f5e
10211021
refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-08-20-a: 4319ba09e4fb8650ee86061075c74a016b6baab9

branches/rxwei-patch-1/lib/ClangImporter/ImportDecl.cpp

Lines changed: 89 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,77 @@ createDefaultConstructor(ClangImporter::Implementation &Impl,
13301330
return constructor;
13311331
}
13321332

1333+
/// Synthesizer callback for the body of a struct value constructor.
1334+
static std::pair<BraceStmt *, bool>
1335+
synthesizeValueConstructorBody(AbstractFunctionDecl *afd, void *context) {
1336+
auto constructor = cast<ConstructorDecl>(afd);
1337+
ArrayRef<VarDecl *> members(static_cast<VarDecl **>(context) + 1,
1338+
static_cast<uintptr_t*>(context)[0]);
1339+
1340+
ASTContext &ctx = constructor->getASTContext();
1341+
1342+
// Assign all of the member variables appropriately.
1343+
SmallVector<ASTNode, 4> stmts;
1344+
1345+
auto *selfDecl = constructor->getImplicitSelfDecl();
1346+
1347+
// To keep DI happy, initialize stored properties before computed.
1348+
auto parameters = constructor->getParameters();
1349+
for (unsigned pass = 0; pass < 2; pass++) {
1350+
unsigned paramPos = 0;
1351+
1352+
for (unsigned i = 0, e = members.size(); i < e; i++) {
1353+
auto var = members[i];
1354+
1355+
if (var->hasClangNode() &&
1356+
isa<clang::IndirectFieldDecl>(var->getClangDecl()))
1357+
continue;
1358+
1359+
if (var->hasStorage() == (pass != 0)) {
1360+
paramPos++;
1361+
continue;
1362+
}
1363+
1364+
// Construct left-hand side.
1365+
Expr *lhs = new (ctx) DeclRefExpr(selfDecl, DeclNameLoc(),
1366+
/*Implicit=*/true);
1367+
lhs->setType(LValueType::get(selfDecl->getType()));
1368+
1369+
auto semantics = (var->hasStorage()
1370+
? AccessSemantics::DirectToStorage
1371+
: AccessSemantics::Ordinary);
1372+
1373+
lhs = new (ctx) MemberRefExpr(lhs, SourceLoc(), var, DeclNameLoc(),
1374+
/*Implicit=*/true, semantics);
1375+
lhs->setType(LValueType::get(var->getType()));
1376+
1377+
// Construct right-hand side.
1378+
auto rhs = new (ctx) DeclRefExpr(parameters->get(paramPos),
1379+
DeclNameLoc(), /*Implicit=*/true);
1380+
rhs->setType(parameters->get(paramPos)->getType());
1381+
1382+
// Add assignment.
1383+
auto assign = new (ctx) AssignExpr(lhs, SourceLoc(), rhs,
1384+
/*Implicit=*/true);
1385+
assign->setType(TupleType::getEmpty(ctx));
1386+
1387+
stmts.push_back(assign);
1388+
paramPos++;
1389+
}
1390+
}
1391+
1392+
auto result = TupleExpr::createEmpty(ctx, SourceLoc(), SourceLoc(),
1393+
/*Implicit=*/true);
1394+
result->setType(TupleType::getEmpty(ctx));
1395+
1396+
auto ret = new (ctx) ReturnStmt(SourceLoc(), result, /*Implicit=*/true);
1397+
stmts.push_back(ret);
1398+
1399+
// Create the function body.
1400+
auto body = BraceStmt::create(ctx, SourceLoc(), stmts, SourceLoc());
1401+
return { body, /*isTypeChecked=*/true };
1402+
}
1403+
13331404
/// Create a constructor that initializes a struct from its members.
13341405
static ConstructorDecl *
13351406
createValueConstructor(ClangImporter::Implementation &Impl,
@@ -1383,66 +1454,14 @@ createValueConstructor(ClangImporter::Implementation &Impl,
13831454
constructor->getAttrs().add(new (context) TransparentAttr(/*implicit*/ true));
13841455

13851456
if (wantBody) {
1386-
// Assign all of the member variables appropriately.
1387-
SmallVector<ASTNode, 4> stmts;
1388-
1389-
auto *selfDecl = constructor->getImplicitSelfDecl();
1390-
1391-
// To keep DI happy, initialize stored properties before computed.
1392-
for (unsigned pass = 0; pass < 2; pass++) {
1393-
unsigned paramPos = 0;
1394-
1395-
for (unsigned i = 0, e = members.size(); i < e; i++) {
1396-
auto var = members[i];
1397-
1398-
if (var->hasClangNode() && isa<clang::IndirectFieldDecl>(var->getClangDecl()))
1399-
continue;
1400-
1401-
if (var->hasStorage() == (pass != 0)) {
1402-
paramPos++;
1403-
continue;
1404-
}
1405-
1406-
// Construct left-hand side.
1407-
Expr *lhs = new (context) DeclRefExpr(selfDecl, DeclNameLoc(),
1408-
/*Implicit=*/true);
1409-
lhs->setType(LValueType::get(selfDecl->getType()));
1410-
1411-
auto semantics = (var->hasStorage()
1412-
? AccessSemantics::DirectToStorage
1413-
: AccessSemantics::Ordinary);
1414-
1415-
lhs = new (context) MemberRefExpr(lhs, SourceLoc(), var, DeclNameLoc(),
1416-
/*Implicit=*/true,
1417-
semantics);
1418-
lhs->setType(LValueType::get(var->getType()));
1419-
1420-
// Construct right-hand side.
1421-
auto rhs = new (context) DeclRefExpr(valueParameters[paramPos],
1422-
DeclNameLoc(),
1423-
/*Implicit=*/true);
1424-
rhs->setType(valueParameters[paramPos]->getType());
1425-
1426-
// Add assignment.
1427-
auto assign = new (context) AssignExpr(lhs, SourceLoc(), rhs,
1428-
/*Implicit=*/true);
1429-
assign->setType(TupleType::getEmpty(context));
1430-
1431-
stmts.push_back(assign);
1432-
paramPos++;
1433-
}
1434-
}
1435-
1436-
auto result = TupleExpr::createEmpty(context, SourceLoc(), SourceLoc(),
1437-
/*Implicit=*/true);
1438-
result->setType(TupleType::getEmpty(context));
1439-
1440-
auto ret = new (context) ReturnStmt(SourceLoc(), result, /*Implicit=*/true);
1441-
stmts.push_back(ret);
1442-
1443-
// Create the function body.
1444-
auto body = BraceStmt::create(context, SourceLoc(), stmts, SourceLoc());
1445-
constructor->setBody(body, AbstractFunctionDecl::BodyKind::TypeChecked);
1457+
auto memberMemory =
1458+
context.AllocateUninitialized<uintptr_t>(members.size() + 1);
1459+
memberMemory[0] = members.size();
1460+
for (unsigned i : indices(members)) {
1461+
memberMemory[i+1] = reinterpret_cast<uintptr_t>(members[i]);
1462+
}
1463+
constructor->setBodySynthesizer(synthesizeValueConstructorBody,
1464+
memberMemory.data());
14461465
}
14471466

14481467
// We're done.
@@ -1523,12 +1542,12 @@ static void makeStructRawValued(
15231542
structDecl->addMember(
15241543
createValueConstructor(Impl, structDecl, var,
15251544
/*wantCtorParamNames=*/false,
1526-
/*wantBody=*/!Impl.hasFinishedTypeChecking()));
1545+
/*wantBody=*/true));
15271546

15281547
auto *initRawValue =
15291548
createValueConstructor(Impl, structDecl, var,
15301549
/*wantCtorParamNames=*/true,
1531-
/*wantBody=*/!Impl.hasFinishedTypeChecking());
1550+
/*wantBody=*/true);
15321551
structDecl->addMember(initRawValue);
15331552
structDecl->addMember(patternBinding);
15341553
structDecl->addMember(var);
@@ -1653,19 +1672,16 @@ static void makeStructRawValuedWithBridge(
16531672
ctx, StaticSpellingKind::None, computedVarPattern, /*InitExpr*/ nullptr,
16541673
structDecl);
16551674

1656-
// Don't bother synthesizing the body if we've already finished
1657-
// type-checking.
1658-
bool wantBody = !Impl.hasFinishedTypeChecking();
1659-
16601675
auto init = createRawValueBridgingConstructor(Impl, structDecl, computedVar,
16611676
storedVar,
1662-
/*wantLabel*/ true, wantBody);
1677+
/*wantLabel*/ true,
1678+
/*wantBody*/ true);
16631679

16641680
ConstructorDecl *unlabeledCtor = nullptr;
16651681
if (makeUnlabeledValueInit)
16661682
unlabeledCtor = createRawValueBridgingConstructor(
16671683
Impl, structDecl, computedVar, storedVar,
1668-
/*wantLabel*/ false, wantBody);
1684+
/*wantLabel*/ false, /*wantBody*/!Impl.hasFinishedTypeChecking());
16691685

16701686
if (unlabeledCtor)
16711687
structDecl->addMember(unlabeledCtor);
@@ -3299,7 +3315,7 @@ namespace {
32993315
auto valueCtor =
33003316
createValueConstructor(Impl, result, VD,
33013317
/*want param names*/true,
3302-
/*wantBody=*/!Impl.hasFinishedTypeChecking());
3318+
/*wantBody=*/true);
33033319
ctors.push_back(valueCtor);
33043320
}
33053321
}
@@ -3318,11 +3334,10 @@ namespace {
33183334
//
33193335
// If we can completely represent the struct in SIL, leave the body
33203336
// implicit, otherwise synthesize one to call property setters.
3321-
bool wantBody = (hasUnreferenceableStorage &&
3322-
!Impl.hasFinishedTypeChecking());
3323-
auto valueCtor = createValueConstructor(Impl, result, members,
3324-
/*want param names*/true,
3325-
/*want body*/wantBody);
3337+
auto valueCtor = createValueConstructor(
3338+
Impl, result, members,
3339+
/*want param names*/true,
3340+
/*want body*/hasUnreferenceableStorage);
33263341
if (!hasUnreferenceableStorage)
33273342
valueCtor->setIsMemberwiseInitializer();
33283343

0 commit comments

Comments
 (0)