From c198dafbe87d59dd3782fa90b2769c47d84f07e0 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 3 Oct 2022 13:09:04 -0700 Subject: [PATCH] Switch semantics-ir tests to lit (#2224) This builds on semantics-ir lit support added by #2222 The googletest setup was feeling cumbersome, especially as I'm thinking about how to add more testing: I feel like I'm wrestling with the infrastructure. The `[[ID1]]` and so on in tests is one advantage of switching: it's easier to do matching of IDs for verification. This is also more agnostic about the numbers than before, something which I'm concerned will be important as I think about builtins. To explain my builtins thought, I think that needs to be another SemanticsIR with basically names pointing at builtin things. But this (a) creates multiple SemanticsIRs, which would confuse the current singleton approach and (b) starts creating more fluctuation for IDs, potentially impacting the numbers used (also, chandlerc's suggested pointers for some use-cases). Overall it felt like I was heading towards a situation with googletest where writing the tests would be really difficult, and it was adding to my hesitance to write more code in the toolchain. I'm hoping this acts as a simplification. Note, the "cp" commit has some incremental changes to googletest that I'd considered for making it easier to add matchers, but ultimately I ended up with this outcome. --- toolchain/semantics/BUILD | 40 ----- toolchain/semantics/nodes/binary_operator.h | 2 +- .../nodes/binary_operator_test_matchers.h | 39 ----- toolchain/semantics/nodes/function.h | 19 +- .../semantics/nodes/function_test_matchers.h | 35 ---- .../nodes/integer_literal_test_matchers.h | 34 ---- .../semantics/nodes/return_test_matchers.h | 33 ---- .../semantics/nodes/set_name_test_matchers.h | 35 ---- toolchain/semantics/nodes_test_matchers.h | 12 -- toolchain/semantics/semantics_ir.cpp | 27 ++- toolchain/semantics/semantics_ir.h | 6 +- .../semantics/semantics_ir_factory_test.cpp | 162 ------------------ toolchain/semantics/semantics_ir_for_test.h | 62 ------- .../semantics/semantics_ir_test_helpers.h | 28 --- .../empty.carbon} | 12 +- .../semantics/testdata/function/basic.carbon | 14 ++ .../semantics/testdata/function/order.carbon | 26 +++ toolchain/semantics/testdata/lit.cfg.py | 12 +- .../testdata/return/binary_op.carbon | 20 +++ .../semantics/testdata/return/literal.carbon | 18 ++ .../semantics/testdata/return/trivial.carbon | 17 ++ toolchain/semantics/testdata/zero.carbon | 12 -- 22 files changed, 146 insertions(+), 519 deletions(-) delete mode 100644 toolchain/semantics/nodes/binary_operator_test_matchers.h delete mode 100644 toolchain/semantics/nodes/function_test_matchers.h delete mode 100644 toolchain/semantics/nodes/integer_literal_test_matchers.h delete mode 100644 toolchain/semantics/nodes/return_test_matchers.h delete mode 100644 toolchain/semantics/nodes/set_name_test_matchers.h delete mode 100644 toolchain/semantics/nodes_test_matchers.h delete mode 100644 toolchain/semantics/semantics_ir_factory_test.cpp delete mode 100644 toolchain/semantics/semantics_ir_for_test.h delete mode 100644 toolchain/semantics/semantics_ir_test_helpers.h rename toolchain/semantics/{semantics_ir_for_test.cpp => testdata/empty.carbon} (51%) create mode 100644 toolchain/semantics/testdata/function/basic.carbon create mode 100644 toolchain/semantics/testdata/function/order.carbon create mode 100644 toolchain/semantics/testdata/return/binary_op.carbon create mode 100644 toolchain/semantics/testdata/return/literal.carbon create mode 100644 toolchain/semantics/testdata/return/trivial.carbon delete mode 100644 toolchain/semantics/testdata/zero.carbon diff --git a/toolchain/semantics/BUILD b/toolchain/semantics/BUILD index d87d8fa81a56..e358caac5f3b 100644 --- a/toolchain/semantics/BUILD +++ b/toolchain/semantics/BUILD @@ -67,43 +67,3 @@ cc_library( "@llvm-project//llvm:Support", ], ) - -cc_library( - name = "semantics_ir_test_helpers", - testonly = 1, - srcs = ["semantics_ir_for_test.cpp"], - hdrs = [ - "nodes/binary_operator_test_matchers.h", - "nodes/function_test_matchers.h", - "nodes/integer_literal_test_matchers.h", - "nodes/return_test_matchers.h", - "nodes/set_name_test_matchers.h", - "semantics_ir_for_test.h", - "semantics_ir_test_helpers.h", - ], - deps = [ - ":nodes", - ":semantics_ir", - "//common:check", - "//common:ostream", - "@com_google_googletest//:gtest", - "@llvm-project//llvm:Support", - ], -) - -cc_test( - name = "semantics_ir_factory_test", - size = "small", - srcs = ["semantics_ir_factory_test.cpp"], - deps = [ - ":semantics_ir_factory", - ":semantics_ir_test_helpers", - "//common:gtest_main", - "//toolchain/diagnostics:mocks", - "//toolchain/lexer:tokenized_buffer", - "//toolchain/parser:parse_tree", - "//toolchain/source:source_buffer", - "@com_google_googletest//:gtest", - "@llvm-project//llvm:Support", - ], -) diff --git a/toolchain/semantics/nodes/binary_operator.h b/toolchain/semantics/nodes/binary_operator.h index 6efda97547fc..81cd552832bd 100644 --- a/toolchain/semantics/nodes/binary_operator.h +++ b/toolchain/semantics/nodes/binary_operator.h @@ -31,7 +31,7 @@ class BinaryOperator { out << "+"; break; } - out << ", " << lhs_id_ << ", %" << rhs_id_ << ")"; + out << ", " << lhs_id_ << ", " << rhs_id_ << ")"; } auto node() const -> ParseTree::Node { return node_; } diff --git a/toolchain/semantics/nodes/binary_operator_test_matchers.h b/toolchain/semantics/nodes/binary_operator_test_matchers.h deleted file mode 100644 index 10a625cc28b1..000000000000 --- a/toolchain/semantics/nodes/binary_operator_test_matchers.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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_NODES_BINARY_OPERATOR_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_BINARY_OPERATOR_TEST_MATCHERS_H_ - -#include - -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/binary_operator.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -MATCHER_P4( - BinaryOperator, id_matcher, op_matcher, lhs_id_matcher, rhs_id_matcher, - llvm::formatv( - "BinaryOperator(`{0}`, `{1}`, `{2}`, `{3}`)", - ::testing::DescribeMatcher(id_matcher), - ::testing::DescribeMatcher(op_matcher), - ::testing::DescribeMatcher(lhs_id_matcher), - ::testing::DescribeMatcher(rhs_id_matcher))) { - const Semantics::NodeRef& node_ref = arg; - if (auto op = - SemanticsIRForTest::GetNode(node_ref)) { - return ExplainMatchResult(id_matcher, op->id(), result_listener) && - ExplainMatchResult(op_matcher, op->op(), result_listener) && - ExplainMatchResult(lhs_id_matcher, op->lhs_id(), result_listener) && - ExplainMatchResult(rhs_id_matcher, op->rhs_id(), result_listener); - } else { - *result_listener << "node is not a BinaryOperator"; - return result_listener; - } -} - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_BINARY_OPERATOR_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/nodes/function.h b/toolchain/semantics/nodes/function.h index c4906fa54e72..d053554dee8c 100644 --- a/toolchain/semantics/nodes/function.h +++ b/toolchain/semantics/nodes/function.h @@ -29,15 +29,16 @@ class Function { // return_expr_(return_expr), body_(std::move(body)) {} - void Print(llvm::raw_ostream& out, - std::function print_node_ref) const { - out << "Function(" << id_ << ", {"; - llvm::ListSeparator sep(", "); - for (auto& node_ref : body_) { - out << sep; - print_node_ref(node_ref); - } - out << "})"; + void Print( + llvm::raw_ostream& out, int indent, + std::function)> print_block) const { + out << "Function(\n"; + int content_intent = indent + 4; + out.indent(content_intent); + out << id_ << ",\n"; + out.indent(content_intent); + print_block(content_intent, body_); + out << ")"; } auto node() const -> ParseTree::Node { return node_; } diff --git a/toolchain/semantics/nodes/function_test_matchers.h b/toolchain/semantics/nodes/function_test_matchers.h deleted file mode 100644 index a14946b9ccf5..000000000000 --- a/toolchain/semantics/nodes/function_test_matchers.h +++ /dev/null @@ -1,35 +0,0 @@ -// 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_NODES_FUNCTION_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_FUNCTION_TEST_MATCHERS_H_ - -#include - -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/function.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -MATCHER_P2(Function, id_matcher, body_matcher, - llvm::formatv( - "Function(`{0}`, `{1}`)", - ::testing::DescribeMatcher(id_matcher), - ::testing::DescribeMatcher>( - body_matcher))) { - const Semantics::NodeRef& node_ref = arg; - if (auto function = - SemanticsIRForTest::GetNode(node_ref)) { - return ExplainMatchResult(id_matcher, function->id(), result_listener) && - ExplainMatchResult(body_matcher, function->body(), result_listener); - } else { - *result_listener << "node is not a Function"; - return result_listener; - } -} - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_FUNCTION_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/nodes/integer_literal_test_matchers.h b/toolchain/semantics/nodes/integer_literal_test_matchers.h deleted file mode 100644 index 34311c1771e6..000000000000 --- a/toolchain/semantics/nodes/integer_literal_test_matchers.h +++ /dev/null @@ -1,34 +0,0 @@ -// 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_NODES_INTEGER_LITERAL_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_INTEGER_LITERAL_TEST_MATCHERS_H_ - -#include - -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/integer_literal.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -MATCHER_P2( - IntegerLiteral, id_matcher, value_matcher, - llvm::formatv("IntegerLiteral(`{0}`, `{1}`)", - ::testing::DescribeMatcher(id_matcher), - ::testing::DescribeMatcher(value_matcher))) { - const Semantics::NodeRef& node_ref = arg; - if (auto lit = - SemanticsIRForTest::GetNode(node_ref)) { - return ExplainMatchResult(id_matcher, lit->id(), result_listener) && - ExplainMatchResult(value_matcher, lit->value(), result_listener); - } else { - *result_listener << "node is not a IntegerLiteral"; - return result_listener; - } -} - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_INTEGER_LITERAL_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/nodes/return_test_matchers.h b/toolchain/semantics/nodes/return_test_matchers.h deleted file mode 100644 index 773193732bad..000000000000 --- a/toolchain/semantics/nodes/return_test_matchers.h +++ /dev/null @@ -1,33 +0,0 @@ -// 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_NODES_RETURN_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_RETURN_TEST_MATCHERS_H_ - -#include - -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/return.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -MATCHER_P( - Return, target_id_matcher, - llvm::formatv("Return(`{0}`)", - ::testing::DescribeMatcher>( - target_id_matcher))) { - const Semantics::NodeRef& node_ref = arg; - if (auto ret = SemanticsIRForTest::GetNode(node_ref)) { - return ExplainMatchResult(target_id_matcher, ret->target_id(), - result_listener); - } else { - *result_listener << "node is not a Return"; - return result_listener; - } -} - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_RETURN_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/nodes/set_name_test_matchers.h b/toolchain/semantics/nodes/set_name_test_matchers.h deleted file mode 100644 index 48c5fdfd3557..000000000000 --- a/toolchain/semantics/nodes/set_name_test_matchers.h +++ /dev/null @@ -1,35 +0,0 @@ -// 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_NODES_SET_NAME_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_SET_NAME_TEST_MATCHERS_H_ - -#include - -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/set_name.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -MATCHER_P2( - SetName, name_matcher, target_id_matcher, - llvm::formatv( - "SetName(`{0}`, `{1}`)", - ::testing::DescribeMatcher(name_matcher), - ::testing::DescribeMatcher(target_id_matcher))) { - const Semantics::NodeRef& node_ref = arg; - if (auto node = SemanticsIRForTest::GetNode(node_ref)) { - return ExplainMatchResult(name_matcher, node->name(), result_listener) && - ExplainMatchResult(target_id_matcher, node->target_id(), - result_listener); - } else { - *result_listener << "node is not a SetName"; - return result_listener; - } -} - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_SET_NAME_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/nodes_test_matchers.h b/toolchain/semantics/nodes_test_matchers.h deleted file mode 100644 index 4777642d128f..000000000000 --- a/toolchain/semantics/nodes_test_matchers.h +++ /dev/null @@ -1,12 +0,0 @@ -// 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_NODES_TEST_MATCHERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_NODES_TEST_MATCHERS_H_ - -// This is a wrapper header that only aggregates all nodes into a single, common -// header so that the list is centralized. -#include "toolchain/semantics/nodes/function_test_matchers.h" - -#endif // CARBON_TOOLCHAIN_SEMANTICS_NODES_TEST_MATCHERS_H_ diff --git a/toolchain/semantics/semantics_ir.cpp b/toolchain/semantics/semantics_ir.cpp index 5490d2777c59..3cfe38ce927c 100644 --- a/toolchain/semantics/semantics_ir.cpp +++ b/toolchain/semantics/semantics_ir.cpp @@ -11,13 +11,25 @@ namespace Carbon { auto SemanticsIR::Print(llvm::raw_ostream& out) const -> void { - for (const auto& node_ref : root_block()) { - Print(out, node_ref); - out << "\n"; - } + PrintBlock(out, 0, root_block()); + out << "\n"; } -auto SemanticsIR::Print(llvm::raw_ostream& out, +auto SemanticsIR::PrintBlock(llvm::raw_ostream& out, int indent, + llvm::ArrayRef node_refs) const + -> void { + out << "{\n"; + int child_indent = indent + 2; + for (const auto& node_ref : node_refs) { + out.indent(child_indent); + Print(out, child_indent, node_ref); + out << ",\n"; + } + out.indent(indent); + out << "}"; +} + +auto SemanticsIR::Print(llvm::raw_ostream& out, int indent, Semantics::NodeRef node_ref) const -> void { switch (node_ref.kind()) { case Semantics::NodeKind::BinaryOperator: @@ -25,7 +37,10 @@ auto SemanticsIR::Print(llvm::raw_ostream& out, return; case Semantics::NodeKind::Function: nodes_.Get(node_ref).Print( - out, [&](Semantics::NodeRef other) { Print(out, other); }); + out, indent, + [&](int block_indent, llvm::ArrayRef block) { + PrintBlock(out, block_indent, block); + }); return; case Semantics::NodeKind::IntegerLiteral: nodes_.Get(node_ref).Print(out); diff --git a/toolchain/semantics/semantics_ir.h b/toolchain/semantics/semantics_ir.h index 768d835a6444..52ae2680b2c6 100644 --- a/toolchain/semantics/semantics_ir.h +++ b/toolchain/semantics/semantics_ir.h @@ -27,8 +27,12 @@ class SemanticsIR { // Prints the full IR. auto Print(llvm::raw_ostream& out) const -> void; + auto PrintBlock(llvm::raw_ostream& out, int indent, + llvm::ArrayRef node_refs) const -> void; + // Prints the node information. - auto Print(llvm::raw_ostream& out, Semantics::NodeRef node_ref) const -> void; + auto Print(llvm::raw_ostream& out, int indent, + Semantics::NodeRef node_ref) const -> void; private: friend class SemanticsIRFactory; diff --git a/toolchain/semantics/semantics_ir_factory_test.cpp b/toolchain/semantics/semantics_ir_factory_test.cpp deleted file mode 100644 index 6767182c9abd..000000000000 --- a/toolchain/semantics/semantics_ir_factory_test.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// 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_ir_factory.h" - -#include -#include - -#include "toolchain/diagnostics/mocks.h" -#include "toolchain/lexer/tokenized_buffer.h" -#include "toolchain/parser/parse_tree.h" -#include "toolchain/semantics/semantics_ir_test_helpers.h" -#include "toolchain/source/source_buffer.h" - -namespace Carbon::Testing { -namespace { - -using ::testing::_; -using ::testing::ElementsAre; -using ::testing::IsEmpty; -using ::testing::Optional; -using ::testing::StrEq; - -class SemanticsIRFactoryTest : public ::testing::Test { - protected: - void Build(llvm::Twine t) { - source_buffer.emplace(std::move(*SourceBuffer::CreateFromText(t))); - tokenized_buffer = TokenizedBuffer::Lex(*source_buffer, consumer); - EXPECT_FALSE(tokenized_buffer->has_errors()); - parse_tree = ParseTree::Parse(*tokenized_buffer, consumer); - EXPECT_FALSE(parse_tree->has_errors()); - SemanticsIRForTest::set_semantics( - SemanticsIRFactory::Build(*tokenized_buffer, *parse_tree)); - } - - ~SemanticsIRFactoryTest() override { SemanticsIRForTest::clear(); } - - auto root_block() const -> llvm::ArrayRef { - return SemanticsIRForTest::semantics().root_block(); - } - - llvm::Optional source_buffer; - llvm::Optional tokenized_buffer; - llvm::Optional parse_tree; - MockDiagnosticConsumer consumer; -}; - -/* -TEST_F(SemanticsIRFactoryTest, SimpleProgram) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(R"(// package FactoryTest api; - - fn Add(x: i32, y: i32) -> i32 { - return x + y; - } - - fn Main() -> i32 { - var x: i32 = Add(3, 10); - x *= 5; - return x; - } - )"); - EXPECT_THAT( - SemanticsIRForTest::semantics().root_block(), - ElementsAre(Function(Eq("Add"), - ElementsAre(PatternBinding(Eq("x"), Literal("i32")), - PatternBinding(Eq("y"), Literal("i32"))), - Optional(Literal("i32"))), - Function(Eq("Main"), IsEmpty(), Optional(Literal("i32"))))); -} -*/ - -TEST_F(SemanticsIRFactoryTest, Empty) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(""); - EXPECT_THAT(root_block(), IsEmpty()); -} - -TEST_F(SemanticsIRFactoryTest, FunctionBasic) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build("fn Foo() {}"); - EXPECT_THAT(root_block(), - ElementsAre(Function(0, IsEmpty()), SetName(StrEq("Foo"), 0))); -} - -/* -TEST_F(SemanticsIRFactoryTest, FunctionParams) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build("fn Foo(x: i32, y: i64) {}"); - ExpectRootBlock( - ElementsAre(Function(Eq("Foo"), - ElementsAre(PatternBinding(Eq("x"), Literal("i32")), - PatternBinding(Eq("y"), Literal("i64"))), - IsNone(), StatementBlock(IsEmpty(), IsEmpty()))), - UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo")))); -} -*/ - -/* -TEST_F(SemanticsIRFactoryTest, FunctionReturnType) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build("fn Foo() -> i32 {}"); - EXPECT_THAT(root_block(), ElementsAre(Function(0, IsEmpty()), - SetName(StrEq("Foo"), 0))); -} -*/ - -TEST_F(SemanticsIRFactoryTest, FunctionOrder) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(R"(fn Foo() {} - fn Bar() {} - fn Bar() {} - )"); - EXPECT_THAT(root_block(), - ElementsAre(Function(2, IsEmpty()), SetName(StrEq("Foo"), 2), - Function(1, IsEmpty()), SetName(StrEq("Bar"), 1), - Function(0, IsEmpty()), SetName(StrEq("Bar"), 0))); -} - -TEST_F(SemanticsIRFactoryTest, TrivialReturn) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(R"(fn Main() { - return; - } - )"); - EXPECT_THAT(root_block(), - ElementsAre(Function(0, ElementsAre(Return(IsNone()))), - SetName(StrEq("Main"), 0))); -} - -TEST_F(SemanticsIRFactoryTest, ReturnLiteral) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(R"(fn Main() { - return 12; - } - )"); - EXPECT_THAT(root_block(), - ElementsAre(Function(0, ElementsAre(IntegerLiteral(1, 12), - Return(Optional(1)))), - SetName(StrEq("Main"), 0))); -} - -TEST_F(SemanticsIRFactoryTest, ReturnArithmetic) { - EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0); - Build(R"(fn Main() { - return 12 + 34; - } - )"); - EXPECT_THAT( - root_block(), - ElementsAre( - Function(0, - ElementsAre(IntegerLiteral(3, 12), IntegerLiteral(2, 34), - BinaryOperator( - 1, Semantics::BinaryOperator::Op::Add, 3, 2), - Return(Optional(1)))), - SetName(StrEq("Main"), 0))); -} - -} // namespace -} // namespace Carbon::Testing diff --git a/toolchain/semantics/semantics_ir_for_test.h b/toolchain/semantics/semantics_ir_for_test.h deleted file mode 100644 index e1ff1df0e0dc..000000000000 --- a/toolchain/semantics/semantics_ir_for_test.h +++ /dev/null @@ -1,62 +0,0 @@ -// 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_IR_FOR_TEST_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_FOR_TEST_H_ - -#include -#include - -#include - -#include "common/check.h" -#include "llvm/ADT/StringExtras.h" -//#include "toolchain/semantics/nodes/infix_operator.h" -#include "toolchain/semantics/semantics_ir.h" - -namespace Carbon::Testing { - -// A singleton SemanticsIR instance, used by the test helpers. -// -// This provides a singleton so that calls like PrintTo(Semantics::Declaration) -// have a SemanticsIR to refer back to; PrintTo must be static. -class SemanticsIRForTest { - public: - template - static auto GetNode(Semantics::NodeRef node_ref) -> llvm::Optional { - if (node_ref.kind() != NodeT::Kind) { - return llvm::None; - } - return semantics().nodes_.Get(node_ref); - } - - static auto semantics() -> const SemanticsIR& { - CARBON_CHECK(g_semantics != llvm::None); - return *g_semantics; - } - - static void set_semantics(SemanticsIR semantics) { - CARBON_CHECK(g_semantics == llvm::None) - << "Call clear() before setting again."; - g_semantics = std::move(semantics); - } - - static void clear() { g_semantics = llvm::None; } - - private: - static llvm::Optional g_semantics; -}; - -} // namespace Carbon::Testing - -namespace Carbon::Semantics { - -inline void PrintTo(const NodeRef& node_ref, std::ostream* out) { - llvm::raw_os_ostream wrapped_out(*out); - Carbon::Testing::SemanticsIRForTest::semantics().Print(wrapped_out, node_ref); -} - -} // namespace Carbon::Semantics - -#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_FOR_TEST_H_ diff --git a/toolchain/semantics/semantics_ir_test_helpers.h b/toolchain/semantics/semantics_ir_test_helpers.h deleted file mode 100644 index 2b7e6511ae96..000000000000 --- a/toolchain/semantics/semantics_ir_test_helpers.h +++ /dev/null @@ -1,28 +0,0 @@ -// 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_IR_TEST_HELPERS_H_ -#define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_TEST_HELPERS_H_ - -#include -#include - -#include "common/check.h" -#include "common/ostream.h" -#include "llvm/ADT/StringExtras.h" -#include "toolchain/semantics/nodes/binary_operator_test_matchers.h" -#include "toolchain/semantics/nodes/function_test_matchers.h" -#include "toolchain/semantics/nodes/integer_literal_test_matchers.h" -#include "toolchain/semantics/nodes/return_test_matchers.h" -#include "toolchain/semantics/nodes/set_name_test_matchers.h" -#include "toolchain/semantics/semantics_ir_for_test.h" - -namespace Carbon::Testing { - -// Avoids gtest confusion of how to print llvm::None. -MATCHER(IsNone, "is llvm::None") { return arg == llvm::None; } - -} // namespace Carbon::Testing - -#endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_TEST_HELPERS_H_ diff --git a/toolchain/semantics/semantics_ir_for_test.cpp b/toolchain/semantics/testdata/empty.carbon similarity index 51% rename from toolchain/semantics/semantics_ir_for_test.cpp rename to toolchain/semantics/testdata/empty.carbon index 288ee1b6bcbb..5aac04177ef9 100644 --- a/toolchain/semantics/semantics_ir_for_test.cpp +++ b/toolchain/semantics/testdata/empty.carbon @@ -1,11 +1,7 @@ // 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_ir_for_test.h" - -namespace Carbon::Testing { - -llvm::Optional SemanticsIRForTest::g_semantics; - -} // namespace Carbon::Testing +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK:} diff --git a/toolchain/semantics/testdata/function/basic.carbon b/toolchain/semantics/testdata/function/basic.carbon new file mode 100644 index 000000000000..982a692ac806 --- /dev/null +++ b/toolchain/semantics/testdata/function/basic.carbon @@ -0,0 +1,14 @@ +// 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 +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK: Function( +// CHECK: %[[ID0:[0-9]+]], +// CHECK: { +// CHECK: }), +// CHECK: SetName(`Foo`, %[[ID0]]), +// CHECK:} + +fn Foo() {} diff --git a/toolchain/semantics/testdata/function/order.carbon b/toolchain/semantics/testdata/function/order.carbon new file mode 100644 index 000000000000..fc2124cbd2b4 --- /dev/null +++ b/toolchain/semantics/testdata/function/order.carbon @@ -0,0 +1,26 @@ +// 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 +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK: Function( +// CHECK: %[[ID0:[0-9]+]], +// CHECK: { +// CHECK: }), +// CHECK: SetName(`Foo`, %[[ID0]]), +// CHECK: Function( +// CHECK: %[[ID1:[0-9]+]], +// CHECK: { +// CHECK: }), +// CHECK: SetName(`Bar`, %[[ID1]]), +// CHECK: Function( +// CHECK: %[[ID2:[0-9]+]], +// CHECK: { +// CHECK: }), +// CHECK: SetName(`Baz`, %[[ID2]]), +// CHECK:} + +fn Foo() {} +fn Bar() {} +fn Baz() {} diff --git a/toolchain/semantics/testdata/lit.cfg.py b/toolchain/semantics/testdata/lit.cfg.py index e975c265d658..91efb7e33f98 100644 --- a/toolchain/semantics/testdata/lit.cfg.py +++ b/toolchain/semantics/testdata/lit.cfg.py @@ -29,7 +29,15 @@ config.substitutions.append( config.substitutions.append(("%{not}", fullpath("llvm-project/llvm/not"))) config.substitutions.append( ( - "%{FileCheck}", - fullpath("llvm-project/llvm/FileCheck --dump-input-filter=all"), + "%{FileCheckStrict}", + " ".join( + [ + fullpath("llvm-project/llvm/FileCheck"), + "--dump-input-filter=all", + "--implicit-check-not={{.}}", + "--match-full-lines", + "--strict-whitespace", + ] + ), ) ) diff --git a/toolchain/semantics/testdata/return/binary_op.carbon b/toolchain/semantics/testdata/return/binary_op.carbon new file mode 100644 index 000000000000..624d8d5d0d44 --- /dev/null +++ b/toolchain/semantics/testdata/return/binary_op.carbon @@ -0,0 +1,20 @@ +// 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 +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK: Function( +// CHECK: %[[ID0:[0-9]+]], +// CHECK: { +// CHECK: IntegerLiteral(%[[ID1:[0-9]+]], 12), +// CHECK: IntegerLiteral(%[[ID2:[0-9]+]], 34), +// CHECK: BinaryOperator(%[[ID3:[0-9]+]], +, %[[ID1]], %[[ID2]]), +// CHECK: Return(%[[ID3]]), +// CHECK: }), +// CHECK: SetName(`Main`, %[[ID0]]), +// CHECK:} + +fn Main() { + return 12 + 34; +} diff --git a/toolchain/semantics/testdata/return/literal.carbon b/toolchain/semantics/testdata/return/literal.carbon new file mode 100644 index 000000000000..e68b654a94ea --- /dev/null +++ b/toolchain/semantics/testdata/return/literal.carbon @@ -0,0 +1,18 @@ +// 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 +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK: Function( +// CHECK: %[[ID0:[0-9]+]], +// CHECK: { +// CHECK: IntegerLiteral(%[[ID1:[0-9]+]], 0), +// CHECK: Return(%[[ID1]]), +// CHECK: }), +// CHECK: SetName(`Main`, %[[ID0]]), +// CHECK:} + +fn Main() { + return 0; +} diff --git a/toolchain/semantics/testdata/return/trivial.carbon b/toolchain/semantics/testdata/return/trivial.carbon new file mode 100644 index 000000000000..222e0aa759eb --- /dev/null +++ b/toolchain/semantics/testdata/return/trivial.carbon @@ -0,0 +1,17 @@ +// 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 +// +// RUN: %{carbon} dump semantics-ir %s 2>&1 | %{FileCheckStrict} %s +// CHECK:{ +// CHECK: Function( +// CHECK: %[[ID0:[0-9]+]], +// CHECK: { +// CHECK: Return(None), +// CHECK: }), +// CHECK: SetName(`Main`, %[[ID0]]), +// CHECK:} + +fn Main() { + return; +} diff --git a/toolchain/semantics/testdata/zero.carbon b/toolchain/semantics/testdata/zero.carbon deleted file mode 100644 index bfdf815b12f3..000000000000 --- a/toolchain/semantics/testdata/zero.carbon +++ /dev/null @@ -1,12 +0,0 @@ -// 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 -// -// RUN: %{carbon} dump semantics-ir %s 2>&1 | \ -// RUN: %{FileCheck} --match-full-lines --allow-unused-prefixes=false %s -// CHECK: Function(%0, {IntegerLiteral(%1, 0), Return(%1)}) -// CHECK: SetName(`Main`, %0) - -fn Main() { - return 0; -}