Files
carbon-lang/toolchain/check/testdata/interop/cpp/function/struct.carbon
T
Jon Ross-PerkinsandGeoff Romer eae3491129 Switch inst namer to queue entities when reached (#5806)
This switches from the `CollectNamesInBlock` approach for entities, to
instead traversing entities as they're encountered. For example, when
traversing constants, when a type is found, the entity will have its
block queued for processing.

This leads to a change in the traversal order, which affects
disambiguation done by numeric sequencing (since that's just showing the
traversal order).

This will allow for simpler "name based on name" logic. This is
something I plan to use for:

- impls: `<type>.as.<interface>.impl`
- functions: `<entity>.<member function>`
  - Note an impl may be used as the entity for a bound function.

By naming the entities as they're encountered, I'll be able to rely on
the generated names rather than recalculating them.

To assist this, I'm also differentiating between the ambiguous and
disambiguated name. Otherwise, we could end up with things like
`<function>.<disambiguator>.<call>.<other disambiguator>`, where the
repeated disambiguator may not be necessary in order to get full
disambiguation. It's also a smaller delta from the current output.

Note, changing `Name` to a class felt appropriate given its shape. I was
also noticing that parts of its API were unused, and the class helps
detect unused private members.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-07-21 17:58:55 +00:00

1024 lines
42 KiB
Plaintext

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/destroy.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/function/struct.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/function/struct.carbon
// ============================================================================
// Forward-declared struct as parameter type
// ============================================================================
// --- decl_value_param_type.h
struct S;
auto foo(S) -> void;
// --- fail_todo_import_decl_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "decl_value_param_type.h";
fn F() {
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo({});
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo({});
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
Cpp.foo({});
}
// --- fail_todo_import_decl_value_param_type_previously_imported.carbon
library "[[@TEST_NAME]]";
import Cpp library "decl_value_param_type.h";
fn F() {
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+11]]:10: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: let s: Cpp.S;
// CHECK:STDERR: ^~~~~
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+8]]:10: note: in `Cpp` name lookup for `S` [InCppNameLookup]
// CHECK:STDERR: let s: Cpp.S;
// CHECK:STDERR: ^~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_todo_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet]
// CHECK:STDERR: let s: Cpp.S;
// CHECK:STDERR: ^
// CHECK:STDERR:
let s: Cpp.S;
Cpp.foo(s);
}
// ============================================================================
// Forward-declared struct as parameter type imported twice
// ============================================================================
// --- double_decl_value_param_type.h
struct S;
auto foo1(S) -> void;
auto foo2(S) -> void;
// --- fail_todo_import_double_decl_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "double_decl_value_param_type.h";
fn F() {
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo1({});
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_todo_import_double_decl_value_param_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo1` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo1({});
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR:
Cpp.foo1({});
Cpp.foo2({});
}
// ============================================================================
// Defined struct without data members as parameter type
// ============================================================================
// --- definition_no_data_members_value_param_type.h
struct S {};
auto foo(S) -> void;
// --- import_definition_no_data_members_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_no_data_members_value_param_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct with a single data member as parameter type
// ============================================================================
// --- definition_single_data_member_value_param_type.h
struct D {};
struct S {
D d;
};
auto foo(S) -> void;
// --- import_definition_single_data_member_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_single_data_member_value_param_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct with multiple data members as parameter type
// ============================================================================
// --- definition_multiple_data_members_value_param_type.h
struct D {};
struct S {
D d1;
D d2;
D d3;
};
auto foo(S) -> void;
// --- import_definition_multiple_data_members_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_multiple_data_members_value_param_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct in namespace
// ============================================================================
// --- definition_in_namespace_value_param_type.h
namespace N { struct S {}; }
auto foo(N::S) -> void;
// --- import_definition_in_namespace_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_in_namespace_value_param_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
// Check that the parameter type was imported correctly.
var x: Cpp.N.S;
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct in relative namespace
// ============================================================================
// --- definition_in_relative_namespace_value_param_type.h
namespace N1 {
namespace N2 { struct S {}; }
auto foo(N2::S) -> void;
}
// --- import_definition_in_relative_namespace_value_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_in_relative_namespace_value_param_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.N1.foo({});
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct in struct
// ============================================================================
// --- definition_in_outer_definition.h
struct O {
struct S {};
};
auto foo(O::S) -> void;
// --- import_definition_in_outer_definition.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_in_outer_definition.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
var x: Cpp.O;
//@dump-sem-ir-end
}
// ============================================================================
// Defined struct and explicitly used
// ============================================================================
// --- definition_with_static_method.h
struct S {
static void bar();
};
auto foo(S) -> void;
// --- import_definition_and_static_method_call_before.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_with_static_method.h";
fn F() {
//@dump-sem-ir-begin
Cpp.S.bar();
Cpp.foo({});
//@dump-sem-ir-end
}
// --- import_definition_and_static_method_call_after.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_with_static_method.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo({});
Cpp.S.bar();
//@dump-sem-ir-end
}
// ============================================================================
// Pointer to forward-declared struct as parameter type
// ============================================================================
// --- decl_pointer_param_type.h
struct S;
auto foo(S* _Nonnull) -> void;
// --- fail_todo_import_decl_pointer_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "decl_pointer_param_type.h";
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+7]]:9: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: fn F(s: Cpp.S*) {
// CHECK:STDERR: ^~~~~
// CHECK:STDERR: fail_todo_import_decl_pointer_param_type.carbon:[[@LINE+4]]:9: note: in `Cpp` name lookup for `S` [InCppNameLookup]
// CHECK:STDERR: fn F(s: Cpp.S*) {
// CHECK:STDERR: ^~~~~
// CHECK:STDERR:
fn F(s: Cpp.S*) {
//@dump-sem-ir-begin
Cpp.foo(s);
//@dump-sem-ir-end
}
// ============================================================================
// Pointer to defined struct as parameter type
// ============================================================================
// --- definition_pointer_param_type.h
struct S {};
auto foo(S* _Nonnull) -> void;
// --- import_definition_pointer_param_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_pointer_param_type.h";
fn F(s: Cpp.S*) {
//@dump-sem-ir-begin
Cpp.foo(s);
//@dump-sem-ir-end
}
// ============================================================================
// Forward-declared struct as return type
// ============================================================================
// --- decl_value_return_type.h
struct S;
auto foo() -> S;
// --- fail_todo_import_decl_value_return_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "decl_value_return_type.h";
fn F() {
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_decl_value_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
Cpp.foo();
}
// ============================================================================
// Defined struct as return type
// ============================================================================
// --- definition_value_return_type.h
struct S {};
auto foo() -> S;
// --- import_definition_value_return_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_value_return_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo();
//@dump-sem-ir-end
}
// ============================================================================
// Pointer to forward-declared struct as return type
// ============================================================================
// --- decl_pointer_return_type.h
struct S;
auto foo() -> S* _Nonnull;
// --- fail_todo_import_decl_pointer_return_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "decl_pointer_return_type.h";
fn F() {
//@dump-sem-ir-begin
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: Record declarations without a definition` [SemanticsTodo]
// CHECK:STDERR: Cpp.foo();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR: fail_todo_import_decl_pointer_return_type.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: Cpp.foo();
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
Cpp.foo();
//@dump-sem-ir-end
}
// ============================================================================
// Pointer to defined struct as return type
// ============================================================================
// --- definition_pointer_return_type.h
struct S {};
auto foo() -> S* _Nonnull;
// --- import_definition_pointer_return_type.carbon
library "[[@TEST_NAME]]";
import Cpp library "definition_pointer_return_type.h";
fn F() {
//@dump-sem-ir-begin
Cpp.foo();
//@dump-sem-ir-end
}
// CHECK:STDOUT: --- import_definition_no_data_members_value_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_single_data_member_value_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_multiple_data_members_value_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_in_namespace_value_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %pattern_type.cd8: type = pattern_type %S [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.2b5: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.9b3: %Op.type.2b5 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.edf: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: .N = %N
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %N: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .S = %S.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %x.patt: %pattern_type.cd8 = binding_pattern x [concrete]
// CHECK:STDOUT: %x.var_patt: %pattern_type.cd8 = var_pattern %x.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x.var: ref %S = var %x.var_patt
// CHECK:STDOUT: %.loc10: type = splice_block %S.ref [concrete = constants.%S] {
// CHECK:STDOUT: %Cpp.ref.loc10: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %N.ref: <namespace> = name_ref N, imports.%N [concrete = imports.%N]
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: ref %S = bind_name x, %x.var
// CHECK:STDOUT: %Op.bound.loc10: <bound method> = bound_method %x.var, constants.%Op.9b3
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc10: <bound method> = bound_method %x.var, %Op.specific_fn.1
// CHECK:STDOUT: %addr.loc10: %ptr.edf = addr_of %x.var
// CHECK:STDOUT: %no_op.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10)
// CHECK:STDOUT: %Op.bound.loc8: <bound method> = bound_method %.loc8_12.2, constants.%Op.9b3
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn.2
// CHECK:STDOUT: %addr.loc8: %ptr.edf = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_in_relative_namespace_value_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.17f: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.463: %Op.type.17f = struct_value () [concrete]
// CHECK:STDOUT: %ptr.887: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .N1 = %N1
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %N1: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %N1.ref: <namespace> = name_ref N1, imports.%N1 [concrete = imports.%N1]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_15.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_15.3: init %S = class_init (), %.loc8_15.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_15.4: ref %S = temporary %.loc8_15.2, %.loc8_15.3
// CHECK:STDOUT: %.loc8_15.5: ref %S = converted %.loc8_15.1, %.loc8_15.4
// CHECK:STDOUT: %.loc8_15.6: %S = bind_value %.loc8_15.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_15.6)
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_15.2, constants.%Op.463
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_15.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.887 = addr_of %.loc8_15.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_in_outer_definition.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %O: type = class_type @O [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %pattern_type.cff: type = pattern_type %O [concrete]
// CHECK:STDOUT: %Op.type.1b8: type = fn_type @Op.1, @Destroy.impl(%O) [concrete]
// CHECK:STDOUT: %Op.2df: %Op.type.1b8 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.820: type = ptr_type %O [concrete]
// CHECK:STDOUT: %Op.type.23f: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.952: %Op.type.23f = struct_value () [concrete]
// CHECK:STDOUT: %ptr.149: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: .O = %O.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %O.decl: type = class_decl @O [concrete = constants.%O] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %x.patt: %pattern_type.cff = binding_pattern x [concrete]
// CHECK:STDOUT: %x.var_patt: %pattern_type.cff = var_pattern %x.patt [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x.var: ref %O = var %x.var_patt
// CHECK:STDOUT: %.loc9: type = splice_block %O.ref [concrete = constants.%O] {
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %O.ref: type = name_ref O, imports.%O.decl [concrete = constants.%O]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: ref %O = bind_name x, %x.var
// CHECK:STDOUT: %Op.bound.loc9: <bound method> = bound_method %x.var, constants.%Op.2df
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc9: <bound method> = bound_method %x.var, %Op.specific_fn.1
// CHECK:STDOUT: %addr.loc9: %ptr.820 = addr_of %x.var
// CHECK:STDOUT: %no_op.loc9: init %empty_tuple.type = call %bound_method.loc9(%addr.loc9)
// CHECK:STDOUT: %Op.bound.loc8: <bound method> = bound_method %.loc8_12.2, constants.%Op.952
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn.2
// CHECK:STDOUT: %addr.loc8: %ptr.149 = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_and_static_method_call_before.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %bar.type: type = fn_type @bar [concrete]
// CHECK:STDOUT: %bar: %bar.type = struct_value () [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .S = %S.decl
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
// CHECK:STDOUT: %bar.decl: %bar.type = fn_decl @bar [concrete = constants.%bar] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
// CHECK:STDOUT: %bar.ref: %bar.type = name_ref bar, imports.%bar.decl [concrete = constants.%bar]
// CHECK:STDOUT: %bar.call: init %empty_tuple.type = call %bar.ref()
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc9_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc9_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc9_12.3: init %S = class_init (), %.loc9_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc9_12.4: ref %S = temporary %.loc9_12.2, %.loc9_12.3
// CHECK:STDOUT: %.loc9_12.5: ref %S = converted %.loc9_12.1, %.loc9_12.4
// CHECK:STDOUT: %.loc9_12.6: %S = bind_value %.loc9_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc9_12.6)
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc9_12.2, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc9_12.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc9_12.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_and_static_method_call_after.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %S.val: %S = struct_value () [concrete]
// CHECK:STDOUT: %bar.type: type = fn_type @bar [concrete]
// CHECK:STDOUT: %bar: %bar.type = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: .S = %S.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %bar.decl: %bar.type = fn_decl @bar [concrete = constants.%bar] {} {}
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal ()
// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage
// CHECK:STDOUT: %.loc8_12.3: init %S = class_init (), %.loc8_12.2 [concrete = constants.%S.val]
// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3
// CHECK:STDOUT: %.loc8_12.5: ref %S = converted %.loc8_12.1, %.loc8_12.4
// CHECK:STDOUT: %.loc8_12.6: %S = bind_value %.loc8_12.5
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%.loc8_12.6)
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S]
// CHECK:STDOUT: %bar.ref: %bar.type = name_ref bar, imports.%bar.decl [concrete = constants.%bar]
// CHECK:STDOUT: %bar.call: init %empty_tuple.type = call %bar.ref()
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_12.2, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_12.2, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_12.2
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .S = <error>
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%s.param: <error>) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %s.ref: <error> = name_ref s, %s
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(<error>)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_pointer_param_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %ptr: type = ptr_type %S [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .S = %S.decl
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {}
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%s.param: %ptr) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %s.ref: %ptr = name_ref s, %s
// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%s.ref)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_value_return_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: %Op.type.642: type = fn_type @Op.1, @Destroy.impl(%S) [concrete]
// CHECK:STDOUT: %Op.ab5: %Op.type.642 = struct_value () [concrete]
// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %.loc8_11.1: ref %S = temporary_storage
// CHECK:STDOUT: %foo.call: init %S = call %foo.ref() to %.loc8_11.1
// CHECK:STDOUT: %.loc8_11.2: ref %S = temporary %.loc8_11.1, %foo.call
// CHECK:STDOUT: %Op.bound: <bound method> = bound_method %.loc8_11.1, constants.%Op.ab5
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc8_11.1, %Op.specific_fn
// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_11.1
// CHECK:STDOUT: %no_op: init %empty_tuple.type = call %bound_method(%addr)
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_todo_import_decl_pointer_return_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %foo.call: init <error> = call %foo.ref()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_definition_pointer_return_type.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %S: type = class_type @S [concrete]
// CHECK:STDOUT: %ptr: type = ptr_type %S [concrete]
// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete]
// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: .foo = %foo.decl
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
// CHECK:STDOUT: %foo.call: init %ptr = call %foo.ref()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: