-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial, extern-ignoring support for extern class decls. (#3891)
This doesn't actually track whether a declaration is `extern`. It does, however: - Factor out and expand merge support for classes, sharing handling with functions. - This makes the ClassRedefinition diagnostic redundant, as the redeclaration checking overlaps. - Add partial `extern` handling to class handling; just some verifications of correct use. - Factor out `extern` on member handling for sharing with `fn`. - Fixes a bug in import_ref where a class's definition_id wasn't assigned when defining. This changes how a redefinition is handled (replaced, rather than merged). I don't know whether that's ideal, but I think it results in easy-to-understand consequences, and it's more consistent with how `fn` works. There's enough work here that this felt like a decent cut point, particularly as the amount of work to actually add `extern` tracking will be significant.
- Loading branch information
Showing
16 changed files
with
1,109 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM | ||
// Exceptions. See /LICENSE for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include "toolchain/check/class.h" | ||
|
||
#include "toolchain/check/merge.h" | ||
|
||
namespace Carbon::Check { | ||
|
||
auto MergeClassRedecl(Context& context, SemIRLoc new_loc, | ||
SemIR::Class& new_class, bool /*new_is_import*/, | ||
bool new_is_definition, bool new_is_extern, | ||
SemIR::ClassId prev_class_id, bool prev_is_extern, | ||
SemIR::ImportIRInstId prev_import_ir_inst_id) -> bool { | ||
auto& prev_class = context.classes().Get(prev_class_id); | ||
SemIRLoc prev_loc = | ||
prev_class.is_defined() ? prev_class.definition_id : prev_class.decl_id; | ||
|
||
// TODO: Check that the generic parameter list agrees with the prior | ||
// declaration. | ||
|
||
CheckIsAllowedRedecl(context, Lex::TokenKind::Class, prev_class.name_id, | ||
{.loc = new_loc, | ||
.is_definition = new_is_definition, | ||
.is_extern = new_is_extern}, | ||
{.loc = prev_loc, | ||
.is_definition = prev_class.is_defined(), | ||
.is_extern = prev_is_extern}, | ||
prev_import_ir_inst_id); | ||
|
||
// The introducer kind must match the previous declaration. | ||
// TODO: The rule here is not yet decided. See #3384. | ||
if (prev_class.inheritance_kind != new_class.inheritance_kind) { | ||
CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducer, Error, | ||
"Class redeclared with different inheritance kind."); | ||
CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducerPrevious, Note, | ||
"Previously declared here."); | ||
context.emitter() | ||
.Build(new_loc, ClassRedeclarationDifferentIntroducer) | ||
.Note(prev_loc, ClassRedeclarationDifferentIntroducerPrevious) | ||
.Emit(); | ||
} | ||
|
||
if (new_is_definition) { | ||
prev_class.definition_id = new_class.definition_id; | ||
prev_class.scope_id = new_class.scope_id; | ||
prev_class.body_block_id = new_class.body_block_id; | ||
prev_class.adapt_id = new_class.adapt_id; | ||
prev_class.base_id = new_class.base_id; | ||
prev_class.object_repr_id = new_class.object_repr_id; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} // namespace Carbon::Check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM | ||
// Exceptions. See /LICENSE for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#ifndef CARBON_TOOLCHAIN_CHECK_CLASS_H_ | ||
#define CARBON_TOOLCHAIN_CHECK_CLASS_H_ | ||
|
||
#include "toolchain/check/context.h" | ||
#include "toolchain/sem_ir/class.h" | ||
#include "toolchain/sem_ir/ids.h" | ||
|
||
namespace Carbon::Check { | ||
|
||
// Tries to merge new_class into prev_class_id. Since new_class won't have a | ||
// definition even if one is upcoming, set is_definition to indicate the planned | ||
// result. | ||
// | ||
// If merging is successful, returns true and may update the previous class. | ||
// Otherwise, returns false. Prints a diagnostic when appropriate. | ||
auto MergeClassRedecl(Context& context, SemIRLoc new_loc, | ||
SemIR::Class& new_class, bool new_is_import, | ||
bool new_is_definition, bool new_is_extern, | ||
SemIR::ClassId prev_class_id, bool prev_is_extern, | ||
SemIR::ImportIRInstId prev_import_ir_inst_id) -> bool; | ||
|
||
} // namespace Carbon::Check | ||
|
||
#endif // CARBON_TOOLCHAIN_CHECK_CLASS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.