Add Make factory function to Block.
Block::Make always makes a real Block object. This is important because
many callers rely on Blocks specifically; e.g. a function body must be a
scoped Block, nothing else will do.
However, unscoped Blocks are just a collection of Statements and usually
have more flexibility. So, Block::MakeUnscoped is a factory function
that will return the Statement as-is for a single-statement unscoped
Block. For an entirely empty Block, MakeUnscoped returns Nop.
Change-Id: Ied65d505bde4ea7f6157a039944018546e4b7333
Bug: skia:11342
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/384180
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 0d42f03..011c443 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -429,9 +429,9 @@
switch (statement.kind()) {
case Statement::Kind::kBlock: {
const Block& b = statement.as<Block>();
- return std::make_unique<Block>(offset, blockStmts(b),
- SymbolTable::WrapIfBuiltin(b.symbolTable()),
- b.isScope());
+ return Block::Make(offset, blockStmts(b),
+ SymbolTable::WrapIfBuiltin(b.symbolTable()),
+ b.isScope());
}
case Statement::Kind::kBreak:
@@ -506,8 +506,7 @@
block.reserve_back(2);
block.push_back(std::move(assignment));
block.push_back(ContinueStatement::Make(offset));
- return std::make_unique<Block>(offset, std::move(block), /*symbols=*/nullptr,
- /*isScope=*/true);
+ return Block::Make(offset, std::move(block), /*symbols=*/nullptr, /*isScope=*/true);
}
// Functions without early returns aren't wrapped in a for loop and don't need to worry
// about breaking out of the control flow.
@@ -623,19 +622,14 @@
bool hasEarlyReturn = (returnComplexity >= ReturnComplexity::kEarlyReturns);
InlinedCall inlinedCall;
- inlinedCall.fInlinedBody = std::make_unique<Block>(offset, StatementArray{},
- /*symbols=*/nullptr,
- /*isScope=*/false);
+ StatementArray inlinedBlockStmts;
+ inlinedBlockStmts.reserve_back(1 + // Inline marker
+ 1 + // Result variable
+ arguments.size() + // Function arguments (passing in)
+ arguments.size() + // Function arguments (copy out-params back)
+ 1); // Block for inlined code
- Block& inlinedBody = *inlinedCall.fInlinedBody;
- inlinedBody.children().reserve_back(
- 1 + // Inline marker
- 1 + // Result variable
- arguments.size() + // Function arguments (passing in)
- arguments.size() + // Function arguments (copy out-params back)
- 1); // Block for inlined code
-
- inlinedBody.children().push_back(InlineMarker::Make(&call->function()));
+ inlinedBlockStmts.push_back(InlineMarker::Make(&call->function()));
std::unique_ptr<Expression> resultExpr;
if (returnComplexity > ReturnComplexity::kSingleSafeReturn &&
@@ -648,7 +642,7 @@
&function.declaration().returnType(),
symbolTable.get(), Modifiers{},
caller->isBuiltin(), &noInitialValue);
- inlinedBody.children().push_back(std::move(var.fVarDecl));
+ inlinedBlockStmts.push_back(std::move(var.fVarDecl));
resultExpr = std::make_unique<VariableReference>(/*offset=*/-1, var.fVarSymbol);
}
@@ -675,7 +669,7 @@
InlineVariable var = this->makeInlineVariable(param->name(), &arguments[i]->type(),
symbolTable.get(), param->modifiers(),
caller->isBuiltin(), &arguments[i]);
- inlinedBody.children().push_back(std::move(var.fVarDecl));
+ inlinedBlockStmts.push_back(std::move(var.fVarDecl));
varMap[param] = std::make_unique<VariableReference>(/*offset=*/-1, var.fVarSymbol);
}
@@ -713,20 +707,20 @@
Token::Kind::TK_PLUSPLUS);
// {...}
- auto innerBlock = std::make_unique<Block>(offset, StatementArray{},
- /*symbols=*/nullptr, /*isScope=*/true);
+ auto innerBlock = Block::Make(offset, StatementArray{},
+ /*symbols=*/nullptr, /*isScope=*/true);
inlineStatements = &innerBlock->children();
// for (int _1_loop = 0; _1_loop < 1; _1_loop++) {...}
- inlinedBody.children().push_back(ForStatement::Make(*fContext, /*offset=*/-1,
- std::move(loopVar.fVarDecl),
- std::move(test),
- std::move(increment),
- std::move(innerBlock),
- symbolTable));
+ inlinedBlockStmts.push_back(ForStatement::Make(*fContext, /*offset=*/-1,
+ std::move(loopVar.fVarDecl),
+ std::move(test),
+ std::move(increment),
+ std::move(innerBlock),
+ symbolTable));
} else {
// No early returns, so we can just dump the code into our existing scopeless block.
- inlineStatements = &inlinedBody.children();
+ inlineStatements = &inlinedBlockStmts;
}
inlineStatements->reserve_back(body.children().size() + argsToCopyBack.size());
@@ -748,6 +742,11 @@
std::move(varMap[p]))));
}
+ // Wrap all of the generated statements in a block. We need a real Block here, so we can't use
+ // MakeUnscoped. This is because we need to add another child statement to the Block later.
+ inlinedCall.fInlinedBody = Block::Make(offset, std::move(inlinedBlockStmts),
+ /*symbols=*/nullptr, /*isScope=*/false);
+
if (resultExpr) {
// Return our result expression as-is.
inlinedCall.fReplacementExpr = std::move(resultExpr);