mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add tracking of function parameters (#2552)
For parameters (and in the future, arguments too; generally comma-separated lists) track two node blocks: 1. param_ir: The complete IR. 2. param_refs: Nodes within the IR that are the "root" parameter. param_refs should allow quick counting of the # of parameters, and more efficient comparison of call args with function parameters. param_ir should be necessary to generate the actual signature. In order to construct this, this refactors the node_block_stack into its own class, which is reused in params_stack. These carry references to the underlying SmallVector for lazy modification in order to avoid a dependency cycle with SemanticsIR (also see notes on empty node blocks below). When finalized, the block pair is pushed onto finished_params_stack. That's because node_stack only has space for one thing, and this is two things -- so I'm essentially choosing a trade-off of adding another stack in order to avoid consuming more space in the expectation that most parse nodes have 0 or 1 things to return, and 2 will be very rare. As factored, this currently consolidates most empty node blocks into a single canonical empty node block. This is because I think empty blocks, i.e. `()`, will be very common. In order to achieve this, SemanticsNodeBlockStack does lazy creation. An alternative approach would have been to use 1 node block per parameter. We decided against this in order to reduce the number of vectors being created.
This commit is contained in:
@@ -34,6 +34,19 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "semantics_node_block_stack",
|
||||
srcs = ["semantics_node_block_stack.cpp"],
|
||||
hdrs = ["semantics_node_block_stack.h"],
|
||||
deps = [
|
||||
":semantics_node",
|
||||
"//common:check",
|
||||
"//common:ostream",
|
||||
"//common:vlog",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "semantics_node_stack",
|
||||
srcs = ["semantics_node_stack.cpp"],
|
||||
@@ -62,6 +75,7 @@ cc_library(
|
||||
deps = [
|
||||
":semantics_builtin_kind",
|
||||
":semantics_node",
|
||||
":semantics_node_block_stack",
|
||||
":semantics_node_stack",
|
||||
"//common:check",
|
||||
"//common:ostream",
|
||||
|
||||
@@ -38,8 +38,8 @@ auto SemanticsIR::MakeBuiltinIR() -> SemanticsIR {
|
||||
semantics.AddNode(block_id, SemanticsNode::MakeBuiltin(
|
||||
SemanticsBuiltinKind::RealType, type_type));
|
||||
|
||||
CARBON_CHECK(semantics.node_blocks_.size() == 1)
|
||||
<< "BuildBuiltins should only produce 1 block, actual: "
|
||||
CARBON_CHECK(semantics.node_blocks_.size() == 2)
|
||||
<< "BuildBuiltins should produce 2 blocks, actual: "
|
||||
<< semantics.node_blocks_.size();
|
||||
return semantics;
|
||||
}
|
||||
@@ -77,6 +77,13 @@ auto SemanticsIR::Print(llvm::raw_ostream& out) const -> void {
|
||||
|
||||
out << "cross_reference_irs_size: " << cross_reference_irs_.size() << "\n";
|
||||
|
||||
out << "callables: [\n";
|
||||
for (auto callable : callables_) {
|
||||
out.indent(Indent);
|
||||
out << callable << "\n";
|
||||
}
|
||||
out << "]\n";
|
||||
|
||||
out << "integer_literals: [\n";
|
||||
for (const auto& integer_literal : integer_literals_) {
|
||||
out.indent(Indent);
|
||||
|
||||
@@ -16,6 +16,19 @@ class SemanticsIRForTest;
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// A callable object.
|
||||
struct SemanticsCallable {
|
||||
auto Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "{param_ir: " << param_ir_id << ", param_refs: " << param_refs_id
|
||||
<< "}";
|
||||
}
|
||||
|
||||
// The full IR for parameters.
|
||||
SemanticsNodeBlockId param_ir_id;
|
||||
// A block containing a single reference node per parameter.
|
||||
SemanticsNodeBlockId param_refs_id;
|
||||
};
|
||||
|
||||
// Provides semantic analysis on a ParseTree.
|
||||
class SemanticsIR {
|
||||
public:
|
||||
@@ -39,7 +52,10 @@ class SemanticsIR {
|
||||
friend class SemanticsParseTreeHandler;
|
||||
|
||||
explicit SemanticsIR(const SemanticsIR* builtin_ir)
|
||||
: cross_reference_irs_({builtin_ir == nullptr ? this : builtin_ir}) {}
|
||||
: cross_reference_irs_({builtin_ir == nullptr ? this : builtin_ir}) {
|
||||
// For SemanticsNodeBlockId::Empty.
|
||||
node_blocks_.resize(1);
|
||||
}
|
||||
|
||||
// Returns the requested node.
|
||||
auto GetNode(SemanticsNodeId node_id) const -> const SemanticsNode& {
|
||||
@@ -51,6 +67,12 @@ class SemanticsIR {
|
||||
return GetNode(node_id).type();
|
||||
}
|
||||
|
||||
auto AddCallable(SemanticsCallable callable) -> SemanticsCallableId {
|
||||
SemanticsCallableId id(callables_.size());
|
||||
callables_.push_back(callable);
|
||||
return id;
|
||||
}
|
||||
|
||||
// Adds an integer literal, returning an ID to reference it.
|
||||
auto AddIntegerLiteral(llvm::APInt integer_literal)
|
||||
-> SemanticsIntegerLiteralId {
|
||||
@@ -59,14 +81,6 @@ class SemanticsIR {
|
||||
return id;
|
||||
}
|
||||
|
||||
// Adds an empty new node block, returning an ID to reference it and add
|
||||
// items.
|
||||
auto AddNodeBlock() -> SemanticsNodeBlockId {
|
||||
SemanticsNodeBlockId id(node_blocks_.size());
|
||||
node_blocks_.resize(node_blocks_.size() + 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
// Adds a node to a specified block, returning an ID to reference the node.
|
||||
auto AddNode(SemanticsNodeBlockId block_id, SemanticsNode node)
|
||||
-> SemanticsNodeId {
|
||||
@@ -76,6 +90,19 @@ class SemanticsIR {
|
||||
return node_id;
|
||||
}
|
||||
|
||||
// Adds an empty new node block, returning an ID to reference it and add
|
||||
// items.
|
||||
auto AddNodeBlock() -> SemanticsNodeBlockId {
|
||||
SemanticsNodeBlockId id(node_blocks_.size());
|
||||
node_blocks_.resize(node_blocks_.size() + 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
auto GetNodeBlock(SemanticsNodeBlockId block_id)
|
||||
-> llvm::SmallVector<SemanticsNodeId>& {
|
||||
return node_blocks_[block_id.index];
|
||||
}
|
||||
|
||||
// Adds an string, returning an ID to reference it.
|
||||
auto AddString(llvm::StringRef str) -> SemanticsStringId {
|
||||
// If the string has already been stored, return the corresponding ID.
|
||||
@@ -101,6 +128,9 @@ class SemanticsIR {
|
||||
|
||||
bool has_errors_ = false;
|
||||
|
||||
// Storage for callable objects.
|
||||
llvm::SmallVector<SemanticsCallable> callables_;
|
||||
|
||||
// Related IRs. There will always be at least 2 entries, the builtin IR (used
|
||||
// for references of builtins) followed by the current IR (used for references
|
||||
// crossing node blocks).
|
||||
|
||||
@@ -23,6 +23,7 @@ using ::testing::AllOf;
|
||||
using ::testing::Contains;
|
||||
using ::testing::Each;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::MatchesRegex;
|
||||
using ::testing::Pair;
|
||||
|
||||
@@ -50,6 +51,7 @@ TEST(SemanticsIRTest, YAML) {
|
||||
Yaml::Value::FromText(print_output),
|
||||
ElementsAre(Yaml::Mapping(ElementsAre(
|
||||
Pair("cross_reference_irs_size", "1"),
|
||||
Pair("callables", Yaml::Sequence(IsEmpty())),
|
||||
Pair("integer_literals", Yaml::Sequence(ElementsAre("0"))),
|
||||
Pair("strings", Yaml::Sequence(ElementsAre("x"))),
|
||||
Pair("nodes",
|
||||
@@ -69,7 +71,8 @@ TEST(SemanticsIRTest, YAML) {
|
||||
Pair("arg1", node_id), Pair("type", node_id))))))),
|
||||
// This production has only one node block.
|
||||
Pair("node_blocks",
|
||||
Yaml::Sequence(ElementsAre(Yaml::Sequence(Each(node_id)))))))));
|
||||
Yaml::Sequence(ElementsAre(Yaml::Sequence(IsEmpty()),
|
||||
Yaml::Sequence(Each(node_id)))))))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -34,6 +34,14 @@ struct SemanticsNodeId : public IndexBase {
|
||||
}
|
||||
};
|
||||
|
||||
// The ID of a callable, such as a function.
|
||||
struct SemanticsCallableId : public IndexBase {
|
||||
using IndexBase::IndexBase;
|
||||
auto Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "callable" << index;
|
||||
}
|
||||
};
|
||||
|
||||
// The ID of a cross-referenced IR.
|
||||
struct SemanticsCrossReferenceIRId : public IndexBase {
|
||||
using IndexBase::IndexBase;
|
||||
@@ -54,6 +62,14 @@ struct SemanticsIntegerLiteralId : public IndexBase {
|
||||
|
||||
// Type-safe storage of node blocks.
|
||||
struct SemanticsNodeBlockId : public IndexBase {
|
||||
// All SemanticsIR instances must provide the 0th node block as empty.
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
static const SemanticsNodeBlockId Empty;
|
||||
|
||||
// An explicitly invalid ID.
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
static const SemanticsNodeBlockId Invalid;
|
||||
|
||||
using IndexBase::IndexBase;
|
||||
auto Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "block";
|
||||
@@ -61,6 +77,11 @@ struct SemanticsNodeBlockId : public IndexBase {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr SemanticsNodeBlockId SemanticsNodeBlockId::Empty =
|
||||
SemanticsNodeBlockId(0);
|
||||
constexpr SemanticsNodeBlockId SemanticsNodeBlockId::Invalid =
|
||||
SemanticsNodeBlockId();
|
||||
|
||||
// Type-safe storage of strings.
|
||||
struct SemanticsStringId : public IndexBase {
|
||||
using IndexBase::IndexBase;
|
||||
@@ -147,14 +168,15 @@ class SemanticsNode {
|
||||
}
|
||||
|
||||
// TODO: The signature should be added as a parameter.
|
||||
static auto MakeFunctionDeclaration(ParseTree::Node parse_node)
|
||||
static auto MakeFunctionDeclaration(ParseTree::Node parse_node,
|
||||
SemanticsCallableId signature)
|
||||
-> SemanticsNode {
|
||||
return SemanticsNode(parse_node, SemanticsNodeKind::FunctionDeclaration,
|
||||
SemanticsNodeId());
|
||||
SemanticsNodeId(), signature.index);
|
||||
}
|
||||
auto GetAsFunctionDeclaration() const -> NoArgs {
|
||||
auto GetAsFunctionDeclaration() const -> SemanticsCallableId {
|
||||
CARBON_CHECK(kind_ == SemanticsNodeKind::FunctionDeclaration);
|
||||
return {};
|
||||
return {SemanticsCallableId(arg0_)};
|
||||
}
|
||||
|
||||
static auto MakeFunctionDefinition(ParseTree::Node parse_node,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/semantics/semantics_node_block_stack.h"
|
||||
|
||||
#include "common/vlog.h"
|
||||
#include "toolchain/semantics/semantics_node.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto SemanticsNodeBlockStack::Push() -> void {
|
||||
CARBON_VLOG() << "NodeBlock Push " << stack_.size() << "\n";
|
||||
CARBON_CHECK(stack_.size() < (1 << 20))
|
||||
<< "Excessive stack size: likely infinite loop";
|
||||
stack_.push_back(SemanticsNodeBlockId::Invalid);
|
||||
}
|
||||
|
||||
auto SemanticsNodeBlockStack::PushWithUnconditionalAlloc()
|
||||
-> SemanticsNodeBlockId {
|
||||
SemanticsNodeBlockId block_id(node_blocks_->size());
|
||||
CARBON_VLOG() << "NodeBlock Push " << stack_.size() << ": " << block_id
|
||||
<< "\n";
|
||||
CARBON_CHECK(stack_.size() < (1 << 20))
|
||||
<< "Excessive stack size: likely infinite loop";
|
||||
node_blocks_->resize(block_id.index + 1);
|
||||
stack_.push_back(block_id);
|
||||
return block_id;
|
||||
}
|
||||
|
||||
auto SemanticsNodeBlockStack::PeekForAdd() -> SemanticsNodeBlockId {
|
||||
auto& back = stack_.back();
|
||||
if (!back.is_valid()) {
|
||||
SemanticsNodeBlockId block_id(node_blocks_->size());
|
||||
node_blocks_->resize(block_id.index + 1);
|
||||
back = block_id;
|
||||
CARBON_VLOG() << "NodeBlock Add " << stack_.size() - 1 << ": " << back
|
||||
<< "\n";
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
auto SemanticsNodeBlockStack::Pop() -> SemanticsNodeBlockId {
|
||||
auto back = stack_.pop_back_val();
|
||||
CARBON_VLOG() << "NodeBlock Pop " << stack_.size() << ": " << back << "\n";
|
||||
if (!back.is_valid()) {
|
||||
return SemanticsNodeBlockId::Empty;
|
||||
}
|
||||
return back;
|
||||
}
|
||||
|
||||
auto SemanticsNodeBlockStack::PrintForStackDump(llvm::raw_ostream& output) const
|
||||
-> void {
|
||||
output << "SemanticsNodeBlockStack:\n";
|
||||
for (int i = 0; i < static_cast<int>(stack_.size()); ++i) {
|
||||
output << "\t" << i << ".\t" << stack_[i] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
@@ -0,0 +1,65 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_BLOCK_STACK_H_
|
||||
#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_BLOCK_STACK_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "common/check.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "toolchain/semantics/semantics_node.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Wraps the stack of node blocks for SemanticsParseTreeHandler.
|
||||
//
|
||||
// All pushes and pops will be vlogged.
|
||||
class SemanticsNodeBlockStack {
|
||||
public:
|
||||
explicit SemanticsNodeBlockStack(
|
||||
llvm::SmallVector<llvm::SmallVector<SemanticsNodeId>>& node_blocks,
|
||||
llvm::raw_ostream* vlog_stream)
|
||||
: node_blocks_(&node_blocks), vlog_stream_(vlog_stream) {}
|
||||
|
||||
~SemanticsNodeBlockStack() { CARBON_CHECK(stack_.empty()) << stack_.size(); }
|
||||
|
||||
// Pushes a new node block. It will be invalid unless PeekForAdd is called in
|
||||
// order to support lazy allocation.
|
||||
auto Push() -> void;
|
||||
|
||||
// Pushes a new node block.
|
||||
// TODO: Try to remove this in favor of the lazy alloc in Push.
|
||||
auto PushWithUnconditionalAlloc() -> SemanticsNodeBlockId;
|
||||
|
||||
// Peeks at the top node block. This does not trigger lazy allocation, so the
|
||||
// returned node block may be invalid.
|
||||
auto Peek() -> SemanticsNodeBlockId { return stack_.back(); }
|
||||
|
||||
// Returns the top node block, allocating one if it's still invalid.
|
||||
auto PeekForAdd() -> SemanticsNodeBlockId;
|
||||
|
||||
// Pops the top node block. This will always return a valid node block;
|
||||
// SemanticsNodeBlockId::Empty is returned if one wasn't allocated.
|
||||
auto Pop() -> SemanticsNodeBlockId;
|
||||
|
||||
// Prints the stack for a stack dump.
|
||||
auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
|
||||
|
||||
private:
|
||||
// The underlying node block storage on SemanticsIR. Always non-null.
|
||||
llvm::SmallVector<llvm::SmallVector<SemanticsNodeId>>* const node_blocks_;
|
||||
|
||||
// Whether to print verbose output.
|
||||
llvm::raw_ostream* vlog_stream_;
|
||||
|
||||
// The actual stack.
|
||||
// PushEntry and PopEntry control modification in order to centralize
|
||||
// vlogging.
|
||||
llvm::SmallVector<SemanticsNodeBlockId> stack_;
|
||||
};
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_BLOCK_STACK_H_
|
||||
@@ -5,18 +5,23 @@
|
||||
#include "toolchain/semantics/semantics_node_stack.h"
|
||||
|
||||
#include "common/vlog.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "toolchain/semantics/semantics_node.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto SemanticsNodeStack::PushEntry(Entry entry, bool is_node_id) -> void {
|
||||
CARBON_VLOG() << "Push " << stack_.size() << ": "
|
||||
auto SemanticsNodeStack::PushEntry(Entry entry, DebugLog debug_log) -> void {
|
||||
CARBON_VLOG() << "Node Push " << stack_.size() << ": "
|
||||
<< parse_tree_->node_kind(entry.parse_node) << " -> ";
|
||||
if (is_node_id) {
|
||||
CARBON_VLOG() << entry.node_id;
|
||||
} else {
|
||||
CARBON_VLOG() << entry.name_id;
|
||||
switch (debug_log) {
|
||||
case DebugLog::None:
|
||||
CARBON_VLOG() << "<none>";
|
||||
break;
|
||||
case DebugLog::NodeId:
|
||||
CARBON_VLOG() << entry.node_id;
|
||||
break;
|
||||
case DebugLog::NameId:
|
||||
CARBON_VLOG() << entry.name_id;
|
||||
break;
|
||||
}
|
||||
CARBON_VLOG() << "\n";
|
||||
CARBON_CHECK(stack_.size() < (1 << 20))
|
||||
@@ -26,7 +31,7 @@ auto SemanticsNodeStack::PushEntry(Entry entry, bool is_node_id) -> void {
|
||||
|
||||
auto SemanticsNodeStack::PopEntry() -> Entry {
|
||||
auto back = stack_.pop_back_val();
|
||||
CARBON_VLOG() << "Pop " << stack_.size() << ": any ("
|
||||
CARBON_VLOG() << "Node Pop " << stack_.size() << ": any ("
|
||||
<< parse_tree_->node_kind(back.parse_node) << ") -> "
|
||||
<< back.node_id << "\n";
|
||||
return back;
|
||||
@@ -34,8 +39,8 @@ auto SemanticsNodeStack::PopEntry() -> Entry {
|
||||
|
||||
auto SemanticsNodeStack::PopEntry(ParseNodeKind pop_parse_kind) -> Entry {
|
||||
auto back = stack_.pop_back_val();
|
||||
CARBON_VLOG() << "Pop " << stack_.size() << ": " << pop_parse_kind << " -> "
|
||||
<< back.node_id << "\n";
|
||||
CARBON_VLOG() << "Node Pop " << stack_.size() << ": " << pop_parse_kind
|
||||
<< " -> " << back.node_id << "\n";
|
||||
RequireParseKind(back, pop_parse_kind);
|
||||
return back;
|
||||
}
|
||||
@@ -47,16 +52,36 @@ auto SemanticsNodeStack::RequireParseKind(Entry entry,
|
||||
<< "Expected " << require_kind << ", found " << actual_kind;
|
||||
}
|
||||
|
||||
// RequireSoloParseNode and RequireValidId rely on type punning. They read
|
||||
// node_id.is_valid, even though that may not be the active union member.
|
||||
// These asserts enforce standard layout in order to help ensure that works.
|
||||
// TODO: Use is_layout_compatible in C++20.
|
||||
static_assert(std::is_standard_layout_v<SemanticsNodeId>,
|
||||
"Need standard layout for type punning");
|
||||
static_assert(std::is_standard_layout_v<SemanticsStringId>,
|
||||
"Need standard layout for type punning");
|
||||
|
||||
auto SemanticsNodeStack::RequireSoloParseNode(Entry entry) -> void {
|
||||
// See above comment on type punning.
|
||||
CARBON_CHECK(!entry.node_id.is_valid())
|
||||
<< "Expected invalid node_id on "
|
||||
<< parse_tree_->node_kind(entry.parse_node) << ", was " << entry.node_id;
|
||||
<< "Expected invalid id on " << parse_tree_->node_kind(entry.parse_node)
|
||||
<< ", was " << entry.node_id << " (may not be node)";
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::RequireNodeId(Entry entry) -> void {
|
||||
auto SemanticsNodeStack::RequireValidId(Entry entry) -> void {
|
||||
// See above comment on type punning.
|
||||
CARBON_CHECK(entry.node_id.is_valid())
|
||||
<< "Expected valid node_id on "
|
||||
<< parse_tree_->node_kind(entry.parse_node);
|
||||
<< "Expected valid id on " << parse_tree_->node_kind(entry.parse_node);
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopAndDiscardId() -> void {
|
||||
auto back = PopEntry();
|
||||
RequireValidId(back);
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopAndDiscardId(ParseNodeKind pop_parse_kind) -> void {
|
||||
auto back = PopEntry(pop_parse_kind);
|
||||
RequireValidId(back);
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopAndDiscardSoloParseNode(
|
||||
@@ -80,48 +105,48 @@ auto SemanticsNodeStack::PopForSoloParseNode(ParseNodeKind pop_parse_kind)
|
||||
|
||||
auto SemanticsNodeStack::PopForNodeId() -> SemanticsNodeId {
|
||||
auto back = PopEntry();
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return back.node_id;
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopForNodeId(ParseNodeKind pop_parse_kind)
|
||||
-> SemanticsNodeId {
|
||||
auto back = PopEntry(pop_parse_kind);
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return back.node_id;
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopForParseNodeAndNodeId()
|
||||
-> std::pair<ParseTree::Node, SemanticsNodeId> {
|
||||
auto back = PopEntry();
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return {back.parse_node, back.node_id};
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopForParseNodeAndNodeId(ParseNodeKind pop_parse_kind)
|
||||
-> std::pair<ParseTree::Node, SemanticsNodeId> {
|
||||
auto back = PopEntry(pop_parse_kind);
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return {back.parse_node, back.node_id};
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PopForParseNodeAndNameId()
|
||||
-> std::pair<ParseTree::Node, SemanticsStringId> {
|
||||
auto back = PopEntry(ParseNodeKind::PatternBinding);
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return {back.parse_node, back.name_id};
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PeekForNameId() -> SemanticsStringId {
|
||||
auto back = stack_.back();
|
||||
RequireParseKind(back, ParseNodeKind::PatternBinding);
|
||||
RequireNodeId(back);
|
||||
RequireValidId(back);
|
||||
return back.name_id;
|
||||
}
|
||||
|
||||
auto SemanticsNodeStack::PrintForStackDump(llvm::raw_ostream& output) const
|
||||
-> void {
|
||||
output << "node_stack_:\n";
|
||||
output << "SemanticsNodeStack:\n";
|
||||
for (int i = 0; i < static_cast<int>(stack_.size()); ++i) {
|
||||
const auto& entry = stack_[i];
|
||||
auto parse_node_kind = parse_tree_->node_kind(entry.parse_node);
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_STACK_H_
|
||||
#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_STACK_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "toolchain/parser/parse_node_kind.h"
|
||||
#include "toolchain/parser/parse_tree.h"
|
||||
@@ -36,21 +38,19 @@ class SemanticsNodeStack {
|
||||
auto Push(ParseTree::Node parse_node) -> void {
|
||||
PushEntry(
|
||||
{.parse_node = parse_node, .node_id = SemanticsNodeId::MakeInvalid()},
|
||||
/*is_node_id=*/true);
|
||||
DebugLog::None);
|
||||
}
|
||||
|
||||
// Pushes a parse tree node onto the stack.
|
||||
auto Push(ParseTree::Node parse_node, SemanticsNodeId node_id) -> void {
|
||||
PushEntry({.parse_node = parse_node, .node_id = node_id},
|
||||
/*is_node_id=*/true);
|
||||
PushEntry({.parse_node = parse_node, .node_id = node_id}, DebugLog::NodeId);
|
||||
}
|
||||
|
||||
// Pushes a PatternBinding parse tree node onto the stack with its name.
|
||||
auto Push(ParseTree::Node parse_node, SemanticsStringId name_id) -> void {
|
||||
CARBON_CHECK(parse_tree_->node_kind(parse_node) ==
|
||||
ParseNodeKind::PatternBinding);
|
||||
PushEntry({.parse_node = parse_node, .name_id = name_id},
|
||||
/*is_node_id=*/false);
|
||||
PushEntry({.parse_node = parse_node, .name_id = name_id}, DebugLog::NameId);
|
||||
}
|
||||
|
||||
// Pops the top of the stack without any verification.
|
||||
@@ -59,6 +59,12 @@ class SemanticsNodeStack {
|
||||
// Pops the top of the stack.
|
||||
auto PopAndDiscardSoloParseNode(ParseNodeKind pop_parse_kind) -> void;
|
||||
|
||||
// Pops the top of the stack, and discards the ID.
|
||||
auto PopAndDiscardId() -> void;
|
||||
|
||||
// Pops the top of the stack, and discards the ID.
|
||||
auto PopAndDiscardId(ParseNodeKind pop_parse_kind) -> void;
|
||||
|
||||
// Pops the top of the stack and returns the parse_node.
|
||||
auto PopForSoloParseNode() -> ParseTree::Node;
|
||||
|
||||
@@ -95,21 +101,34 @@ class SemanticsNodeStack {
|
||||
auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
|
||||
|
||||
private:
|
||||
// An entry in node_stack_.
|
||||
// An entry in stack_.
|
||||
struct Entry {
|
||||
// The node associated with the stack entry.
|
||||
ParseTree::Node parse_node;
|
||||
|
||||
// The entries will evaluate as invalid if and only if they're a solo
|
||||
// parse_node. Invalid is used instead of optional to save space.
|
||||
//
|
||||
// A discriminator isn't needed because the caller can determine which field
|
||||
// is used based on the ParseNodeKind.
|
||||
union {
|
||||
// The node_id will be invalid if and only if it's a solo parse_node.
|
||||
SemanticsNodeId node_id;
|
||||
// The name_id is provided for PatternBindings.
|
||||
|
||||
// Right now name_id is exclusively for PatternBinding, which is enforced.
|
||||
SemanticsStringId name_id;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(Entry) == 8, "Unexpected Entry size");
|
||||
|
||||
// Pushes an entry onto the stack. is_node_id is provided for debug output
|
||||
// only.
|
||||
auto PushEntry(Entry entry, bool is_node_id) -> void;
|
||||
// Which Entry union member to log.
|
||||
enum DebugLog {
|
||||
None,
|
||||
NodeId,
|
||||
NameId,
|
||||
};
|
||||
|
||||
// Pushes an entry onto the stack.
|
||||
auto PushEntry(Entry entry, DebugLog debug_log) -> void;
|
||||
|
||||
// Pops an entry.
|
||||
auto PopEntry() -> Entry;
|
||||
@@ -121,12 +140,10 @@ class SemanticsNodeStack {
|
||||
auto RequireParseKind(Entry entry, ParseNodeKind require_kind) -> void;
|
||||
|
||||
// Requires an entry to have a invalid node_id.
|
||||
// Also works with name_id in the union due to type compatibility.
|
||||
auto RequireSoloParseNode(Entry entry) -> void;
|
||||
|
||||
// Requires an entry to have a valid node_id.
|
||||
// Also works with name_id in the union due to type compatibility.
|
||||
auto RequireNodeId(Entry entry) -> void;
|
||||
// Requires an entry to have a valid id.
|
||||
auto RequireValidId(Entry entry) -> void;
|
||||
|
||||
// The file's parse tree.
|
||||
const ParseTree* parse_tree_;
|
||||
|
||||
@@ -4,58 +4,43 @@
|
||||
|
||||
#include "toolchain/semantics/semantics_parse_tree_handler.h"
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include "common/vlog.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "toolchain/lexer/token_kind.h"
|
||||
#include "toolchain/lexer/tokenized_buffer.h"
|
||||
#include "toolchain/parser/parse_node_kind.h"
|
||||
#include "toolchain/semantics/semantics_builtin_kind.h"
|
||||
#include "toolchain/semantics/semantics_ir.h"
|
||||
#include "toolchain/semantics/semantics_node.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
class SemanticsParseTreeHandler::PrettyStackTraceNodeStack
|
||||
: public llvm::PrettyStackTraceEntry {
|
||||
class PrettyStackTraceFunction : public llvm::PrettyStackTraceEntry {
|
||||
public:
|
||||
explicit PrettyStackTraceNodeStack(const SemanticsParseTreeHandler* handler)
|
||||
: handler_(handler) {}
|
||||
~PrettyStackTraceNodeStack() override = default;
|
||||
explicit PrettyStackTraceFunction(std::function<void(llvm::raw_ostream&)> fn)
|
||||
: fn_(std::move(fn)) {}
|
||||
~PrettyStackTraceFunction() override = default;
|
||||
|
||||
auto print(llvm::raw_ostream& output) const -> void override {
|
||||
handler_->node_stack_.PrintForStackDump(output);
|
||||
}
|
||||
auto print(llvm::raw_ostream& output) const -> void override { fn_(output); }
|
||||
|
||||
private:
|
||||
const SemanticsParseTreeHandler* handler_;
|
||||
};
|
||||
|
||||
class SemanticsParseTreeHandler::PrettyStackTraceNodeBlockStack
|
||||
: public llvm::PrettyStackTraceEntry {
|
||||
public:
|
||||
explicit PrettyStackTraceNodeBlockStack(
|
||||
const SemanticsParseTreeHandler* handler)
|
||||
: handler_(handler) {}
|
||||
~PrettyStackTraceNodeBlockStack() override = default;
|
||||
|
||||
auto print(llvm::raw_ostream& output) const -> void override {
|
||||
output << "node_block_stack_:\n";
|
||||
for (int i = 0; i < static_cast<int>(handler_->node_block_stack_.size());
|
||||
++i) {
|
||||
const auto& entry = handler_->node_block_stack_[i];
|
||||
output << "\t" << i << ".\t" << entry << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const SemanticsParseTreeHandler* handler_;
|
||||
const std::function<void(llvm::raw_ostream&)> fn_;
|
||||
};
|
||||
|
||||
auto SemanticsParseTreeHandler::Build() -> void {
|
||||
PrettyStackTraceNodeStack pretty_node_stack(this);
|
||||
PrettyStackTraceNodeBlockStack pretty_node_block_stack(this);
|
||||
PrettyStackTraceFunction pretty_node_stack([&](llvm::raw_ostream& output) {
|
||||
node_stack_.PrintForStackDump(output);
|
||||
});
|
||||
PrettyStackTraceFunction pretty_node_block_stack(
|
||||
[&](llvm::raw_ostream& output) {
|
||||
node_block_stack_.PrintForStackDump(output);
|
||||
});
|
||||
|
||||
// Add a block for the ParseTree.
|
||||
node_block_stack_.push_back(semantics_->AddNodeBlock());
|
||||
node_block_stack_.Push();
|
||||
PushScope();
|
||||
|
||||
for (auto parse_node : parse_tree_->postorder()) {
|
||||
@@ -69,8 +54,7 @@ auto SemanticsParseTreeHandler::Build() -> void {
|
||||
}
|
||||
}
|
||||
|
||||
node_block_stack_.pop_back();
|
||||
CARBON_CHECK(node_block_stack_.empty()) << node_block_stack_.size();
|
||||
node_block_stack_.Pop();
|
||||
|
||||
PopScope();
|
||||
CARBON_CHECK(name_lookup_.empty()) << name_lookup_.size();
|
||||
@@ -78,8 +62,9 @@ auto SemanticsParseTreeHandler::Build() -> void {
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::AddNode(SemanticsNode node) -> SemanticsNodeId {
|
||||
CARBON_VLOG() << "AddNode " << current_block_id() << ": " << node << "\n";
|
||||
return semantics_->AddNode(current_block_id(), node);
|
||||
auto block = node_block_stack_.PeekForAdd();
|
||||
CARBON_VLOG() << "AddNode " << block << ": " << node << "\n";
|
||||
return semantics_->AddNode(block, node);
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::AddNodeAndPush(ParseTree::Node parse_node,
|
||||
@@ -244,7 +229,7 @@ auto SemanticsParseTreeHandler::HandleExpressionStatement(
|
||||
// Pop the expression without investigating its contents.
|
||||
// TODO: This will probably eventually need to do some "do not discard"
|
||||
// analysis.
|
||||
node_stack_.PopAndIgnore();
|
||||
node_stack_.PopAndDiscardId();
|
||||
node_stack_.Push(parse_node);
|
||||
}
|
||||
|
||||
@@ -288,23 +273,35 @@ auto SemanticsParseTreeHandler::HandleFunctionDefinition(
|
||||
node_stack_.PopAndIgnore();
|
||||
|
||||
PopScope();
|
||||
node_block_stack_.pop_back();
|
||||
node_block_stack_.Pop();
|
||||
node_stack_.Push(parse_node);
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::HandleFunctionDefinitionStart(
|
||||
ParseTree::Node parse_node) -> void {
|
||||
node_stack_.PopAndDiscardSoloParseNode(ParseNodeKind::ParameterList);
|
||||
node_stack_.PopForSoloParseNode(ParseNodeKind::ParameterList);
|
||||
auto [param_ir_id, param_refs_id] = finished_params_stack_.pop_back_val();
|
||||
auto name_node = node_stack_.PopForSoloParseNode(ParseNodeKind::DeclaredName);
|
||||
auto fn_node =
|
||||
node_stack_.PopForSoloParseNode(ParseNodeKind::FunctionIntroducer);
|
||||
|
||||
auto decl_id = AddNode(SemanticsNode::MakeFunctionDeclaration(fn_node));
|
||||
SemanticsCallable callable;
|
||||
callable.param_ir_id = param_ir_id;
|
||||
callable.param_refs_id = param_refs_id;
|
||||
auto callable_id = semantics_->AddCallable(callable);
|
||||
auto decl_id =
|
||||
AddNode(SemanticsNode::MakeFunctionDeclaration(fn_node, callable_id));
|
||||
// TODO: Propagate the type of the function.
|
||||
BindName(name_node, SemanticsNodeId::MakeInvalid(), decl_id);
|
||||
auto block_id = semantics_->AddNodeBlock();
|
||||
AddNode(SemanticsNode::MakeFunctionDefinition(parse_node, decl_id, block_id));
|
||||
node_block_stack_.push_back(block_id);
|
||||
|
||||
// TODO: Consider approaches that allow lazy creation of the definition block.
|
||||
auto outer_block = node_block_stack_.PeekForAdd();
|
||||
auto def_block = node_block_stack_.PushWithUnconditionalAlloc();
|
||||
auto node =
|
||||
SemanticsNode::MakeFunctionDefinition(parse_node, decl_id, def_block);
|
||||
CARBON_VLOG() << "AddNode " << outer_block << ": " << node << "\n";
|
||||
semantics_->AddNode(outer_block, node);
|
||||
|
||||
PushScope();
|
||||
node_stack_.Push(parse_node);
|
||||
}
|
||||
@@ -451,23 +448,76 @@ auto SemanticsParseTreeHandler::HandlePackageLibrary(
|
||||
CARBON_FATAL() << "TODO";
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::SaveParam() -> bool {
|
||||
// Copy the last node added to the IR block into the params block.
|
||||
auto ir_id = node_block_stack_.Peek();
|
||||
if (!ir_id.is_valid()) {
|
||||
return false;
|
||||
}
|
||||
auto& ir = semantics_->GetNodeBlock(ir_id);
|
||||
CARBON_CHECK(!ir.empty())
|
||||
<< "Should only have a valid ID if a node was added";
|
||||
auto& param = ir.back();
|
||||
auto& params = semantics_->GetNodeBlock(params_stack_.PeekForAdd());
|
||||
if (!params.empty() && param == params.back()) {
|
||||
// The param was already added after a comma.
|
||||
return false;
|
||||
}
|
||||
params.push_back(ir.back());
|
||||
return true;
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::HandleParameterList(ParseTree::Node parse_node)
|
||||
-> void {
|
||||
// TODO: This should transform into a usable parameter list. For now
|
||||
// it's unused and only stored so that node counts match.
|
||||
node_stack_.PopAndDiscardSoloParseNode(ParseNodeKind::ParameterListStart);
|
||||
node_stack_.Push(parse_node);
|
||||
// If there's a node in the IR block that has yet to be added to the params
|
||||
// block, add it now.
|
||||
SaveParam();
|
||||
|
||||
while (true) {
|
||||
switch (auto parse_kind =
|
||||
parse_tree_->node_kind(node_stack_.PeekParseNode())) {
|
||||
case ParseNodeKind::ParameterListStart:
|
||||
node_stack_.PopAndDiscardSoloParseNode(
|
||||
ParseNodeKind::ParameterListStart);
|
||||
finished_params_stack_.push_back(
|
||||
{node_block_stack_.Pop(), params_stack_.Pop()});
|
||||
node_stack_.Push(parse_node);
|
||||
return;
|
||||
|
||||
case ParseNodeKind::ParameterListComma:
|
||||
node_stack_.PopAndDiscardSoloParseNode(
|
||||
ParseNodeKind::ParameterListComma);
|
||||
break;
|
||||
|
||||
case ParseNodeKind::PatternBinding:
|
||||
node_stack_.PopAndDiscardId(ParseNodeKind::PatternBinding);
|
||||
break;
|
||||
|
||||
default:
|
||||
// This should only occur for invalid parse trees.
|
||||
CARBON_FATAL() << "TODO: " << parse_kind;
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("loop always exits");
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::HandleParameterListComma(
|
||||
ParseTree::Node /*parse_node*/) -> void {
|
||||
CARBON_FATAL() << "TODO";
|
||||
ParseTree::Node parse_node) -> void {
|
||||
node_stack_.Push(parse_node);
|
||||
|
||||
// Copy the last node added to the IR block into the params block.
|
||||
bool had_param_before_comma = SaveParam();
|
||||
CARBON_CHECK(had_param_before_comma)
|
||||
<< "TODO: Should have a param before comma, will need error recovery";
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::HandleParameterListStart(
|
||||
ParseTree::Node parse_node) -> void {
|
||||
// TODO: See HandleParameterList.
|
||||
node_stack_.Push(parse_node);
|
||||
|
||||
params_stack_.Push();
|
||||
node_block_stack_.Push();
|
||||
}
|
||||
|
||||
auto SemanticsParseTreeHandler::HandleParenExpression(
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "toolchain/parser/parse_tree.h"
|
||||
#include "toolchain/semantics/semantics_ir.h"
|
||||
#include "toolchain/semantics/semantics_node.h"
|
||||
#include "toolchain/semantics/semantics_node_block_stack.h"
|
||||
#include "toolchain/semantics/semantics_node_stack.h"
|
||||
|
||||
namespace Carbon {
|
||||
@@ -28,7 +29,9 @@ class SemanticsParseTreeHandler {
|
||||
parse_tree_(&parse_tree),
|
||||
semantics_(&semantics),
|
||||
vlog_stream_(vlog_stream),
|
||||
node_stack_(parse_tree, vlog_stream) {}
|
||||
node_stack_(parse_tree, vlog_stream),
|
||||
node_block_stack_(semantics.node_blocks_, vlog_stream),
|
||||
params_stack_(semantics.node_blocks_, vlog_stream) {}
|
||||
|
||||
// Outputs the ParseTree information into SemanticsIR.
|
||||
auto Build() -> void;
|
||||
@@ -98,15 +101,15 @@ class SemanticsParseTreeHandler {
|
||||
SemanticsNodeId rhs_id, bool can_convert_lhs)
|
||||
-> SemanticsNodeId;
|
||||
|
||||
// Saves a parameter from the top block in node_stack_ to the top block in
|
||||
// params_stack_. Returns false if nothing is copied.
|
||||
auto SaveParam() -> bool;
|
||||
|
||||
// Parse node handlers.
|
||||
#define CARBON_PARSE_NODE_KIND(Name) \
|
||||
auto Handle##Name(ParseTree::Node parse_node)->void;
|
||||
#include "toolchain/parser/parse_node_kind.def"
|
||||
|
||||
auto current_block_id() -> SemanticsNodeBlockId {
|
||||
return node_block_stack_.back();
|
||||
}
|
||||
|
||||
auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); }
|
||||
|
||||
// Tokens for getting data on literals.
|
||||
@@ -127,9 +130,14 @@ class SemanticsParseTreeHandler {
|
||||
// The stack during Build. Will contain file-level parse nodes on return.
|
||||
SemanticsNodeStack node_stack_;
|
||||
|
||||
// The stack of node blocks during build. Only updated on ParseTree nodes that
|
||||
// affect the stack.
|
||||
llvm::SmallVector<SemanticsNodeBlockId> node_block_stack_;
|
||||
// The stack of node blocks being used for general IR generation.
|
||||
SemanticsNodeBlockStack node_block_stack_;
|
||||
|
||||
// The stack of node blocks being used for parameters.
|
||||
SemanticsNodeBlockStack params_stack_;
|
||||
|
||||
llvm::SmallVector<std::pair<SemanticsNodeBlockId, SemanticsNodeBlockId>>
|
||||
finished_params_stack_;
|
||||
|
||||
// A stack for scope context.
|
||||
llvm::SmallVector<ScopeStackEntry> scope_stack_;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -15,12 +18,14 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@
|
||||
// RUN: %{carbon} -v dump semantics-ir %s | %{FileCheck-allow-unmatched}
|
||||
//
|
||||
// Only checks a couple statements in order to minimize manual update churn.
|
||||
// CHECK:STDERR: Push 0: FunctionIntroducer -> node<invalid>
|
||||
// CHECK:STDERR: AddNode block0: {kind: BindName, arg0: str0, arg1: node4}
|
||||
// CHECK:STDERR: Node Push 0: FunctionIntroducer -> <none>
|
||||
// CHECK:STDERR: AddNode block{{[0-9]+}}: {kind: BindName, arg0: str{{[0-9]+}}, arg1: node{{[0-9]+}}}
|
||||
|
||||
fn Foo() {
|
||||
return;
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -15,12 +18,14 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+13
-6
@@ -5,6 +5,11 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -17,18 +22,20 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable1},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node7, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node7, arg1: block3},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node10},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node10, arg1: block3},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node10, arg1: block4},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block1, param_refs: block2}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: Foo,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block0, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node6},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node6, arg1: block4},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node6,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: node8,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
|
||||
fn Foo(a: i32) {}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block1, param_refs: block2}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: Foo,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block0, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node6},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node6, arg1: block4},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node6,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: node8,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
|
||||
fn Foo(a: i32,) {}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block1, param_refs: block2}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: b,
|
||||
// CHECK:STDOUT: Foo,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block0, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node6, type: node2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node8},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node8, arg1: block4},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node8,
|
||||
// CHECK:STDOUT: node9,
|
||||
// CHECK:STDOUT: node10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
|
||||
fn Foo(a: i32, b: i32) {}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block1, param_refs: block2}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: b,
|
||||
// CHECK:STDOUT: Foo,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block0, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node6, type: node2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node8},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node8, arg1: block4},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node8,
|
||||
// CHECK:STDOUT: node9,
|
||||
// CHECK:STDOUT: node10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
|
||||
fn Foo(a: i32, b: i32,) {}
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 12,
|
||||
// CHECK:STDOUT: 34,
|
||||
@@ -17,9 +20,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: node2},
|
||||
// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node7, arg1: node8, type: node2},
|
||||
@@ -27,6 +30,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 12,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -16,9 +19,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
// CHECK:STDOUT: {kind: RealLiteral, type: node3},
|
||||
// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node7, arg1: node8, type: node1},
|
||||
@@ -26,6 +29,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 12,
|
||||
// CHECK:STDOUT: 12,
|
||||
@@ -17,9 +20,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
// CHECK:STDOUT: {kind: RealLiteral, type: node3},
|
||||
// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node7, arg1: node8, type: node1},
|
||||
@@ -29,6 +32,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -16,14 +19,16 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node7, type: node2},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -15,13 +18,15 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -16,14 +19,16 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -17,9 +20,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
@@ -27,6 +30,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: 0,
|
||||
@@ -18,9 +21,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
@@ -32,6 +35,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -16,9 +19,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: RealLiteral, type: node3},
|
||||
@@ -26,6 +29,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -16,15 +19,17 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node7, arg1: node1, type: node1},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{not} %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -17,9 +20,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
@@ -28,6 +31,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
@@ -20,6 +22,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: ],
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -23,6 +25,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -27,6 +29,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -22,15 +25,17 @@
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node4, arg1: node6, type: node2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node8},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node8, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node8, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str2, arg1: node11, type: node2},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node11, arg1: node4, type: node2},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
+7
-2
@@ -5,6 +5,9 @@
|
||||
// AUTOUPDATE
|
||||
// RUN: %{carbon-run-semantics}
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: callables: [
|
||||
// CHECK:STDOUT: {param_ir: block0, param_refs: block0}
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 0,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -17,9 +20,9 @@
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block1, type: node1},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block2, type: node0},
|
||||
// CHECK:STDOUT: {kind: CrossReference, arg0: ir0, arg1: block3, type: node0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: callable0},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str0, arg1: node4},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block1},
|
||||
// CHECK:STDOUT: {kind: FunctionDefinition, arg0: node4, arg1: block2},
|
||||
// CHECK:STDOUT: {kind: VarStorage, type: node2},
|
||||
// CHECK:STDOUT: {kind: BindName, arg0: str1, arg1: node7, type: node2},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: node2},
|
||||
@@ -27,6 +30,8 @@
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node4,
|
||||
// CHECK:STDOUT: node5,
|
||||
// CHECK:STDOUT: node6,
|
||||
|
||||
Reference in New Issue
Block a user