// 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_CHECK_DEFERRED_DEFINITION_SCOPE_H_ #define CARBON_TOOLCHAIN_CHECK_DEFERRED_DEFINITION_SCOPE_H_ #include "common/array_stack.h" #include "toolchain/check/scope_stack.h" #include "toolchain/sem_ir/inst.h" namespace Carbon::Check { // A thunk that has been declared but not yet defined. // // This type is large, so moves of this type should be avoided. struct PendingThunk : public MoveOnly { SemIR::FunctionId signature_id; SemIR::FunctionId function_id; SemIR::InstId decl_id; SemIR::InstId callee_id; ScopeStack::SuspendedScope scope; }; // A stack of the current non-nested deferred definition scopes. For example, in // this code: // // class A { // class B { // fn F() { // class C { // // ... // } // } // } // } // // ... we have two non-nested deferred definition scopes: one for class A, and // one for class C. The scope for class B is nested, so is not tracked. // // At the end of each such scope, pending function definitions for functions // defined inline are processed. At this location, we also generate bodies for // thunks generated by checking. class DeferredDefinitionScopeStack { public: // Push a new scope. auto Push() -> void { pending_thunks_.PushArray(); } // Pop a scope. auto Pop() -> void { pending_thunks_.PopArray(); } // Add a pending thunk definition for the current scope. auto AddPendingThunk(PendingThunk&& thunk) -> void { pending_thunks_.AppendToTop(std::move(thunk)); } // Peek the list of pending thunks in this scope. auto PeekPendingThunks() -> llvm::MutableArrayRef { return pending_thunks_.PeekArray(); } private: ArrayStack pending_thunks_; }; } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_DEFERRED_DEFINITION_SCOPE_H_