mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Support for types (particularly classes) is left as a TODO. There's also an issue I'm observing with a "define in impl" test, but this is probably an issue with resolving the prior declaration which is imported indirectly. The PR was already feeling big, so I'm choosing to cut here. Note, this does not implement the rule "The owning library's API file must import the `extern` declaration, and must also contain a declaration."
102 lines
3.9 KiB
C++
102 lines
3.9 KiB
C++
// 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_MERGE_H_
|
|
#define CARBON_TOOLCHAIN_CHECK_MERGE_H_
|
|
|
|
#include "toolchain/check/context.h"
|
|
#include "toolchain/check/subst.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
// Information on new and previous declarations for CheckIsAllowedRedecl.
|
|
struct RedeclInfo {
|
|
explicit RedeclInfo(SemIR::EntityWithParamsBase params, SemIRLoc loc,
|
|
bool is_definition)
|
|
: loc(loc),
|
|
is_definition(is_definition),
|
|
is_extern(params.is_extern),
|
|
extern_library_id(params.extern_library_id) {}
|
|
|
|
// The associated diagnostic location.
|
|
SemIRLoc loc;
|
|
// True if a definition.
|
|
bool is_definition;
|
|
// True if an `extern` declaration.
|
|
bool is_extern;
|
|
// The library name in `extern library`, or invalid if not present.
|
|
SemIR::LibraryNameId extern_library_id;
|
|
};
|
|
|
|
// Checks if a redeclaration is allowed prior to merging. This may emit a
|
|
// diagnostic, but diagnostics do not prevent merging.
|
|
//
|
|
// The kinds of things this verifies are:
|
|
// - A declaration is not redundant.
|
|
// - A definition doesn't redefine a prior definition.
|
|
// - The use of `extern` is consistent within a library.
|
|
// - Multiple libraries do not declare non-`extern`.
|
|
auto CheckIsAllowedRedecl(Context& context, Lex::TokenKind decl_kind,
|
|
SemIR::NameId name_id, RedeclInfo new_decl,
|
|
RedeclInfo prev_decl,
|
|
SemIR::ImportIRId prev_import_ir_id) -> void;
|
|
|
|
// When the prior name lookup result is an import and we are successfully
|
|
// merging, replace the name lookup result with the reference in the current
|
|
// file.
|
|
auto ReplacePrevInstForMerge(Context& context, SemIR::NameScopeId scope_id,
|
|
SemIR::NameId name_id, SemIR::InstId new_inst_id)
|
|
-> void;
|
|
|
|
// Information about the parameters of a declaration, which is common across
|
|
// different kinds of entity such as classes and functions.
|
|
struct DeclParams {
|
|
explicit DeclParams(const SemIR::EntityWithParamsBase& base)
|
|
: loc(base.latest_decl_id()),
|
|
first_param_node_id(base.first_param_node_id),
|
|
last_param_node_id(base.last_param_node_id),
|
|
implicit_param_refs_id(base.implicit_param_refs_id),
|
|
param_refs_id(base.param_refs_id) {}
|
|
|
|
DeclParams(SemIRLoc loc, Parse::NodeId first_param_node_id,
|
|
Parse::NodeId last_param_node_id,
|
|
SemIR::InstBlockId implicit_params_id,
|
|
SemIR::InstBlockId params_id)
|
|
: loc(loc),
|
|
first_param_node_id(first_param_node_id),
|
|
last_param_node_id(last_param_node_id),
|
|
implicit_param_refs_id(implicit_params_id),
|
|
param_refs_id(params_id) {}
|
|
|
|
// The location of the declaration of the entity.
|
|
SemIRLoc loc;
|
|
|
|
// Parse tree bounds for the parameters, including both implicit and explicit
|
|
// parameters. These will be compared to match between declaration and
|
|
// definition.
|
|
Parse::NodeId first_param_node_id;
|
|
Parse::NodeId last_param_node_id;
|
|
|
|
// The implicit parameters of the entity. Can be Invalid if there is no
|
|
// implicit parameter list.
|
|
SemIR::InstBlockId implicit_param_refs_id;
|
|
// The explicit parameters of the entity. Can be Invalid if there is no
|
|
// explicit parameter list.
|
|
SemIR::InstBlockId param_refs_id;
|
|
};
|
|
|
|
// Checks that the parameters in a redeclaration of an entity match the
|
|
// parameters in the prior declaration. If not, produces a diagnostic and
|
|
// returns false.
|
|
auto CheckRedeclParamsMatch(
|
|
Context& context, const DeclParams& new_entity,
|
|
const DeclParams& prev_entity,
|
|
SemIR::SpecificId prev_specific_id = SemIR::SpecificId::Invalid,
|
|
bool check_syntax = true) -> bool;
|
|
|
|
} // namespace Carbon::Check
|
|
|
|
#endif // CARBON_TOOLCHAIN_CHECK_MERGE_H_
|