mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:20:11 +01:00
Remove the SemIRLoc typedef (#5299)
Replace SemIRLoc typedef uses with explicitly SemIR::LocId, loc -> loc_id for consistency.
This commit is contained in:
@@ -25,17 +25,18 @@ Context::Context(DiagnosticEmitterBase* emitter,
|
||||
scope_stack_(sem_ir_),
|
||||
vtable_stack_("vtable_stack_", *sem_ir, vlog_stream),
|
||||
global_init_(this),
|
||||
region_stack_(
|
||||
[this](SemIRLoc loc, std::string label) { TODO(loc, label); }) {
|
||||
region_stack_([this](SemIR::LocId loc_id, std::string label) {
|
||||
TODO(loc_id, label);
|
||||
}) {
|
||||
// Prepare fields which relate to the number of IRs available for import.
|
||||
import_irs().Reserve(imported_ir_count);
|
||||
import_ir_constant_values_.reserve(imported_ir_count);
|
||||
check_ir_map_.resize(total_ir_count, SemIR::ImportIRId::None);
|
||||
}
|
||||
|
||||
auto Context::TODO(SemIRLoc loc, std::string label) -> bool {
|
||||
auto Context::TODO(SemIR::LocId loc_id, std::string label) -> bool {
|
||||
CARBON_DIAGNOSTIC(SemanticsTodo, Error, "semantics TODO: `{0}`", std::string);
|
||||
emitter_->Emit(loc, SemanticsTodo, std::move(label));
|
||||
emitter_->Emit(loc_id, SemanticsTodo, std::move(label));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class Context {
|
||||
int total_ir_count, llvm::raw_ostream* vlog_stream);
|
||||
|
||||
// Marks an implementation TODO. Always returns false.
|
||||
auto TODO(SemIRLoc loc, std::string label) -> bool;
|
||||
auto TODO(SemIR::LocId loc_id, std::string label) -> bool;
|
||||
|
||||
// Runs verification that the processing cleanly finished.
|
||||
auto VerifyOnFinish() const -> void;
|
||||
@@ -152,7 +152,7 @@ class Context {
|
||||
}
|
||||
|
||||
auto definitions_required_by_use()
|
||||
-> llvm::SmallVector<std::pair<SemIRLoc, SemIR::SpecificId>>& {
|
||||
-> llvm::SmallVector<std::pair<SemIR::LocId, SemIR::SpecificId>>& {
|
||||
return definitions_required_by_use_;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ class Context {
|
||||
// Entities that should have definitions by the end of the current source
|
||||
// file, because of a generic was used a concrete specific. This is currently
|
||||
// only tracking specific functions that should have a definition emitted.
|
||||
llvm::SmallVector<std::pair<SemIRLoc, SemIR::SpecificId>>
|
||||
llvm::SmallVector<std::pair<SemIR::LocId, SemIR::SpecificId>>
|
||||
definitions_required_by_use_;
|
||||
|
||||
// State for global initialization.
|
||||
|
||||
@@ -609,14 +609,14 @@ using InheritancePath =
|
||||
|
||||
// Computes the inheritance path from class `derived_id` to class `base_id`.
|
||||
// Returns nullopt if `derived_id` is not a class derived from `base_id`.
|
||||
static auto ComputeInheritancePath(Context& context, SemIRLoc loc,
|
||||
static auto ComputeInheritancePath(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::TypeId derived_id,
|
||||
SemIR::TypeId base_id)
|
||||
-> std::optional<InheritancePath> {
|
||||
// We intend for NRVO to be applied to `result`. All `return` statements in
|
||||
// this function should `return result;`.
|
||||
std::optional<InheritancePath> result(std::in_place);
|
||||
if (!TryToCompleteType(context, derived_id, loc)) {
|
||||
if (!TryToCompleteType(context, derived_id, loc_id)) {
|
||||
// TODO: Should we give an error here? If we don't, and there is an
|
||||
// inheritance path when the class is defined, we may have a coherence
|
||||
// problem.
|
||||
|
||||
@@ -206,7 +206,7 @@ auto DeclNameStack::LookupOrAddName(NameContext name_context,
|
||||
// `fn Class(T:! type).F(n: i32)` we will push the scope for `Class(T:! type)`
|
||||
// between the scope containing the declaration of `T` and the scope
|
||||
// containing the declaration of `n`.
|
||||
static auto PushNameQualifierScope(Context& context, SemIRLoc loc,
|
||||
static auto PushNameQualifierScope(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId scope_inst_id,
|
||||
SemIR::NameScopeId scope_id,
|
||||
SemIR::GenericId generic_id,
|
||||
@@ -219,7 +219,7 @@ static auto PushNameQualifierScope(Context& context, SemIRLoc loc,
|
||||
if (generic_id.has_value()) {
|
||||
self_specific_id = context.generics().GetSelfSpecific(generic_id);
|
||||
// When declaring a member of a generic, resolve the self specific.
|
||||
ResolveSpecificDefinition(context, loc, self_specific_id);
|
||||
ResolveSpecificDefinition(context, loc_id, self_specific_id);
|
||||
}
|
||||
|
||||
// Close the generic stack scope and open a new one for whatever comes after
|
||||
@@ -325,14 +325,14 @@ static auto CheckQualifierIsResolved(
|
||||
// Diagnose that a qualified declaration name specifies an incomplete class as
|
||||
// its scope.
|
||||
static auto DiagnoseQualifiedDeclInIncompleteClassScope(Context& context,
|
||||
SemIRLoc loc,
|
||||
SemIR::LocId loc_id,
|
||||
SemIR::ClassId class_id)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(QualifiedDeclInIncompleteClassScope, Error,
|
||||
"cannot declare a member of incomplete class {0}",
|
||||
SemIR::TypeId);
|
||||
auto builder =
|
||||
context.emitter().Build(loc, QualifiedDeclInIncompleteClassScope,
|
||||
context.emitter().Build(loc_id, QualifiedDeclInIncompleteClassScope,
|
||||
context.classes().Get(class_id).self_type_id);
|
||||
NoteIncompleteClass(context, class_id, builder);
|
||||
builder.Emit();
|
||||
@@ -341,13 +341,13 @@ static auto DiagnoseQualifiedDeclInIncompleteClassScope(Context& context,
|
||||
// Diagnose that a qualified declaration name specifies an undefined interface
|
||||
// as its scope.
|
||||
static auto DiagnoseQualifiedDeclInUndefinedInterfaceScope(
|
||||
Context& context, SemIRLoc loc, SemIR::InterfaceId interface_id,
|
||||
Context& context, SemIR::LocId loc_id, SemIR::InterfaceId interface_id,
|
||||
SemIR::InstId interface_inst_id) -> void {
|
||||
CARBON_DIAGNOSTIC(QualifiedDeclInUndefinedInterfaceScope, Error,
|
||||
"cannot declare a member of undefined interface {0}",
|
||||
InstIdAsType);
|
||||
auto builder = context.emitter().Build(
|
||||
loc, QualifiedDeclInUndefinedInterfaceScope, interface_inst_id);
|
||||
loc_id, QualifiedDeclInUndefinedInterfaceScope, interface_inst_id);
|
||||
NoteIncompleteInterface(context, interface_id, builder);
|
||||
builder.Emit();
|
||||
}
|
||||
@@ -355,32 +355,32 @@ static auto DiagnoseQualifiedDeclInUndefinedInterfaceScope(
|
||||
// Diagnose that a qualified declaration name specifies a different package as
|
||||
// its scope.
|
||||
static auto DiagnoseQualifiedDeclInImportedPackage(Context& context,
|
||||
SemIRLoc use_loc,
|
||||
SemIRLoc import_loc)
|
||||
SemIR::LocId use_loc_id,
|
||||
SemIR::LocId import_loc_id)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(QualifiedDeclOutsidePackage, Error,
|
||||
"imported packages cannot be used for declarations");
|
||||
CARBON_DIAGNOSTIC(QualifiedDeclOutsidePackageSource, Note,
|
||||
"package imported here");
|
||||
context.emitter()
|
||||
.Build(use_loc, QualifiedDeclOutsidePackage)
|
||||
.Note(import_loc, QualifiedDeclOutsidePackageSource)
|
||||
.Build(use_loc_id, QualifiedDeclOutsidePackage)
|
||||
.Note(import_loc_id, QualifiedDeclOutsidePackageSource)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
// Diagnose that a qualified declaration name specifies a non-scope entity as
|
||||
// its scope.
|
||||
static auto DiagnoseQualifiedDeclInNonScope(Context& context, SemIRLoc use_loc,
|
||||
SemIRLoc non_scope_entity_loc)
|
||||
-> void {
|
||||
static auto DiagnoseQualifiedDeclInNonScope(
|
||||
Context& context, SemIR::LocId use_loc_id,
|
||||
SemIR::LocId non_scope_entity_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(QualifiedNameInNonScope, Error,
|
||||
"name qualifiers are only allowed for entities that "
|
||||
"provide a scope");
|
||||
CARBON_DIAGNOSTIC(QualifiedNameNonScopeEntity, Note,
|
||||
"referenced non-scope entity declared here");
|
||||
context.emitter()
|
||||
.Build(use_loc, QualifiedNameInNonScope)
|
||||
.Note(non_scope_entity_loc, QualifiedNameNonScopeEntity)
|
||||
.Build(use_loc_id, QualifiedNameInNonScope)
|
||||
.Note(non_scope_entity_loc_id, QualifiedNameNonScopeEntity)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
// Handles the transformation of a SemIRLoc to a DiagnosticLoc.
|
||||
// Handles the transformation of a SemIR::LocId to a DiagnosticLoc.
|
||||
class DiagnosticEmitter : public DiagnosticEmitterBase {
|
||||
public:
|
||||
explicit DiagnosticEmitter(
|
||||
|
||||
@@ -11,17 +11,14 @@
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
// TODO: Update code to use LocId directly.
|
||||
using SemIRLoc = SemIR::LocId;
|
||||
|
||||
// TODO: Consider instead changing calls to `SemIR::LocId::TokenOnly(...)`.
|
||||
inline auto TokenOnly(SemIR::LocId loc_id) -> SemIRLoc {
|
||||
inline auto TokenOnly(SemIR::LocId loc_id) -> SemIR::LocId {
|
||||
return loc_id.ToTokenOnly();
|
||||
}
|
||||
|
||||
// We define the emitter separately for dependencies, so only provide a base
|
||||
// here.
|
||||
using DiagnosticEmitterBase = Diagnostics::Emitter<SemIRLoc>;
|
||||
using DiagnosticEmitterBase = Diagnostics::Emitter<SemIR::LocId>;
|
||||
|
||||
using DiagnosticBuilder = DiagnosticEmitterBase::Builder;
|
||||
|
||||
|
||||
+47
-42
@@ -39,31 +39,32 @@ struct SpecificEvalInfo {
|
||||
class EvalContext {
|
||||
public:
|
||||
explicit EvalContext(
|
||||
Context* context, SemIRLoc fallback_loc,
|
||||
Context* context, SemIR::LocId fallback_loc_id,
|
||||
SemIR::SpecificId specific_id = SemIR::SpecificId::None,
|
||||
std::optional<SpecificEvalInfo> specific_eval_info = std::nullopt)
|
||||
: context_(context),
|
||||
fallback_loc_(fallback_loc),
|
||||
fallback_loc_id_(fallback_loc_id),
|
||||
specific_id_(specific_id),
|
||||
specific_eval_info_(specific_eval_info) {}
|
||||
|
||||
// Gets the location to use for diagnostics if a better location is
|
||||
// unavailable.
|
||||
// TODO: This is also sometimes unavailable.
|
||||
auto fallback_loc() const -> SemIRLoc { return fallback_loc_; }
|
||||
auto fallback_loc_id() const -> SemIR::LocId { return fallback_loc_id_; }
|
||||
|
||||
// Returns a location to use to point at an instruction in a diagnostic, given
|
||||
// a list of instructions that might have an attached location. This is the
|
||||
// location of the first instruction in the list that has a location if there
|
||||
// is one, and otherwise the fallback location.
|
||||
auto GetDiagnosticLoc(llvm::ArrayRef<SemIR::InstId> inst_ids) -> SemIRLoc {
|
||||
auto GetDiagnosticLoc(llvm::ArrayRef<SemIR::InstId> inst_ids)
|
||||
-> SemIR::LocId {
|
||||
for (auto inst_id : inst_ids) {
|
||||
if (inst_id.has_value() &&
|
||||
context_->insts().GetLocId(inst_id).has_value()) {
|
||||
return inst_id;
|
||||
}
|
||||
}
|
||||
return fallback_loc_;
|
||||
return fallback_loc_id_;
|
||||
}
|
||||
|
||||
// Gets the value of the specified compile-time binding in this context.
|
||||
@@ -199,7 +200,7 @@ class EvalContext {
|
||||
// The type-checking context in which we're performing evaluation.
|
||||
Context* context_;
|
||||
// The location to use for diagnostics when a better location isn't available.
|
||||
SemIRLoc fallback_loc_;
|
||||
SemIR::LocId fallback_loc_id_;
|
||||
// The specific that we are evaluating within.
|
||||
SemIR::SpecificId specific_id_;
|
||||
// If we are currently evaluating an eval block for `specific_id_`,
|
||||
@@ -549,11 +550,11 @@ static auto GetConstantValue(EvalContext& eval_context,
|
||||
.Get(specific.generic_id)
|
||||
.decl_block_id.has_value()) {
|
||||
ResolveSpecificDeclaration(eval_context.context(),
|
||||
eval_context.fallback_loc(), specific_id);
|
||||
eval_context.fallback_loc_id(), specific_id);
|
||||
}
|
||||
return specific_id;
|
||||
}
|
||||
return MakeSpecific(eval_context.context(), eval_context.fallback_loc(),
|
||||
return MakeSpecific(eval_context.context(), eval_context.fallback_loc_id(),
|
||||
specific.generic_id, args_id);
|
||||
}
|
||||
|
||||
@@ -819,14 +820,14 @@ static auto PerformArrayIndex(EvalContext& eval_context, SemIR::ArrayIndex inst)
|
||||
|
||||
// Forms a constant int type as an evaluation result. Requires that width_id is
|
||||
// constant.
|
||||
static auto MakeIntTypeResult(Context& context, SemIRLoc loc,
|
||||
static auto MakeIntTypeResult(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::IntKind int_kind, SemIR::InstId width_id,
|
||||
Phase phase) -> SemIR::ConstantId {
|
||||
auto result = SemIR::IntType{
|
||||
.type_id = GetSingletonType(context, SemIR::TypeType::SingletonInstId),
|
||||
.int_kind = int_kind,
|
||||
.bit_width_id = width_id};
|
||||
if (!ValidateIntType(context, loc, result)) {
|
||||
if (!ValidateIntType(context, loc_id, result)) {
|
||||
return SemIR::ErrorInst::SingletonConstantId;
|
||||
}
|
||||
return MakeConstantResult(context, result, phase);
|
||||
@@ -854,7 +855,7 @@ static auto PerformIntConvert(Context& context, SemIR::InstId arg_id,
|
||||
|
||||
// Performs a conversion between integer types, diagnosing if the value doesn't
|
||||
// fit in the destination type.
|
||||
static auto PerformCheckedIntConvert(Context& context, SemIRLoc loc,
|
||||
static auto PerformCheckedIntConvert(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId arg_id,
|
||||
SemIR::TypeId dest_type_id)
|
||||
-> SemIR::ConstantId {
|
||||
@@ -872,7 +873,7 @@ static auto PerformCheckedIntConvert(Context& context, SemIRLoc loc,
|
||||
NegativeIntInUnsignedType, Error,
|
||||
"negative integer value {0} converted to unsigned type {1}", TypedInt,
|
||||
SemIR::TypeId);
|
||||
context.emitter().Emit(loc, NegativeIntInUnsignedType,
|
||||
context.emitter().Emit(loc_id, NegativeIntInUnsignedType,
|
||||
{.type = arg.type_id, .value = arg_val},
|
||||
dest_type_id);
|
||||
}
|
||||
@@ -882,7 +883,7 @@ static auto PerformCheckedIntConvert(Context& context, SemIRLoc loc,
|
||||
CARBON_DIAGNOSTIC(IntTooLargeForType, Error,
|
||||
"integer value {0} too large for type {1}", TypedInt,
|
||||
SemIR::TypeId);
|
||||
context.emitter().Emit(loc, IntTooLargeForType,
|
||||
context.emitter().Emit(loc_id, IntTooLargeForType,
|
||||
{.type = arg.type_id, .value = arg_val},
|
||||
dest_type_id);
|
||||
}
|
||||
@@ -893,9 +894,10 @@ static auto PerformCheckedIntConvert(Context& context, SemIRLoc loc,
|
||||
}
|
||||
|
||||
// Issues a diagnostic for a compile-time division by zero.
|
||||
static auto DiagnoseDivisionByZero(Context& context, SemIRLoc loc) -> void {
|
||||
static auto DiagnoseDivisionByZero(Context& context, SemIR::LocId loc_id)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(CompileTimeDivisionByZero, Error, "division by zero");
|
||||
context.emitter().Emit(loc, CompileTimeDivisionByZero);
|
||||
context.emitter().Emit(loc_id, CompileTimeDivisionByZero);
|
||||
}
|
||||
|
||||
// Get an integer at a suitable bit-width: either `bit_width_id` if it has a
|
||||
@@ -908,7 +910,7 @@ static auto GetIntAtSuitableWidth(Context& context, IntId int_id,
|
||||
}
|
||||
|
||||
// Performs a builtin unary integer -> integer operation.
|
||||
static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc,
|
||||
static auto PerformBuiltinUnaryIntOp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::BuiltinFunctionKind builtin_kind,
|
||||
SemIR::InstId arg_id)
|
||||
-> SemIR::ConstantId {
|
||||
@@ -923,7 +925,7 @@ static auto PerformBuiltinUnaryIntOp(Context& context, SemIRLoc loc,
|
||||
if (bit_width_id.has_value()) {
|
||||
CARBON_DIAGNOSTIC(CompileTimeIntegerNegateOverflow, Error,
|
||||
"integer overflow in negation of {0}", TypedInt);
|
||||
context.emitter().Emit(loc, CompileTimeIntegerNegateOverflow,
|
||||
context.emitter().Emit(loc_id, CompileTimeIntegerNegateOverflow,
|
||||
{.type = op.type_id, .value = op_val});
|
||||
} else {
|
||||
// Widen the integer so we don't overflow into the sign bit.
|
||||
@@ -1075,7 +1077,7 @@ static auto ComputeBinaryIntOpResult(SemIR::BuiltinFunctionKind builtin_kind,
|
||||
}
|
||||
|
||||
// Performs a builtin integer bit shift operation.
|
||||
static auto PerformBuiltinIntShiftOp(Context& context, SemIRLoc loc,
|
||||
static auto PerformBuiltinIntShiftOp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::BuiltinFunctionKind builtin_kind,
|
||||
SemIR::InstId lhs_id, SemIR::InstId rhs_id)
|
||||
-> SemIR::ConstantId {
|
||||
@@ -1094,7 +1096,7 @@ static auto PerformBuiltinIntShiftOp(Context& context, SemIRLoc loc,
|
||||
"shift distance >= type width of {0} in `{1} {2:<<|>>} {3}`", unsigned,
|
||||
TypedInt, Diagnostics::BoolAsSelect, TypedInt);
|
||||
context.emitter().Emit(
|
||||
loc, CompileTimeShiftOutOfRange, lhs_val.getBitWidth(),
|
||||
loc_id, CompileTimeShiftOutOfRange, lhs_val.getBitWidth(),
|
||||
{.type = lhs.type_id, .value = lhs_val},
|
||||
builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift,
|
||||
{.type = rhs.type_id, .value = rhs_orig_val});
|
||||
@@ -1108,7 +1110,8 @@ static auto PerformBuiltinIntShiftOp(Context& context, SemIRLoc loc,
|
||||
"shift distance negative in `{0} {1:<<|>>} {2}`",
|
||||
TypedInt, Diagnostics::BoolAsSelect, TypedInt);
|
||||
context.emitter().Emit(
|
||||
loc, CompileTimeShiftNegative, {.type = lhs.type_id, .value = lhs_val},
|
||||
loc_id, CompileTimeShiftNegative,
|
||||
{.type = lhs.type_id, .value = lhs_val},
|
||||
builtin_kind == SemIR::BuiltinFunctionKind::IntLeftShift,
|
||||
{.type = rhs.type_id, .value = rhs_orig_val});
|
||||
// TODO: Is it useful to recover by returning 0 or -1?
|
||||
@@ -1128,7 +1131,7 @@ static auto PerformBuiltinIntShiftOp(Context& context, SemIRLoc loc,
|
||||
"integer whose width is greater than the "
|
||||
"maximum supported width of {1}",
|
||||
TypedInt, int);
|
||||
context.emitter().Emit(loc, CompileTimeUnsizedShiftOutOfRange,
|
||||
context.emitter().Emit(loc_id, CompileTimeUnsizedShiftOutOfRange,
|
||||
{.type = rhs.type_id, .value = rhs_orig_val},
|
||||
IntStore::MaxIntWidth);
|
||||
return SemIR::ErrorInst::SingletonConstantId;
|
||||
@@ -1152,7 +1155,7 @@ static auto PerformBuiltinIntShiftOp(Context& context, SemIRLoc loc,
|
||||
}
|
||||
|
||||
// Performs a homogeneous builtin binary integer -> integer operation.
|
||||
static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
|
||||
static auto PerformBuiltinBinaryIntOp(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::BuiltinFunctionKind builtin_kind,
|
||||
SemIR::InstId lhs_id,
|
||||
SemIR::InstId rhs_id)
|
||||
@@ -1174,7 +1177,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
|
||||
case SemIR::BuiltinFunctionKind::IntUDiv:
|
||||
case SemIR::BuiltinFunctionKind::IntUMod:
|
||||
if (rhs_val.isZero()) {
|
||||
DiagnoseDivisionByZero(context, loc);
|
||||
DiagnoseDivisionByZero(context, loc_id);
|
||||
return SemIR::ErrorInst::SingletonConstantId;
|
||||
}
|
||||
break;
|
||||
@@ -1216,7 +1219,7 @@ static auto PerformBuiltinBinaryIntOp(Context& context, SemIRLoc loc,
|
||||
CARBON_DIAGNOSTIC(CompileTimeIntegerOverflow, Error,
|
||||
"integer overflow in calculation `{0} {1} {2}`", TypedInt,
|
||||
Lex::TokenKind, TypedInt);
|
||||
context.emitter().Emit(loc, CompileTimeIntegerOverflow,
|
||||
context.emitter().Emit(loc_id, CompileTimeIntegerOverflow,
|
||||
{.type = type_id, .value = lhs_val}, result.op_token,
|
||||
{.type = type_id, .value = rhs_val});
|
||||
}
|
||||
@@ -1366,8 +1369,8 @@ static auto PerformBuiltinBoolComparison(
|
||||
}
|
||||
|
||||
// Returns a constant for a call to a builtin function.
|
||||
static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
SemIR::Call call,
|
||||
static auto MakeConstantForBuiltinCall(EvalContext& eval_context,
|
||||
SemIR::LocId loc_id, SemIR::Call call,
|
||||
SemIR::BuiltinFunctionKind builtin_kind,
|
||||
llvm::ArrayRef<SemIR::InstId> arg_ids,
|
||||
Phase phase) -> SemIR::ConstantId {
|
||||
@@ -1403,7 +1406,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
// say if it's referring to the left or the right side for the error.
|
||||
// The `arg_id` instruction has no location in it for some reason.
|
||||
context.emitter().Emit(
|
||||
loc, FacetTypeRequiredForTypeAndOperator,
|
||||
loc_id, FacetTypeRequiredForTypeAndOperator,
|
||||
context.types().GetTypeIdForTypeInstId(type_arg_id));
|
||||
}
|
||||
}
|
||||
@@ -1430,12 +1433,12 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
}
|
||||
|
||||
case SemIR::BuiltinFunctionKind::IntMakeTypeSigned: {
|
||||
return MakeIntTypeResult(context, loc, SemIR::IntKind::Signed, arg_ids[0],
|
||||
phase);
|
||||
return MakeIntTypeResult(context, loc_id, SemIR::IntKind::Signed,
|
||||
arg_ids[0], phase);
|
||||
}
|
||||
|
||||
case SemIR::BuiltinFunctionKind::IntMakeTypeUnsigned: {
|
||||
return MakeIntTypeResult(context, loc, SemIR::IntKind::Unsigned,
|
||||
return MakeIntTypeResult(context, loc_id, SemIR::IntKind::Unsigned,
|
||||
arg_ids[0], phase);
|
||||
}
|
||||
|
||||
@@ -1444,7 +1447,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
if (phase != Phase::Concrete) {
|
||||
break;
|
||||
}
|
||||
if (!ValidateFloatBitWidth(context, loc, arg_ids[0])) {
|
||||
if (!ValidateFloatBitWidth(context, loc_id, arg_ids[0])) {
|
||||
return SemIR::ErrorInst::SingletonConstantId;
|
||||
}
|
||||
return context.constant_values().Get(
|
||||
@@ -1466,7 +1469,8 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
if (phase != Phase::Concrete) {
|
||||
return MakeConstantResult(context, call, phase);
|
||||
}
|
||||
return PerformCheckedIntConvert(context, loc, arg_ids[0], call.type_id);
|
||||
return PerformCheckedIntConvert(context, loc_id, arg_ids[0],
|
||||
call.type_id);
|
||||
}
|
||||
|
||||
// Unary integer -> integer operations.
|
||||
@@ -1476,7 +1480,8 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
if (phase != Phase::Concrete) {
|
||||
break;
|
||||
}
|
||||
return PerformBuiltinUnaryIntOp(context, loc, builtin_kind, arg_ids[0]);
|
||||
return PerformBuiltinUnaryIntOp(context, loc_id, builtin_kind,
|
||||
arg_ids[0]);
|
||||
}
|
||||
|
||||
// Homogeneous binary integer -> integer operations.
|
||||
@@ -1496,8 +1501,8 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
if (phase != Phase::Concrete) {
|
||||
break;
|
||||
}
|
||||
return PerformBuiltinBinaryIntOp(context, loc, builtin_kind, arg_ids[0],
|
||||
arg_ids[1]);
|
||||
return PerformBuiltinBinaryIntOp(context, loc_id, builtin_kind,
|
||||
arg_ids[0], arg_ids[1]);
|
||||
}
|
||||
|
||||
// Bit shift operations.
|
||||
@@ -1506,7 +1511,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
if (phase != Phase::Concrete) {
|
||||
break;
|
||||
}
|
||||
return PerformBuiltinIntShiftOp(context, loc, builtin_kind, arg_ids[0],
|
||||
return PerformBuiltinIntShiftOp(context, loc_id, builtin_kind, arg_ids[0],
|
||||
arg_ids[1]);
|
||||
}
|
||||
|
||||
@@ -1574,7 +1579,7 @@ static auto MakeConstantForBuiltinCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
}
|
||||
|
||||
// Makes a constant for a call instruction.
|
||||
static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
static auto MakeConstantForCall(EvalContext& eval_context, SemIR::LocId loc_id,
|
||||
SemIR::Call call) -> SemIR::ConstantId {
|
||||
Phase phase = Phase::Concrete;
|
||||
|
||||
@@ -1630,7 +1635,7 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
CARBON_DIAGNOSTIC(CompTimeOnlyFunctionHere, Note,
|
||||
"compile-time-only function declared here");
|
||||
eval_context.emitter()
|
||||
.Build(loc, NonConstantCallToCompTimeOnlyFunction)
|
||||
.Build(loc_id, NonConstantCallToCompTimeOnlyFunction)
|
||||
.Note(eval_context.functions()
|
||||
.Get(callee_function.function_id)
|
||||
.latest_decl_id(),
|
||||
@@ -1643,7 +1648,7 @@ static auto MakeConstantForCall(EvalContext& eval_context, SemIRLoc loc,
|
||||
// Handle calls to builtins.
|
||||
if (builtin_kind != SemIR::BuiltinFunctionKind::None) {
|
||||
return MakeConstantForBuiltinCall(
|
||||
eval_context, loc, call, builtin_kind,
|
||||
eval_context, loc_id, call, builtin_kind,
|
||||
eval_context.inst_blocks().Get(call.args_id), phase);
|
||||
}
|
||||
|
||||
@@ -1948,7 +1953,7 @@ auto TryEvalInstUnsafe(Context& context, SemIR::InstId inst_id,
|
||||
return TryEvalInstInContext(eval_context, inst_id, inst);
|
||||
}
|
||||
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIRLoc loc,
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id,
|
||||
SemIR::GenericInstIndex::Region region)
|
||||
-> SemIR::InstBlockId {
|
||||
@@ -1959,7 +1964,7 @@ auto TryEvalBlockForSpecific(Context& context, SemIRLoc loc,
|
||||
llvm::SmallVector<SemIR::InstId> result;
|
||||
result.resize(eval_block.size(), SemIR::InstId::None);
|
||||
|
||||
EvalContext eval_context(&context, loc, specific_id,
|
||||
EvalContext eval_context(&context, loc_id, specific_id,
|
||||
SpecificEvalInfo{
|
||||
.region = region,
|
||||
.values = result,
|
||||
@@ -1969,7 +1974,7 @@ auto TryEvalBlockForSpecific(Context& context, SemIRLoc loc,
|
||||
&context.emitter(), [&](auto& builder) {
|
||||
CARBON_DIAGNOSTIC(ResolvingSpecificHere, Note, "in {0} used here",
|
||||
SemIR::SpecificId);
|
||||
builder.Note(loc, ResolvingSpecificHere, specific_id);
|
||||
builder.Note(loc_id, ResolvingSpecificHere, specific_id);
|
||||
});
|
||||
|
||||
for (auto [i, inst_id] : llvm::enumerate(eval_block)) {
|
||||
|
||||
@@ -52,7 +52,7 @@ auto TryEvalInst(Context& context, InstT inst) -> SemIR::ConstantId {
|
||||
// Evaluates the eval block for a region of a specific. Produces a block
|
||||
// containing the evaluated constant values of the instructions in the eval
|
||||
// block.
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIRLoc loc,
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id,
|
||||
SemIR::GenericInstIndex::Region region)
|
||||
-> SemIR::InstBlockId;
|
||||
|
||||
@@ -39,20 +39,20 @@ static auto WitnessAccessMatchesInterface(
|
||||
}
|
||||
|
||||
static auto IncompleteFacetTypeDiagnosticBuilder(
|
||||
Context& context, SemIRLoc loc, SemIR::TypeInstId facet_type_inst_id,
|
||||
Context& context, SemIR::LocId loc_id, SemIR::TypeInstId facet_type_inst_id,
|
||||
bool is_definition) -> DiagnosticBuilder {
|
||||
if (is_definition) {
|
||||
CARBON_DIAGNOSTIC(ImplAsIncompleteFacetTypeDefinition, Error,
|
||||
"definition of impl as incomplete facet type {0}",
|
||||
InstIdAsType);
|
||||
return context.emitter().Build(loc, ImplAsIncompleteFacetTypeDefinition,
|
||||
return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeDefinition,
|
||||
facet_type_inst_id);
|
||||
} else {
|
||||
CARBON_DIAGNOSTIC(
|
||||
ImplAsIncompleteFacetTypeRewrites, Error,
|
||||
"declaration of impl as incomplete facet type {0} with rewrites",
|
||||
InstIdAsType);
|
||||
return context.emitter().Build(loc, ImplAsIncompleteFacetTypeRewrites,
|
||||
return context.emitter().Build(loc_id, ImplAsIncompleteFacetTypeRewrites,
|
||||
facet_type_inst_id);
|
||||
}
|
||||
}
|
||||
@@ -244,14 +244,14 @@ auto InitialFacetTypeImplWitness(
|
||||
}
|
||||
|
||||
auto RequireCompleteFacetTypeForImplDefinition(
|
||||
Context& context, SemIRLoc loc, SemIR::TypeInstId facet_type_inst_id)
|
||||
Context& context, SemIR::LocId loc_id, SemIR::TypeInstId facet_type_inst_id)
|
||||
-> bool {
|
||||
auto facet_type_id =
|
||||
context.types().GetTypeIdForTypeInstId(facet_type_inst_id);
|
||||
return RequireCompleteType(context, facet_type_id,
|
||||
context.insts().GetLocId(facet_type_inst_id), [&] {
|
||||
return IncompleteFacetTypeDiagnosticBuilder(
|
||||
context, loc, facet_type_inst_id,
|
||||
context, loc_id, facet_type_inst_id,
|
||||
/*is_definition=*/true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ auto InitialFacetTypeImplWitness(
|
||||
// Returns `true` if the facet type is complete. Otherwise issues a diagnostic
|
||||
// and returns `false`.
|
||||
auto RequireCompleteFacetTypeForImplDefinition(
|
||||
Context& context, SemIRLoc loc, SemIR::TypeInstId facet_type_inst_id)
|
||||
Context& context, SemIR::LocId loc_id, SemIR::TypeInstId facet_type_inst_id)
|
||||
-> bool;
|
||||
|
||||
// Replaces the placeholder created by `InitialFacetTypeImplWitness` with an
|
||||
|
||||
+17
-14
@@ -466,7 +466,7 @@ auto BuildGeneric(Context& context, SemIR::InstId decl_id) -> SemIR::GenericId {
|
||||
return generic_id;
|
||||
}
|
||||
|
||||
auto FinishGenericDecl(Context& context, SemIRLoc loc,
|
||||
auto FinishGenericDecl(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id) -> void {
|
||||
if (!generic_id.has_value()) {
|
||||
return;
|
||||
@@ -477,7 +477,7 @@ auto FinishGenericDecl(Context& context, SemIRLoc loc,
|
||||
context.generic_region_stack().Pop();
|
||||
context.generics().Get(generic_id).decl_block_id = decl_block_id;
|
||||
|
||||
ResolveSpecificDeclaration(context, loc,
|
||||
ResolveSpecificDeclaration(context, loc_id,
|
||||
context.generics().GetSelfSpecific(generic_id));
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@ auto FinishGenericDefinition(Context& context, SemIR::GenericId generic_id)
|
||||
context.generic_region_stack().Pop();
|
||||
}
|
||||
|
||||
auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc,
|
||||
auto ResolveSpecificDeclaration(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id) -> void {
|
||||
// If this is the first time we've formed this specific, evaluate its decl
|
||||
// block to form information about the specific.
|
||||
@@ -535,7 +535,7 @@ auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc,
|
||||
SemIR::InstBlockId::Empty;
|
||||
|
||||
auto decl_block_id =
|
||||
TryEvalBlockForSpecific(context, loc, specific_id,
|
||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||
SemIR::GenericInstIndex::Region::Declaration);
|
||||
// Note that TryEvalBlockForSpecific may reallocate the list of specifics,
|
||||
// so re-lookup the specific here.
|
||||
@@ -543,17 +543,19 @@ auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc,
|
||||
}
|
||||
}
|
||||
|
||||
auto MakeSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id,
|
||||
SemIR::InstBlockId args_id) -> SemIR::SpecificId {
|
||||
auto MakeSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id, SemIR::InstBlockId args_id)
|
||||
-> SemIR::SpecificId {
|
||||
auto specific_id = context.specifics().GetOrAdd(generic_id, args_id);
|
||||
ResolveSpecificDeclaration(context, loc, specific_id);
|
||||
ResolveSpecificDeclaration(context, loc_id, specific_id);
|
||||
return specific_id;
|
||||
}
|
||||
|
||||
auto MakeSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id,
|
||||
auto MakeSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id,
|
||||
llvm::ArrayRef<SemIR::InstId> args) -> SemIR::SpecificId {
|
||||
auto args_id = context.inst_blocks().AddCanonical(args);
|
||||
return MakeSpecific(context, loc, generic_id, args_id);
|
||||
return MakeSpecific(context, loc_id, generic_id, args_id);
|
||||
}
|
||||
|
||||
static auto MakeSelfSpecificId(Context& context, SemIR::GenericId generic_id)
|
||||
@@ -575,18 +577,18 @@ static auto MakeSelfSpecificId(Context& context, SemIR::GenericId generic_id)
|
||||
return context.specifics().GetOrAdd(generic_id, args_id);
|
||||
}
|
||||
|
||||
auto MakeSelfSpecific(Context& context, SemIRLoc loc,
|
||||
auto MakeSelfSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id) -> SemIR::SpecificId {
|
||||
// Build a corresponding specific.
|
||||
SemIR::SpecificId specific_id = MakeSelfSpecificId(context, generic_id);
|
||||
// TODO: This could be made more efficient. We don't need to perform
|
||||
// substitution here; we know we want identity mappings for all constants and
|
||||
// types. We could also consider not storing the mapping at all in this case.
|
||||
ResolveSpecificDeclaration(context, loc, specific_id);
|
||||
ResolveSpecificDeclaration(context, loc_id, specific_id);
|
||||
return specific_id;
|
||||
}
|
||||
|
||||
auto ResolveSpecificDefinition(Context& context, SemIRLoc loc,
|
||||
auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id) -> bool {
|
||||
// TODO: Handle recursive resolution of the same generic definition.
|
||||
auto& specific = context.specifics().Get(specific_id);
|
||||
@@ -600,8 +602,9 @@ auto ResolveSpecificDefinition(Context& context, SemIRLoc loc,
|
||||
// The generic is not defined yet.
|
||||
return false;
|
||||
}
|
||||
auto definition_block_id = TryEvalBlockForSpecific(
|
||||
context, loc, specific_id, SemIR::GenericInstIndex::Region::Definition);
|
||||
auto definition_block_id =
|
||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||
SemIR::GenericInstIndex::Region::Definition);
|
||||
// Note that TryEvalBlockForSpecific may reallocate the list of specifics,
|
||||
// so re-lookup the specific here.
|
||||
context.specifics().Get(specific_id).definition_block_id =
|
||||
|
||||
@@ -28,7 +28,7 @@ auto DiscardGenericDecl(Context& context) -> void;
|
||||
auto BuildGeneric(Context& context, SemIR::InstId decl_id) -> SemIR::GenericId;
|
||||
|
||||
// Builds eval block for the declaration.
|
||||
auto FinishGenericDecl(Context& context, SemIRLoc loc,
|
||||
auto FinishGenericDecl(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id) -> void;
|
||||
|
||||
// BuildGeneric() and FinishGenericDecl() combined. Normally you would call this
|
||||
@@ -55,31 +55,33 @@ auto RebuildGenericEvalBlock(Context& context, SemIR::GenericId generic_id,
|
||||
// Builds a new specific with a given argument list, or finds an existing one if
|
||||
// this generic has already been referenced with these arguments. Performs
|
||||
// substitution into the declaration, but not the definition, of the generic.
|
||||
auto MakeSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id,
|
||||
auto MakeSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id,
|
||||
llvm::ArrayRef<SemIR::InstId> args) -> SemIR::SpecificId;
|
||||
|
||||
// Builds a new specific or finds an existing one in the case where the argument
|
||||
// list has already been converted into an instruction block. `args_id` should
|
||||
// be a canonical instruction block referring to constants.
|
||||
auto MakeSpecific(Context& context, SemIRLoc loc, SemIR::GenericId generic_id,
|
||||
SemIR::InstBlockId args_id) -> SemIR::SpecificId;
|
||||
auto MakeSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id, SemIR::InstBlockId args_id)
|
||||
-> SemIR::SpecificId;
|
||||
|
||||
// Builds the specific that describes how the generic should refer to itself.
|
||||
// For example, for a generic `G(T:! type)`, this is the specific `G(T)`. If
|
||||
// `generic_id` is `None`, returns `None`.
|
||||
auto MakeSelfSpecific(Context& context, SemIRLoc loc,
|
||||
auto MakeSelfSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::GenericId generic_id) -> SemIR::SpecificId;
|
||||
|
||||
// Resolve the declaration of the given specific, by evaluating the eval block
|
||||
// of the corresponding generic and storing a corresponding value block in the
|
||||
// specific.
|
||||
auto ResolveSpecificDeclaration(Context& context, SemIRLoc loc,
|
||||
auto ResolveSpecificDeclaration(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id) -> void;
|
||||
|
||||
// Attempts to resolve the definition of the given specific, by evaluating the
|
||||
// eval block of the corresponding generic and storing a corresponding value
|
||||
// block in the specific. Returns false if a definition is not available.
|
||||
auto ResolveSpecificDefinition(Context& context, SemIRLoc loc,
|
||||
auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id) -> bool;
|
||||
|
||||
// Diagnoses if an entity has implicit parameters, indicating it's generic, but
|
||||
|
||||
@@ -54,7 +54,7 @@ static auto MergeClassRedecl(Context& context, Parse::AnyClassDeclId node_id,
|
||||
SemIR::ClassId prev_class_id,
|
||||
SemIR::ImportIRId prev_import_ir_id) -> bool {
|
||||
auto& prev_class = context.classes().Get(prev_class_id);
|
||||
SemIRLoc prev_loc = prev_class.latest_decl_id();
|
||||
SemIR::LocId prev_loc_id = prev_class.latest_decl_id();
|
||||
|
||||
// Check the generic parameters match, if they were specified.
|
||||
if (!CheckRedeclParamsMatch(context, DeclParams(new_class),
|
||||
@@ -65,7 +65,7 @@ static auto MergeClassRedecl(Context& context, Parse::AnyClassDeclId node_id,
|
||||
DiagnoseIfInvalidRedecl(
|
||||
context, Lex::TokenKind::Class, prev_class.name_id,
|
||||
RedeclInfo(new_class, node_id, new_is_definition),
|
||||
RedeclInfo(prev_class, prev_loc, prev_class.has_definition_started()),
|
||||
RedeclInfo(prev_class, prev_loc_id, prev_class.has_definition_started()),
|
||||
prev_import_ir_id);
|
||||
|
||||
if (new_is_definition && prev_class.has_definition_started()) {
|
||||
@@ -301,22 +301,23 @@ auto HandleParseNode(Context& context, Parse::ClassDefinitionStartId node_id)
|
||||
|
||||
// Diagnoses a class-specific declaration appearing outside a class.
|
||||
static auto DiagnoseClassSpecificDeclOutsideClass(Context& context,
|
||||
SemIRLoc loc,
|
||||
SemIR::LocId loc_id,
|
||||
Lex::TokenKind tok) -> void {
|
||||
CARBON_DIAGNOSTIC(ClassSpecificDeclOutsideClass, Error,
|
||||
"`{0}` declaration outside class", Lex::TokenKind);
|
||||
context.emitter().Emit(loc, ClassSpecificDeclOutsideClass, tok);
|
||||
context.emitter().Emit(loc_id, ClassSpecificDeclOutsideClass, tok);
|
||||
}
|
||||
|
||||
// Returns the current scope's class declaration, or diagnoses if it isn't a
|
||||
// class.
|
||||
static auto GetCurrentScopeAsClassOrDiagnose(Context& context, SemIRLoc loc,
|
||||
static auto GetCurrentScopeAsClassOrDiagnose(Context& context,
|
||||
SemIR::LocId loc_id,
|
||||
Lex::TokenKind tok)
|
||||
-> std::optional<SemIR::ClassDecl> {
|
||||
auto class_scope =
|
||||
context.scope_stack().GetCurrentScopeAs<SemIR::ClassDecl>();
|
||||
if (!class_scope) {
|
||||
DiagnoseClassSpecificDeclOutsideClass(context, loc, tok);
|
||||
DiagnoseClassSpecificDeclOutsideClass(context, loc_id, tok);
|
||||
}
|
||||
return class_scope;
|
||||
}
|
||||
@@ -324,8 +325,8 @@ static auto GetCurrentScopeAsClassOrDiagnose(Context& context, SemIRLoc loc,
|
||||
// Diagnoses a class-specific declaration that is repeated within a class, but
|
||||
// is not permitted to be repeated.
|
||||
static auto DiagnoseClassSpecificDeclRepeated(Context& context,
|
||||
SemIRLoc new_loc,
|
||||
SemIRLoc prev_loc,
|
||||
SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id,
|
||||
Lex::TokenKind tok) -> void {
|
||||
CARBON_DIAGNOSTIC(AdaptDeclRepeated, Error,
|
||||
"multiple `adapt` declarations in class");
|
||||
@@ -336,9 +337,9 @@ static auto DiagnoseClassSpecificDeclRepeated(Context& context,
|
||||
"previous `{0}` declaration is here", Lex::TokenKind);
|
||||
CARBON_CHECK(tok == Lex::TokenKind::Adapt || tok == Lex::TokenKind::Base);
|
||||
context.emitter()
|
||||
.Build(new_loc, tok == Lex::TokenKind::Adapt ? AdaptDeclRepeated
|
||||
: BaseDeclRepeated)
|
||||
.Note(prev_loc, ClassSpecificDeclPrevious, tok)
|
||||
.Build(new_loc_id, tok == Lex::TokenKind::Adapt ? AdaptDeclRepeated
|
||||
: BaseDeclRepeated)
|
||||
.Note(prev_loc_id, ClassSpecificDeclPrevious, tok)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
|
||||
@@ -608,7 +608,7 @@ static auto AddNamespaceFromOtherPackage(Context& context,
|
||||
}
|
||||
|
||||
auto ImportNameFromOtherPackage(
|
||||
Context& context, SemIRLoc loc, SemIR::NameScopeId scope_id,
|
||||
Context& context, SemIR::LocId loc_id, SemIR::NameScopeId scope_id,
|
||||
llvm::ArrayRef<std::pair<SemIR::ImportIRId, SemIR::NameScopeId>>
|
||||
import_ir_scopes,
|
||||
SemIR::NameId name_id) -> SemIR::InstId {
|
||||
@@ -626,7 +626,7 @@ auto ImportNameFromOtherPackage(
|
||||
&context.emitter(), [&](auto& builder) {
|
||||
CARBON_DIAGNOSTIC(InNameLookup, Note, "in name lookup for `{0}`",
|
||||
SemIR::NameId);
|
||||
builder.Note(loc, InNameLookup, name_id);
|
||||
builder.Note(loc_id, InNameLookup, name_id);
|
||||
});
|
||||
|
||||
// Although we track the result here and look in each IR, we pretty much use
|
||||
|
||||
@@ -88,7 +88,7 @@ auto ImportLibrariesFromOtherPackage(Context& context,
|
||||
// Arguments are all in the context of the current IR. Scope lookup is expected
|
||||
// to be resolved first.
|
||||
auto ImportNameFromOtherPackage(
|
||||
Context& context, SemIRLoc loc, SemIR::NameScopeId scope_id,
|
||||
Context& context, SemIR::LocId loc_id, SemIR::NameScopeId scope_id,
|
||||
llvm::ArrayRef<std::pair<SemIR::ImportIRId, SemIR::NameScopeId>>
|
||||
import_ir_scopes,
|
||||
SemIR::NameId name_id) -> SemIR::InstId;
|
||||
|
||||
@@ -55,8 +55,8 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
public:
|
||||
// Creates an instance with the location that triggers calling Clang.
|
||||
// `context` must not be null.
|
||||
explicit CarbonClangDiagnosticConsumer(Context* context, SemIRLoc loc)
|
||||
: context_(context), loc_(loc) {}
|
||||
explicit CarbonClangDiagnosticConsumer(Context* context, SemIR::LocId loc_id)
|
||||
: context_(context), loc_id_(loc_id) {}
|
||||
|
||||
// Generates a Carbon warning for each Clang warning and a Carbon error for
|
||||
// each Clang error or fatal.
|
||||
@@ -87,9 +87,10 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
case clang::DiagnosticsEngine::Note:
|
||||
case clang::DiagnosticsEngine::Remark: {
|
||||
context_->TODO(
|
||||
loc_, llvm::formatv(
|
||||
"Unsupported: C++ diagnostic level for diagnostic\n{0}",
|
||||
diagnostics_str));
|
||||
loc_id_,
|
||||
llvm::formatv(
|
||||
"Unsupported: C++ diagnostic level for diagnostic\n{0}",
|
||||
diagnostics_str));
|
||||
return;
|
||||
}
|
||||
case clang::DiagnosticsEngine::Warning:
|
||||
@@ -112,7 +113,7 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
? CppInteropParseWarning
|
||||
: CppInteropParseError,
|
||||
diagnostics_str)
|
||||
.Note(loc_, InCppImport)
|
||||
.Note(loc_id_, InCppImport)
|
||||
.Emit();
|
||||
return;
|
||||
}
|
||||
@@ -124,7 +125,7 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
|
||||
Context* context_;
|
||||
|
||||
// The location that triggered calling Clang.
|
||||
SemIRLoc loc_;
|
||||
SemIR::LocId loc_id_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -139,9 +140,9 @@ static auto GenerateAst(Context& context, llvm::StringRef importing_file_path,
|
||||
-> std::pair<std::unique_ptr<clang::ASTUnit>, bool> {
|
||||
// TODO: Use all import locations by referring each Clang diagnostic to the
|
||||
// relevant import.
|
||||
SemIRLoc loc = imports.back().node_id;
|
||||
SemIR::LocId loc_id = imports.back().node_id;
|
||||
|
||||
CarbonClangDiagnosticConsumer diagnostics_consumer(&context, loc);
|
||||
CarbonClangDiagnosticConsumer diagnostics_consumer(&context, loc_id);
|
||||
|
||||
// TODO: Share compilation flags with ClangRunner.
|
||||
auto ast = clang::tooling::buildASTFromCodeWithArgs(
|
||||
@@ -327,7 +328,7 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
|
||||
// Returns the return type of the given function declaration.
|
||||
// Currently only void and 32-bit int are supported.
|
||||
// TODO: Support more return types.
|
||||
static auto GetReturnType(Context& context, SemIRLoc loc_id,
|
||||
static auto GetReturnType(Context& context, SemIR::LocId loc_id,
|
||||
const clang::FunctionDecl* clang_decl)
|
||||
-> SemIR::InstId {
|
||||
clang::QualType ret_type = clang_decl->getReturnType().getCanonicalType();
|
||||
|
||||
@@ -125,10 +125,10 @@ static auto GetGenericArgsWithSelfType(Context& context,
|
||||
}
|
||||
|
||||
auto GetSelfSpecificForInterfaceMemberWithSelfType(
|
||||
Context& context, SemIRLoc loc, SemIR::SpecificId interface_specific_id,
|
||||
SemIR::GenericId generic_id, SemIR::SpecificId enclosing_specific_id,
|
||||
SemIR::TypeId self_type_id, SemIR::InstId witness_inst_id)
|
||||
-> SemIR::SpecificId {
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId interface_specific_id, SemIR::GenericId generic_id,
|
||||
SemIR::SpecificId enclosing_specific_id, SemIR::TypeId self_type_id,
|
||||
SemIR::InstId witness_inst_id) -> SemIR::SpecificId {
|
||||
const auto& generic = context.generics().Get(generic_id);
|
||||
auto self_specific_args = context.inst_blocks().Get(
|
||||
context.specifics().Get(generic.self_specific_id).args_id);
|
||||
@@ -169,10 +169,10 @@ auto GetSelfSpecificForInterfaceMemberWithSelfType(
|
||||
arg_ids.push_back(new_arg_id);
|
||||
}
|
||||
|
||||
return MakeSpecific(context, loc, generic_id, arg_ids);
|
||||
return MakeSpecific(context, loc_id, generic_id, arg_ids);
|
||||
}
|
||||
|
||||
auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
|
||||
auto GetTypeForSpecificAssociatedEntity(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId interface_specific_id,
|
||||
SemIR::InstId decl_id,
|
||||
SemIR::TypeId self_type_id,
|
||||
@@ -189,7 +189,7 @@ auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
|
||||
auto arg_ids =
|
||||
GetGenericArgsWithSelfType(context, interface_specific_id, generic_id,
|
||||
self_type_id, self_witness_id);
|
||||
auto const_specific_id = MakeSpecific(context, loc, generic_id, arg_ids);
|
||||
auto const_specific_id = MakeSpecific(context, loc_id, generic_id, arg_ids);
|
||||
return SemIR::GetTypeOfInstInSpecific(context.sem_ir(), const_specific_id,
|
||||
decl_id);
|
||||
} else if (auto fn = context.types().TryGetAs<SemIR::FunctionType>(
|
||||
|
||||
@@ -20,14 +20,14 @@ auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
|
||||
// Gets the self specific of a generic declaration that is an interface member,
|
||||
// given a specific for the interface plus a type to use as `Self`.
|
||||
auto GetSelfSpecificForInterfaceMemberWithSelfType(
|
||||
Context& context, SemIRLoc loc, SemIR::SpecificId interface_specific_id,
|
||||
SemIR::GenericId generic_id, SemIR::SpecificId enclosing_specific_id,
|
||||
SemIR::TypeId self_type_id, SemIR::InstId witness_inst_id)
|
||||
-> SemIR::SpecificId;
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId interface_specific_id, SemIR::GenericId generic_id,
|
||||
SemIR::SpecificId enclosing_specific_id, SemIR::TypeId self_type_id,
|
||||
SemIR::InstId witness_inst_id) -> SemIR::SpecificId;
|
||||
|
||||
// Gets the type of the specified associated entity, given the specific for the
|
||||
// interface and the type of `Self`.
|
||||
auto GetTypeForSpecificAssociatedEntity(Context& context, SemIRLoc loc,
|
||||
auto GetTypeForSpecificAssociatedEntity(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId interface_specific_id,
|
||||
SemIR::InstId decl_id,
|
||||
SemIR::TypeId self_type_id,
|
||||
|
||||
+55
-50
@@ -17,40 +17,41 @@ CARBON_DIAGNOSTIC(RedeclPrevDecl, Note, "previously declared here");
|
||||
|
||||
// Diagnoses a redeclaration which is redundant.
|
||||
static auto DiagnoseRedundant(Context& context, Lex::TokenKind decl_kind,
|
||||
SemIR::NameId name_id, SemIRLoc new_loc,
|
||||
SemIRLoc prev_loc) -> void {
|
||||
SemIR::NameId name_id, SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(RedeclRedundant, Error,
|
||||
"redeclaration of `{0} {1}` is redundant", Lex::TokenKind,
|
||||
SemIR::NameId);
|
||||
context.emitter()
|
||||
.Build(new_loc, RedeclRedundant, decl_kind, name_id)
|
||||
.Note(prev_loc, RedeclPrevDecl)
|
||||
.Build(new_loc_id, RedeclRedundant, decl_kind, name_id)
|
||||
.Note(prev_loc_id, RedeclPrevDecl)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
// Diagnoses a redefinition.
|
||||
static auto DiagnoseRedef(Context& context, Lex::TokenKind decl_kind,
|
||||
SemIR::NameId name_id, SemIRLoc new_loc,
|
||||
SemIRLoc prev_loc) -> void {
|
||||
SemIR::NameId name_id, SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(RedeclRedef, Error, "redefinition of `{0} {1}`",
|
||||
Lex::TokenKind, SemIR::NameId);
|
||||
CARBON_DIAGNOSTIC(RedeclPrevDef, Note, "previously defined here");
|
||||
context.emitter()
|
||||
.Build(new_loc, RedeclRedef, decl_kind, name_id)
|
||||
.Note(prev_loc, RedeclPrevDef)
|
||||
.Build(new_loc_id, RedeclRedef, decl_kind, name_id)
|
||||
.Note(prev_loc_id, RedeclPrevDef)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
// Diagnoses an `extern` versus non-`extern` mismatch.
|
||||
static auto DiagnoseExternMismatch(Context& context, Lex::TokenKind decl_kind,
|
||||
SemIR::NameId name_id, SemIRLoc new_loc,
|
||||
SemIRLoc prev_loc) -> void {
|
||||
SemIR::NameId name_id,
|
||||
SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(RedeclExternMismatch, Error,
|
||||
"redeclarations of `{0} {1}` must match use of `extern`",
|
||||
Lex::TokenKind, SemIR::NameId);
|
||||
context.emitter()
|
||||
.Build(new_loc, RedeclExternMismatch, decl_kind, name_id)
|
||||
.Note(prev_loc, RedeclPrevDecl)
|
||||
.Build(new_loc_id, RedeclExternMismatch, decl_kind, name_id)
|
||||
.Note(prev_loc_id, RedeclPrevDecl)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
@@ -58,20 +59,21 @@ static auto DiagnoseExternMismatch(Context& context, Lex::TokenKind decl_kind,
|
||||
static auto DiagnoseExternLibraryInImporter(Context& context,
|
||||
Lex::TokenKind decl_kind,
|
||||
SemIR::NameId name_id,
|
||||
SemIRLoc new_loc, SemIRLoc prev_loc)
|
||||
-> void {
|
||||
SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(ExternLibraryInImporter, Error,
|
||||
"cannot declare imported `{0} {1}` as `extern library`",
|
||||
Lex::TokenKind, SemIR::NameId);
|
||||
context.emitter()
|
||||
.Build(new_loc, ExternLibraryInImporter, decl_kind, name_id)
|
||||
.Note(prev_loc, RedeclPrevDecl)
|
||||
.Build(new_loc_id, ExternLibraryInImporter, decl_kind, name_id)
|
||||
.Note(prev_loc_id, RedeclPrevDecl)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
// Diagnoses `extern library` pointing to the wrong library.
|
||||
static auto DiagnoseExternLibraryIncorrect(Context& context, SemIRLoc new_loc,
|
||||
SemIRLoc prev_loc) -> void {
|
||||
static auto DiagnoseExternLibraryIncorrect(Context& context,
|
||||
SemIR::LocId new_loc_id,
|
||||
SemIR::LocId prev_loc_id) -> void {
|
||||
CARBON_DIAGNOSTIC(
|
||||
ExternLibraryIncorrect, Error,
|
||||
"declaration in {0} doesn't match `extern library` declaration",
|
||||
@@ -79,17 +81,17 @@ static auto DiagnoseExternLibraryIncorrect(Context& context, SemIRLoc new_loc,
|
||||
CARBON_DIAGNOSTIC(ExternLibraryExpected, Note,
|
||||
"previously declared with `extern library` here");
|
||||
context.emitter()
|
||||
.Build(new_loc, ExternLibraryIncorrect, context.sem_ir().library_id())
|
||||
.Note(prev_loc, ExternLibraryExpected)
|
||||
.Build(new_loc_id, ExternLibraryIncorrect, context.sem_ir().library_id())
|
||||
.Note(prev_loc_id, ExternLibraryExpected)
|
||||
.Emit();
|
||||
}
|
||||
|
||||
auto DiagnoseExternRequiresDeclInApiFile(Context& context, SemIRLoc loc)
|
||||
auto DiagnoseExternRequiresDeclInApiFile(Context& context, SemIR::LocId loc_id)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(
|
||||
ExternRequiresDeclInApiFile, Error,
|
||||
"`extern` entities must have a declaration in the API file");
|
||||
context.emitter().Emit(loc, ExternRequiresDeclInApiFile);
|
||||
context.emitter().Emit(loc_id, ExternRequiresDeclInApiFile);
|
||||
}
|
||||
|
||||
auto DiagnoseIfInvalidRedecl(Context& context, Lex::TokenKind decl_kind,
|
||||
@@ -99,17 +101,18 @@ auto DiagnoseIfInvalidRedecl(Context& context, Lex::TokenKind decl_kind,
|
||||
if (!import_ir_id.has_value()) {
|
||||
// Check for disallowed redeclarations in the same file.
|
||||
if (!new_decl.is_definition) {
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
if (prev_decl.is_definition) {
|
||||
DiagnoseRedef(context, decl_kind, name_id, new_decl.loc, prev_decl.loc);
|
||||
DiagnoseRedef(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
if (prev_decl.is_extern != new_decl.is_extern) {
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
@@ -120,16 +123,17 @@ auto DiagnoseIfInvalidRedecl(Context& context, Lex::TokenKind decl_kind,
|
||||
// forward declaration in the impl is allowed.
|
||||
if (prev_decl.is_definition) {
|
||||
if (new_decl.is_definition) {
|
||||
DiagnoseRedef(context, decl_kind, name_id, new_decl.loc, prev_decl.loc);
|
||||
DiagnoseRedef(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
} else {
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (prev_decl.is_extern != new_decl.is_extern) {
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
@@ -140,26 +144,26 @@ auto DiagnoseIfInvalidRedecl(Context& context, Lex::TokenKind decl_kind,
|
||||
// We continue after issuing the "missing API declaration" diagnostic,
|
||||
// because it may still be helpful to note other issues with the
|
||||
// declarations.
|
||||
DiagnoseExternRequiresDeclInApiFile(context, new_decl.loc);
|
||||
DiagnoseExternRequiresDeclInApiFile(context, new_decl.loc_id);
|
||||
}
|
||||
if (prev_decl.is_extern != new_decl.is_extern) {
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseExternMismatch(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
if (!prev_decl.extern_library_id.has_value()) {
|
||||
if (new_decl.extern_library_id.has_value()) {
|
||||
DiagnoseExternLibraryInImporter(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseExternLibraryInImporter(context, decl_kind, name_id,
|
||||
new_decl.loc_id, prev_decl.loc_id);
|
||||
} else {
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc,
|
||||
prev_decl.loc);
|
||||
DiagnoseRedundant(context, decl_kind, name_id, new_decl.loc_id,
|
||||
prev_decl.loc_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (prev_decl.extern_library_id != SemIR::LibraryNameId::Error &&
|
||||
prev_decl.extern_library_id != context.sem_ir().library_id()) {
|
||||
DiagnoseExternLibraryIncorrect(context, new_decl.loc, prev_decl.loc);
|
||||
DiagnoseExternLibraryIncorrect(context, new_decl.loc_id, prev_decl.loc_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -305,9 +309,9 @@ static auto CheckRedeclParam(Context& context, bool is_implicit_param,
|
||||
}
|
||||
|
||||
// Returns false if the param refs differ for a redeclaration.
|
||||
static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
|
||||
static auto CheckRedeclParams(Context& context, SemIR::LocId new_decl_loc_id,
|
||||
SemIR::InstBlockId new_param_patterns_id,
|
||||
SemIRLoc prev_decl_loc,
|
||||
SemIR::LocId prev_decl_loc_id,
|
||||
SemIR::InstBlockId prev_param_patterns_id,
|
||||
bool is_implicit_param,
|
||||
SemIR::SpecificId prev_specific_id, bool diagnose,
|
||||
@@ -331,9 +335,9 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
|
||||
"{1:with|without} {0:implicit |}parameter list",
|
||||
Diagnostics::BoolAsSelect, Diagnostics::BoolAsSelect);
|
||||
context.emitter()
|
||||
.Build(new_decl_loc, RedeclParamListDiffers, is_implicit_param,
|
||||
.Build(new_decl_loc_id, RedeclParamListDiffers, is_implicit_param,
|
||||
new_param_patterns_id.has_value())
|
||||
.Note(prev_decl_loc, RedeclParamListPrevious, is_implicit_param,
|
||||
.Note(prev_decl_loc_id, RedeclParamListPrevious, is_implicit_param,
|
||||
prev_param_patterns_id.has_value())
|
||||
.Emit();
|
||||
return false;
|
||||
@@ -358,9 +362,9 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
|
||||
"previously declared with {0:implicit |}parameter count of {1}",
|
||||
Diagnostics::BoolAsSelect, int32_t);
|
||||
context.emitter()
|
||||
.Build(new_decl_loc, RedeclParamCountDiffers, is_implicit_param,
|
||||
.Build(new_decl_loc_id, RedeclParamCountDiffers, is_implicit_param,
|
||||
new_param_pattern_ids.size())
|
||||
.Note(prev_decl_loc, RedeclParamCountPrevious, is_implicit_param,
|
||||
.Note(prev_decl_loc_id, RedeclParamCountPrevious, is_implicit_param,
|
||||
prev_param_pattern_ids.size())
|
||||
.Emit();
|
||||
return false;
|
||||
@@ -487,15 +491,16 @@ auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity,
|
||||
return false;
|
||||
}
|
||||
if (!CheckRedeclParams(
|
||||
context, new_entity.loc, new_entity.implicit_param_patterns_id,
|
||||
prev_entity.loc, prev_entity.implicit_param_patterns_id,
|
||||
context, new_entity.loc_id, new_entity.implicit_param_patterns_id,
|
||||
prev_entity.loc_id, prev_entity.implicit_param_patterns_id,
|
||||
/*is_implicit_param=*/true, prev_specific_id, diagnose, check_self)) {
|
||||
return false;
|
||||
}
|
||||
// Don't forward `check_self` here because it's extra cost, and `self` is only
|
||||
// allowed in implicit params.
|
||||
if (!CheckRedeclParams(context, new_entity.loc, new_entity.param_patterns_id,
|
||||
prev_entity.loc, prev_entity.param_patterns_id,
|
||||
if (!CheckRedeclParams(context, new_entity.loc_id,
|
||||
new_entity.param_patterns_id, prev_entity.loc_id,
|
||||
prev_entity.param_patterns_id,
|
||||
/*is_implicit_param=*/false, prev_specific_id,
|
||||
diagnose, /*check_self=*/true)) {
|
||||
return false;
|
||||
|
||||
@@ -13,20 +13,20 @@ namespace Carbon::Check {
|
||||
|
||||
// Diagnoses an `extern` declaration that was not preceded by a declaration in
|
||||
// the API file.
|
||||
auto DiagnoseExternRequiresDeclInApiFile(Context& context, SemIRLoc loc)
|
||||
auto DiagnoseExternRequiresDeclInApiFile(Context& context, SemIR::LocId loc_id)
|
||||
-> void;
|
||||
|
||||
// Information on new and previous declarations for DiagnoseIfInvalidRedecl.
|
||||
struct RedeclInfo {
|
||||
explicit RedeclInfo(SemIR::EntityWithParamsBase params, SemIRLoc loc,
|
||||
explicit RedeclInfo(SemIR::EntityWithParamsBase params, SemIR::LocId loc_id,
|
||||
bool is_definition)
|
||||
: loc(loc),
|
||||
: loc_id(loc_id),
|
||||
is_definition(is_definition),
|
||||
is_extern(params.is_extern),
|
||||
extern_library_id(params.extern_library_id) {}
|
||||
|
||||
// The associated diagnostic location.
|
||||
SemIRLoc loc;
|
||||
SemIR::LocId loc_id;
|
||||
// True if a definition.
|
||||
bool is_definition;
|
||||
// True if an `extern` declaration.
|
||||
@@ -60,24 +60,24 @@ auto ReplacePrevInstForMerge(Context& context, SemIR::NameScopeId scope_id,
|
||||
// different kinds of entity such as classes and functions.
|
||||
struct DeclParams {
|
||||
explicit DeclParams(const SemIR::EntityWithParamsBase& base)
|
||||
: loc(base.latest_decl_id()),
|
||||
: loc_id(base.latest_decl_id()),
|
||||
first_param_node_id(base.first_param_node_id),
|
||||
last_param_node_id(base.last_param_node_id),
|
||||
implicit_param_patterns_id(base.implicit_param_patterns_id),
|
||||
param_patterns_id(base.param_patterns_id) {}
|
||||
|
||||
DeclParams(SemIRLoc loc, Parse::NodeId first_param_node_id,
|
||||
DeclParams(SemIR::LocId loc_id, Parse::NodeId first_param_node_id,
|
||||
Parse::NodeId last_param_node_id,
|
||||
SemIR::InstBlockId implicit_param_patterns_id,
|
||||
SemIR::InstBlockId param_patterns_id)
|
||||
: loc(loc),
|
||||
: loc_id(loc_id),
|
||||
first_param_node_id(first_param_node_id),
|
||||
last_param_node_id(last_param_node_id),
|
||||
implicit_param_patterns_id(implicit_param_patterns_id),
|
||||
param_patterns_id(param_patterns_id) {}
|
||||
|
||||
// The location of the declaration of the entity.
|
||||
SemIRLoc loc;
|
||||
SemIR::LocId loc_id;
|
||||
|
||||
// Parse tree bounds for the parameters, including both implicit and explicit
|
||||
// parameters. These will be compared to match between declaration and
|
||||
|
||||
@@ -191,12 +191,10 @@ auto LookupNameInExactScope(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
|
||||
// Prints diagnostics on invalid qualified name access.
|
||||
static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc,
|
||||
SemIR::InstId scope_result_id,
|
||||
SemIR::NameId name_id,
|
||||
SemIR::AccessKind access_kind,
|
||||
bool is_parent_access,
|
||||
AccessInfo access_info) -> void {
|
||||
static auto DiagnoseInvalidQualifiedNameAccess(
|
||||
Context& context, SemIR::LocId loc_id, SemIR::InstId scope_result_id,
|
||||
SemIR::NameId name_id, SemIR::AccessKind access_kind, bool is_parent_access,
|
||||
AccessInfo access_info) -> void {
|
||||
auto class_type = context.insts().TryGetAs<SemIR::ClassType>(
|
||||
context.constant_values().GetInstId(access_info.constant_id));
|
||||
if (!class_type) {
|
||||
@@ -228,7 +226,7 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc,
|
||||
Diagnostics::BoolAsSelect, SemIR::NameId, SemIR::TypeId);
|
||||
CARBON_DIAGNOSTIC(ClassMemberDeclaration, Note, "declared here");
|
||||
context.emitter()
|
||||
.Build(loc, ClassInvalidMemberAccess,
|
||||
.Build(loc_id, ClassInvalidMemberAccess,
|
||||
access_kind == SemIR::AccessKind::Private, name_id, parent_type_id)
|
||||
.Note(scope_result_id, ClassMemberDeclaration)
|
||||
.Emit();
|
||||
@@ -351,7 +349,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
|
||||
// Prints a diagnostic for a missing qualified name.
|
||||
static auto DiagnoseMemberNameNotFound(
|
||||
Context& context, SemIRLoc loc, SemIR::NameId name_id,
|
||||
Context& context, SemIR::LocId loc_id, SemIR::NameId name_id,
|
||||
llvm::ArrayRef<LookupScope> lookup_scopes) -> void {
|
||||
if (lookup_scopes.size() == 1 &&
|
||||
lookup_scopes.front().name_scope_id.has_value()) {
|
||||
@@ -360,7 +358,7 @@ static auto DiagnoseMemberNameNotFound(
|
||||
CARBON_DIAGNOSTIC(MemberNameNotFoundInSpecificScope, Error,
|
||||
"member name `{0}` not found in {1}", SemIR::NameId,
|
||||
SemIR::SpecificId);
|
||||
context.emitter().Emit(loc, MemberNameNotFoundInSpecificScope, name_id,
|
||||
context.emitter().Emit(loc_id, MemberNameNotFoundInSpecificScope, name_id,
|
||||
specific_id);
|
||||
} else {
|
||||
auto scope_inst_id = context.name_scopes()
|
||||
@@ -369,7 +367,7 @@ static auto DiagnoseMemberNameNotFound(
|
||||
CARBON_DIAGNOSTIC(MemberNameNotFoundInInstScope, Error,
|
||||
"member name `{0}` not found in {1}", SemIR::NameId,
|
||||
InstIdAsType);
|
||||
context.emitter().Emit(loc, MemberNameNotFoundInInstScope, name_id,
|
||||
context.emitter().Emit(loc_id, MemberNameNotFoundInInstScope, name_id,
|
||||
scope_inst_id);
|
||||
}
|
||||
return;
|
||||
@@ -377,7 +375,7 @@ static auto DiagnoseMemberNameNotFound(
|
||||
|
||||
CARBON_DIAGNOSTIC(MemberNameNotFound, Error, "member name `{0}` not found",
|
||||
SemIR::NameId);
|
||||
context.emitter().Emit(loc, MemberNameNotFound, name_id);
|
||||
context.emitter().Emit(loc_id, MemberNameNotFound, name_id);
|
||||
}
|
||||
|
||||
auto LookupQualifiedName(Context& context, SemIR::LocId loc_id,
|
||||
@@ -547,7 +545,8 @@ auto LookupNameInCore(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
|
||||
auto DiagnoseDuplicateName(Context& context, SemIR::NameId name_id,
|
||||
SemIRLoc dup_def, SemIRLoc prev_def) -> void {
|
||||
SemIR::LocId dup_def, SemIR::LocId prev_def)
|
||||
-> void {
|
||||
CARBON_DIAGNOSTIC(NameDeclDuplicate, Error,
|
||||
"duplicate name `{0}` being declared in the same scope",
|
||||
SemIR::NameId);
|
||||
@@ -572,10 +571,10 @@ auto DiagnosePoisonedName(Context& context, SemIR::NameId name_id,
|
||||
.Emit();
|
||||
}
|
||||
|
||||
auto DiagnoseNameNotFound(Context& context, SemIRLoc loc, SemIR::NameId name_id)
|
||||
-> void {
|
||||
auto DiagnoseNameNotFound(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::NameId name_id) -> void {
|
||||
CARBON_DIAGNOSTIC(NameNotFound, Error, "name `{0}` not found", SemIR::NameId);
|
||||
context.emitter().Emit(loc, NameNotFound, name_id);
|
||||
context.emitter().Emit(loc_id, NameNotFound, name_id);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -101,7 +101,7 @@ auto LookupNameInCore(Context& context, SemIR::LocId loc_id,
|
||||
|
||||
// Prints a diagnostic for a duplicate name.
|
||||
auto DiagnoseDuplicateName(Context& context, SemIR::NameId name_id,
|
||||
SemIRLoc dup_def, SemIRLoc prev_def) -> void;
|
||||
SemIR::LocId dup_def, SemIR::LocId prev_def) -> void;
|
||||
|
||||
// Prints a diagnostic for a poisoned name when it's later declared.
|
||||
auto DiagnosePoisonedName(Context& context, SemIR::NameId name_id,
|
||||
@@ -109,8 +109,8 @@ auto DiagnosePoisonedName(Context& context, SemIR::NameId name_id,
|
||||
SemIR::LocId decl_name_loc_id) -> void;
|
||||
|
||||
// Prints a diagnostic for a missing name.
|
||||
auto DiagnoseNameNotFound(Context& context, SemIRLoc loc, SemIR::NameId name_id)
|
||||
-> void;
|
||||
auto DiagnoseNameNotFound(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::NameId name_id) -> void;
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Carbon::Check {
|
||||
class RegionStack {
|
||||
public:
|
||||
// A callback for Context::TODO.
|
||||
using TodoFn = std::function<auto(SemIRLoc, std::string)->void>;
|
||||
using TodoFn = std::function<auto(SemIR::LocId, std::string)->void>;
|
||||
|
||||
explicit RegionStack(TodoFn todo_fn) : todo_fn_(std::move(todo_fn)) {}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
namespace Carbon::Check {
|
||||
|
||||
// Enforces that an integer type has a valid bit width.
|
||||
auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result)
|
||||
-> bool {
|
||||
auto ValidateIntType(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::IntType result) -> bool {
|
||||
auto bit_width =
|
||||
context.insts().TryGetAs<SemIR::IntValue>(result.bit_width_id);
|
||||
if (!bit_width) {
|
||||
@@ -26,7 +26,7 @@ auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result)
|
||||
CARBON_DIAGNOSTIC(IntWidthNotPositive, Error,
|
||||
"integer type width of {0} is not positive", TypedInt);
|
||||
context.emitter().Emit(
|
||||
loc, IntWidthNotPositive,
|
||||
loc_id, IntWidthNotPositive,
|
||||
{.type = bit_width->type_id, .value = bit_width_val});
|
||||
return false;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result)
|
||||
"integer type width of {0} is greater than the "
|
||||
"maximum supported width of {1}",
|
||||
TypedInt, int);
|
||||
context.emitter().Emit(loc, IntWidthTooLarge,
|
||||
context.emitter().Emit(loc_id, IntWidthTooLarge,
|
||||
{.type = bit_width->type_id, .value = bit_width_val},
|
||||
IntStore::MaxIntWidth);
|
||||
return false;
|
||||
@@ -44,7 +44,7 @@ auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result)
|
||||
}
|
||||
|
||||
// Enforces that the bit width is 64 for a float.
|
||||
auto ValidateFloatBitWidth(Context& context, SemIRLoc loc,
|
||||
auto ValidateFloatBitWidth(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId inst_id) -> bool {
|
||||
auto inst = context.insts().GetAs<SemIR::IntValue>(inst_id);
|
||||
if (context.ints().Get(inst.int_id) == 64) {
|
||||
@@ -52,20 +52,20 @@ auto ValidateFloatBitWidth(Context& context, SemIRLoc loc,
|
||||
}
|
||||
|
||||
CARBON_DIAGNOSTIC(CompileTimeFloatBitWidth, Error, "bit width must be 64");
|
||||
context.emitter().Emit(loc, CompileTimeFloatBitWidth);
|
||||
context.emitter().Emit(loc_id, CompileTimeFloatBitWidth);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enforces that a float type has a valid bit width.
|
||||
auto ValidateFloatType(Context& context, SemIRLoc loc, SemIR::FloatType result)
|
||||
-> bool {
|
||||
auto ValidateFloatType(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::FloatType result) -> bool {
|
||||
auto bit_width =
|
||||
context.insts().TryGetAs<SemIR::IntValue>(result.bit_width_id);
|
||||
if (!bit_width) {
|
||||
// Symbolic bit width.
|
||||
return true;
|
||||
}
|
||||
return ValidateFloatBitWidth(context, loc, result.bit_width_id);
|
||||
return ValidateFloatBitWidth(context, loc_id, result.bit_width_id);
|
||||
}
|
||||
|
||||
// Gets or forms a type_id for a type, given the instruction kind and arguments.
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
namespace Carbon::Check {
|
||||
|
||||
// Enforces that an integer type has a valid bit width.
|
||||
auto ValidateIntType(Context& context, SemIRLoc loc, SemIR::IntType result)
|
||||
-> bool;
|
||||
auto ValidateIntType(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::IntType result) -> bool;
|
||||
|
||||
// Enforces that the bit width is 64 for a float.
|
||||
auto ValidateFloatBitWidth(Context& context, SemIRLoc loc,
|
||||
auto ValidateFloatBitWidth(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId inst_id) -> bool;
|
||||
|
||||
// Enforces that a float type has a valid bit width.
|
||||
auto ValidateFloatType(Context& context, SemIRLoc loc, SemIR::FloatType result)
|
||||
-> bool;
|
||||
auto ValidateFloatType(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::FloatType result) -> bool;
|
||||
|
||||
// Gets the type to use for an unbound associated entity declared in this
|
||||
// interface. For example, this is the type of `I.T` after
|
||||
|
||||
@@ -30,9 +30,9 @@ namespace {
|
||||
class TypeCompleter {
|
||||
public:
|
||||
// `context` mut not be null.
|
||||
TypeCompleter(Context* context, SemIRLoc loc,
|
||||
TypeCompleter(Context* context, SemIR::LocId loc_id,
|
||||
MakeDiagnosticBuilderFn diagnoser)
|
||||
: context_(context), loc_(loc), diagnoser_(diagnoser) {}
|
||||
: context_(context), loc_id_(loc_id), diagnoser_(diagnoser) {}
|
||||
|
||||
// Attempts to complete the given type. Returns true if it is now complete,
|
||||
// false if it could not be completed.
|
||||
@@ -165,7 +165,7 @@ class TypeCompleter {
|
||||
|
||||
Context* context_;
|
||||
llvm::SmallVector<WorkItem> work_list_;
|
||||
SemIRLoc loc_;
|
||||
SemIR::LocId loc_id_;
|
||||
MakeDiagnosticBuilderFn diagnoser_;
|
||||
};
|
||||
} // namespace
|
||||
@@ -274,7 +274,7 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool {
|
||||
return false;
|
||||
}
|
||||
if (inst.specific_id.has_value()) {
|
||||
ResolveSpecificDefinition(*context_, loc_, inst.specific_id);
|
||||
ResolveSpecificDefinition(*context_, loc_id_, inst.specific_id);
|
||||
}
|
||||
if (auto adapted_type_id =
|
||||
class_info.GetAdaptedType(context_->sem_ir(), inst.specific_id);
|
||||
@@ -307,7 +307,8 @@ auto TypeCompleter::AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool {
|
||||
}
|
||||
|
||||
if (req_interface.specific_id.has_value()) {
|
||||
ResolveSpecificDefinition(*context_, loc_, req_interface.specific_id);
|
||||
ResolveSpecificDefinition(*context_, loc_id_,
|
||||
req_interface.specific_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -531,9 +532,10 @@ auto TypeCompleter::BuildInfo(SemIR::TypeId type_id, SemIR::Inst inst) const
|
||||
}
|
||||
}
|
||||
|
||||
auto TryToCompleteType(Context& context, SemIR::TypeId type_id, SemIRLoc loc,
|
||||
MakeDiagnosticBuilderFn diagnoser) -> bool {
|
||||
return TypeCompleter(&context, loc, diagnoser).Complete(type_id);
|
||||
auto TryToCompleteType(Context& context, SemIR::TypeId type_id,
|
||||
SemIR::LocId loc_id, MakeDiagnosticBuilderFn diagnoser)
|
||||
-> bool {
|
||||
return TypeCompleter(&context, loc_id, diagnoser).Complete(type_id);
|
||||
}
|
||||
|
||||
auto CompleteTypeOrCheckFail(Context& context, SemIR::TypeId type_id) -> void {
|
||||
|
||||
@@ -20,7 +20,8 @@ namespace Carbon::Check {
|
||||
// However, it's important that we use it during monomorphization, where we
|
||||
// don't want to trigger a request for more monomorphization.
|
||||
// TODO: Remove the other call to this function.
|
||||
auto TryToCompleteType(Context& context, SemIR::TypeId type_id, SemIRLoc loc,
|
||||
auto TryToCompleteType(Context& context, SemIR::TypeId type_id,
|
||||
SemIR::LocId loc_id,
|
||||
MakeDiagnosticBuilderFn diagnoser = nullptr) -> bool;
|
||||
|
||||
// Completes the type `type_id`. CHECK-fails if it can't be completed.
|
||||
|
||||
Reference in New Issue
Block a user