diff --git a/toolchain/semantics/BUILD b/toolchain/semantics/BUILD index 6f0ed425546d..e1e4c0279f73 100644 --- a/toolchain/semantics/BUILD +++ b/toolchain/semantics/BUILD @@ -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", diff --git a/toolchain/semantics/semantics_ir.cpp b/toolchain/semantics/semantics_ir.cpp index e4a348fdb61d..c99d95880a1a 100644 --- a/toolchain/semantics/semantics_ir.cpp +++ b/toolchain/semantics/semantics_ir.cpp @@ -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); diff --git a/toolchain/semantics/semantics_ir.h b/toolchain/semantics/semantics_ir.h index c2875872ae9f..d41f7980791a 100644 --- a/toolchain/semantics/semantics_ir.h +++ b/toolchain/semantics/semantics_ir.h @@ -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& { + 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 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). diff --git a/toolchain/semantics/semantics_ir_test.cpp b/toolchain/semantics/semantics_ir_test.cpp index 742654339348..a5c41f7338d7 100644 --- a/toolchain/semantics/semantics_ir_test.cpp +++ b/toolchain/semantics/semantics_ir_test.cpp @@ -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 diff --git a/toolchain/semantics/semantics_node.h b/toolchain/semantics/semantics_node.h index 9ba051ccc9f5..4e65decbb87d 100644 --- a/toolchain/semantics/semantics_node.h +++ b/toolchain/semantics/semantics_node.h @@ -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, diff --git a/toolchain/semantics/semantics_node_block_stack.cpp b/toolchain/semantics/semantics_node_block_stack.cpp new file mode 100644 index 000000000000..0c681d066bb5 --- /dev/null +++ b/toolchain/semantics/semantics_node_block_stack.cpp @@ -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(stack_.size()); ++i) { + output << "\t" << i << ".\t" << stack_[i] << "\n"; + } +} + +} // namespace Carbon diff --git a/toolchain/semantics/semantics_node_block_stack.h b/toolchain/semantics/semantics_node_block_stack.h new file mode 100644 index 000000000000..d2e20eb28b0c --- /dev/null +++ b/toolchain/semantics/semantics_node_block_stack.h @@ -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 + +#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>& 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>* 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 stack_; +}; + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_BLOCK_STACK_H_ diff --git a/toolchain/semantics/semantics_node_stack.cpp b/toolchain/semantics/semantics_node_stack.cpp index e494854b47e8..9a3650e7e86e 100644 --- a/toolchain/semantics/semantics_node_stack.cpp +++ b/toolchain/semantics/semantics_node_stack.cpp @@ -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() << ""; + 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, + "Need standard layout for type punning"); +static_assert(std::is_standard_layout_v, + "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 { auto back = PopEntry(); - RequireNodeId(back); + RequireValidId(back); return {back.parse_node, back.node_id}; } auto SemanticsNodeStack::PopForParseNodeAndNodeId(ParseNodeKind pop_parse_kind) -> std::pair { auto back = PopEntry(pop_parse_kind); - RequireNodeId(back); + RequireValidId(back); return {back.parse_node, back.node_id}; } auto SemanticsNodeStack::PopForParseNodeAndNameId() -> std::pair { 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(stack_.size()); ++i) { const auto& entry = stack_[i]; auto parse_node_kind = parse_tree_->node_kind(entry.parse_node); diff --git a/toolchain/semantics/semantics_node_stack.h b/toolchain/semantics/semantics_node_stack.h index f261aed6062c..3a54005b0438 100644 --- a/toolchain/semantics/semantics_node_stack.h +++ b/toolchain/semantics/semantics_node_stack.h @@ -5,6 +5,8 @@ #ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_STACK_H_ #define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_NODE_STACK_H_ +#include + #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_; diff --git a/toolchain/semantics/semantics_parse_tree_handler.cpp b/toolchain/semantics/semantics_parse_tree_handler.cpp index 8194a56402ae..4ffc43018f88 100644 --- a/toolchain/semantics/semantics_parse_tree_handler.cpp +++ b/toolchain/semantics/semantics_parse_tree_handler.cpp @@ -4,58 +4,43 @@ #include "toolchain/semantics/semantics_parse_tree_handler.h" +#include +#include + #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 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(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 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( diff --git a/toolchain/semantics/semantics_parse_tree_handler.h b/toolchain/semantics/semantics_parse_tree_handler.h index 3d5fbf2b1992..178ddad021b5 100644 --- a/toolchain/semantics/semantics_parse_tree_handler.h +++ b/toolchain/semantics/semantics_parse_tree_handler.h @@ -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 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> + finished_params_stack_; // A stack for scope context. llvm::SmallVector scope_stack_; diff --git a/toolchain/semantics/testdata/basics/empty.carbon b/toolchain/semantics/testdata/basics/empty.carbon index 73d7fbba6880..8a2d20041219 100644 --- a/toolchain/semantics/testdata/basics/empty.carbon +++ b/toolchain/semantics/testdata/basics/empty.carbon @@ -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: [ diff --git a/toolchain/semantics/testdata/basics/empty_decl.carbon b/toolchain/semantics/testdata/basics/empty_decl.carbon index 6da0ce1cb6e1..5816c3f100b6 100644 --- a/toolchain/semantics/testdata/basics/empty_decl.carbon +++ b/toolchain/semantics/testdata/basics/empty_decl.carbon @@ -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: [ diff --git a/toolchain/semantics/testdata/basics/fail_name_lookup.carbon b/toolchain/semantics/testdata/basics/fail_name_lookup.carbon index 876227509c6b..81c818fc8a4a 100644 --- a/toolchain/semantics/testdata/basics/fail_name_lookup.carbon +++ b/toolchain/semantics/testdata/basics/fail_name_lookup.carbon @@ -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, diff --git a/toolchain/semantics/testdata/basics/verbose.carbon b/toolchain/semantics/testdata/basics/verbose.carbon index db82f2ec75b5..8fdbef83c6f8 100644 --- a/toolchain/semantics/testdata/basics/verbose.carbon +++ b/toolchain/semantics/testdata/basics/verbose.carbon @@ -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 -// CHECK:STDERR: AddNode block0: {kind: BindName, arg0: str0, arg1: node4} +// CHECK:STDERR: Node Push 0: FunctionIntroducer -> +// CHECK:STDERR: AddNode block{{[0-9]+}}: {kind: BindName, arg0: str{{[0-9]+}}, arg1: node{{[0-9]+}}} fn Foo() { return; diff --git a/toolchain/semantics/testdata/function/basic.carbon b/toolchain/semantics/testdata/function/basic.carbon index b884198e075f..4f2fc3260d87 100644 --- a/toolchain/semantics/testdata/function/basic.carbon +++ b/toolchain/semantics/testdata/function/basic.carbon @@ -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, diff --git a/toolchain/semantics/testdata/function/order.carbon b/toolchain/semantics/testdata/function/order.carbon index c23964583d75..da3c12efc682 100644 --- a/toolchain/semantics/testdata/function/order.carbon +++ b/toolchain/semantics/testdata/function/order.carbon @@ -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, diff --git a/toolchain/semantics/testdata/function/params_one.carbon b/toolchain/semantics/testdata/function/params_one.carbon new file mode 100644 index 000000000000..d7297b79451d --- /dev/null +++ b/toolchain/semantics/testdata/function/params_one.carbon @@ -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) {} diff --git a/toolchain/semantics/testdata/function/params_one_comma.carbon b/toolchain/semantics/testdata/function/params_one_comma.carbon new file mode 100644 index 000000000000..755180d27c23 --- /dev/null +++ b/toolchain/semantics/testdata/function/params_one_comma.carbon @@ -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,) {} diff --git a/toolchain/semantics/testdata/function/params_two.carbon b/toolchain/semantics/testdata/function/params_two.carbon new file mode 100644 index 000000000000..b25f1c896207 --- /dev/null +++ b/toolchain/semantics/testdata/function/params_two.carbon @@ -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) {} diff --git a/toolchain/semantics/testdata/function/params_two_comma.carbon b/toolchain/semantics/testdata/function/params_two_comma.carbon new file mode 100644 index 000000000000..c2184a7a93ed --- /dev/null +++ b/toolchain/semantics/testdata/function/params_two_comma.carbon @@ -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,) {} diff --git a/toolchain/semantics/testdata/operators/binary_op.carbon b/toolchain/semantics/testdata/operators/binary_op.carbon index 2f81f778877c..6a4a5a5baaf3 100644 --- a/toolchain/semantics/testdata/operators/binary_op.carbon +++ b/toolchain/semantics/testdata/operators/binary_op.carbon @@ -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, diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon index 6bb86cacd658..9e062a73a1d6 100644 --- a/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon @@ -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, diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon index 30dcf1a4881f..ced8a124b8e5 100644 --- a/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon @@ -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, diff --git a/toolchain/semantics/testdata/return/literal.carbon b/toolchain/semantics/testdata/return/literal.carbon index 0834fdb8d791..e4533ac08693 100644 --- a/toolchain/semantics/testdata/return/literal.carbon +++ b/toolchain/semantics/testdata/return/literal.carbon @@ -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, diff --git a/toolchain/semantics/testdata/return/trivial.carbon b/toolchain/semantics/testdata/return/trivial.carbon index aa7c4ee4ab85..dd6bc37b57cf 100644 --- a/toolchain/semantics/testdata/return/trivial.carbon +++ b/toolchain/semantics/testdata/return/trivial.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/decl.carbon b/toolchain/semantics/testdata/var/decl.carbon index 1944d25271bc..66d1e6839ab7 100644 --- a/toolchain/semantics/testdata/var/decl.carbon +++ b/toolchain/semantics/testdata/var/decl.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/decl_with_init.carbon b/toolchain/semantics/testdata/var/decl_with_init.carbon index ed7a475d4283..6908c8a4faae 100644 --- a/toolchain/semantics/testdata/var/decl_with_init.carbon +++ b/toolchain/semantics/testdata/var/decl_with_init.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/fail_duplicate_decl.carbon b/toolchain/semantics/testdata/var/fail_duplicate_decl.carbon index 04c7f0e117b8..5bcdb3e13d20 100644 --- a/toolchain/semantics/testdata/var/fail_duplicate_decl.carbon +++ b/toolchain/semantics/testdata/var/fail_duplicate_decl.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/fail_init_type_mismatch.carbon b/toolchain/semantics/testdata/var/fail_init_type_mismatch.carbon index e95be47a7890..ba84a916be47 100644 --- a/toolchain/semantics/testdata/var/fail_init_type_mismatch.carbon +++ b/toolchain/semantics/testdata/var/fail_init_type_mismatch.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/fail_init_with_self.carbon b/toolchain/semantics/testdata/var/fail_init_with_self.carbon index 9f306343e580..8db9d0b946a9 100644 --- a/toolchain/semantics/testdata/var/fail_init_with_self.carbon +++ b/toolchain/semantics/testdata/var/fail_init_with_self.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/fail_lookup_outside_scope.carbon b/toolchain/semantics/testdata/var/fail_lookup_outside_scope.carbon index de366416f1f4..27948ec26b26 100644 --- a/toolchain/semantics/testdata/var/fail_lookup_outside_scope.carbon +++ b/toolchain/semantics/testdata/var/fail_lookup_outside_scope.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/global_decl.carbon b/toolchain/semantics/testdata/var/global_decl.carbon index fa6666cb5675..6f3f219912d3 100644 --- a/toolchain/semantics/testdata/var/global_decl.carbon +++ b/toolchain/semantics/testdata/var/global_decl.carbon @@ -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: ], diff --git a/toolchain/semantics/testdata/var/global_decl_with_init.carbon b/toolchain/semantics/testdata/var/global_decl_with_init.carbon index 1c91d6814550..ab160301b08c 100644 --- a/toolchain/semantics/testdata/var/global_decl_with_init.carbon +++ b/toolchain/semantics/testdata/var/global_decl_with_init.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/global_lookup.carbon b/toolchain/semantics/testdata/var/global_lookup.carbon index 3dd8aeb035e0..4ee8a4bf7784 100644 --- a/toolchain/semantics/testdata/var/global_lookup.carbon +++ b/toolchain/semantics/testdata/var/global_lookup.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon b/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon index b2054e320ac1..0642b0710a62 100644 --- a/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon +++ b/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon @@ -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, diff --git a/toolchain/semantics/testdata/var/lookup.carbon b/toolchain/semantics/testdata/var/lookup.carbon index 26a3e5d1b8ca..1233b7758546 100644 --- a/toolchain/semantics/testdata/var/lookup.carbon +++ b/toolchain/semantics/testdata/var/lookup.carbon @@ -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,