context.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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_CHECK_CONTEXT_H_
  5. #define CARBON_TOOLCHAIN_CHECK_CONTEXT_H_
  6. #include "llvm/ADT/DenseMap.h"
  7. #include "llvm/ADT/DenseSet.h"
  8. #include "llvm/ADT/FoldingSet.h"
  9. #include "llvm/ADT/SmallVector.h"
  10. #include "toolchain/check/decl_name_stack.h"
  11. #include "toolchain/check/inst_block_stack.h"
  12. #include "toolchain/check/node_stack.h"
  13. #include "toolchain/parse/tree.h"
  14. #include "toolchain/sem_ir/file.h"
  15. #include "toolchain/sem_ir/ids.h"
  16. #include "toolchain/sem_ir/inst.h"
  17. namespace Carbon::Check {
  18. // Context and shared functionality for semantics handlers.
  19. class Context {
  20. public:
  21. using DiagnosticEmitter = Carbon::DiagnosticEmitter<Parse::Node>;
  22. using DiagnosticBuilder = DiagnosticEmitter::DiagnosticBuilder;
  23. // A scope in which `break` and `continue` can be used.
  24. struct BreakContinueScope {
  25. SemIR::InstBlockId break_target;
  26. SemIR::InstBlockId continue_target;
  27. };
  28. // A scope in which `return` can be used.
  29. struct ReturnScope {
  30. // The declaration from which we can return. Inside a function, this will
  31. // be a `FunctionDecl`.
  32. SemIR::InstId decl_id;
  33. // The value corresponding to the current `returned var`, if any. Will be
  34. // set and unset as `returned var`s are declared and go out of scope.
  35. SemIR::InstId returned_var = SemIR::InstId::Invalid;
  36. };
  37. // Stores references for work.
  38. explicit Context(const Lex::TokenizedBuffer& tokens,
  39. DiagnosticEmitter& emitter, const Parse::Tree& parse_tree,
  40. SemIR::File& semantics, llvm::raw_ostream* vlog_stream);
  41. // Marks an implementation TODO. Always returns false.
  42. auto TODO(Parse::Node parse_node, std::string label) -> bool;
  43. // Runs verification that the processing cleanly finished.
  44. auto VerifyOnFinish() -> void;
  45. // Adds an instruction to the current block, returning the produced ID.
  46. auto AddInst(SemIR::Inst inst) -> SemIR::InstId;
  47. // Adds an instruction to the constants block, returning the produced ID.
  48. auto AddConstantInst(SemIR::Inst inst) -> SemIR::InstId;
  49. // Pushes a parse tree node onto the stack, storing the SemIR::Inst as the
  50. // result.
  51. auto AddInstAndPush(Parse::Node parse_node, SemIR::Inst inst) -> void;
  52. // Adds a package's imports to name lookup, with all libraries together.
  53. // sem_irs will all be non-null; has_load_error must be used for any errors.
  54. auto AddPackageImports(Parse::Node import_node, IdentifierId package_id,
  55. llvm::ArrayRef<const SemIR::File*> sem_irs,
  56. bool has_load_error) -> void;
  57. // Adds a name to name lookup. Prints a diagnostic for name conflicts.
  58. auto AddNameToLookup(Parse::Node name_node, SemIR::NameId name_id,
  59. SemIR::InstId target_id) -> void;
  60. // Performs name lookup in a specified scope for a name appearing in a
  61. // declaration, returning the referenced instruction. If scope_id is invalid,
  62. // uses the current contextual scope.
  63. auto LookupNameInDecl(Parse::Node parse_node, SemIR::NameId name_id,
  64. SemIR::NameScopeId scope_id) -> SemIR::InstId;
  65. // Performs an unqualified name lookup, returning the referenced instruction.
  66. auto LookupUnqualifiedName(Parse::Node parse_node, SemIR::NameId name_id)
  67. -> SemIR::InstId;
  68. // Performs a qualified name lookup in a specified scope and in scopes that
  69. // it extends, returning the referenced instruction.
  70. auto LookupQualifiedName(Parse::Node parse_node, SemIR::NameId name_id,
  71. SemIR::NameScopeId scope_id, bool required = true)
  72. -> SemIR::InstId;
  73. // Prints a diagnostic for a duplicate name.
  74. auto DiagnoseDuplicateName(Parse::Node parse_node, SemIR::InstId prev_def_id)
  75. -> void;
  76. // Prints a diagnostic for a missing name.
  77. auto DiagnoseNameNotFound(Parse::Node parse_node, SemIR::NameId name_id)
  78. -> void;
  79. // Adds a note to a diagnostic explaining that a class is incomplete.
  80. auto NoteIncompleteClass(SemIR::ClassId class_id, DiagnosticBuilder& builder)
  81. -> void;
  82. // Pushes a new scope onto scope_stack_.
  83. auto PushScope(SemIR::InstId scope_inst_id = SemIR::InstId::Invalid,
  84. SemIR::NameScopeId scope_id = SemIR::NameScopeId::Invalid)
  85. -> void;
  86. // Pops the top scope from scope_stack_, cleaning up names from name_lookup_.
  87. auto PopScope() -> void;
  88. // Pops scopes until we return to the specified scope index.
  89. auto PopToScope(ScopeIndex index) -> void;
  90. // Returns the scope index associated with the current scope.
  91. auto current_scope_index() const -> ScopeIndex {
  92. return current_scope().index;
  93. }
  94. // Returns the name scope associated with the current lexical scope, if any.
  95. auto current_scope_id() const -> SemIR::NameScopeId {
  96. return current_scope().scope_id;
  97. }
  98. // Returns the current scope, if it is of the specified kind. Otherwise,
  99. // returns nullopt.
  100. template <typename InstT>
  101. auto GetCurrentScopeAs() -> std::optional<InstT> {
  102. auto current_scope_inst_id = current_scope().scope_inst_id;
  103. if (!current_scope_inst_id.is_valid()) {
  104. return std::nullopt;
  105. }
  106. return insts().Get(current_scope_inst_id).TryAs<InstT>();
  107. }
  108. // If there is no `returned var` in scope, sets the given instruction to be
  109. // the current `returned var` and returns an invalid instruction ID. If there
  110. // is already a `returned var`, returns it instead.
  111. auto SetReturnedVarOrGetExisting(SemIR::InstId bind_id) -> SemIR::InstId;
  112. // Follows NameRef instructions to find the value named by a given
  113. // instruction.
  114. auto FollowNameRefs(SemIR::InstId inst_id) -> SemIR::InstId;
  115. // Gets the constant value of the given instruction, if it has one.
  116. auto GetConstantValue(SemIR::InstId inst_id) -> SemIR::InstId;
  117. // Adds a `Branch` instruction branching to a new instruction block, and
  118. // returns the ID of the new block. All paths to the branch target must go
  119. // through the current block, though not necessarily through this branch.
  120. auto AddDominatedBlockAndBranch(Parse::Node parse_node) -> SemIR::InstBlockId;
  121. // Adds a `Branch` instruction branching to a new instruction block with a
  122. // value, and returns the ID of the new block. All paths to the branch target
  123. // must go through the current block.
  124. auto AddDominatedBlockAndBranchWithArg(Parse::Node parse_node,
  125. SemIR::InstId arg_id)
  126. -> SemIR::InstBlockId;
  127. // Adds a `BranchIf` instruction branching to a new instruction block, and
  128. // returns the ID of the new block. All paths to the branch target must go
  129. // through the current block.
  130. auto AddDominatedBlockAndBranchIf(Parse::Node parse_node,
  131. SemIR::InstId cond_id)
  132. -> SemIR::InstBlockId;
  133. // Handles recovergence of control flow. Adds branches from the top
  134. // `num_blocks` on the instruction block stack to a new block, pops the
  135. // existing blocks, and pushes the new block onto the instruction block stack.
  136. auto AddConvergenceBlockAndPush(Parse::Node parse_node, int num_blocks)
  137. -> void;
  138. // Handles recovergence of control flow with a result value. Adds branches
  139. // from the top few blocks on the instruction block stack to a new block, pops
  140. // the existing blocks, and pushes the new block onto the instruction block
  141. // stack. The number of blocks popped is the size of `block_args`, and the
  142. // corresponding result values are the elements of `block_args`. Returns an
  143. // instruction referring to the result value.
  144. auto AddConvergenceBlockWithArgAndPush(
  145. Parse::Node parse_node,
  146. std::initializer_list<SemIR::InstId> blocks_and_args) -> SemIR::InstId;
  147. // Add the current code block to the enclosing function.
  148. // TODO: The parse_node is taken for expressions, which can occur in
  149. // non-function contexts. This should be refactored to support non-function
  150. // contexts, and parse_node removed.
  151. auto AddCurrentCodeBlockToFunction(
  152. Parse::Node parse_node = Parse::Node::Invalid) -> void;
  153. // Returns whether the current position in the current block is reachable.
  154. auto is_current_position_reachable() -> bool;
  155. // Canonicalizes a type which is tracked as a single instruction.
  156. auto CanonicalizeType(SemIR::InstId inst_id) -> SemIR::TypeId;
  157. // Handles canonicalization of struct types. This may create a new struct type
  158. // when it has a new structure, or reference an existing struct type when it
  159. // duplicates a prior type.
  160. //
  161. // Individual struct type fields aren't canonicalized because they may have
  162. // name conflicts or other diagnostics during creation, which can use the
  163. // parse node.
  164. auto CanonicalizeStructType(Parse::Node parse_node,
  165. SemIR::InstBlockId refs_id) -> SemIR::TypeId;
  166. // Handles canonicalization of tuple types. This may create a new tuple type
  167. // if the `type_ids` doesn't match an existing tuple type.
  168. auto CanonicalizeTupleType(Parse::Node parse_node,
  169. llvm::ArrayRef<SemIR::TypeId> type_ids)
  170. -> SemIR::TypeId;
  171. // Attempts to complete the type `type_id`. Returns `true` if the type is
  172. // complete, or `false` if it could not be completed. A complete type has
  173. // known object and value representations.
  174. //
  175. // If the type is not complete, `diagnoser` is invoked to diagnose the issue.
  176. // The builder it returns will be annotated to describe the reason why the
  177. // type is not complete.
  178. auto TryToCompleteType(
  179. SemIR::TypeId type_id,
  180. std::optional<llvm::function_ref<auto()->DiagnosticBuilder>> diagnoser =
  181. std::nullopt) -> bool;
  182. // Gets a builtin type. The returned type will be complete.
  183. auto GetBuiltinType(SemIR::BuiltinKind kind) -> SemIR::TypeId;
  184. // Returns a pointer type whose pointee type is `pointee_type_id`.
  185. auto GetPointerType(Parse::Node parse_node, SemIR::TypeId pointee_type_id)
  186. -> SemIR::TypeId;
  187. // Removes any top-level `const` qualifiers from a type.
  188. auto GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId;
  189. // Starts handling parameters or arguments.
  190. auto ParamOrArgStart() -> void;
  191. // On a comma, pushes the entry. On return, the top of node_stack_ will be
  192. // start_kind.
  193. auto ParamOrArgComma() -> void;
  194. // Detects whether there's an entry to push from the end of a parameter or
  195. // argument list, and if so, moves it to the current parameter or argument
  196. // list. Does not pop the list. `start_kind` is the node kind at the start
  197. // of the parameter or argument list, and will be at the top of the parse node
  198. // stack when this function returns.
  199. auto ParamOrArgEndNoPop(Parse::NodeKind start_kind) -> void;
  200. // Pops the current parameter or argument list. Should only be called after
  201. // `ParamOrArgEndNoPop`.
  202. auto ParamOrArgPop() -> SemIR::InstBlockId;
  203. // Detects whether there's an entry to push. Pops and returns the argument
  204. // list. This is the same as `ParamOrArgEndNoPop` followed by `ParamOrArgPop`.
  205. auto ParamOrArgEnd(Parse::NodeKind start_kind) -> SemIR::InstBlockId;
  206. // Saves a parameter from the top block in node_stack_ to the top block in
  207. // params_or_args_stack_.
  208. auto ParamOrArgSave(SemIR::InstId inst_id) -> void {
  209. params_or_args_stack_.AddInstId(inst_id);
  210. }
  211. // Prints information for a stack dump.
  212. auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
  213. auto tokens() -> const Lex::TokenizedBuffer& { return *tokens_; }
  214. auto emitter() -> DiagnosticEmitter& { return *emitter_; }
  215. auto parse_tree() -> const Parse::Tree& { return *parse_tree_; }
  216. auto sem_ir() -> SemIR::File& { return *sem_ir_; }
  217. auto node_stack() -> NodeStack& { return node_stack_; }
  218. auto inst_block_stack() -> InstBlockStack& { return inst_block_stack_; }
  219. auto params_or_args_stack() -> InstBlockStack& {
  220. return params_or_args_stack_;
  221. }
  222. auto args_type_info_stack() -> InstBlockStack& {
  223. return args_type_info_stack_;
  224. }
  225. auto return_scope_stack() -> llvm::SmallVector<ReturnScope>& {
  226. return return_scope_stack_;
  227. }
  228. auto break_continue_stack() -> llvm::SmallVector<BreakContinueScope>& {
  229. return break_continue_stack_;
  230. }
  231. auto decl_name_stack() -> DeclNameStack& { return decl_name_stack_; }
  232. // Directly expose SemIR::File data accessors for brevity in calls.
  233. auto identifiers() -> StringStoreWrapper<IdentifierId>& {
  234. return sem_ir().identifiers();
  235. }
  236. auto integers() -> ValueStore<IntegerId>& { return sem_ir().integers(); }
  237. auto reals() -> ValueStore<RealId>& { return sem_ir().reals(); }
  238. auto string_literals() -> StringStoreWrapper<StringLiteralId>& {
  239. return sem_ir().string_literals();
  240. }
  241. auto functions() -> ValueStore<SemIR::FunctionId, SemIR::Function>& {
  242. return sem_ir().functions();
  243. }
  244. auto classes() -> ValueStore<SemIR::ClassId, SemIR::Class>& {
  245. return sem_ir().classes();
  246. }
  247. auto cross_ref_irs() -> ValueStore<SemIR::CrossRefIRId, const SemIR::File*>& {
  248. return sem_ir().cross_ref_irs();
  249. }
  250. auto names() -> SemIR::NameStoreWrapper { return sem_ir().names(); }
  251. auto name_scopes() -> SemIR::NameScopeStore& {
  252. return sem_ir().name_scopes();
  253. }
  254. auto types() -> ValueStore<SemIR::TypeId, SemIR::TypeInfo>& {
  255. return sem_ir().types();
  256. }
  257. auto type_blocks()
  258. -> SemIR::BlockValueStore<SemIR::TypeBlockId, SemIR::TypeId>& {
  259. return sem_ir().type_blocks();
  260. }
  261. auto insts() -> SemIR::InstStore& { return sem_ir().insts(); }
  262. auto inst_blocks() -> SemIR::InstBlockStore& {
  263. return sem_ir().inst_blocks();
  264. }
  265. auto constants() -> SemIR::ConstantStore& { return sem_ir().constants(); }
  266. private:
  267. // A FoldingSet node for a type.
  268. class TypeNode : public llvm::FastFoldingSetNode {
  269. public:
  270. explicit TypeNode(const llvm::FoldingSetNodeID& node_id,
  271. SemIR::TypeId type_id)
  272. : llvm::FastFoldingSetNode(node_id), type_id_(type_id) {}
  273. auto type_id() -> SemIR::TypeId { return type_id_; }
  274. private:
  275. SemIR::TypeId type_id_;
  276. };
  277. // An entry in scope_stack_.
  278. struct ScopeStackEntry {
  279. // The sequential index of this scope entry within the file.
  280. ScopeIndex index;
  281. // The instruction associated with this entry, if any. This can be one of:
  282. //
  283. // - A `ClassDecl`, for a class definition scope.
  284. // - A `FunctionDecl`, for the outermost scope in a function
  285. // definition.
  286. // - Invalid, for any other scope.
  287. SemIR::InstId scope_inst_id;
  288. // The name scope associated with this entry, if any.
  289. SemIR::NameScopeId scope_id;
  290. // Names which are registered with name_lookup_, and will need to be
  291. // unregistered when the scope ends.
  292. llvm::DenseSet<SemIR::NameId> names;
  293. // Whether a `returned var` was introduced in this scope, and needs to be
  294. // unregistered when the scope ends.
  295. bool has_returned_var = false;
  296. // TODO: This likely needs to track things which need to be destructed.
  297. };
  298. // A lookup result in the lexical lookup table `name_lookup_`.
  299. struct LexicalLookupResult {
  300. // The node that was added to lookup.
  301. SemIR::InstId node_id;
  302. // The scope in which the node was added.
  303. ScopeIndex scope_index;
  304. };
  305. // Forms a canonical type ID for a type. This function is given two
  306. // callbacks:
  307. //
  308. // `profile_type(canonical_id)` is called to build a fingerprint for this
  309. // type. The ID should be distinct for all distinct type values with the same
  310. // `kind`.
  311. //
  312. // `make_inst()` is called to obtain a `SemIR::InstId` that describes the
  313. // type. It is only called if the type does not already exist, so can be used
  314. // to lazily build the `SemIR::Inst`. `make_inst()` is not permitted to
  315. // directly or indirectly canonicalize any types.
  316. auto CanonicalizeTypeImpl(
  317. SemIR::InstKind kind,
  318. llvm::function_ref<bool(llvm::FoldingSetNodeID& canonical_id)>
  319. profile_type,
  320. llvm::function_ref<SemIR::InstId()> make_inst) -> SemIR::TypeId;
  321. // Forms a canonical type ID for a type. If the type is new, adds the
  322. // instruction to the current block.
  323. auto CanonicalizeTypeAndAddInstIfNew(SemIR::Inst inst) -> SemIR::TypeId;
  324. auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); }
  325. auto current_scope() const -> const ScopeStackEntry& {
  326. return scope_stack_.back();
  327. }
  328. // Tokens for getting data on literals.
  329. const Lex::TokenizedBuffer* tokens_;
  330. // Handles diagnostics.
  331. DiagnosticEmitter* emitter_;
  332. // The file's parse tree.
  333. const Parse::Tree* parse_tree_;
  334. // The SemIR::File being added to.
  335. SemIR::File* sem_ir_;
  336. // Whether to print verbose output.
  337. llvm::raw_ostream* vlog_stream_;
  338. // The stack during Build. Will contain file-level parse nodes on return.
  339. NodeStack node_stack_;
  340. // The stack of instruction blocks being used for general IR generation.
  341. InstBlockStack inst_block_stack_;
  342. // The stack of instruction blocks being used for per-element tracking of
  343. // instructions in parameter and argument instruction blocks. Versus
  344. // inst_block_stack_, an element will have 1 or more instructions in blocks in
  345. // inst_block_stack_, but only ever 1 instruction in blocks here.
  346. InstBlockStack params_or_args_stack_;
  347. // The stack of instruction blocks being used for type information while
  348. // processing arguments. This is used in parallel with params_or_args_stack_.
  349. // It's currently only used for struct literals, where we need to track names
  350. // for a type separate from the literal arguments.
  351. InstBlockStack args_type_info_stack_;
  352. // A stack of scopes from which we can `return`.
  353. llvm::SmallVector<ReturnScope> return_scope_stack_;
  354. // A stack of `break` and `continue` targets.
  355. llvm::SmallVector<BreakContinueScope> break_continue_stack_;
  356. // A stack for scope context.
  357. llvm::SmallVector<ScopeStackEntry> scope_stack_;
  358. // Information about non-lexical scopes. This is a subset of the entries and
  359. // the information in scope_stack_.
  360. llvm::SmallVector<std::pair<ScopeIndex, SemIR::NameScopeId>>
  361. non_lexical_scope_stack_;
  362. // The index of the next scope that will be pushed onto scope_stack_.
  363. ScopeIndex next_scope_index_ = ScopeIndex(0);
  364. // The stack used for qualified declaration name construction.
  365. DeclNameStack decl_name_stack_;
  366. // Maps identifiers to name lookup results. Values are a stack of name lookup
  367. // results in the ancestor scopes. This offers constant-time lookup of names,
  368. // regardless of how many scopes exist between the name declaration and
  369. // reference. The corresponding scope for each lookup result is tracked, so
  370. // that lexical lookup results can be interleaved with lookup results from
  371. // non-lexical scopes such as classes.
  372. //
  373. // Names which no longer have lookup results are erased.
  374. llvm::DenseMap<SemIR::NameId, llvm::SmallVector<LexicalLookupResult>>
  375. name_lookup_;
  376. // Cache of the mapping from instructions to types, to avoid recomputing the
  377. // folding set ID.
  378. llvm::DenseMap<SemIR::InstId, SemIR::TypeId> canonical_types_;
  379. // Tracks the canonical representation of types that have been defined.
  380. llvm::FoldingSet<TypeNode> canonical_type_nodes_;
  381. // Storage for the nodes in canonical_type_nodes_. This stores in pointers so
  382. // that FoldingSet can have stable pointers.
  383. llvm::SmallVector<std::unique_ptr<TypeNode>> type_node_storage_;
  384. };
  385. // Parse node handlers. Returns false for unrecoverable errors.
  386. #define CARBON_PARSE_NODE_KIND(Name) \
  387. auto Handle##Name(Context& context, Parse::Node parse_node)->bool;
  388. #include "toolchain/parse/node_kind.def"
  389. } // namespace Carbon::Check
  390. #endif // CARBON_TOOLCHAIN_CHECK_CONTEXT_H_