semantics_context.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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_CONTEXT_H_
  5. #define CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_CONTEXT_H_
  6. #include "llvm/ADT/DenseMap.h"
  7. #include "llvm/ADT/DenseSet.h"
  8. #include "llvm/ADT/SmallVector.h"
  9. #include "toolchain/parser/parse_tree.h"
  10. #include "toolchain/semantics/semantics_ir.h"
  11. #include "toolchain/semantics/semantics_node.h"
  12. #include "toolchain/semantics/semantics_node_block_stack.h"
  13. #include "toolchain/semantics/semantics_node_stack.h"
  14. namespace Carbon {
  15. // Context and shared functionality for semantics handlers.
  16. class SemanticsContext {
  17. public:
  18. // Stores references for work.
  19. explicit SemanticsContext(const TokenizedBuffer& tokens,
  20. DiagnosticEmitter<ParseTree::Node>& emitter,
  21. const ParseTree& parse_tree, SemanticsIR& semantics,
  22. llvm::raw_ostream* vlog_stream);
  23. // Marks an implementation TODO. Always returns false.
  24. auto TODO(ParseTree::Node parse_node, std::string label) -> bool;
  25. // Runs verification that the processing cleanly finished.
  26. auto VerifyOnFinish() -> void;
  27. // Adds a node to the current block, returning the produced ID.
  28. auto AddNode(SemanticsNode node) -> SemanticsNodeId;
  29. // Pushes a parse tree node onto the stack, storing the SemanticsNode as the
  30. // result.
  31. auto AddNodeAndPush(ParseTree::Node parse_node, SemanticsNode node) -> void;
  32. // Adds a name to name lookup.
  33. auto AddNameToLookup(ParseTree::Node name_node, SemanticsStringId name_id,
  34. SemanticsNodeId target_id) -> void;
  35. // Binds a DeclaredName to a target node with the given type.
  36. auto BindName(ParseTree::Node name_node, SemanticsNodeId type_id,
  37. SemanticsNodeId target_id) -> SemanticsStringId;
  38. // Temporarily remove name lookup entries added by the `var`. These will be
  39. // restored by `VariableDeclaration` using `ReaddNameToLookup`.
  40. auto TempRemoveLatestNameFromLookup() -> SemanticsNodeId;
  41. // Re-adds a name to name lookup. This is typically done through BindName, but
  42. // can also be used to restore removed names.
  43. auto ReaddNameToLookup(SemanticsStringId name_id, SemanticsNodeId storage_id)
  44. -> void {
  45. name_lookup_[name_id].push_back(storage_id);
  46. }
  47. // Lookup up a name, returning the referenced node.
  48. auto LookupName(ParseTree::Node parse_node, llvm::StringRef name)
  49. -> SemanticsNodeId;
  50. // Pushes a new scope onto scope_stack_.
  51. auto PushScope() -> void;
  52. // Pops the top scope from scope_stack_, cleaning up names from name_lookup_.
  53. auto PopScope() -> void;
  54. // Runs ImplicitAsImpl for a set of arguments and parameters.
  55. //
  56. // This will eventually need to support checking against multiple possible
  57. // overloads, multiple of which may be possible but not "best". While this can
  58. // currently be done by calling twice, toggling `apply_implicit_as`, in the
  59. // future we may want to remember the right implicit conversions to do for
  60. // valid cases in order to efficiently handle generics.
  61. auto ImplicitAsForArgs(
  62. SemanticsNodeBlockId arg_ir_id, SemanticsNodeBlockId arg_refs_id,
  63. ParseTree::Node param_parse_node, SemanticsNodeBlockId param_refs_id,
  64. DiagnosticEmitter<ParseTree::Node>::DiagnosticBuilder* diagnostic)
  65. -> bool;
  66. // Runs ImplicitAsImpl for a situation where a cast is required, returning the
  67. // updated `value_id`. Prints a diagnostic and returns an InvalidType if
  68. // unsupported.
  69. auto ImplicitAsRequired(ParseTree::Node parse_node, SemanticsNodeId value_id,
  70. SemanticsNodeId as_type_id) -> SemanticsNodeId;
  71. // Starts handling parameters or arguments.
  72. auto ParamOrArgStart() -> void;
  73. // On a comma, pushes the entry. On return, the top of node_stack_ will be
  74. // start_kind.
  75. auto ParamOrArgComma(bool for_args) -> void;
  76. // Detects whether there's an entry to push. On return, the top of
  77. // node_stack_ will be start_kind, and the caller should do type-specific
  78. // processing. Returns a pair of {ir_id, refs_id}.
  79. auto ParamOrArgEnd(bool for_args, ParseNodeKind start_kind)
  80. -> std::pair<SemanticsNodeBlockId, SemanticsNodeBlockId>;
  81. // Saves a parameter from the top block in node_stack_ to the top block in
  82. // params_or_args_stack_. If for_args, adds a StubReference of the previous
  83. // node's result to the IR.
  84. //
  85. // This should only be called by other ParamOrArg functions, not directly.
  86. auto ParamOrArgSave(bool for_args) -> void;
  87. // Prints information for a stack dump.
  88. auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
  89. auto tokens() -> const TokenizedBuffer& { return *tokens_; }
  90. auto emitter() -> DiagnosticEmitter<ParseTree::Node>& { return *emitter_; }
  91. auto parse_tree() -> const ParseTree& { return *parse_tree_; }
  92. auto semantics() -> SemanticsIR& { return *semantics_; }
  93. auto node_stack() -> SemanticsNodeStack& { return node_stack_; }
  94. auto node_block_stack() -> SemanticsNodeBlockStack& {
  95. return node_block_stack_;
  96. }
  97. auto args_type_info_stack() -> SemanticsNodeBlockStack& {
  98. return args_type_info_stack_;
  99. }
  100. auto finished_params_stack() -> llvm::SmallVector<
  101. std::pair<SemanticsNodeBlockId, SemanticsNodeBlockId>>& {
  102. return finished_params_stack_;
  103. }
  104. auto return_scope_stack() -> llvm::SmallVector<SemanticsNodeId>& {
  105. return return_scope_stack_;
  106. }
  107. private:
  108. // For CanImplicitAs, the detected conversion to apply.
  109. enum ImplicitAsKind {
  110. // Incompatible types.
  111. Incompatible,
  112. // No conversion required.
  113. Identical,
  114. // ImplicitAs is required.
  115. Compatible,
  116. };
  117. // Provides DenseMapInfo for SemanticsStringId.
  118. struct SemanticsStringIdMapInfo {
  119. static inline auto getEmptyKey() -> SemanticsStringId {
  120. return SemanticsStringId(llvm::DenseMapInfo<int32_t>::getEmptyKey());
  121. }
  122. static inline auto getTombstoneKey() -> SemanticsStringId {
  123. return SemanticsStringId(llvm::DenseMapInfo<int32_t>::getTombstoneKey());
  124. }
  125. static auto getHashValue(const SemanticsStringId& val) -> unsigned {
  126. return llvm::DenseMapInfo<int32_t>::getHashValue(val.index);
  127. }
  128. static auto isEqual(const SemanticsStringId& lhs,
  129. const SemanticsStringId& rhs) -> bool {
  130. return lhs == rhs;
  131. }
  132. };
  133. // An entry in scope_stack_.
  134. struct ScopeStackEntry {
  135. // Names which are registered with name_lookup_, and will need to be
  136. // deregistered when the scope ends.
  137. llvm::DenseSet<SemanticsStringId, SemanticsStringIdMapInfo> names;
  138. // TODO: This likely needs to track things which need to be destructed.
  139. };
  140. // Runs ImplicitAs behavior to convert `value` to `as_type`, returning the
  141. // result type. The result will be the node to use to replace `value`.
  142. //
  143. // If `output_value_id` is null, then this only checks if the conversion is
  144. // possible.
  145. //
  146. // If `output_value_id` is not null, then it will be set if there is a need to
  147. // cast.
  148. auto ImplicitAsImpl(SemanticsNodeId value_id, SemanticsNodeId as_type_id,
  149. SemanticsNodeId* output_value_id) -> ImplicitAsKind;
  150. // Returns true if the ImplicitAs can use struct conversion.
  151. // TODO: This currently only supports struct types that precisely match.
  152. auto CanImplicitAsStruct(SemanticsNode value_type, SemanticsNode as_type)
  153. -> bool;
  154. auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); }
  155. // Tokens for getting data on literals.
  156. const TokenizedBuffer* tokens_;
  157. // Handles diagnostics.
  158. DiagnosticEmitter<ParseTree::Node>* emitter_;
  159. // The file's parse tree.
  160. const ParseTree* parse_tree_;
  161. // The SemanticsIR being added to.
  162. SemanticsIR* semantics_;
  163. // Whether to print verbose output.
  164. llvm::raw_ostream* vlog_stream_;
  165. // The stack during Build. Will contain file-level parse nodes on return.
  166. SemanticsNodeStack node_stack_;
  167. // The stack of node blocks being used for general IR generation.
  168. SemanticsNodeBlockStack node_block_stack_;
  169. // The stack of node blocks being used for per-element tracking of nodes in
  170. // parameter and argument node blocks. Versus node_block_stack_, an element
  171. // will have 1 or more nodes in blocks in node_block_stack_, but only ever 1
  172. // node in blocks here.
  173. SemanticsNodeBlockStack params_or_args_stack_;
  174. // The stack of node blocks being used for type information while processing
  175. // arguments. This is used in parallel with params_or_args_stack_. It's
  176. // currently only used for struct literals, where we need to track names
  177. // for a type separate from the literal arguments.
  178. SemanticsNodeBlockStack args_type_info_stack_;
  179. // Completed parameters that are held temporarily on a side-channel for a
  180. // function. This can't use node_stack_ because it has space for only one
  181. // value, whereas parameters return two values.
  182. llvm::SmallVector<std::pair<SemanticsNodeBlockId, SemanticsNodeBlockId>>
  183. finished_params_stack_;
  184. // A stack of return scopes; i.e., targets for `return`. Inside a function,
  185. // this will be a FunctionDeclaration.
  186. llvm::SmallVector<SemanticsNodeId> return_scope_stack_;
  187. // A stack for scope context.
  188. llvm::SmallVector<ScopeStackEntry> scope_stack_;
  189. // Maps identifiers to name lookup results. Values are a stack of name lookup
  190. // results in the ancestor scopes. This offers constant-time lookup of names,
  191. // regardless of how many scopes exist between the name declaration and
  192. // reference.
  193. //
  194. // Names which no longer have lookup results are erased.
  195. llvm::DenseMap<SemanticsStringId, llvm::SmallVector<SemanticsNodeId>,
  196. SemanticsStringIdMapInfo>
  197. name_lookup_;
  198. };
  199. // Parse node handlers. Returns false for unrecoverable errors.
  200. #define CARBON_PARSE_NODE_KIND(Name) \
  201. auto SemanticsHandle##Name(SemanticsContext& context, \
  202. ParseTree::Node parse_node) \
  203. ->bool;
  204. #include "toolchain/parser/parse_node_kind.def"
  205. } // namespace Carbon
  206. #endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_CONTEXT_H_