generic_region_stack.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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_GENERIC_REGION_STACK_H_
  5. #define CARBON_TOOLCHAIN_CHECK_GENERIC_REGION_STACK_H_
  6. #include "common/array_stack.h"
  7. #include "llvm/ADT/BitmaskEnum.h"
  8. #include "toolchain/sem_ir/ids.h"
  9. namespace Carbon::Check {
  10. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
  11. // A stack of enclosing regions that might be declaring or defining a generic
  12. // entity. In such a region, we track the generic constructs that are used, such
  13. // as symbolic constants and types, and instructions that depend on a template
  14. // parameter.
  15. //
  16. // TODO: For now we're just tracking symbolic constants.
  17. //
  18. // We split a generic into two regions -- declaration and definition -- because
  19. // these are in general introduced separately, and substituted into separately.
  20. // For example, for `class C(T:! type, N:! T) { var x: T; }`, a use such as
  21. // `C(i32, 0)*` substitutes into just the declaration, whereas a use such as
  22. // `var x: C(i32, 0) = {.x = 0};` also substitutes into the definition.
  23. class GenericRegionStack {
  24. public:
  25. // Ways in which an instruction can depend on a generic parameter.
  26. enum class DependencyKind : int8_t {
  27. None = 0x0,
  28. // The type of the instruction depends on a checked generic parameter.
  29. SymbolicType = 0x1,
  30. // The constant value of the instruction depends on a checked generic
  31. // parameter.
  32. SymbolicConstant = 0x2,
  33. Template = 0x4,
  34. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Template)
  35. };
  36. // An instruction that depends on a generic parameter in some way.
  37. struct DependentInst {
  38. SemIR::InstId inst_id;
  39. DependencyKind kind;
  40. };
  41. // Pushes a region that might be declaring or defining a generic.
  42. auto Push() -> void;
  43. // Pops a generic region.
  44. auto Pop() -> void;
  45. // Adds an instruction to the list of instructions in the current region that
  46. // in some way depend on a generic parameter.
  47. auto AddDependentInst(DependentInst inst) -> void;
  48. // Returns the list of dependent instructions in the current generic region.
  49. auto PeekDependentInsts() -> llvm::ArrayRef<DependentInst>;
  50. private:
  51. // A stack of symbolic constants for enclosing generic regions.
  52. ArrayStack<DependentInst> dependent_insts_stack_;
  53. };
  54. } // namespace Carbon::Check
  55. #endif // CARBON_TOOLCHAIN_CHECK_GENERIC_REGION_STACK_H_