mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Remove offsets from InstId formatting, trying to name more (#4645)
The offsets were originally added to deal with churn from builtins in the raw semir. In textual semir, we mostly see instruction IDs for imports, and builtins have also settled down more. On imports, where possible, use the `EntityNameId` for an import instead of printing an instruction. Next, show the source location if we have a node. Only show the instruction if there's no location. This also exposes `Parse::Tree` and `TokenizedBuffer`, so that we can pass a `SemIR::File` without the component parts. In particular this allows us to get the `TokenizedBuffer` for import IRs without substantial structural modifications. We may want to make these optional for serialized `SemIR` later, but the nodes/tokens contain source location, which we'd need for debug information -- so it's not clear how much we can really make them optional without substantial information loss. Reduce arguments to just `File` in a few spots, as a result of the accompanying `TokenizedBuffer` and `Parse::Tree`. Also updates style to pass around `const File*` where the reference is maintained, instead of `const File&`. I was considering keeping a direct reference to the tree and tokens on `Context`, but initially my thought was it wouldn't make much difference. I can re-add those if desired, just as direct caching of the `File` fields.
This commit is contained in:
+101
-90
@@ -25,7 +25,7 @@ namespace Carbon::SemIR {
|
||||
// Formatter for printing textual Semantics IR.
|
||||
class FormatterImpl {
|
||||
public:
|
||||
explicit FormatterImpl(const File& sem_ir, InstNamer* inst_namer,
|
||||
explicit FormatterImpl(const File* sem_ir, InstNamer* inst_namer,
|
||||
Formatter::ShouldFormatEntityFn should_format_entity,
|
||||
int indent)
|
||||
: sem_ir_(sem_ir),
|
||||
@@ -35,7 +35,7 @@ class FormatterImpl {
|
||||
// Create the first chunk and assign it to all instructions that don't have
|
||||
// a chunk of their own.
|
||||
auto first_chunk = AddChunkNoFlush(true);
|
||||
tentative_inst_chunks_.resize(sem_ir.insts().size(), first_chunk);
|
||||
tentative_inst_chunks_.resize(sem_ir_->insts().size(), first_chunk);
|
||||
}
|
||||
|
||||
// Prints the SemIR.
|
||||
@@ -44,12 +44,12 @@ class FormatterImpl {
|
||||
// including file-scoped instructions. The file scope may contain entity
|
||||
// declarations which are defined later, such as classes.
|
||||
auto Format() -> void {
|
||||
out_ << "--- " << sem_ir_.filename() << "\n\n";
|
||||
out_ << "--- " << sem_ir_->filename() << "\n\n";
|
||||
|
||||
FormatScopeIfUsed(InstNamer::ScopeId::Constants,
|
||||
sem_ir_.constants().array_ref());
|
||||
sem_ir_->constants().array_ref());
|
||||
FormatScopeIfUsed(InstNamer::ScopeId::ImportRefs,
|
||||
sem_ir_.inst_blocks().Get(InstBlockId::ImportRefs));
|
||||
sem_ir_->inst_blocks().Get(InstBlockId::ImportRefs));
|
||||
|
||||
out_ << inst_namer_->GetScopeName(InstNamer::ScopeId::File) << " ";
|
||||
OpenBrace();
|
||||
@@ -57,7 +57,7 @@ class FormatterImpl {
|
||||
// TODO: Handle the case where there are multiple top-level instruction
|
||||
// blocks. For example, there may be branching in the initializer of a
|
||||
// global or a type expression.
|
||||
if (auto block_id = sem_ir_.top_inst_block_id(); block_id.is_valid()) {
|
||||
if (auto block_id = sem_ir_->top_inst_block_id(); block_id.is_valid()) {
|
||||
llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeId::File);
|
||||
FormatCodeBlock(block_id);
|
||||
}
|
||||
@@ -65,23 +65,23 @@ class FormatterImpl {
|
||||
CloseBrace();
|
||||
out_ << '\n';
|
||||
|
||||
for (int i : llvm::seq(sem_ir_.interfaces().size())) {
|
||||
for (int i : llvm::seq(sem_ir_->interfaces().size())) {
|
||||
FormatInterface(InterfaceId(i));
|
||||
}
|
||||
|
||||
for (int i : llvm::seq(sem_ir_.impls().size())) {
|
||||
for (int i : llvm::seq(sem_ir_->impls().size())) {
|
||||
FormatImpl(ImplId(i));
|
||||
}
|
||||
|
||||
for (int i : llvm::seq(sem_ir_.classes().size())) {
|
||||
for (int i : llvm::seq(sem_ir_->classes().size())) {
|
||||
FormatClass(ClassId(i));
|
||||
}
|
||||
|
||||
for (int i : llvm::seq(sem_ir_.functions().size())) {
|
||||
for (int i : llvm::seq(sem_ir_->functions().size())) {
|
||||
FormatFunction(FunctionId(i));
|
||||
}
|
||||
|
||||
for (int i : llvm::seq(sem_ir_.specifics().size())) {
|
||||
for (int i : llvm::seq(sem_ir_->specifics().size())) {
|
||||
FormatSpecific(SpecificId(i));
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class FormatterImpl {
|
||||
|
||||
// Formats a full class.
|
||||
auto FormatClass(ClassId id) -> void {
|
||||
const Class& class_info = sem_ir_.classes().Get(id);
|
||||
const Class& class_info = sem_ir_->classes().Get(id);
|
||||
if (!ShouldFormatEntity(class_info)) {
|
||||
return;
|
||||
}
|
||||
@@ -289,7 +289,7 @@ class FormatterImpl {
|
||||
|
||||
// Formats a full interface.
|
||||
auto FormatInterface(InterfaceId id) -> void {
|
||||
const Interface& interface_info = sem_ir_.interfaces().Get(id);
|
||||
const Interface& interface_info = sem_ir_->interfaces().Get(id);
|
||||
if (!ShouldFormatEntity(interface_info)) {
|
||||
return;
|
||||
}
|
||||
@@ -325,7 +325,7 @@ class FormatterImpl {
|
||||
|
||||
// Formats a full impl.
|
||||
auto FormatImpl(ImplId id) -> void {
|
||||
const Impl& impl_info = sem_ir_.impls().Get(id);
|
||||
const Impl& impl_info = sem_ir_->impls().Get(id);
|
||||
if (!ShouldFormatEntity(impl_info)) {
|
||||
return;
|
||||
}
|
||||
@@ -368,7 +368,7 @@ class FormatterImpl {
|
||||
|
||||
// Formats a full function.
|
||||
auto FormatFunction(FunctionId id) -> void {
|
||||
const Function& fn = sem_ir_.functions().Get(id);
|
||||
const Function& fn = sem_ir_->functions().Get(id);
|
||||
if (!ShouldFormatEntity(fn)) {
|
||||
return;
|
||||
}
|
||||
@@ -400,13 +400,13 @@ class FormatterImpl {
|
||||
|
||||
if (fn.return_slot_pattern_id.is_valid()) {
|
||||
out_ << " -> ";
|
||||
auto return_info = ReturnTypeInfo::ForFunction(sem_ir_, fn);
|
||||
auto return_info = ReturnTypeInfo::ForFunction(*sem_ir_, fn);
|
||||
if (!fn.body_block_ids.empty() && return_info.is_valid() &&
|
||||
return_info.has_return_slot()) {
|
||||
FormatName(fn.return_slot_pattern_id);
|
||||
out_ << ": ";
|
||||
}
|
||||
FormatType(sem_ir_.insts().Get(fn.return_slot_pattern_id).type_id());
|
||||
FormatType(sem_ir_->insts().Get(fn.return_slot_pattern_id).type_id());
|
||||
}
|
||||
|
||||
if (fn.builtin_function_kind != BuiltinFunctionKind::None) {
|
||||
@@ -450,8 +450,8 @@ class FormatterImpl {
|
||||
out_ << "!" << region_name << ":\n";
|
||||
}
|
||||
for (auto [generic_inst_id, specific_inst_id] : llvm::zip_longest(
|
||||
sem_ir_.inst_blocks().GetOrEmpty(generic.GetEvalBlock(region)),
|
||||
sem_ir_.inst_blocks().GetOrEmpty(
|
||||
sem_ir_->inst_blocks().GetOrEmpty(generic.GetEvalBlock(region)),
|
||||
sem_ir_->inst_blocks().GetOrEmpty(
|
||||
specific.GetValueBlock(region)))) {
|
||||
Indent();
|
||||
if (generic_inst_id) {
|
||||
@@ -471,8 +471,8 @@ class FormatterImpl {
|
||||
|
||||
// Formats a full specific.
|
||||
auto FormatSpecific(SpecificId id) -> void {
|
||||
const auto& specific = sem_ir_.specifics().Get(id);
|
||||
const auto& generic = sem_ir_.generics().Get(specific.generic_id);
|
||||
const auto& specific = sem_ir_->specifics().Get(id);
|
||||
const auto& generic = sem_ir_->generics().Get(specific.generic_id);
|
||||
if (!should_format_entity_(generic.decl_id)) {
|
||||
// Omit specifics if we also omitted the generic.
|
||||
return;
|
||||
@@ -500,7 +500,7 @@ class FormatterImpl {
|
||||
// Handles generic-specific setup for FormatEntityStart.
|
||||
auto FormatGenericStart(llvm::StringRef entity_kind, GenericId generic_id)
|
||||
-> void {
|
||||
const auto& generic = sem_ir_.generics().Get(generic_id);
|
||||
const auto& generic = sem_ir_->generics().Get(generic_id);
|
||||
out_ << "\n";
|
||||
Indent();
|
||||
out_ << "generic " << entity_kind << " ";
|
||||
@@ -529,11 +529,12 @@ class FormatterImpl {
|
||||
// If this entity was imported from a different IR, annotate the name of
|
||||
// that IR in the output before the `{` or `;`.
|
||||
if (entity.first_owning_decl_id.is_valid()) {
|
||||
auto loc_id = sem_ir_.insts().GetLocId(entity.first_owning_decl_id);
|
||||
auto loc_id = sem_ir_->insts().GetLocId(entity.first_owning_decl_id);
|
||||
if (loc_id.is_import_ir_inst_id()) {
|
||||
auto import_ir_id =
|
||||
sem_ir_.import_ir_insts().Get(loc_id.import_ir_inst_id()).ir_id;
|
||||
const auto* import_file = sem_ir_.import_irs().Get(import_ir_id).sem_ir;
|
||||
sem_ir_->import_ir_insts().Get(loc_id.import_ir_inst_id()).ir_id;
|
||||
const auto* import_file =
|
||||
sem_ir_->import_irs().Get(import_ir_id).sem_ir;
|
||||
pending_imported_from_ = import_file->filename();
|
||||
}
|
||||
}
|
||||
@@ -575,19 +576,19 @@ class FormatterImpl {
|
||||
out_ << (is_implicit ? "[" : "(");
|
||||
|
||||
llvm::ListSeparator sep;
|
||||
for (InstId param_id : sem_ir_.inst_blocks().Get(param_patterns_id)) {
|
||||
for (InstId param_id : sem_ir_->inst_blocks().Get(param_patterns_id)) {
|
||||
out_ << sep;
|
||||
if (!param_id.is_valid()) {
|
||||
out_ << "invalid";
|
||||
continue;
|
||||
}
|
||||
if (auto addr = sem_ir_.insts().TryGetAs<SemIR::AddrPattern>(param_id)) {
|
||||
if (auto addr = sem_ir_->insts().TryGetAs<SemIR::AddrPattern>(param_id)) {
|
||||
out_ << "addr ";
|
||||
param_id = addr->inner_id;
|
||||
}
|
||||
FormatName(param_id);
|
||||
out_ << ": ";
|
||||
FormatType(sem_ir_.insts().Get(param_id).type_id());
|
||||
FormatType(sem_ir_->insts().Get(param_id).type_id());
|
||||
}
|
||||
|
||||
out_ << (is_implicit ? "]" : ")");
|
||||
@@ -595,7 +596,7 @@ class FormatterImpl {
|
||||
|
||||
// Prints instructions for a code block.
|
||||
auto FormatCodeBlock(InstBlockId block_id) -> void {
|
||||
for (const InstId inst_id : sem_ir_.inst_blocks().GetOrEmpty(block_id)) {
|
||||
for (const InstId inst_id : sem_ir_->inst_blocks().GetOrEmpty(block_id)) {
|
||||
FormatInst(inst_id);
|
||||
}
|
||||
}
|
||||
@@ -611,7 +612,7 @@ class FormatterImpl {
|
||||
|
||||
// Prints the contents of a name scope, with an optional label.
|
||||
auto FormatNameScope(NameScopeId id, llvm::StringRef label = "") -> void {
|
||||
const auto& scope = sem_ir_.name_scopes().Get(id);
|
||||
const auto& scope = sem_ir_->name_scopes().Get(id);
|
||||
|
||||
if (scope.names.empty() && scope.extended_scopes.empty() &&
|
||||
scope.import_ir_scopes.empty() && !scope.has_error) {
|
||||
@@ -684,7 +685,7 @@ class FormatterImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
FormatInst(inst_id, sem_ir_.insts().Get(inst_id));
|
||||
FormatInst(inst_id, sem_ir_->insts().Get(inst_id));
|
||||
}
|
||||
|
||||
auto FormatInst(InstId inst_id, Inst inst) -> void {
|
||||
@@ -703,9 +704,9 @@ class FormatterImpl {
|
||||
Indent();
|
||||
FormatInstLHS(inst_id, inst);
|
||||
out_ << InstT::Kind.ir_name();
|
||||
pending_constant_value_ = sem_ir_.constant_values().Get(inst_id);
|
||||
pending_constant_value_ = sem_ir_->constant_values().Get(inst_id);
|
||||
pending_constant_value_is_self_ =
|
||||
sem_ir_.constant_values().GetInstIdIfValid(pending_constant_value_) ==
|
||||
sem_ir_->constant_values().GetInstIdIfValid(pending_constant_value_) ==
|
||||
inst_id;
|
||||
FormatInstRHS(inst);
|
||||
FormatPendingConstantValue(AddSpace::Before);
|
||||
@@ -774,7 +775,7 @@ class FormatterImpl {
|
||||
case InstValueKind::Typed:
|
||||
FormatName(inst_id);
|
||||
out_ << ": ";
|
||||
switch (GetExprCategory(sem_ir_, inst_id)) {
|
||||
switch (GetExprCategory(*sem_ir_, inst_id)) {
|
||||
case ExprCategory::NotExpr:
|
||||
case ExprCategory::Error:
|
||||
case ExprCategory::Value:
|
||||
@@ -898,9 +899,9 @@ class FormatterImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
llvm::ArrayRef<InstId> args = sem_ir_.inst_blocks().Get(inst.args_id);
|
||||
llvm::ArrayRef<InstId> args = sem_ir_->inst_blocks().Get(inst.args_id);
|
||||
|
||||
auto return_info = ReturnTypeInfo::ForType(sem_ir_, inst.type_id);
|
||||
auto return_info = ReturnTypeInfo::ForType(*sem_ir_, inst.type_id);
|
||||
bool has_return_slot = return_info.has_return_slot();
|
||||
InstId return_slot_arg_id = InstId::Invalid;
|
||||
if (has_return_slot) {
|
||||
@@ -975,7 +976,7 @@ class FormatterImpl {
|
||||
llvm::SaveAndRestore class_scope(
|
||||
scope_, inst_namer_->GetScopeFor(inst.function_id));
|
||||
FormatTrailingBlock(
|
||||
sem_ir_.functions().Get(inst.function_id).pattern_block_id);
|
||||
sem_ir_->functions().Get(inst.function_id).pattern_block_id);
|
||||
FormatTrailingBlock(inst.decl_block_id);
|
||||
}
|
||||
|
||||
@@ -983,7 +984,7 @@ class FormatterImpl {
|
||||
FormatArgs(inst.class_id);
|
||||
llvm::SaveAndRestore class_scope(scope_,
|
||||
inst_namer_->GetScopeFor(inst.class_id));
|
||||
FormatTrailingBlock(sem_ir_.classes().Get(inst.class_id).pattern_block_id);
|
||||
FormatTrailingBlock(sem_ir_->classes().Get(inst.class_id).pattern_block_id);
|
||||
FormatTrailingBlock(inst.decl_block_id);
|
||||
}
|
||||
|
||||
@@ -991,7 +992,7 @@ class FormatterImpl {
|
||||
FormatArgs(inst.impl_id);
|
||||
llvm::SaveAndRestore class_scope(scope_,
|
||||
inst_namer_->GetScopeFor(inst.impl_id));
|
||||
FormatTrailingBlock(sem_ir_.impls().Get(inst.impl_id).pattern_block_id);
|
||||
FormatTrailingBlock(sem_ir_->impls().Get(inst.impl_id).pattern_block_id);
|
||||
FormatTrailingBlock(inst.decl_block_id);
|
||||
}
|
||||
|
||||
@@ -1000,31 +1001,63 @@ class FormatterImpl {
|
||||
llvm::SaveAndRestore class_scope(
|
||||
scope_, inst_namer_->GetScopeFor(inst.interface_id));
|
||||
FormatTrailingBlock(
|
||||
sem_ir_.interfaces().Get(inst.interface_id).pattern_block_id);
|
||||
sem_ir_->interfaces().Get(inst.interface_id).pattern_block_id);
|
||||
FormatTrailingBlock(inst.decl_block_id);
|
||||
}
|
||||
|
||||
auto FormatInstRHS(IntValue inst) -> void {
|
||||
out_ << " ";
|
||||
sem_ir_.ints()
|
||||
sem_ir_->ints()
|
||||
.Get(inst.int_id)
|
||||
.print(out_, sem_ir_.types().IsSignedInt(inst.type_id));
|
||||
.print(out_, sem_ir_->types().IsSignedInt(inst.type_id));
|
||||
}
|
||||
|
||||
auto FormatInstRHS(FloatLiteral inst) -> void {
|
||||
llvm::SmallVector<char, 16> buffer;
|
||||
sem_ir_.floats().Get(inst.float_id).toString(buffer);
|
||||
sem_ir_->floats().Get(inst.float_id).toString(buffer);
|
||||
out_ << " " << buffer;
|
||||
}
|
||||
|
||||
auto FormatInstRHS(ImportRefUnloaded inst) -> void {
|
||||
FormatArgs(inst.import_ir_inst_id);
|
||||
out_ << ", unloaded";
|
||||
auto FormatImportRefRHS(ImportIRInstId import_ir_inst_id,
|
||||
EntityNameId entity_name_id,
|
||||
llvm::StringLiteral loaded_label) -> void {
|
||||
out_ << " ";
|
||||
auto import_ir_inst = sem_ir_->import_ir_insts().Get(import_ir_inst_id);
|
||||
FormatArg(import_ir_inst.ir_id);
|
||||
out_ << ", ";
|
||||
if (entity_name_id.is_valid()) {
|
||||
// Prefer to show the entity name when possible.
|
||||
FormatArg(entity_name_id);
|
||||
} else {
|
||||
// Show a name based on the location when possible, or the numeric
|
||||
// instruction as a last resort.
|
||||
const auto& import_ir = sem_ir_->import_irs().Get(import_ir_inst.ir_id);
|
||||
auto loc_id = import_ir.sem_ir->insts().GetLocId(import_ir_inst.inst_id);
|
||||
if (!loc_id.is_valid()) {
|
||||
out_ << import_ir_inst.inst_id << " [no loc]";
|
||||
} else if (loc_id.is_import_ir_inst_id()) {
|
||||
// TODO: Probably don't want to format each indirection, but maybe reuse
|
||||
// GetCanonicalImportIRInst?
|
||||
out_ << import_ir_inst.inst_id << " [indirect]";
|
||||
} else if (loc_id.is_node_id()) {
|
||||
// Formats a NodeId from the import.
|
||||
const auto& tree = import_ir.sem_ir->parse_tree();
|
||||
auto token = tree.node_token(loc_id.node_id());
|
||||
out_ << "loc" << tree.tokens().GetLineNumber(token) << "_"
|
||||
<< tree.tokens().GetColumnNumber(token);
|
||||
} else {
|
||||
CARBON_FATAL("Unexpected LocId: {0}", loc_id);
|
||||
}
|
||||
}
|
||||
out_ << ", " << loaded_label;
|
||||
}
|
||||
|
||||
auto FormatInstRHS(ImportRefLoaded inst) -> void {
|
||||
FormatArgs(inst.import_ir_inst_id);
|
||||
out_ << ", loaded";
|
||||
FormatImportRefRHS(inst.import_ir_inst_id, inst.entity_name_id, "loaded");
|
||||
}
|
||||
|
||||
auto FormatInstRHS(ImportRefUnloaded inst) -> void {
|
||||
FormatImportRefRHS(inst.import_ir_inst_id, inst.entity_name_id, "unloaded");
|
||||
}
|
||||
|
||||
auto FormatInstRHS(SpliceBlock inst) -> void {
|
||||
@@ -1040,7 +1073,7 @@ class FormatterImpl {
|
||||
auto FormatInstRHS(StructType inst) -> void {
|
||||
out_ << " {";
|
||||
llvm::ListSeparator sep;
|
||||
for (auto field : sem_ir_.struct_type_fields().Get(inst.fields_id)) {
|
||||
for (auto field : sem_ir_->struct_type_fields().Get(inst.fields_id)) {
|
||||
out_ << sep << ".";
|
||||
FormatName(field.name_id);
|
||||
out_ << ": ";
|
||||
@@ -1069,7 +1102,7 @@ class FormatterImpl {
|
||||
auto FormatArg(BoolValue v) -> void { out_ << v; }
|
||||
|
||||
auto FormatArg(EntityNameId id) -> void {
|
||||
const auto& info = sem_ir_.entity_names().Get(id);
|
||||
const auto& info = sem_ir_->entity_names().Get(id);
|
||||
FormatName(info.name_id);
|
||||
if (info.bind_index.is_valid()) {
|
||||
out_ << ", " << info.bind_index.index;
|
||||
@@ -1077,7 +1110,7 @@ class FormatterImpl {
|
||||
}
|
||||
|
||||
auto FormatArg(FacetTypeId id) -> void {
|
||||
const auto& info = sem_ir_.facet_types().Get(id);
|
||||
const auto& info = sem_ir_->facet_types().Get(id);
|
||||
// Nothing output to indicate that this is a facet type since this is only
|
||||
// used as the argument to a `facet_type` instruction.
|
||||
out_ << "<";
|
||||
@@ -1125,30 +1158,9 @@ class FormatterImpl {
|
||||
}
|
||||
}
|
||||
|
||||
auto FormatArg(ImportIRInstId id) -> void {
|
||||
// Don't format the inst_id because it refers to a different IR.
|
||||
// TODO: Consider a better way to format the InstID from other IRs.
|
||||
auto import_ir_inst = sem_ir_.import_ir_insts().Get(id);
|
||||
FormatArg(import_ir_inst.ir_id);
|
||||
out_ << ", " << import_ir_inst.inst_id;
|
||||
}
|
||||
|
||||
auto FormatArg(IntId id) -> void {
|
||||
// We don't know the signedness to use here. Default to unsigned.
|
||||
sem_ir_.ints().Get(id).print(out_, /*isSigned=*/false);
|
||||
}
|
||||
|
||||
auto FormatArg(LocId id) -> void {
|
||||
if (id.is_import_ir_inst_id()) {
|
||||
out_ << "{";
|
||||
FormatArg(id.import_ir_inst_id());
|
||||
out_ << "}";
|
||||
} else {
|
||||
// TODO: For a NodeId, this prints the index of the node. Do we want it to
|
||||
// print a line number or something in order to make it less dependent on
|
||||
// parse?
|
||||
out_ << id;
|
||||
}
|
||||
sem_ir_->ints().Get(id).print(out_, /*isSigned=*/false);
|
||||
}
|
||||
|
||||
auto FormatArg(ElementIndex index) -> void { out_ << index; }
|
||||
@@ -1169,7 +1181,7 @@ class FormatterImpl {
|
||||
|
||||
out_ << '(';
|
||||
llvm::ListSeparator sep;
|
||||
for (auto inst_id : sem_ir_.inst_blocks().Get(id)) {
|
||||
for (auto inst_id : sem_ir_->inst_blocks().Get(id)) {
|
||||
out_ << sep;
|
||||
FormatArg(inst_id);
|
||||
}
|
||||
@@ -1178,14 +1190,14 @@ class FormatterImpl {
|
||||
|
||||
auto FormatArg(RealId id) -> void {
|
||||
// TODO: Format with a `.` when the exponent is near zero.
|
||||
const auto& real = sem_ir_.reals().Get(id);
|
||||
const auto& real = sem_ir_->reals().Get(id);
|
||||
real.mantissa.print(out_, /*isSigned=*/false);
|
||||
out_ << (real.is_decimal ? 'e' : 'p') << real.exponent;
|
||||
}
|
||||
|
||||
auto FormatArg(StringLiteralValueId id) -> void {
|
||||
out_ << '"';
|
||||
out_.write_escaped(sem_ir_.string_literal_values().Get(id),
|
||||
out_.write_escaped(sem_ir_->string_literal_values().Get(id),
|
||||
/*UseHexEscapes=*/true);
|
||||
out_ << '"';
|
||||
}
|
||||
@@ -1195,7 +1207,7 @@ class FormatterImpl {
|
||||
auto FormatArg(TypeBlockId id) -> void {
|
||||
out_ << '(';
|
||||
llvm::ListSeparator sep;
|
||||
for (auto type_id : sem_ir_.type_blocks().Get(id)) {
|
||||
for (auto type_id : sem_ir_->type_blocks().Get(id)) {
|
||||
out_ << sep;
|
||||
FormatArg(type_id);
|
||||
}
|
||||
@@ -1216,7 +1228,7 @@ class FormatterImpl {
|
||||
}
|
||||
|
||||
auto FormatName(NameId id) -> void {
|
||||
out_ << sem_ir_.names().GetFormatted(id);
|
||||
out_ << sem_ir_->names().GetFormatted(id);
|
||||
}
|
||||
|
||||
auto FormatName(InstId id) -> void {
|
||||
@@ -1231,7 +1243,7 @@ class FormatterImpl {
|
||||
}
|
||||
|
||||
auto FormatName(SpecificId id) -> void {
|
||||
const auto& specific = sem_ir_.specifics().Get(id);
|
||||
const auto& specific = sem_ir_->specifics().Get(id);
|
||||
FormatName(specific.generic_id);
|
||||
FormatArg(specific.args_id);
|
||||
}
|
||||
@@ -1250,21 +1262,21 @@ class FormatterImpl {
|
||||
// generic first, and the canonical constant second.
|
||||
if (id.is_symbolic()) {
|
||||
const auto& symbolic_constant =
|
||||
sem_ir_.constant_values().GetSymbolicConstant(id);
|
||||
sem_ir_->constant_values().GetSymbolicConstant(id);
|
||||
if (symbolic_constant.generic_id.is_valid()) {
|
||||
const auto& generic =
|
||||
sem_ir_.generics().Get(symbolic_constant.generic_id);
|
||||
FormatName(sem_ir_.inst_blocks().Get(generic.GetEvalBlock(
|
||||
sem_ir_->generics().Get(symbolic_constant.generic_id);
|
||||
FormatName(sem_ir_->inst_blocks().Get(generic.GetEvalBlock(
|
||||
symbolic_constant.index
|
||||
.region()))[symbolic_constant.index.index()]);
|
||||
out_ << " (";
|
||||
FormatName(sem_ir_.constant_values().GetInstId(id));
|
||||
FormatName(sem_ir_->constant_values().GetInstId(id));
|
||||
out_ << ")";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FormatName(sem_ir_.constant_values().GetInstId(id));
|
||||
FormatName(sem_ir_->constant_values().GetInstId(id));
|
||||
}
|
||||
|
||||
auto FormatType(TypeId id) -> void {
|
||||
@@ -1274,7 +1286,7 @@ class FormatterImpl {
|
||||
// Types are formatted in the `constants` scope because they only refer to
|
||||
// constants.
|
||||
llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeId::Constants);
|
||||
FormatConstant(sem_ir_.types().GetConstantId(id));
|
||||
FormatConstant(sem_ir_->types().GetConstantId(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,7 +1294,7 @@ class FormatterImpl {
|
||||
auto GetImportIRLabel(ImportIRId id) -> std::string {
|
||||
CARBON_CHECK(id.is_valid(),
|
||||
"GetImportIRLabel should only be called where we a valid ID.");
|
||||
const auto& import_ir = *sem_ir_.import_irs().Get(id).sem_ir;
|
||||
const auto& import_ir = *sem_ir_->import_irs().Get(id).sem_ir;
|
||||
CARBON_CHECK(import_ir.library_id().is_valid());
|
||||
|
||||
llvm::StringRef package_name =
|
||||
@@ -1297,7 +1309,7 @@ class FormatterImpl {
|
||||
return llvm::formatv("{0}//{1}", package_name, library_name);
|
||||
}
|
||||
|
||||
const File& sem_ir_;
|
||||
const File* sem_ir_;
|
||||
InstNamer* const inst_namer_;
|
||||
Formatter::ShouldFormatEntityFn should_format_entity_;
|
||||
|
||||
@@ -1347,12 +1359,11 @@ class FormatterImpl {
|
||||
llvm::SmallVector<size_t, 0> tentative_inst_chunks_;
|
||||
};
|
||||
|
||||
Formatter::Formatter(const Lex::TokenizedBuffer& tokenized_buffer,
|
||||
const Parse::Tree& parse_tree, const File& sem_ir,
|
||||
Formatter::Formatter(const File* sem_ir,
|
||||
ShouldFormatEntityFn should_format_entity)
|
||||
: sem_ir_(sem_ir),
|
||||
should_format_entity_(should_format_entity),
|
||||
inst_namer_(tokenized_buffer, parse_tree, sem_ir) {}
|
||||
inst_namer_(sem_ir) {}
|
||||
|
||||
Formatter::~Formatter() = default;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user