Adjust formatting of blocks and scopes (#5474)

This is making two inter-related changes:

- Change `file` to reuse the formatter logic of `constants` and
`imports`, meaning empty `file` scopes will be omitted
- Mark `<elided>` sections in blocks (not in non-block scopes, because
they're not as sequential)
This commit is contained in:
Jon Ross-Perkins
2025-05-16 22:50:28 +00:00
committed by GitHub
parent e68d65d4f6
commit e78a57bb82
24 changed files with 107 additions and 113 deletions
@@ -43,8 +43,6 @@ fn F() {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_nested.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -59,8 +57,6 @@ fn F() {
// CHECK:STDOUT: %false: bool = bool_literal false [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: generic class @C(<unexpected>.inst28.loc4_14: bool) {
// CHECK:STDOUT: %B: bool = bind_symbolic_name B, 0 [symbolic = %B (constants.%B.7dd)]
// CHECK:STDOUT:
@@ -88,6 +88,18 @@ fn F();
// CHECK:STDOUT: --- function.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
// CHECK:STDOUT: %B.type: type = fn_type @B [concrete]
// CHECK:STDOUT: %B: %B.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
// CHECK:STDOUT: %C: %C.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %C.decl: %C.type = fn_decl @C [concrete = constants.%C] {
// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete]
@@ -102,10 +114,12 @@ fn F();
// CHECK:STDOUT:
// CHECK:STDOUT: fn @B() -> %empty_tuple.type {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %b.ref.loc11: ref %empty_tuple.type = name_ref b, %b
// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A]
// CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.ref()
// CHECK:STDOUT: assign %b.ref.loc11, %A.call
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @C() -> %empty_tuple.type {
@@ -132,12 +146,23 @@ fn F();
// CHECK:STDOUT:
// CHECK:STDOUT: --- class.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %A: type = class_type @A [concrete]
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %I.type: type = fn_type @I [concrete]
// CHECK:STDOUT: %I: %I.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @A {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {}
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: complete_type_witness = %complete_type
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -148,6 +173,7 @@ fn F();
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %I.decl: %I.type = fn_decl @I [concrete = constants.%I] {} {}
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: complete_type_witness = %complete_type
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -162,22 +188,33 @@ fn F();
// CHECK:STDOUT:
// CHECK:STDOUT: --- call_params.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
// CHECK:STDOUT: %C: %C.type = struct_value () [concrete]
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A]
// CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.ref()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %C.call: init %empty_tuple.type = call %C.ref()
// CHECK:STDOUT: %.loc13_7.1: ref %empty_tuple.type = temporary_storage
// CHECK:STDOUT: %.loc13_7.2: ref %empty_tuple.type = temporary %.loc13_7.1, %A.call
// CHECK:STDOUT: %tuple.loc13: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc13_7.3: %empty_tuple.type = converted %A.call, %tuple.loc13 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc17_7.1: ref %empty_tuple.type = temporary_storage
// CHECK:STDOUT: %.loc17_7.2: ref %empty_tuple.type = temporary %.loc17_7.1, %C.call
// CHECK:STDOUT: %tuple.loc17: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc17_7.3: %empty_tuple.type = converted %C.call, %tuple.loc17 [concrete = constants.%empty_tuple]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- file_without_ranges.carbon
@@ -26,6 +26,11 @@ fn F();
// CHECK:STDOUT: --- with-range.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {}
// CHECK:STDOUT: }
-8
View File
@@ -196,8 +196,6 @@ var test_f128: f128;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- uN.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -268,13 +266,7 @@ var test_f128: f128;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_fN_bad_width.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_fN_todo_unsupported.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -22,5 +22,3 @@ fn N.base() {}
// CHECK:STDOUT: --- fail_base_as_declared_name.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -37,8 +37,6 @@ fn F() -> bool {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.b [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: class @Class {
// CHECK:STDOUT: %bool.make_type: init type = call constants.%Bool() [concrete = bool]
// CHECK:STDOUT: %.loc12_10.1: type = value_of_initializer %bool.make_type [concrete = bool]
@@ -94,8 +94,6 @@ var x: Class = {};
// CHECK:STDOUT: %Class: type = class_type @Class [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: class @Class {
// CHECK:STDOUT: complete_type_witness = invalid
// CHECK:STDOUT:
@@ -1049,8 +1049,6 @@ interface J {
// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] {
@@ -113,7 +113,15 @@ fn F(T: Z where .X = (), v: T.X);
// CHECK:STDOUT: --- facet_value_copy_from_reference.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %I.type [concrete]
// CHECK:STDOUT: %pattern_type.2b5: type = pattern_type %I.type [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%c.param: %C) {
// CHECK:STDOUT: !entry:
@@ -126,11 +134,21 @@ fn F(T: Z where .X = (), v: T.X);
// CHECK:STDOUT: %.loc13_15.2: %I.type = bind_value %.loc13_15.1
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %a: %I.type = bind_name a, %.loc13_15.2
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_facet_copy_narrowing_from_reference.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %facet_type: type = facet_type <@I & @J> [concrete]
// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %facet_type [concrete]
// CHECK:STDOUT: %pattern_type.2b5: type = pattern_type %I.type [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%c.param: %C) {
// CHECK:STDOUT: !entry:
@@ -143,5 +161,6 @@ fn F(T: Z where .X = (), v: T.X);
// CHECK:STDOUT: %.loc21_15.2: %facet_type = bind_value %.loc21_15.1
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %a: %I.type = bind_name a, <error>
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -299,8 +299,6 @@ extern library "extern_library_owner" fn F() {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_extern_library_mismatch_owner.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_extern_self_library.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -166,12 +166,8 @@ fn A {
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_arrow_body.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_invalid_file_generic_regression_test.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -87,22 +87,16 @@ fn F() {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_types.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_in_param.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_class.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -110,8 +104,6 @@ fn F() {
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true]
// CHECK:STDOUT: if %true br !if.expr.then else br !if.expr.else
@@ -134,8 +126,6 @@ fn F() {
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: generic class @C(<unexpected>.inst17.loc4_14: type) {
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
// CHECK:STDOUT:
@@ -123,8 +123,6 @@ interface I {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = <unexpected>.inst17
@@ -136,8 +134,6 @@ interface I {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = <unexpected>.inst17
@@ -77,8 +77,6 @@ var or_val: bool = true or true;
// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%b.param: bool) -> type {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %b.ref: bool = name_ref b, <unexpected>.inst28.loc5_6
@@ -106,8 +104,6 @@ var or_val: bool = true or true;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_or.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -118,8 +114,6 @@ var or_val: bool = true or true;
// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%b.param: bool) -> type {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %b.ref: bool = name_ref b, <unexpected>.inst28.loc5_6
@@ -147,5 +141,3 @@ var or_val: bool = true or true;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -344,8 +344,6 @@ export Poison;
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_export_in_impl.impl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- export_export.impl.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -374,9 +374,5 @@ var n: {} = i32;
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_prelude_as_namespace.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_prelude_as_class.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -467,8 +467,6 @@ fn F() -> {} {
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: complete_type_witness = invalid
// CHECK:STDOUT:
@@ -525,7 +523,5 @@ fn F() -> {} {
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() -> %empty_struct_type;
// CHECK:STDOUT:
@@ -26,5 +26,3 @@ fn G() { return {.return = 5}; };
// CHECK:STDOUT: --- fail_keyword_name.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -569,8 +569,6 @@ let (a: {}, b: {}) = ({}, {}, {});
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: complete_type_witness = invalid
// CHECK:STDOUT:
@@ -77,26 +77,18 @@ var y2: bool = false or true;
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_if_false.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_true_or_false.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_false_or_true.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
@@ -361,8 +361,6 @@ class C {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @f();
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_implicit.carbon
@@ -370,8 +368,6 @@ class C {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%.param: <error>);
// CHECK:STDOUT:
// CHECK:STDOUT: --- var_self.carbon
@@ -25,7 +25,5 @@ fn Main() {
// CHECK:STDOUT: constants {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {}
// CHECK:STDOUT:
// CHECK:STDOUT: fn @Main();
// CHECK:STDOUT:
+40 -32
View File
@@ -64,26 +64,18 @@ Formatter::Formatter(const File* sem_ir,
}
auto Formatter::Format() -> void {
out_ << "--- " << sem_ir_->filename() << "\n\n";
out_ << "--- " << sem_ir_->filename() << "\n";
FormatScopeIfUsed(InstNamer::ScopeId::Constants,
sem_ir_->constants().array_ref());
FormatScopeIfUsed(InstNamer::ScopeId::ImportRefs,
sem_ir_->inst_blocks().Get(InstBlockId::ImportRefs));
out_ << inst_namer_.GetScopeName(InstNamer::ScopeId::File) << " ";
OpenBrace();
// 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.has_value()) {
llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeId::File);
FormatCodeBlock(block_id);
}
CloseBrace();
out_ << '\n';
FormatTopLevelScopeIfUsed(InstNamer::ScopeId::Constants,
sem_ir_->constants().array_ref(),
/*use_tentative_output_scopes=*/true);
FormatTopLevelScopeIfUsed(InstNamer::ScopeId::ImportRefs,
sem_ir_->inst_blocks().Get(InstBlockId::ImportRefs),
/*use_tentative_output_scopes=*/true);
FormatTopLevelScopeIfUsed(
InstNamer::ScopeId::File,
sem_ir_->inst_blocks().GetOrEmpty(sem_ir_->top_inst_block_id()),
/*use_tentative_output_scopes=*/false);
for (auto [id, _] : sem_ir_->interfaces().enumerate()) {
FormatInterface(id);
@@ -109,7 +101,6 @@ auto Formatter::Format() -> void {
FormatSpecific(id);
}
// End-of-file newline.
out_ << "\n";
}
@@ -284,9 +275,11 @@ auto Formatter::IndentLabel() -> void {
Indent(-2);
}
auto Formatter::FormatScopeIfUsed(InstNamer::ScopeId scope_id,
llvm::ArrayRef<InstId> block) -> void {
if (use_dump_sem_ir_ranges_) {
auto Formatter::FormatTopLevelScopeIfUsed(InstNamer::ScopeId scope_id,
llvm::ArrayRef<InstId> block,
bool use_tentative_output_scopes)
-> void {
if (!use_tentative_output_scopes && use_dump_sem_ir_ranges_) {
// Don't format the scope if no instructions are in a dump range.
block = block.drop_while(
[&](InstId inst_id) { return !ShouldFormatInst(inst_id); });
@@ -299,13 +292,23 @@ auto Formatter::FormatScopeIfUsed(InstNamer::ScopeId scope_id,
llvm::SaveAndRestore scope(scope_, scope_id);
// Note, we don't use OpenBrace() / CloseBrace() here because we always want
// a newline to avoid misformatting if the first instruction is omitted.
out_ << inst_namer_.GetScopeName(scope_id) << " {\n";
out_ << "\n" << inst_namer_.GetScopeName(scope_id) << " {\n";
indent_ += 2;
for (const InstId inst_id : block) {
TentativeOutputScope scope(*this, tentative_inst_chunks_[inst_id.index]);
FormatInst(inst_id);
// Format instructions when needed, but do nothing for elided entries;
// unlike normal code blocks, scopes are non-sequential so skipped
// instructions are assumed to be uninteresting.
if (use_tentative_output_scopes) {
// This is for constants and imports. These use tentative logic to
// determine whether an instruction is printed.
TentativeOutputScope scope(*this, tentative_inst_chunks_[inst_id.index]);
FormatInst(inst_id);
} else if (ShouldFormatInst(inst_id)) {
// This is for the file scope. It uses only the range-based filtering.
FormatInst(inst_id);
}
}
out_ << "}\n\n";
out_ << "}\n";
indent_ -= 2;
}
@@ -645,8 +648,17 @@ auto Formatter::FormatParamList(InstBlockId params_id, bool has_return_slot)
}
auto Formatter::FormatCodeBlock(InstBlockId block_id) -> void {
bool elided = false;
for (const InstId inst_id : sem_ir_->inst_blocks().GetOrEmpty(block_id)) {
FormatInst(inst_id);
if (ShouldFormatInst(inst_id)) {
FormatInst(inst_id);
elided = false;
} else if (!elided) {
// When formatting a block, leave a hint that instructions were elided.
Indent();
out_ << "<elided>\n";
elided = true;
}
}
}
@@ -753,10 +765,6 @@ auto Formatter::FormatInst(InstId inst_id, ImportRefUnloaded inst) -> void {
}
auto Formatter::FormatInst(InstId inst_id) -> void {
if (!ShouldFormatInst(inst_id)) {
return;
}
if (!inst_id.has_value()) {
Indent();
out_ << "none\n";
+3 -2
View File
@@ -142,8 +142,9 @@ class Formatter {
// Formats a top-level scope, and any of the instructions in that scope that
// are used.
auto FormatScopeIfUsed(InstNamer::ScopeId scope_id,
llvm::ArrayRef<InstId> block) -> void;
auto FormatTopLevelScopeIfUsed(InstNamer::ScopeId scope_id,
llvm::ArrayRef<InstId> block,
bool use_tentative_output_scopes) -> void;
// Formats a full class.
auto FormatClass(ClassId id) -> void;