class.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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::ImportIRInstId prev_import_ir_inst_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. // TODO: Check that the generic parameter list agrees with the prior
  16. // declaration.
  17. CheckIsAllowedRedecl(context, Lex::TokenKind::Class, prev_class.name_id,
  18. {.loc = new_loc,
  19. .is_definition = new_is_definition,
  20. .is_extern = new_is_extern},
  21. {.loc = prev_loc,
  22. .is_definition = prev_class.is_defined(),
  23. .is_extern = prev_is_extern},
  24. prev_import_ir_inst_id);
  25. // The introducer kind must match the previous declaration.
  26. // TODO: The rule here is not yet decided. See #3384.
  27. if (prev_class.inheritance_kind != new_class.inheritance_kind) {
  28. CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducer, Error,
  29. "Class redeclared with different inheritance kind.");
  30. CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducerPrevious, Note,
  31. "Previously declared here.");
  32. context.emitter()
  33. .Build(new_loc, ClassRedeclarationDifferentIntroducer)
  34. .Note(prev_loc, ClassRedeclarationDifferentIntroducerPrevious)
  35. .Emit();
  36. }
  37. if (new_is_definition) {
  38. prev_class.definition_id = new_class.definition_id;
  39. prev_class.scope_id = new_class.scope_id;
  40. prev_class.body_block_id = new_class.body_block_id;
  41. prev_class.adapt_id = new_class.adapt_id;
  42. prev_class.base_id = new_class.base_id;
  43. prev_class.object_repr_id = new_class.object_repr_id;
  44. }
  45. if ((prev_import_ir_inst_id.is_valid() && !new_is_import) ||
  46. (prev_is_extern && !new_is_extern)) {
  47. prev_class.decl_id = new_class.decl_id;
  48. ReplacePrevInstForMerge(
  49. context, prev_class.enclosing_scope_id, prev_class.name_id,
  50. new_is_import ? new_loc.inst_id : new_class.decl_id);
  51. }
  52. return true;
  53. }
  54. } // namespace Carbon::Check