Skip to content

Commit ee49794

Browse files
committed
[AST] Introduce Argument::implicitInOut
This will allow us to abstract away the creation of InOutExpr for bits of code synthesis.
1 parent 5e7d7ed commit ee49794

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

include/swift/AST/ArgumentList.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class Argument final {
5151
return Argument(SourceLoc(), Identifier(), expr);
5252
}
5353

54+
/// Make an implicit unlabeled 'inout' argument.
55+
static Argument implicitInOut(ASTContext &ctx, Expr *expr);
56+
5457
SourceLoc getStartLoc() const { return getSourceRange().Start; }
5558
SourceLoc getEndLoc() const { return getSourceRange().End; }
5659
SourceRange getSourceRange() const;

lib/AST/ArgumentList.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ SourceRange Argument::getSourceRange() const {
3535
return SourceRange(labelLoc, exprEndLoc);
3636
}
3737

38+
Argument Argument::implicitInOut(ASTContext &ctx, Expr *expr) {
39+
assert(!isa<InOutExpr>(expr) && "Cannot nest InOutExpr");
40+
41+
// Eventually this will set an 'inout' bit on Argument, but for now,
42+
// synthesize in the InOutExpr.
43+
Type objectTy;
44+
if (auto subTy = expr->getType())
45+
objectTy = subTy->castTo<LValueType>()->getObjectType();
46+
47+
return Argument::unlabeled(
48+
new (ctx) InOutExpr(SourceLoc(), expr, objectTy, /*isImplicit*/ true));
49+
}
50+
3851
bool Argument::isInOut() const {
3952
return ArgExpr->isSemanticallyInOutExpr();
4053
}

lib/ClangImporter/ClangImporter.cpp

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5417,30 +5417,30 @@ synthesizeDependentTypeThunkParamForwarding(AbstractFunctionDecl *afd, void *con
54175417
paramIndex++;
54185418
continue;
54195419
}
5420+
auto paramTy = param->getType();
5421+
auto isInOut = param->isInOut();
5422+
auto specParamTy =
5423+
specializedFuncDecl->getParameters()->get(paramIndex)->getType();
54205424

54215425
Expr *paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(),
54225426
/*Implicit=*/true);
5423-
paramRefExpr->setType(param->getType());
5424-
5425-
if (param->isInOut()) {
5426-
paramRefExpr->setType(LValueType::get(param->getType()));
5427-
5428-
paramRefExpr = new (ctx) InOutExpr(
5429-
SourceLoc(), paramRefExpr, param->getType(), /*isImplicit*/ true);
5430-
paramRefExpr->setType(InOutType::get(param->getType()));
5431-
}
5432-
5433-
auto specParamTy = specializedFuncDecl->getParameters()->get(paramIndex)->getType();
5434-
5435-
Expr *argExpr = nullptr;
5436-
if (specParamTy->isEqual(param->getType())) {
5437-
argExpr = paramRefExpr;
5438-
} else {
5439-
argExpr = ForcedCheckedCastExpr::createImplicit(ctx, paramRefExpr,
5440-
specParamTy);
5441-
}
5427+
paramRefExpr->setType(isInOut ? LValueType::get(paramTy) : paramTy);
54425428

5443-
forwardingParams.push_back(Argument(SourceLoc(), Identifier(), argExpr));
5429+
Argument arg = [&]() {
5430+
if (isInOut) {
5431+
assert(specParamTy->isEqual(paramTy));
5432+
return Argument::implicitInOut(ctx, paramRefExpr);
5433+
}
5434+
Expr *argExpr = nullptr;
5435+
if (specParamTy->isEqual(paramTy)) {
5436+
argExpr = paramRefExpr;
5437+
} else {
5438+
argExpr = ForcedCheckedCastExpr::createImplicit(ctx, paramRefExpr,
5439+
specParamTy);
5440+
}
5441+
return Argument::unlabeled(argExpr);
5442+
}();
5443+
forwardingParams.push_back(arg);
54445444
paramIndex++;
54455445
}
54465446

@@ -5559,19 +5559,16 @@ synthesizeForwardingThunkBody(AbstractFunctionDecl *afd, void *context) {
55595559
if (isa<MetatypeType>(param->getType().getPointer())) {
55605560
continue;
55615561
}
5562+
auto paramTy = param->getType();
5563+
auto isInOut = param->isInOut();
5564+
55625565
Expr *paramRefExpr = new (ctx) DeclRefExpr(param, DeclNameLoc(),
55635566
/*Implicit=*/true);
5564-
paramRefExpr->setType(param->getType());
5565-
5566-
if (param->isInOut()) {
5567-
paramRefExpr->setType(LValueType::get(param->getType()));
5568-
5569-
paramRefExpr = new (ctx) InOutExpr(
5570-
SourceLoc(), paramRefExpr, param->getType(), /*isImplicit*/ true);
5571-
paramRefExpr->setType(InOutType::get(param->getType()));
5572-
}
5567+
paramRefExpr->setType(isInOut ? LValueType::get(paramTy) : paramTy);
55735568

5574-
forwardingParams.push_back(Argument(SourceLoc(), Identifier(), paramRefExpr));
5569+
auto arg = isInOut ? Argument::implicitInOut(ctx, paramRefExpr)
5570+
: Argument::unlabeled(paramRefExpr);
5571+
forwardingParams.push_back(arg);
55755572
}
55765573

55775574
Expr *specializedFuncDeclRef = new (ctx) DeclRefExpr(ConcreteDeclRef(specializedFuncDecl),

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,26 +1821,22 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
18211821
auto methodDecl =
18221822
static_cast<FuncDecl *>(context); /* Swift version of CXXMethod */
18231823

1824-
SmallVector<Expr *, 8> forwardingParams;
1824+
SmallVector<Argument, 8> forwardingArgs;
18251825

18261826
// We start from +1 since the first param is our lhs. All other params are
18271827
// forwarded
18281828
for (auto itr = funcDecl->getParameters()->begin() + 1;
18291829
itr != funcDecl->getParameters()->end(); itr++) {
18301830
auto param = *itr;
1831+
auto isInOut = param->isInOut();
1832+
auto paramTy = param->getType();
18311833
Expr *paramRefExpr =
18321834
new (ctx) DeclRefExpr(param, DeclNameLoc(), /*Implicit*/ true);
1833-
paramRefExpr->setType(param->getType());
1835+
paramRefExpr->setType(isInOut ? LValueType::get(paramTy) : paramTy);
18341836

1835-
if (param->isInOut()) {
1836-
paramRefExpr->setType(LValueType::get(param->getType()));
1837-
1838-
paramRefExpr = new (ctx) InOutExpr(SourceLoc(), paramRefExpr,
1839-
param->getType(), /*isImplicit*/ true);
1840-
paramRefExpr->setType(InOutType::get(param->getType()));
1841-
}
1842-
1843-
forwardingParams.push_back(paramRefExpr);
1837+
auto arg = isInOut ? Argument::implicitInOut(ctx, paramRefExpr)
1838+
: Argument::unlabeled(paramRefExpr);
1839+
forwardingArgs.push_back(arg);
18441840
}
18451841

18461842
auto methodExpr =
@@ -1865,7 +1861,7 @@ synthesizeOperatorMethodBody(AbstractFunctionDecl *afd, void *context) {
18651861
dotCallExpr->setType(methodDecl->getMethodInterfaceType());
18661862
dotCallExpr->setThrows(false);
18671863

1868-
auto *argList = ArgumentList::forImplicitUnlabeled(ctx, forwardingParams);
1864+
auto *argList = ArgumentList::createImplicit(ctx, forwardingArgs);
18691865
auto callExpr = CallExpr::createImplicit(ctx, dotCallExpr, argList);
18701866
callExpr->setType(funcDecl->getResultInterfaceType());
18711867
callExpr->setThrows(false);

0 commit comments

Comments
 (0)