semantics_ir_for_test.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_FOR_TEST_H_
  5. #define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_FOR_TEST_H_
  6. #include <gmock/gmock.h>
  7. #include <gtest/gtest.h>
  8. #include <sstream>
  9. #include "common/check.h"
  10. #include "llvm/ADT/StringExtras.h"
  11. #include "toolchain/semantics/nodes/infix_operator.h"
  12. #include "toolchain/semantics/semantics_ir.h"
  13. namespace Carbon::Testing {
  14. // A singleton SemanticsIR instance, used by the test helpers.
  15. //
  16. // This provides a singleton so that calls like PrintTo(Semantics::Declaration)
  17. // have a SemanticsIR to refer back to; PrintTo must be static.
  18. class SemanticsIRForTest {
  19. public:
  20. template <typename NodeT>
  21. static auto GetDeclaration(Semantics::Declaration decl)
  22. -> llvm::Optional<NodeT> {
  23. if (decl.kind() != NodeT::MetaNodeKind) {
  24. return llvm::None;
  25. }
  26. return semantics().declarations_.Get<NodeT>(decl);
  27. }
  28. template <typename NodeT>
  29. static auto GetExpression(Semantics::Expression expr)
  30. -> llvm::Optional<NodeT> {
  31. if (expr.kind() != NodeT::MetaNodeKind) {
  32. return llvm::None;
  33. }
  34. return semantics().expressions_.Get<NodeT>(expr);
  35. }
  36. template <typename NodeT>
  37. static auto GetStatement(Semantics::Statement expr) -> llvm::Optional<NodeT> {
  38. if (expr.kind() != NodeT::MetaNodeKind) {
  39. return llvm::None;
  40. }
  41. return semantics().statements_.Get<NodeT>(expr);
  42. }
  43. static auto GetNodeText(ParseTree::Node node) -> llvm::StringRef {
  44. return semantics().parse_tree_->GetNodeText(node);
  45. }
  46. template <typename PrintableT>
  47. static void PrintTo(const PrintableT& printable, std::ostream* out) {
  48. llvm::raw_os_ostream wrapped_out(*out);
  49. semantics().Print(wrapped_out, printable);
  50. }
  51. static auto semantics() -> const SemanticsIR& {
  52. CARBON_CHECK(g_semantics != llvm::None);
  53. return *g_semantics;
  54. }
  55. static void set_semantics(SemanticsIR semantics) {
  56. CARBON_CHECK(g_semantics == llvm::None)
  57. << "Call clear() before setting again.";
  58. g_semantics = std::move(semantics);
  59. }
  60. static void clear() { g_semantics = llvm::None; }
  61. private:
  62. static llvm::Optional<SemanticsIR> g_semantics;
  63. };
  64. } // namespace Carbon::Testing
  65. namespace Carbon::Semantics {
  66. // Meta node printers.
  67. inline void PrintTo(const Declaration& node, std::ostream* out) {
  68. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  69. }
  70. inline void PrintTo(const Expression& node, std::ostream* out) {
  71. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  72. }
  73. inline void PrintTo(const Statement& node, std::ostream* out) {
  74. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  75. }
  76. // Other node printers.
  77. inline void PrintTo(const DeclaredName& node, std::ostream* out) {
  78. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  79. }
  80. inline void PrintTo(const ExpressionStatement& node, std::ostream* out) {
  81. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  82. }
  83. inline void PrintTo(const Function& node, std::ostream* out) {
  84. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  85. }
  86. inline void PrintTo(const InfixOperator& node, std::ostream* out) {
  87. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  88. }
  89. inline void PrintTo(const Literal& node, std::ostream* out) {
  90. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  91. }
  92. inline void PrintTo(const PatternBinding& node, std::ostream* out) {
  93. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  94. }
  95. inline void PrintTo(const Return& node, std::ostream* out) {
  96. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  97. }
  98. inline void PrintTo(const StatementBlock& node, std::ostream* out) {
  99. Carbon::Testing::SemanticsIRForTest::PrintTo(node, out);
  100. }
  101. } // namespace Carbon::Semantics
  102. namespace llvm {
  103. // Prints a StringMapEntry for gmock.
  104. inline void PrintTo(
  105. const llvm::StringMapEntry<Carbon::Semantics::Declaration>& entry,
  106. std::ostream* out) {
  107. *out << "StringMapEntry(" << entry.getKey() << ", ";
  108. Carbon::Testing::SemanticsIRForTest::PrintTo(entry.getValue(), out);
  109. *out << ")";
  110. }
  111. // Prints a StringMapEntry for gmock.
  112. inline void PrintTo(
  113. const llvm::StringMapEntry<Carbon::Semantics::Statement>& entry,
  114. std::ostream* out) {
  115. *out << "StringMapEntry(" << entry.getKey() << ", ";
  116. Carbon::Testing::SemanticsIRForTest::PrintTo(entry.getValue(), out);
  117. *out << ")";
  118. }
  119. } // namespace llvm
  120. #endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_FOR_TEST_H_