Fill in source locations in implicit function builder expressions

to satisfy the code-coverage instrumentation.

rdar://51612977
This commit is contained in:
John McCall
2019-07-18 18:21:53 -04:00
parent 934b60e299
commit db4c7d2d4c
3 changed files with 57 additions and 12 deletions

View File

@@ -60,8 +60,10 @@ private:
// to get diagnostics if something about this builder call fails,
// e.g. if there isn't a matching overload for `buildBlock`.
// But we can only do this if there isn't a type variable in the type.
TypeLoc typeLoc(nullptr,
builderType->hasTypeVariable() ? Type() : builderType);
TypeLoc typeLoc;
if (!builderType->hasTypeVariable()) {
typeLoc = TypeLoc(new (ctx) FixedTypeRepr(builderType, loc), builderType);
}
auto typeExpr = new (ctx) TypeExpr(typeLoc);
if (cs) {
@@ -69,10 +71,19 @@ private:
cs->setType(&typeExpr->getTypeLoc(), builderType);
}
SmallVector<SourceLoc, 4> argLabelLocs;
for (auto i : indices(argLabels)) {
argLabelLocs.push_back(args[i]->getStartLoc());
}
typeExpr->setImplicit();
auto memberRef = new (ctx) UnresolvedDotExpr(
typeExpr, loc, fnName, DeclNameLoc(loc), /*implicit=*/true);
return CallExpr::createImplicit(ctx, memberRef, args, argLabels);
SourceLoc openLoc = args.empty() ? loc : args.front()->getStartLoc();
SourceLoc closeLoc = args.empty() ? loc : args.back()->getEndLoc();
return CallExpr::create(ctx, memberRef, openLoc, args,
argLabels, argLabelLocs, closeLoc,
/*trailing closure*/ nullptr, /*implicit*/true);
}
/// Check whether the builder supports the given operation.
@@ -400,10 +411,12 @@ public:
auto optionalDecl = ctx.getOptionalDecl();
auto optionalType = optionalDecl->getDeclaredType();
auto optionalTypeExpr = TypeExpr::createImplicit(optionalType, ctx);
auto loc = arg->getStartLoc();
auto optionalTypeExpr =
TypeExpr::createImplicitHack(loc, optionalType, ctx);
auto someRef = new (ctx) UnresolvedDotExpr(
optionalTypeExpr, SourceLoc(), ctx.getIdentifier("some"),
DeclNameLoc(), /*implicit=*/true);
optionalTypeExpr, loc, ctx.getIdentifier("some"),
DeclNameLoc(loc), /*implicit=*/true);
return CallExpr::createImplicit(ctx, someRef, arg, { });
}
@@ -411,7 +424,8 @@ public:
auto optionalDecl = ctx.getOptionalDecl();
auto optionalType = optionalDecl->getDeclaredType();
auto optionalTypeExpr = TypeExpr::createImplicit(optionalType, ctx);
auto optionalTypeExpr =
TypeExpr::createImplicitHack(endLoc, optionalType, ctx);
return new (ctx) UnresolvedDotExpr(
optionalTypeExpr, endLoc, ctx.getIdentifier("none"),
DeclNameLoc(endLoc), /*implicit=*/true);
@@ -492,7 +506,9 @@ TypeChecker::applyFunctionBuilderBodyTransform(FuncDecl *FD,
if (!returnType || returnType->hasError())
return nullptr;
auto returnStmt = new (Context) ReturnStmt(SourceLoc(), returnExpr);
auto loc = returnExpr->getStartLoc();
auto returnStmt =
new (Context) ReturnStmt(loc, returnExpr, /*implicit*/ true);
return BraceStmt::create(Context, body->getLBraceLoc(), { returnStmt },
body->getRBraceLoc());
}

View File

@@ -3,8 +3,8 @@
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_CLOSURE_COLOR_CONTEXT | %FileCheck %s -check-prefix=IN_CLOSURE_COLOR_CONTEXT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_CLOSURE_COLOR_CONTEXT_DOT | %FileCheck %s -check-prefix=IN_CLOSURE_COLOR_CONTEXT_DOT
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_1 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_2 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_1 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_2 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_3 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_4 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_VALID
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CONTEXTUAL_TYPE_5 | %FileCheck %s -check-prefix=CONTEXTUAL_TYPE_INVALID
@@ -123,11 +123,9 @@ func acceptBuilder(@EnumToVoidBuilder body: () -> Void) {}
func testContextualType() {
acceptBuilder {
// FIXME: This should suggest enum values.
.#^CONTEXTUAL_TYPE_1^#
}
acceptBuilder {
// FIXME: This should suggest enum values.
.#^CONTEXTUAL_TYPE_2^#;
.north;
}

View File

@@ -0,0 +1,31 @@
// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_functon_builder %s | %FileCheck %s
@_functionBuilder
struct Summer {
static func buildBlock(_ x: Int...) -> Int {
return x.reduce(0, +)
}
static func buildIf(_ x: Int?) -> Int {
return x ?? 0
}
}
// CHECK-LABEL: sil_coverage_map {{.*}} "$s24coverage_functon_builder5test0SiyF"
@Summer
func test0() -> Int {
// CHECK: [[@LINE-1]]:21 -> [[@LINE+3]]:2 : 0
18
12
}
// CHECK-LABEL: sil_coverage_map {{.*}} "$s24coverage_functon_builder5test1SiyF"
@Summer
func test1() -> Int {
// CHECK: [[@LINE-1]]:21 -> [[@LINE+7]]:2 : 0
18
12
if 7 < 23 {
11
8
}
}