entity_with_params_base.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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_SEM_IR_ENTITY_WITH_PARAMS_BASE_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_ENTITY_WITH_PARAMS_BASE_H_
  6. #include "toolchain/sem_ir/ids.h"
  7. namespace Carbon::SemIR {
  8. // Common entity fields.
  9. //
  10. // `EntityWithParamsBase` would be a base class of entities like `Function`,
  11. // except that then we couldn't use named initialization (or would need to
  12. // disable warnings about mixing named and unnamed initialization) due to how
  13. // C++ handles initialization of base structs. Instead, this is composed with a
  14. // `Fields` struct to provide an entity's actual struct.
  15. //
  16. // For example:
  17. // struct FunctionFields {
  18. // ... data members ...
  19. // };
  20. //
  21. // struct Function : public EntityWithParamsBase,
  22. // public FunctionFields, public Printable<Function> {
  23. // ... methods ...
  24. // };
  25. //
  26. // This achieves a few things:
  27. // - Allows named initialization, such as:
  28. // `{{.name_id = ...}, {.function_field = ...}}`
  29. // - Makes `entity.name_id` access work.
  30. // - Allows passing a `EntityWithParamsBase*` when only common fields are
  31. // needed.
  32. // - Does all this in a way that's vanilla C++.
  33. struct EntityWithParamsBase {
  34. auto PrintBaseFields(llvm::raw_ostream& out) const -> void {
  35. out << "name: " << name_id << ", parent_scope: " << parent_scope_id;
  36. }
  37. // When merging a declaration and definition, prefer things which would point
  38. // at the definition for diagnostics.
  39. auto MergeDefinition(const EntityWithParamsBase& definition) -> void {
  40. first_param_node_id = definition.first_param_node_id;
  41. last_param_node_id = definition.last_param_node_id;
  42. pattern_block_id = definition.pattern_block_id;
  43. implicit_param_patterns_id = definition.implicit_param_patterns_id;
  44. param_patterns_id = definition.param_patterns_id;
  45. call_params_id = definition.call_params_id;
  46. definition_id = definition.definition_id;
  47. }
  48. // Determines whether the definition of this entity has begun. This is false
  49. // until we reach the `{` of the definition.
  50. auto has_definition_started() const -> bool {
  51. return definition_id.has_value();
  52. }
  53. // Returns the instruction for the first declaration.
  54. auto first_decl_id() const -> SemIR::InstId {
  55. if (non_owning_decl_id.has_value()) {
  56. return non_owning_decl_id;
  57. }
  58. CARBON_CHECK(first_owning_decl_id.has_value());
  59. return first_owning_decl_id;
  60. }
  61. // Returns the instruction for the latest declaration.
  62. auto latest_decl_id() const -> SemIR::InstId {
  63. if (has_definition_started()) {
  64. return definition_id;
  65. }
  66. if (first_owning_decl_id.has_value()) {
  67. return first_owning_decl_id;
  68. }
  69. return non_owning_decl_id;
  70. }
  71. // Determines whether this entity has any parameter lists.
  72. auto has_parameters() const -> bool {
  73. return implicit_param_patterns_id.has_value() ||
  74. param_patterns_id.has_value();
  75. }
  76. // The following members always have values, and do not change throughout the
  77. // lifetime of the entity.
  78. // The entity's name.
  79. NameId name_id;
  80. // The parent scope.
  81. NameScopeId parent_scope_id;
  82. // If this is a generic entity, information about the generic.
  83. GenericId generic_id;
  84. // Parse tree bounds for the parameters, including both implicit and explicit
  85. // parameters. These will be compared to match between declaration and
  86. // definition.
  87. Parse::NodeId first_param_node_id;
  88. Parse::NodeId last_param_node_id;
  89. // A block containing the pattern insts for the parameter lists.
  90. InstBlockId pattern_block_id;
  91. // A block containing, for each implicit parameter, a reference to the
  92. // instruction in the entity's pattern block that depends on all other
  93. // pattern insts pertaining to that parameter.
  94. InstBlockId implicit_param_patterns_id;
  95. // A block containing, for each explicit parameter, a reference to the
  96. // instruction in the entity's pattern block that depends on all other
  97. // pattern insts pertaining to that parameter.
  98. InstBlockId param_patterns_id;
  99. // If this entity is a function, this block consists of references to the
  100. // `AnyParam` insts that represent the function's `Call` parameters. The
  101. // "`Call` parameters" are the parameters corresponding to the arguments that
  102. // are passed to a `Call` inst, so they do not include compile-time
  103. // parameters, but they do include the return slot.
  104. //
  105. // The parameters appear in declaration order: `self` (if present), then the
  106. // explicit runtime parameters, then the return slot (which is "declared" by
  107. // the function's return type declaration). This is not populated on imported
  108. // functions, because it is relevant only for a function definition.
  109. //
  110. // TODO: Can this be moved to `Function`, since it is not applicable to other
  111. // kinds of entities?
  112. InstBlockId call_params_id;
  113. // True if declarations are `extern`.
  114. bool is_extern;
  115. // For an `extern library` declaration, the library name.
  116. SemIR::LibraryNameId extern_library_id;
  117. // The non-owning declaration of the entity, if present. This will be a
  118. // <entity>Decl.
  119. InstId non_owning_decl_id;
  120. // The first owning declaration of the entity, if present. This will be a
  121. // <entity>Decl. It may either be a forward declaration, or the same as
  122. // `definition_id`.
  123. InstId first_owning_decl_id;
  124. // The following members are set at the `{` of the definition.
  125. // The definition of the entity. This will be a <entity>Decl.
  126. InstId definition_id = InstId::None;
  127. };
  128. } // namespace Carbon::SemIR
  129. #endif // CARBON_TOOLCHAIN_SEM_IR_ENTITY_WITH_PARAMS_BASE_H_