class.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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/class.h"
  5. #include "toolchain/check/merge.h"
  6. namespace Carbon::Check {
  7. auto MergeClassRedecl(Context& context, SemIRLoc new_loc,
  8. SemIR::Class& new_class, bool new_is_import,
  9. bool new_is_definition, bool new_is_extern,
  10. SemIR::ClassId prev_class_id, bool prev_is_extern,
  11. SemIR::ImportIRId prev_import_ir_id) -> bool {
  12. auto& prev_class = context.classes().Get(prev_class_id);
  13. SemIRLoc prev_loc =
  14. prev_class.is_defined() ? prev_class.definition_id : prev_class.decl_id;
  15. // Check the generic parameters match, if they were specified.
  16. if (!CheckRedeclParamsMatch(context, DeclParams(new_class),
  17. DeclParams(prev_class), {})) {
  18. return false;
  19. }
  20. CheckIsAllowedRedecl(context, Lex::TokenKind::Class, prev_class.name_id,
  21. {.loc = new_loc,
  22. .is_definition = new_is_definition,
  23. .is_extern = new_is_extern},
  24. {.loc = prev_loc,
  25. .is_definition = prev_class.is_defined(),
  26. .is_extern = prev_is_extern},
  27. prev_import_ir_id);
  28. // The introducer kind must match the previous declaration.
  29. // TODO: The rule here is not yet decided. See #3384.
  30. if (prev_class.inheritance_kind != new_class.inheritance_kind) {
  31. CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducer, Error,
  32. "Class redeclared with different inheritance kind.");
  33. CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducerPrevious, Note,
  34. "Previously declared here.");
  35. context.emitter()
  36. .Build(new_loc, ClassRedeclarationDifferentIntroducer)
  37. .Note(prev_loc, ClassRedeclarationDifferentIntroducerPrevious)
  38. .Emit();
  39. }
  40. if (new_is_definition) {
  41. prev_class.implicit_param_refs_id = new_class.implicit_param_refs_id;
  42. prev_class.param_refs_id = new_class.param_refs_id;
  43. prev_class.definition_id = new_class.definition_id;
  44. prev_class.scope_id = new_class.scope_id;
  45. prev_class.body_block_id = new_class.body_block_id;
  46. prev_class.adapt_id = new_class.adapt_id;
  47. prev_class.base_id = new_class.base_id;
  48. prev_class.object_repr_id = new_class.object_repr_id;
  49. }
  50. if ((prev_import_ir_id.is_valid() && !new_is_import) ||
  51. (prev_is_extern && !new_is_extern)) {
  52. prev_class.decl_id = new_class.decl_id;
  53. ReplacePrevInstForMerge(
  54. context, prev_class.enclosing_scope_id, prev_class.name_id,
  55. new_is_import ? new_loc.inst_id : new_class.decl_id);
  56. }
  57. return true;
  58. }
  59. } // namespace Carbon::Check