| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- // 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/check/context.h"
- #include <string>
- #include <utility>
- #include "common/check.h"
- #include "toolchain/base/kind_switch.h"
- #include "toolchain/check/deferred_definition_worklist.h"
- #include "toolchain/sem_ir/ids.h"
- namespace Carbon::Check {
- Context::Context(DiagnosticEmitterBase* emitter,
- Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter,
- SemIR::File* sem_ir, int imported_ir_count, int total_ir_count,
- llvm::raw_ostream* vlog_stream)
- : emitter_(emitter),
- tree_and_subtrees_getter_(tree_and_subtrees_getter),
- sem_ir_(sem_ir),
- total_ir_count_(total_ir_count),
- vlog_stream_(vlog_stream),
- node_stack_(sem_ir->parse_tree(), vlog_stream),
- inst_block_stack_("inst_block_stack_", *sem_ir, vlog_stream),
- pattern_block_stack_("pattern_block_stack_", *sem_ir, vlog_stream),
- param_and_arg_refs_stack_(*sem_ir, vlog_stream, node_stack_),
- args_type_info_stack_("args_type_info_stack_", *sem_ir, vlog_stream),
- decl_name_stack_(this),
- scope_stack_(sem_ir_),
- deferred_definition_worklist_(vlog_stream),
- vtable_stack_("vtable_stack_", *sem_ir, vlog_stream),
- check_ir_map_(FixedSizeValueStore<SemIR::CheckIRId, SemIR::ImportIRId>::
- MakeWithExplicitSize(IdTag(), total_ir_count_,
- SemIR::ImportIRId::None)),
- global_init_(this),
- region_stack_([this](SemIR::LocId loc_id, std::string label) {
- TODO(loc_id, label);
- }),
- core_identifiers_(&identifiers()) {
- // Prepare fields which relate to the number of IRs available for import.
- import_irs().Reserve(imported_ir_count);
- import_ir_constant_values_.reserve(imported_ir_count);
- }
- auto Context::TODO(SemIR::LocId loc_id, std::string label) -> bool {
- CARBON_DIAGNOSTIC(SemanticsTodo, Error, "semantics TODO: `{0}`", std::string);
- emitter_->Emit(loc_id, SemanticsTodo, std::move(label));
- return false;
- }
- auto Context::TODO(SemIR::InstId loc_inst_id, std::string label) -> bool {
- return TODO(SemIR::LocId(loc_inst_id), label);
- }
- auto Context::VerifyOnFinish() const -> void {
- // Information in all the various context objects should be cleaned up as
- // various pieces of context go out of scope. At this point, nothing should
- // remain, so we verify stacks are empty. `node_stack_` is an exception
- // because it ends containing all top-level entities.
- inst_block_stack_.VerifyOnFinish();
- pattern_block_stack_.VerifyOnFinish();
- param_and_arg_refs_stack_.VerifyOnFinish();
- args_type_info_stack_.VerifyOnFinish();
- CARBON_CHECK(struct_type_fields_stack_.empty());
- CARBON_CHECK(field_decls_stack_.empty());
- decl_name_stack_.VerifyOnFinish();
- decl_introducer_state_stack_.VerifyOnFinish();
- scope_stack_.VerifyOnFinish();
- generic_region_stack_.VerifyOnFinish();
- vtable_stack_.VerifyOnFinish();
- region_stack_.VerifyOnFinish();
- CARBON_CHECK(impl_lookup_stack_.empty());
- CARBON_CHECK(return_type_inst_id_ == std::nullopt);
- #ifndef NDEBUG
- if (auto verify = sem_ir_->Verify(); !verify.ok()) {
- CARBON_FATAL("{0}Built invalid semantics IR: {1}\n", sem_ir_,
- verify.error());
- }
- if (!sem_ir_->has_errors()) {
- auto ref_tags_needed = sem_ir_->CollectRefTagsNeeded();
- ref_tags_.ForEach([&ref_tags_needed](SemIR::InstId inst_id, RefTag kind) {
- CARBON_CHECK(
- ref_tags_needed.Erase(inst_id) || kind == RefTag::NotRequired,
- "Inst has unnecessary `ref` tag: {0}", inst_id);
- });
- ref_tags_needed.ForEach([this](SemIR::InstId inst_id) {
- CARBON_FATAL("Inst missing `ref` tag: {0}", insts().Get(inst_id));
- });
- }
- #endif
- }
- auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void {
- output << "Check::Context\n";
- // In a stack dump, this is probably indented by a tab. We treat that as 8
- // spaces then add a couple to indent past the Context label.
- constexpr int Indent = 10;
- output.indent(Indent);
- output << "filename: " << tokens().source().filename() << "\n";
- node_stack_.PrintForStackDump(Indent, output);
- inst_block_stack_.PrintForStackDump(Indent, output);
- pattern_block_stack_.PrintForStackDump(Indent, output);
- param_and_arg_refs_stack_.PrintForStackDump(Indent, output);
- args_type_info_stack_.PrintForStackDump(Indent, output);
- }
- } // namespace Carbon::Check
|