check.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. #include "common/check.h"
  5. #include "toolchain/base/pretty_stack_trace_function.h"
  6. #include "toolchain/check/context.h"
  7. #include "toolchain/parse/tree_node_location_translator.h"
  8. #include "toolchain/sem_ir/file.h"
  9. namespace Carbon::Check {
  10. auto CheckParseTree(const SemIR::File& builtin_ir,
  11. const Lex::TokenizedBuffer& tokens,
  12. const Parse::Tree& parse_tree, DiagnosticConsumer& consumer,
  13. llvm::raw_ostream* vlog_stream) -> SemIR::File {
  14. auto semantics_ir = SemIR::File(&builtin_ir);
  15. Parse::NodeLocationTranslator translator(&tokens, &parse_tree);
  16. ErrorTrackingDiagnosticConsumer err_tracker(consumer);
  17. DiagnosticEmitter<Parse::Node> emitter(translator, err_tracker);
  18. Check::Context context(tokens, emitter, parse_tree, semantics_ir,
  19. vlog_stream);
  20. PrettyStackTraceFunction context_dumper(
  21. [&](llvm::raw_ostream& output) { context.PrintForStackDump(output); });
  22. // Add a block for the Parse::Tree.
  23. context.node_block_stack().Push();
  24. context.PushScope();
  25. // Loops over all nodes in the tree. On some errors, this may return early,
  26. // for example if an unrecoverable state is encountered.
  27. for (auto parse_node : parse_tree.postorder()) {
  28. // clang warns on unhandled enum values; clang-tidy is incorrect here.
  29. // NOLINTNEXTLINE(bugprone-switch-missing-default-case)
  30. switch (auto parse_kind = parse_tree.node_kind(parse_node)) {
  31. #define CARBON_PARSE_NODE_KIND(Name) \
  32. case Parse::NodeKind::Name: { \
  33. if (!Check::Handle##Name(context, parse_node)) { \
  34. CARBON_CHECK(err_tracker.seen_error()) \
  35. << "Handle" #Name " returned false without printing a diagnostic"; \
  36. semantics_ir.set_has_errors(true); \
  37. return semantics_ir; \
  38. } \
  39. break; \
  40. }
  41. #include "toolchain/parse/node_kind.def"
  42. }
  43. }
  44. // Pop information for the file-level scope.
  45. semantics_ir.set_top_node_block_id(context.node_block_stack().Pop());
  46. context.PopScope();
  47. context.VerifyOnFinish();
  48. semantics_ir.set_has_errors(err_tracker.seen_error());
  49. #ifndef NDEBUG
  50. if (auto verify = semantics_ir.Verify(); !verify.ok()) {
  51. CARBON_FATAL() << semantics_ir
  52. << "Built invalid semantics IR: " << verify.error() << "\n";
  53. }
  54. #endif
  55. return semantics_ir;
  56. }
  57. } // namespace Carbon::Check