generic.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. #include "toolchain/check/generic.h"
  5. #include "toolchain/sem_ir/ids.h"
  6. namespace Carbon::Check {
  7. auto StartGenericDecl(Context& /*context*/) -> void {
  8. // TODO: Start tracking the contents of this declaration.
  9. }
  10. auto StartGenericDefinition(Context& /*context*/,
  11. SemIR::GenericId /*generic_id*/) -> void {
  12. // TODO: Start tracking the contents of this definition.
  13. }
  14. auto FinishGenericDecl(Context& context, SemIR::InstId decl_id)
  15. -> SemIR::GenericId {
  16. if (context.scope_stack().compile_time_binding_stack().empty()) {
  17. return SemIR::GenericId::Invalid;
  18. }
  19. auto bindings_id = context.inst_blocks().Add(
  20. context.scope_stack().compile_time_binding_stack());
  21. return context.generics().Add(
  22. SemIR::Generic{.decl_id = decl_id, .bindings_id = bindings_id});
  23. }
  24. auto FinishGenericRedecl(Context& /*context*/, SemIR::InstId /*decl_id*/,
  25. SemIR::GenericId /*generic_id*/) -> void {
  26. // TODO: Compare contents of this declaration with the existing one on the
  27. // generic.
  28. }
  29. auto FinishGenericDefinition(Context& /*context*/,
  30. SemIR::GenericId /*generic_id*/) -> void {
  31. // TODO: Track contents of this generic definition.
  32. }
  33. auto MakeGenericInstance(Context& context, SemIR::GenericId generic_id,
  34. SemIR::InstBlockId args_id)
  35. -> SemIR::GenericInstanceId {
  36. auto instance_id = context.generic_instances().GetOrAdd(generic_id, args_id);
  37. // TODO: Perform substitution into the generic declaration if needed.
  38. return instance_id;
  39. }
  40. auto MakeGenericSelfInstance(Context& context, SemIR::GenericId generic_id)
  41. -> SemIR::GenericInstanceId {
  42. // TODO: Remove this once we import generics properly.
  43. if (!generic_id.is_valid()) {
  44. return SemIR::GenericInstanceId::Invalid;
  45. }
  46. auto& generic = context.generics().Get(generic_id);
  47. auto args = context.inst_blocks().Get(generic.bindings_id);
  48. // Form a canonical argument list for the generic.
  49. llvm::SmallVector<SemIR::InstId> arg_ids;
  50. arg_ids.reserve(args.size());
  51. for (auto arg_id : args) {
  52. arg_ids.push_back(context.constant_values().GetConstantInstId(arg_id));
  53. }
  54. auto args_id = context.inst_blocks().AddCanonical(arg_ids);
  55. // Build a corresponding instance.
  56. // TODO: This could be made more efficient. We don't need to perform
  57. // substitution here; we know we want identity mappings for all constants and
  58. // types. We could also consider not storing the mapping at all in this case.
  59. return MakeGenericInstance(context, generic_id, args_id);
  60. }
  61. } // namespace Carbon::Check