mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 08:51:04 +01:00
Start adding extern logic for functions. (#3809)
This starts propagating is_extern on import, and warns when merging an imported non-extern declaration with a local non-extern declaration. Note this doesn't address import conflicts yet (i.e., two libraries define an equivalent name) because they don't call merge logic. On merge, I'm only setting values when new_is_definition because I think it better matches the comment and resulting behavior. Note I now set them even for bad redefinitions; I think this matches the comment, and there's not a perfect choice here. I could change the flow back if preferred. Note this puts a spotlight on invalid nodes on imported decls, which I think I'm going to need to address now. This isn't addressed by ImportRef logic directly because the Function's decl_id is a FunctionDecl, rather than the ImportRef that led to it. While I could add the ImportRef link to each decl, I think adjusting the associated NodeId is a better approach.
This commit is contained in:
@@ -165,14 +165,22 @@ static auto BuildFunctionDecl(Context& context,
|
||||
}
|
||||
|
||||
// Check whether this is a redeclaration.
|
||||
auto existing_id =
|
||||
auto prev_id =
|
||||
context.decl_name_stack().LookupOrAddName(name_context, lookup_result_id);
|
||||
if (existing_id.is_valid()) {
|
||||
if (auto existing_function_decl =
|
||||
context.insts().Get(existing_id).TryAs<SemIR::FunctionDecl>()) {
|
||||
if (MergeFunctionRedecl(context, node_id, function_info,
|
||||
if (prev_id.is_valid()) {
|
||||
auto prev_inst = context.insts().Get(prev_id);
|
||||
bool prev_is_import = false;
|
||||
|
||||
if (prev_inst.Is<SemIR::ImportRefUsed>()) {
|
||||
prev_inst =
|
||||
context.insts().Get(context.constant_values().Get(prev_id).inst_id());
|
||||
prev_is_import = true;
|
||||
}
|
||||
|
||||
if (auto existing_function_decl = prev_inst.TryAs<SemIR::FunctionDecl>()) {
|
||||
if (MergeFunctionRedecl(context, node_id, function_info, is_definition,
|
||||
existing_function_decl->function_id,
|
||||
is_definition)) {
|
||||
prev_is_import)) {
|
||||
// When merging, use the existing function rather than adding a new one.
|
||||
function_decl.function_id = existing_function_decl->function_id;
|
||||
}
|
||||
@@ -180,7 +188,7 @@ static auto BuildFunctionDecl(Context& context,
|
||||
// This is a redeclaration of something other than a function. This
|
||||
// includes the case where an associated function redeclares another
|
||||
// associated function.
|
||||
context.DiagnoseDuplicateName(function_info.decl_id, existing_id);
|
||||
context.DiagnoseDuplicateName(function_info.decl_id, prev_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user