diff --git a/toolchain/check/cpp/impl_lookup.cpp b/toolchain/check/cpp/impl_lookup.cpp index b5a0a9cdb436..7ea58640792d 100644 --- a/toolchain/check/cpp/impl_lookup.cpp +++ b/toolchain/check/cpp/impl_lookup.cpp @@ -53,7 +53,7 @@ namespace { // See `GetDeclForCoreInterface`. struct DeclInfo { clang::NamedDecl* decl; - int num_params; + SemIR::ClangDeclKey::Signature signature; }; } // namespace @@ -68,9 +68,10 @@ auto GetDeclForCoreInterface(clang::Sema& clang_sema, case CoreInterface::Copy: return {.decl = clang_sema.LookupCopyingConstructor( class_decl, clang::Qualifiers::Const), - .num_params = 1}; + .signature = {.num_params = 1}}; case CoreInterface::Destroy: - return {.decl = clang_sema.LookupDestructor(class_decl), .num_params = 0}; + return {.decl = clang_sema.LookupDestructor(class_decl), + .signature = {.num_params = 0}}; case CoreInterface::Unknown: CARBON_FATAL("shouldn't be called with `Unknown`"); } @@ -102,7 +103,7 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id, } auto fn_id = - ImportCppFunctionDecl(context, loc_id, cpp_fn, decl_info.num_params); + ImportCppFunctionDecl(context, loc_id, cpp_fn, decl_info.signature); if (fn_id == SemIR::ErrorInst::InstId) { return SemIR::ErrorInst::InstId; } diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index 1ff276830326..53a8e6daee83 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -1126,23 +1126,25 @@ static auto MakeImplicitParamPatternsBlockId( // Returns a block id for the explicit parameters of the given function // declaration. If the function declaration has no parameters, it returns // `SemIR::InstBlockId::Empty`. In the case of an unsupported parameter type, it -// produces an error and returns `SemIR::InstBlockId::None`. +// produces an error and returns `SemIR::InstBlockId::None`. `signature` +// specifies how to convert the C++ signature to the Carbon signature. // TODO: Consider refactoring to extract and reuse more logic from // `HandleAnyBindingPattern()`. static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id, const clang::FunctionDecl& clang_decl, - int num_params) -> SemIR::InstBlockId { - if (clang_decl.parameters().empty() || num_params == 0) { - return SemIR::InstBlockId::Empty; - } - llvm::SmallVector params; - params.reserve(num_params); - CARBON_CHECK( - static_cast(clang_decl.getNumNonObjectParams()) >= num_params, - "varargs functions are not supported"); + SemIR::ClangDeclKey::Signature signature) + -> SemIR::InstBlockId { + llvm::SmallVector param_ids; + llvm::SmallVector param_type_ids; + param_ids.reserve(signature.num_params); + param_type_ids.reserve(signature.num_params); + CARBON_CHECK(static_cast(clang_decl.getNumNonObjectParams()) >= + signature.num_params, + "Function has fewer parameters than requested: {0} < {1}", + clang_decl.getNumNonObjectParams(), signature.num_params); const auto* function_type = clang_decl.getType()->castAs(); - for (int i : llvm::seq(num_params)) { + for (int i : llvm::seq(signature.num_params)) { const auto* param = clang_decl.getNonObjectParameter(i); clang::QualType orig_param_type = function_type->getParamType( clang_decl.hasCXXExplicitFunctionObjectParameter() + i); @@ -1157,12 +1159,12 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id, // created later with the call of `EndSubpatternAsExpr()`. BeginSubpattern(context); auto param_info = MapParameterType(context, loc_id, param_type); - auto [orig_type_inst_id, type_id] = param_info.type; + auto [type_inst_id, type_id] = param_info.type; // Type expression of the binding pattern - a single-entry/single-exit // region that allows control flow in the type expression e.g. fn F(x: if C // then i32 else i64). SemIR::ExprRegionId type_expr_region_id = - EndSubpatternAsExpr(context, orig_type_inst_id); + EndSubpatternAsExpr(context, type_inst_id); if (!type_id.has_value()) { context.TODO(loc_id, llvm::formatv("Unsupported: parameter type: {0}", @@ -1185,9 +1187,33 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id, SemIR::InstId pattern_id = AddParamPattern(context, param_loc_id, name_id, type_expr_region_id, type_id, param_info.want_ref_pattern); - params.push_back(pattern_id); + param_ids.push_back(pattern_id); + param_type_ids.push_back(type_inst_id); } - return context.inst_blocks().Add(params); + + switch (signature.kind) { + case SemIR::ClangDeclKey::Signature::Normal: { + // Use the converted parameter list as-is. + break; + } + + case SemIR::ClangDeclKey::Signature::TuplePattern: { + // Replace the parameters with a single tuple pattern containing the + // converted parameter list. + auto param_block_id = context.inst_blocks().Add(param_ids); + auto tuple_pattern_type_id = + GetPatternType(context, GetTupleType(context, param_type_ids)); + SemIR::InstId pattern_id = AddPatternInst( + context, + SemIR::LocIdAndInst::UncheckedLoc( + loc_id, SemIR::TuplePattern{.type_id = tuple_pattern_type_id, + .elements_id = param_block_id})); + param_ids = {pattern_id}; + break; + } + } + + return context.inst_blocks().Add(param_ids); } // Returns the return `TypeExpr` of the given function declaration. In case of @@ -1333,10 +1359,11 @@ struct FunctionSignatureInsts { // pattern match to create the `Call` parameters, and returns a // FunctionSignatureInsts containing the results. Produces a diagnostic and // returns `std::nullopt` if the function declaration has an unsupported -// parameter type. -static auto CreateFunctionSignatureInsts(Context& context, SemIR::LocId loc_id, - clang::FunctionDecl* clang_decl, - int num_params) +// parameter type. `signature` specifies how to convert the C++ function +// signature to the Carbon function signature. +static auto CreateFunctionSignatureInsts( + Context& context, SemIR::LocId loc_id, clang::FunctionDecl* clang_decl, + SemIR::ClangDeclKey::Signature signature) -> std::optional { context.full_pattern_stack().PushFullPattern( FullPatternStack::Kind::ImplicitParamList); @@ -1349,7 +1376,7 @@ static auto CreateFunctionSignatureInsts(Context& context, SemIR::LocId loc_id, } context.full_pattern_stack().EndImplicitParamList(); auto param_patterns_id = - MakeParamPatternsBlockId(context, loc_id, *clang_decl, num_params); + MakeParamPatternsBlockId(context, loc_id, *clang_decl, signature); if (!param_patterns_id.has_value()) { return std::nullopt; } @@ -1403,19 +1430,25 @@ static auto GetFunctionName(Context& context, clang::FunctionDecl* clang_decl) } // Creates a `FunctionDecl` and a `Function` without C++ thunk information. -// Returns std::nullopt on failure. The given Clang declaration is assumed to: +// Returns std::nullopt on failure. +// +// The given Clang declaration is assumed to: // * Have not been imported before. // * Be of supported type (ignoring parameters). +// +// `signature` specifies how to convert the C++ function signature to the Carbon +// function signature. static auto ImportFunction(Context& context, SemIR::LocId loc_id, SemIR::ImportIRInstId import_ir_inst_id, - clang::FunctionDecl* clang_decl, int num_params) + clang::FunctionDecl* clang_decl, + SemIR::ClangDeclKey::Signature signature) -> std::optional { context.scope_stack().PushForDeclName(); context.inst_block_stack().Push(); context.pattern_block_stack().Push(); auto function_params_insts = - CreateFunctionSignatureInsts(context, loc_id, clang_decl, num_params); + CreateFunctionSignatureInsts(context, loc_id, clang_decl, signature); auto pattern_block_id = context.pattern_block_stack().Pop(); auto decl_block_id = context.inst_block_stack().Pop(); @@ -1471,7 +1504,7 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id, .self_param_id = FindSelfPattern( context, function_params_insts->implicit_param_patterns_id), .clang_decl_id = context.clang_decls().Add( - {.key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, num_params), + {.key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, signature), .inst_id = decl_id})}}; function_decl.function_id = context.functions().Add(function_info); @@ -1482,13 +1515,15 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id, } // Imports a C++ function, returning a corresponding Carbon function. -// `num_params` specifies how many parameters the corresponding Carbon function -// should have, which may be fewer than the number of parameters that the C++ -// function has if default arguments are available for the trailing parameters. +// `signature` specifies how to convert the C++ function signature to the Carbon +// function signature. `signature.num_params` may be less than the number of +// parameters that the C++ function has if default arguments are available for +// the trailing parameters. static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id, - clang::FunctionDecl* clang_decl, int num_params) + clang::FunctionDecl* clang_decl, + SemIR::ClangDeclKey::Signature signature) -> SemIR::InstId { - auto key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, num_params); + auto key = SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, signature); // Check if the declaration is already mapped. if (SemIR::InstId existing_inst_id = LookupClangDeclInstId(context, key); @@ -1514,8 +1549,8 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id, CARBON_CHECK(clang_decl->getFunctionType()->isFunctionProtoType(), "Not Prototype function (non-C++ code)"); - auto function_id = ImportFunction(context, loc_id, import_ir_inst_id, - clang_decl, num_params); + auto function_id = + ImportFunction(context, loc_id, import_ir_inst_id, clang_decl, signature); if (!function_id) { MarkFailedDecl(context, key); return SemIR::ErrorInst::InstId; @@ -1534,7 +1569,8 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id, BuildCppThunk(context, function_info)) { if (auto thunk_function_id = ImportFunction( context, loc_id, import_ir_inst_id, thunk_clang_decl, - thunk_clang_decl->getNumParams())) { + {.num_params = + static_cast(thunk_clang_decl->getNumParams())})) { SemIR::InstId thunk_function_decl_id = context.functions().Get(*thunk_function_id).first_owning_decl_id; function_info.SetHasCppThunk(thunk_function_decl_id); @@ -1610,12 +1646,13 @@ static auto AddDependentUnimportedTypeDecls(Context& context, // Finds all decls that need to be imported before importing the given function // and adds them to the given set. static auto AddDependentUnimportedFunctionDecls( - Context& context, const clang::FunctionDecl& clang_decl, int num_params, - ImportWorklist& worklist) -> void { + Context& context, const clang::FunctionDecl& clang_decl, + SemIR::ClangDeclKey::Signature signature, ImportWorklist& worklist) + -> void { const auto* function_type = clang_decl.getType()->castAs(); for (int i : llvm::seq(clang_decl.hasCXXExplicitFunctionObjectParameter() + - num_params)) { + signature.num_params)) { AddDependentUnimportedTypeDecls(context, function_type->getParamType(i), worklist); } @@ -1631,7 +1668,7 @@ static auto AddDependentUnimportedDecls(Context& context, clang::Decl* clang_decl = key.decl; if (auto* clang_function_decl = clang_decl->getAsFunction()) { AddDependentUnimportedFunctionDecls(context, *clang_function_decl, - key.num_params, worklist); + key.signature, worklist); } else if (auto* type_decl = dyn_cast(clang_decl)) { if (!isa(clang_decl)) { AddDependentUnimportedTypeDecls( @@ -1748,7 +1785,7 @@ static auto ImportDeclAfterDependencies(Context& context, SemIR::LocId loc_id, clang::Decl* clang_decl = key.decl; if (auto* clang_function_decl = clang_decl->getAsFunction()) { return ImportFunctionDecl(context, loc_id, clang_function_decl, - key.num_params); + key.signature); } if (auto* clang_namespace_decl = dyn_cast(clang_decl)) { return ImportNamespaceDecl(context, clang_namespace_decl); diff --git a/toolchain/check/cpp/import.h b/toolchain/check/cpp/import.h index 5d95823ba205..3827e201522f 100644 --- a/toolchain/check/cpp/import.h +++ b/toolchain/check/cpp/import.h @@ -13,6 +13,7 @@ #include "toolchain/check/convert.h" #include "toolchain/check/diagnostic_helpers.h" #include "toolchain/diagnostics/diagnostic_emitter.h" +#include "toolchain/sem_ir/clang_decl.h" #include "toolchain/sem_ir/ids.h" namespace Carbon::Check { @@ -37,10 +38,11 @@ auto ImportCppDecl(Context& context, SemIR::LocId loc_id, // imported, returns the mapped instruction. inline auto ImportCppFunctionDecl(Context& context, SemIR::LocId loc_id, clang::FunctionDecl* clang_decl, - int num_params) -> SemIR::InstId { + SemIR::ClangDeclKey::Signature signature) + -> SemIR::InstId { return ImportCppDecl( context, loc_id, - SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, num_params)); + SemIR::ClangDeclKey::ForFunctionDecl(clang_decl, signature)); } // Imports a function declaration from Clang to Carbon. If successful, returns diff --git a/toolchain/check/cpp/operators.cpp b/toolchain/check/cpp/operators.cpp index 5fb84868fea5..67fd1139c39a 100644 --- a/toolchain/check/cpp/operators.cpp +++ b/toolchain/check/cpp/operators.cpp @@ -193,10 +193,62 @@ static auto GetClangOperatorKind(Context& context, SemIR::LocId loc_id, } } +// Returns information about the Carbon signature to import when importing a C++ +// constructor or conversion operator. +static auto GetConversionSignatureToImport( + Context& context, SemIR::InstId source_id, + clang::InitializationSequence::StepKind step_kind, + clang::FunctionDecl* function_decl) -> SemIR::ClangDeclKey::Signature { + // If we're performing a constructor initialization from a list, form a + // function signature that takes a single tuple or struct pattern + // instead of a function signature with one parameter per C++ parameter. + if (step_kind == + clang::InitializationSequence::SK_ConstructorInitializationFromList) { + // The source type should always be a tuple type, because we don't support + // C++ initialization from struct types. + auto tuple_type = context.types().TryGetAs( + context.insts().Get(source_id).type_id()); + CARBON_CHECK(tuple_type, "List initialization from non-tuple type"); + + // Initialization from a tuple `(a, b, c)` results in a constructor + // function that takes a tuple pattern: + // + // fn Class.Class((a: A, b: B, c: C)) -> Class; + return { + .kind = SemIR::ClangDeclKey::Signature::Kind::TuplePattern, + .num_params = static_cast( + context.inst_blocks().Get(tuple_type->type_elements_id).size())}; + } + + // Any other initialization using a constructor is calling a converting + // constructor: + // + // fn Class.Class(a: A) -> Class; + if (isa(function_decl)) { + return {.kind = SemIR::ClangDeclKey::Signature::Kind::Normal, + .num_params = 1}; + } + + // Otherwise, the initialization is calling a conversion function + // `Source::operator Dest`: + // + // fn Source.[self: Source]() -> Dest; + CARBON_CHECK(isa(function_decl)); + return {.kind = SemIR::ClangDeclKey::Signature::Kind::Normal, + .num_params = 0}; +} + static auto LookupCppConversion(Context& context, SemIR::LocId loc_id, SemIR::InstId source_id, SemIR::TypeId dest_type_id, bool allow_explicit) -> SemIR::InstId { + if (context.types().Is( + context.insts().Get(source_id).type_id())) { + // Structs can only be used to initialize C++ aggregates. That case is + // handled by Convert, not here. + return SemIR::InstId::None; + } + auto dest_type = MapToCppType(context, dest_type_id); if (dest_type.isNull()) { return SemIR::InstId::None; @@ -243,7 +295,9 @@ static auto LookupCppConversion(Context& context, SemIR::LocId loc_id, for (const auto& step : init.steps()) { switch (step.Kind) { case clang::InitializationSequence::SK_UserConversion: - case clang::InitializationSequence::SK_ConstructorInitialization: { + case clang::InitializationSequence::SK_ConstructorInitialization: + case clang::InitializationSequence:: + SK_ConstructorInitializationFromList: { if (auto* ctor = dyn_cast(step.Function.Function); ctor && ctor->isCopyOrMoveConstructor()) { @@ -260,12 +314,10 @@ static auto LookupCppConversion(Context& context, SemIR::LocId loc_id, sema.MarkFunctionReferenced(loc, step.Function.Function); + auto signature = GetConversionSignatureToImport( + context, source_id, step.Kind, step.Function.Function); auto result_id = ImportCppFunctionDecl( - context, loc_id, step.Function.Function, - // If this is a constructor, the source is passed as an argument; - // otherwise, this is a conversion function and the source is passed - // as `self`. - isa(step.Function.Function) ? 1 : 0); + context, loc_id, step.Function.Function, signature); if (auto fn_decl = context.insts().TryGetAsWithId( result_id)) { CheckCppOverloadAccess(context, loc_id, step.Function.FoundDecl, @@ -386,11 +438,16 @@ auto LookupCppOperator(Context& context, SemIR::LocId loc_id, Operator op, return SemIR::ErrorInst::InstId; } sema.MarkFunctionReferenced(loc, best_viable_fn->Function); - auto result_id = ImportCppFunctionDecl( - context, loc_id, best_viable_fn->Function, - // If this is an operator method, the first arg will be used as self. - arg_ids.size() - - (isa(best_viable_fn->Function) ? 1 : 0)); + + // If this is an operator method, the first arg will be used as self. + int32_t num_params = arg_ids.size(); + if (isa(best_viable_fn->Function)) { + --num_params; + } + + auto result_id = + ImportCppFunctionDecl(context, loc_id, best_viable_fn->Function, + {.num_params = num_params}); if (result_id != SemIR::ErrorInst::InstId) { CheckCppOverloadAccess( context, loc_id, best_viable_fn->FoundDecl, diff --git a/toolchain/check/cpp/overload_resolution.cpp b/toolchain/check/cpp/overload_resolution.cpp index 034b283c045b..8cafd86b91d4 100644 --- a/toolchain/check/cpp/overload_resolution.cpp +++ b/toolchain/check/cpp/overload_resolution.cpp @@ -163,7 +163,8 @@ auto PerformCppOverloadResolution(Context& context, SemIR::LocId loc_id, CARBON_CHECK(best_viable_fn->Function); CARBON_CHECK(!best_viable_fn->RewriteKind); SemIR::InstId result_id = ImportCppFunctionDecl( - context, loc_id, best_viable_fn->Function, arg_exprs.size()); + context, loc_id, best_viable_fn->Function, + {.num_params = static_cast(arg_exprs.size())}); if (result_id != SemIR::ErrorInst::InstId) { CheckCppOverloadAccess( context, loc_id, best_viable_fn->FoundDecl, diff --git a/toolchain/check/cpp/thunk.cpp b/toolchain/check/cpp/thunk.cpp index f1722bd32c2e..fe09f3f347aa 100644 --- a/toolchain/check/cpp/thunk.cpp +++ b/toolchain/check/cpp/thunk.cpp @@ -39,12 +39,21 @@ static auto GetGlobalDecl(const clang::FunctionDecl* decl) // Returns the C++ thunk mangled name given the callee function. static auto GenerateThunkMangledName( clang::MangleContext& mangle_context, - const clang::FunctionDecl& callee_function_decl, int num_params) + const clang::FunctionDecl& callee_function_decl, + SemIR::ClangDeclKey::Signature::Kind signature_kind, int num_params) -> std::string { RawStringOstream mangled_name_stream; mangle_context.mangleName(GetGlobalDecl(&callee_function_decl), mangled_name_stream); - mangled_name_stream << ".carbon_thunk"; + switch (signature_kind) { + case SemIR::ClangDeclKey::Signature::Normal: + mangled_name_stream << ".carbon_thunk"; + break; + case SemIR::ClangDeclKey::Signature::TuplePattern: + mangled_name_stream << ".carbon_thunk_tuple"; + break; + } + if (num_params != static_cast(callee_function_decl.getNumNonObjectParams())) { mangled_name_stream << num_params; @@ -99,9 +108,12 @@ static auto IsSimpleAbiType(clang::ASTContext& ast_context, namespace { // Information about the callee of a thunk. struct CalleeFunctionInfo { - explicit CalleeFunctionInfo(clang::FunctionDecl* decl, int num_params) + explicit CalleeFunctionInfo(clang::FunctionDecl* decl, + SemIR::ClangDeclKey::Signature signature) : decl(decl), - num_params(num_params + decl->hasCXXExplicitFunctionObjectParameter()) { + signature_kind(signature.kind), + num_params(signature.num_params + + decl->hasCXXExplicitFunctionObjectParameter()) { auto& ast_context = decl->getASTContext(); const auto* method_decl = dyn_cast(decl); bool is_ctor = isa(decl); @@ -149,6 +161,9 @@ struct CalleeFunctionInfo { // The callee function. clang::FunctionDecl* decl; + // The kind of function signature being imported. + SemIR::ClangDeclKey::Signature::Kind signature_kind; + // The number of explicit parameters to import. This may be less than the // number of parameters that the function has if default arguments are being // used. @@ -181,15 +196,16 @@ auto IsCppThunkRequired(Context& context, const SemIR::Function& function) const auto& decl_info = context.clang_decls().Get(function.clang_decl_id); auto* decl = cast(decl_info.key.decl); - if (decl_info.key.num_params != - static_cast(decl->getNumNonObjectParams())) { + if (decl_info.key.signature.kind != SemIR::ClangDeclKey::Signature::Normal || + decl_info.key.signature.num_params != + static_cast(decl->getNumNonObjectParams())) { // We require a thunk if the number of parameters we want isn't all of them. // This happens if default arguments are in use, or (eventually) when // calling a varargs function. return true; } - CalleeFunctionInfo callee_info(decl, decl_info.key.num_params); + CalleeFunctionInfo callee_info(decl, decl_info.key.signature); if (!callee_info.has_simple_return_type) { return true; } @@ -388,6 +404,7 @@ static auto CreateThunkFunctionDecl( ast_context, GenerateThunkMangledName( context.cpp_context()->clang_mangle_context(), *callee_info.decl, + callee_info.signature_kind, callee_info.num_params - callee_info.has_explicit_object_parameter()), clang_loc)); @@ -558,15 +575,18 @@ static auto BuildThunkBody(clang::Sema& sema, auto BuildCppThunk(Context& context, const SemIR::Function& callee_function) -> clang::FunctionDecl* { + auto clang_decl_key = + context.clang_decls().Get(callee_function.clang_decl_id).key; clang::FunctionDecl* callee_function_decl = - context.clang_decls() - .Get(callee_function.clang_decl_id) - .key.decl->getAsFunction(); + clang_decl_key.decl->getAsFunction(); CARBON_CHECK(callee_function_decl); - CalleeFunctionInfo callee_info( - callee_function_decl, - context.inst_blocks().Get(callee_function.param_patterns_id).size()); + // TODO: The signature kind doesn't affect the thunk that we build, so we + // shouldn't consider it here. However, to do that, we would need to cache the + // thunks we build so that we don't build the same thunk multiple times if + // it's used with multiple different signature kinds. + CalleeFunctionInfo callee_info(callee_function_decl, + clang_decl_key.signature); // Build the thunk function declaration. auto thunk_param_types = @@ -639,8 +659,8 @@ auto PerformCppThunkCall(Context& context, SemIR::LocId loc_id, callee_function_params.drop_back(callee_return_patterns.size()); // We assume that the call parameters exactly match the parameter patterns for - // both the thunk and the callee. This is currently guaranteed because we only - // create trivial *ParamPatterns when importing a C++ function. + // both the thunk and the callee. This is guaranteed even when we generate a + // tuple pattern wrapping the function parameters. CARBON_CHECK(num_callee_args == callee_function_params.size(), "{0} != {1}", num_callee_args, callee_function_params.size()); CARBON_CHECK(num_callee_args == callee_arg_ids.size()); diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index d8cf1482da76..ad46b853cdca 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -245,8 +245,9 @@ auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::AnyBindingPattern binding_pattern, MatchContext::WorkItem entry) -> void { if (kind_ == MatchKind::Caller) { - CARBON_CHECK(binding_pattern.kind == SemIR::SymbolicBindingPattern::Kind, - "Found runtime binding pattern during caller pattern match"); + CARBON_CHECK( + binding_pattern.kind == SemIR::SymbolicBindingPattern::Kind, + "Found named runtime binding pattern during caller pattern match"); return; } // We're logically consuming this map entry, so we invalidate it in order @@ -534,8 +535,12 @@ auto MatchContext::DoEmitPatternMatch(Context& context, }; if (!entry.scrutinee_id.has_value()) { CARBON_CHECK(kind_ == MatchKind::Callee); - context.TODO(entry.pattern_id, - "Support patterns besides bindings in parameter list"); + // If we don't have a scrutinee yet, we're still on the caller side of the + // pattern, so the subpatterns don't have a scrutinee either. + for (auto subpattern_id : llvm::reverse(subpattern_ids)) { + AddWork( + {.pattern_id = subpattern_id, .scrutinee_id = SemIR::InstId::None}); + } return; } auto scrutinee = context.insts().GetWithLocId(entry.scrutinee_id); diff --git a/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon b/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon index c7c0b689a734..b0c8b6f9266f 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/cpp_interop.carbon @@ -56,10 +56,10 @@ fn G(x: Cpp.X) { // CHECK:STDOUT: clang_decl_id60000000: {key: "", inst_id: inst60000011} // CHECK:STDOUT: clang_decl_id60000001: {key: "struct X {}", inst_id: inst60000014} // CHECK:STDOUT: clang_decl_id60000002: {key: "X * _Nonnull p", inst_id: inst60000022} -// CHECK:STDOUT: clang_decl_id60000003: {key: {decl: "void f(X x = {})", num_params: 0}, inst_id: inst6000002D} -// CHECK:STDOUT: clang_decl_id60000004: {key: {decl: "extern void f__carbon_thunk()", num_params: 0}, inst_id: inst60000030} -// CHECK:STDOUT: clang_decl_id60000005: {key: {decl: "void f(X x = {})", num_params: 1}, inst_id: inst6000003B} -// CHECK:STDOUT: clang_decl_id60000006: {key: {decl: "extern void f__carbon_thunk(X * _Nonnull x)", num_params: 1}, inst_id: inst60000043} +// CHECK:STDOUT: clang_decl_id60000003: {key: {decl: "void f(X x = {})", kind: normal, num_params: 0}, inst_id: inst6000002D} +// CHECK:STDOUT: clang_decl_id60000004: {key: {decl: "extern void f__carbon_thunk()", kind: normal, num_params: 0}, inst_id: inst60000030} +// CHECK:STDOUT: clang_decl_id60000005: {key: {decl: "void f(X x = {})", kind: normal, num_params: 1}, inst_id: inst6000003B} +// CHECK:STDOUT: clang_decl_id60000006: {key: {decl: "extern void f__carbon_thunk(X * _Nonnull x)", kind: normal, num_params: 1}, inst_id: inst60000043} // CHECK:STDOUT: clang_decl_id60000007: {key: "X * _Nonnull global", inst_id: inst6000004E} // CHECK:STDOUT: name_scopes: // CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name(Cpp): inst60000011, name0: inst6000001D}} diff --git a/toolchain/check/testdata/function/declaration/fail_pattern_in_signature.carbon b/toolchain/check/testdata/function/declaration/fail_pattern_in_signature.carbon deleted file mode 100644 index 96274f9f7157..000000000000 --- a/toolchain/check/testdata/function/declaration/fail_pattern_in_signature.carbon +++ /dev/null @@ -1,56 +0,0 @@ -// 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/none.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/declaration/fail_pattern_in_signature.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/declaration/fail_pattern_in_signature.carbon - -// CHECK:STDERR: fail_pattern_in_signature.carbon:[[@LINE+4]]:6: error: semantics TODO: `Support patterns besides bindings in parameter list` [SemanticsTodo] -// CHECK:STDERR: fn F((a: {}, b: {}), c: {}); -// CHECK:STDERR: ^~~~~~~~~~~~~~ -// CHECK:STDERR: -fn F((a: {}, b: {}), c: {}); - -// CHECK:STDOUT: --- fail_pattern_in_signature.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete] -// CHECK:STDOUT: %tuple.type: type = tuple_type (%empty_struct_type, %empty_struct_type) [concrete] -// CHECK:STDOUT: %pattern_type.de4: type = pattern_type %tuple.type [concrete] -// 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: package: = namespace [concrete] { -// CHECK:STDOUT: .F = %F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %a.patt: %pattern_type.a96 = value_binding_pattern a [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type.a96 = value_param_pattern %a.patt, call_param0 [concrete] -// CHECK:STDOUT: %b.patt: %pattern_type.a96 = value_binding_pattern b [concrete] -// CHECK:STDOUT: %b.param_patt: %pattern_type.a96 = value_param_pattern %b.patt, call_param1 [concrete] -// CHECK:STDOUT: %.loc19_19: %pattern_type.de4 = tuple_pattern (%a.param_patt, %b.param_patt) [concrete] -// CHECK:STDOUT: %c.patt: %pattern_type.a96 = value_binding_pattern c [concrete] -// CHECK:STDOUT: %c.param_patt: %pattern_type.a96 = value_param_pattern %c.patt, call_param2 [concrete] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %c.param: %empty_struct_type = value_param call_param2 -// CHECK:STDOUT: %.loc19_26.1: type = splice_block %.loc19_26.3 [concrete = constants.%empty_struct_type] { -// CHECK:STDOUT: %.loc19_26.2: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %.loc19_26.3: type = converted %.loc19_26.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %c: %empty_struct_type = value_binding c, %c.param -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F(%c.param: %empty_struct_type); -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/pattern_in_signature.carbon b/toolchain/check/testdata/function/declaration/pattern_in_signature.carbon new file mode 100644 index 000000000000..ca75c39d0afa --- /dev/null +++ b/toolchain/check/testdata/function/declaration/pattern_in_signature.carbon @@ -0,0 +1,108 @@ +// 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/none.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/declaration/pattern_in_signature.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/declaration/pattern_in_signature.carbon + +//@dump-sem-ir-begin +fn F((a: {}, b: {}), c: {}) {} +//@dump-sem-ir-end + +//@dump-sem-ir-begin +fn CallF(ab: ({}, {}), c: {}) { + F(ab, c); +} +//@dump-sem-ir-end + +// CHECK:STDOUT: --- pattern_in_signature.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %pattern_type.a96: type = pattern_type %empty_struct_type [concrete] +// CHECK:STDOUT: %tuple.type.b6b: type = tuple_type (%empty_struct_type, %empty_struct_type) [concrete] +// CHECK:STDOUT: %pattern_type.de4: type = pattern_type %tuple.type.b6b [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %tuple: %tuple.type.b6b = tuple_value (%empty_struct, %empty_struct) [concrete] +// CHECK:STDOUT: %CallF.type: type = fn_type @CallF [concrete] +// CHECK:STDOUT: %CallF: %CallF.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: %a.patt: %pattern_type.a96 = value_binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.a96 = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %b.patt: %pattern_type.a96 = value_binding_pattern b [concrete] +// CHECK:STDOUT: %b.param_patt: %pattern_type.a96 = value_param_pattern %b.patt, call_param1 [concrete] +// CHECK:STDOUT: %.loc14_19: %pattern_type.de4 = tuple_pattern (%a.param_patt, %b.param_patt) [concrete] +// CHECK:STDOUT: %c.patt: %pattern_type.a96 = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.a96 = value_param_pattern %c.patt, call_param2 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %a.param: %empty_struct_type = value_param call_param0 +// CHECK:STDOUT: %.loc14_11.1: type = splice_block %.loc14_11.3 [concrete = constants.%empty_struct_type] { +// CHECK:STDOUT: %.loc14_11.2: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc14_11.3: type = converted %.loc14_11.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a: %empty_struct_type = value_binding a, %a.param +// CHECK:STDOUT: %b.param: %empty_struct_type = value_param call_param1 +// CHECK:STDOUT: %.loc14_18.1: type = splice_block %.loc14_18.3 [concrete = constants.%empty_struct_type] { +// CHECK:STDOUT: %.loc14_18.2: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc14_18.3: type = converted %.loc14_18.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b: %empty_struct_type = value_binding b, %b.param +// CHECK:STDOUT: %c.param: %empty_struct_type = value_param call_param2 +// CHECK:STDOUT: %.loc14_26.1: type = splice_block %.loc14_26.3 [concrete = constants.%empty_struct_type] { +// CHECK:STDOUT: %.loc14_26.2: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc14_26.3: type = converted %.loc14_26.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c: %empty_struct_type = value_binding c, %c.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallF.decl: %CallF.type = fn_decl @CallF [concrete = constants.%CallF] { +// CHECK:STDOUT: %ab.patt: %pattern_type.de4 = value_binding_pattern ab [concrete] +// CHECK:STDOUT: %ab.param_patt: %pattern_type.de4 = value_param_pattern %ab.patt, call_param0 [concrete] +// CHECK:STDOUT: %c.patt: %pattern_type.a96 = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.a96 = value_param_pattern %c.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %ab.param: %tuple.type.b6b = value_param call_param0 +// CHECK:STDOUT: %.loc18_21.1: type = splice_block %.loc18_21.5 [concrete = constants.%tuple.type.b6b] { +// CHECK:STDOUT: %.loc18_16: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc18_20: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc18_21.2: %tuple.type.b6b = tuple_literal (%.loc18_16, %.loc18_20) [concrete = constants.%tuple] +// CHECK:STDOUT: %.loc18_21.3: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc18_21.4: type = converted constants.%empty_struct, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %.loc18_21.5: type = converted %.loc18_21.2, constants.%tuple.type.b6b [concrete = constants.%tuple.type.b6b] +// CHECK:STDOUT: } +// CHECK:STDOUT: %ab: %tuple.type.b6b = value_binding ab, %ab.param +// CHECK:STDOUT: %c.param: %empty_struct_type = value_param call_param1 +// CHECK:STDOUT: %.loc18_28.1: type = splice_block %.loc18_28.3 [concrete = constants.%empty_struct_type] { +// CHECK:STDOUT: %.loc18_28.2: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc18_28.3: type = converted %.loc18_28.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c: %empty_struct_type = value_binding c, %c.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%a.param: %empty_struct_type, %b.param: %empty_struct_type, %c.param: %empty_struct_type) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallF(%ab.param: %tuple.type.b6b, %c.param: %empty_struct_type) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %ab.ref: %tuple.type.b6b = name_ref ab, %ab +// CHECK:STDOUT: %c.ref: %empty_struct_type = name_ref c, %c +// CHECK:STDOUT: %tuple.elem0: %empty_struct_type = tuple_access %ab.ref, element0 +// CHECK:STDOUT: %tuple.elem1: %empty_struct_type = tuple_access %ab.ref, element1 +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%tuple.elem0, %tuple.elem1, %c.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interop/cpp/function/class.carbon b/toolchain/check/testdata/interop/cpp/function/class.carbon index 8ace75123a3b..0f05490a8cb9 100644 --- a/toolchain/check/testdata/interop/cpp/function/class.carbon +++ b/toolchain/check/testdata/interop/cpp/function/class.carbon @@ -18,85 +18,66 @@ class C; -auto foo(C) -> void; +auto foo1(C) -> void; +auto foo2(C) -> void; // --- fail_import_decl_value_param_type.carbon library "[[@TEST_NAME]]"; +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:4:6: error: argument type 'C' is incomplete [CppInteropParseError] +// CHECK:STDERR: 4 | auto foo1(C) -> void; +// CHECK:STDERR: | ^~~~ +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:2:7: note: forward declaration of 'C' [CppInteropParseNote] +// CHECK:STDERR: 2 | class C; +// CHECK:STDERR: | ^ import Cpp library "decl_value_param_type.h"; -fn F() { - // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:11: error: invalid use of incomplete type `Cpp.C` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] +fn F(p: Cpp.C*) { + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-7]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:6: error: argument type 'C' is incomplete [CppInteropParseError] + // CHECK:STDERR: 5 | auto foo2(C) -> void; + // CHECK:STDERR: | ^~~~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-11]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: forward declaration of 'C' [CppInteropParseNote] + // CHECK:STDERR: 2 | class C; + // CHECK:STDERR: | ^ + Cpp.foo1(*p); + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+28]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-5]]:12: error: forming value of incomplete type `Cpp.C` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-23]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: class C; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-27]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:4:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo1(C) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - Cpp.foo({} as Cpp.C); -} - -// --- fail_import_decl_value_param_type_previously_imported.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE+12]]:10: error: binding pattern has incomplete type `C` in name binding declaration [IncompleteTypeInBindingDecl] - // CHECK:STDERR: let c: Cpp.C; - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:12: error: forming value of incomplete type `Cpp.C` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-35]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: class C; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-39]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo2(C) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet] - // CHECK:STDERR: let c: Cpp.C; - // CHECK:STDERR: ^ - // CHECK:STDERR: - let c: Cpp.C; - Cpp.foo(c); -} - -// ============================================================================ -// Forward-declared class as parameter type imported twice -// ============================================================================ - -// --- double_decl_value_param_type.h - -class C; - -auto foo1(C) -> void; -auto foo2(C) -> void; - -// --- fail_import_double_decl_value_param_type.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "double_decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.C` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo1({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: class C; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo1({} as Cpp.C); - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.C` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo2({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-15]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: class C; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo2({} as Cpp.C); + Cpp.foo2(*p); } // ============================================================================ @@ -115,9 +96,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_no_data_members_value_param_type.h"; -fn F() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.C); + Cpp.foo(c); //@dump-sem-ir-end } @@ -151,13 +132,13 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: | ^ import Cpp library "non_copyable_param_type.h"; -fn F() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin // CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+4]]:3: note: in thunk for C++ function used here [InCppThunk] - // CHECK:STDERR: Cpp.foo({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: Cpp.foo(c); + // CHECK:STDERR: ^~~~~~~~~~ // CHECK:STDERR: - Cpp.foo({} as Cpp.C); + Cpp.foo(c); //@dump-sem-ir-end } @@ -175,21 +156,15 @@ class C { auto foo(C) -> void; -// --- fail_todo_import_definition_single_data_member_value_param_type.carbon +// --- 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() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: zero initialization [class C] -> list initialization via constructor [class C] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.C); + Cpp.foo(c); //@dump-sem-ir-end } @@ -209,21 +184,15 @@ class C { auto foo(C) -> void; -// --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon +// --- 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() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: zero initialization [class C] -> list initialization via constructor [class C] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.C); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.C); + Cpp.foo(c); //@dump-sem-ir-end } @@ -243,9 +212,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_namespace_value_param_type.h"; -fn F() { +fn F(c: Cpp.N.C) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.N.C); + Cpp.foo(c); // Check that the parameter type was imported correctly. var x: Cpp.N.C; //@dump-sem-ir-end @@ -268,9 +237,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_relative_namespace_value_param_type.h"; -fn F() { +fn F(c: Cpp.N1.N2.C) { //@dump-sem-ir-begin - Cpp.N1.foo({} as Cpp.N1.N2.C); + Cpp.N1.foo(c); //@dump-sem-ir-end } @@ -293,9 +262,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_outer_definition.h"; -fn F() { +fn F(c: Cpp.O.C) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.O.C); + Cpp.foo(c); var x: Cpp.O; //@dump-sem-ir-end } @@ -319,10 +288,10 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin Cpp.C.bar(); - Cpp.foo({} as Cpp.C); + Cpp.foo(c); //@dump-sem-ir-end } @@ -332,9 +301,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(c: Cpp.C) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.C); + Cpp.foo(c); Cpp.C.bar(); //@dump-sem-ir-end } @@ -527,27 +496,22 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -555,52 +519,36 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %C to %.loc8_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %C = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %C = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %C = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8_14.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %C) = "no_op"; -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_non_copyable_param_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] // CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -608,85 +556,88 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc24_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc24: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc24_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc24_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc24_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc24_12.3: init %C to %.loc24_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc24_12.4: ref %C = temporary %.loc24_12.2, %.loc24_12.3 -// CHECK:STDOUT: %.loc24_14.1: ref %C = converted %.loc24_12.1, %.loc24_12.4 -// CHECK:STDOUT: %.loc24_14.2: %C = acquire_value %.loc24_14.1 -// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc24_14.2) -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc24_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc24_12.4) +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%c.ref) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %C) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_import_definition_single_data_member_value_param_type.carbon +// 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: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc14_14: %C = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon +// 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: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc14_14: %C = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -694,13 +645,10 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %pattern_type.69f: type = pattern_type %C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.69f: type = pattern_type %C [concrete] // CHECK:STDOUT: %ptr.838: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -710,16 +658,16 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N: = namespace [concrete] { // CHECK:STDOUT: .C = %C.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -727,21 +675,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N.ref.loc8: = name_ref N, imports.%N [concrete = imports.%N] -// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %C to %.loc8_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %C = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %C = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %C = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.838 = addr_of %.loc8_14.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.838 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.69f = ref_binding_pattern x [concrete] @@ -754,10 +694,8 @@ fn F() { // CHECK:STDOUT: %C.ref.loc10: type = name_ref C, imports.%C.decl [concrete = constants.%C] // CHECK:STDOUT: } // CHECK:STDOUT: %x: ref %C = ref_binding x, %x.var -// CHECK:STDOUT: %C.cpp_destructor.bound.loc10: = bound_method %x.var, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call.loc10: init %empty_tuple.type = call %C.cpp_destructor.bound.loc10(%x.var) -// CHECK:STDOUT: %C.cpp_destructor.bound.loc8: = bound_method %.loc8_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call.loc8: init %empty_tuple.type = call %C.cpp_destructor.bound.loc8(%.loc8_12.4) +// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %x.var, constants.%C.cpp_destructor +// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%x.var) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -767,17 +705,12 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %ptr.c0c: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -786,16 +719,16 @@ fn F() { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %N1: = namespace [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N2: = namespace [concrete] { // CHECK:STDOUT: .C = %C.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -803,61 +736,42 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_6: = name_ref N1, imports.%N1 [concrete = imports.%N1] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %N1.ref.loc8: = name_ref N1, imports.%N1 [concrete = imports.%N1] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_20: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_23: = name_ref N1, imports.%N1 [concrete = imports.%N1] -// CHECK:STDOUT: %N2.ref: = name_ref N2, imports.%N2 [concrete = imports.%N2] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc8_15.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc8_15.3: init %C to %.loc8_15.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc8_15.4: ref %C = temporary %.loc8_15.2, %.loc8_15.3 -// CHECK:STDOUT: %.loc8_17.1: ref %C = converted %.loc8_15.1, %.loc8_15.4 -// CHECK:STDOUT: %.loc8_17.2: %C = acquire_value %.loc8_17.1 -// CHECK:STDOUT: %.loc8_17.3: ref %C = value_as_ref %.loc8_17.2 -// CHECK:STDOUT: %addr: %ptr.c0c = addr_of %.loc8_17.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.c0c = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc8_15.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc8_15.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %C) = "no_op"; -// 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %O: type = class_type @O [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %ptr.de2: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.cff: type = pattern_type %O [concrete] // CHECK:STDOUT: %O.cpp_destructor.type: type = fn_type @O.cpp_destructor [concrete] // CHECK:STDOUT: %O.cpp_destructor: %O.cpp_destructor.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .O = %O.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %O.decl: type = class_decl @O [concrete = constants.%O] {} {} -// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -865,21 +779,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %O.ref.loc8: type = name_ref O, imports.%O.decl [concrete = constants.%O] -// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %C to %.loc8_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %C = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %C = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %C = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.de2 = addr_of %.loc8_14.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.de2 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.cff = ref_binding_pattern x [concrete] @@ -893,34 +799,25 @@ fn F() { // CHECK:STDOUT: %x: ref %O = ref_binding x, %x.var // CHECK:STDOUT: %O.cpp_destructor.bound: = bound_method %x.var, constants.%O.cpp_destructor // CHECK:STDOUT: %O.cpp_destructor.call: init %empty_tuple.type = call %O.cpp_destructor.bound(%x.var) -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc9(%self.param: %O) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc8(%self.param: %C) = "no_op"; +// CHECK:STDOUT: fn @DestroyOp(%self.param: %O) = "no_op"; // 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: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %C.bar.cpp_overload_set.type: type = cpp_overload_set_type @C.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %C.bar.cpp_overload_set.value: %C.bar.cpp_overload_set.type = cpp_overload_set_value @C.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %C.bar.type: type = fn_type @C.bar [concrete] // CHECK:STDOUT: %C.bar: %C.bar.type = struct_value () [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -940,42 +837,28 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %C.ref.loc8: type = name_ref C, imports.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %bar.ref: %C.bar.cpp_overload_set.type = name_ref bar, imports.%C.bar.cpp_overload_set.value [concrete = constants.%C.bar.cpp_overload_set.value] // CHECK:STDOUT: %C.bar.call: init %empty_tuple.type = call imports.%C.bar.decl() -// CHECK:STDOUT: %Cpp.ref.loc9_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc9_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc9_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref.loc9: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc9_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc9_12.3: init %C to %.loc9_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc9_12.4: ref %C = temporary %.loc9_12.2, %.loc9_12.3 -// CHECK:STDOUT: %.loc9_14.1: ref %C = converted %.loc9_12.1, %.loc9_12.4 -// CHECK:STDOUT: %.loc9_14.2: %C = acquire_value %.loc9_14.1 -// CHECK:STDOUT: %.loc9_14.3: ref %C = value_as_ref %.loc9_14.2 -// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc9_14.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc9: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc9 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc9_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc9_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %C) = "no_op"; -// 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: %C: type = class_type @C [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %ptr.d9e: type = ptr_type %C [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -983,18 +866,16 @@ fn F() { // CHECK:STDOUT: %C.bar.cpp_overload_set.value: %C.bar.cpp_overload_set.type = cpp_overload_set_value @C.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %C.bar.type: type = fn_type @C.bar [concrete] // CHECK:STDOUT: %C.bar: %C.bar.type = struct_value () [concrete] -// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete] -// CHECK:STDOUT: %C.cpp_destructor: %C.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -1004,32 +885,21 @@ fn F() { // CHECK:STDOUT: %C.bar.decl: %C.bar.type = fn_decl @C.bar [concrete = constants.%C.bar] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%c.param: %C) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, imports.%C.decl [concrete = constants.%C] -// CHECK:STDOUT: %.loc8_12.2: ref %C = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %C to %.loc8_12.2 = class_init () [concrete = constants.%C.val] -// CHECK:STDOUT: %.loc8_12.4: ref %C = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %C = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %C = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %C = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8_14.3 +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %.loc8: ref %C = value_as_ref %c.ref +// CHECK:STDOUT: %addr: %ptr.d9e = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %C.ref.loc9: type = name_ref C, imports.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %bar.ref: %C.bar.cpp_overload_set.type = name_ref bar, imports.%C.bar.cpp_overload_set.value [concrete = constants.%C.bar.cpp_overload_set.value] // CHECK:STDOUT: %C.bar.call: init %empty_tuple.type = call imports.%C.bar.decl() -// CHECK:STDOUT: %C.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%C.cpp_destructor -// CHECK:STDOUT: %C.cpp_destructor.call: init %empty_tuple.type = call %C.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %C) = "no_op"; -// CHECK:STDOUT: // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interop/cpp/function/overloads.carbon b/toolchain/check/testdata/interop/cpp/function/overloads.carbon index 64ba52f46fed..6e302ad0ef7b 100644 --- a/toolchain/check/testdata/interop/cpp/function/overloads.carbon +++ b/toolchain/check/testdata/interop/cpp/function/overloads.carbon @@ -262,60 +262,65 @@ import Cpp library "struct_init.h"; fn MakeThreeFields() -> {.a: i32, .b: i32, .c: i32}; fn ThreeFields(value: {.a: i32, .b: i32, .c: i32}, ref reference: {.a: i32, .b: i32, .c: i32}) { - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+10]]:23: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct ThreeFields] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+11]]:23: error: cannot implicitly convert expression of type `{.a: Core.IntLiteral, .b: Core.IntLiteral, .c: Core.IntLiteral}` to `Cpp.ThreeFields` [ConversionFailure] // CHECK:STDERR: Cpp.PassThreeFields({.a = 1, .b = 2, .c = 3}); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-10]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+8]]:23: note: type `{.a: Core.IntLiteral, .b: Core.IntLiteral, .c: Core.IntLiteral}` does not implement interface `Core.ImplicitAs(Cpp.ThreeFields)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.PassThreeFields({.a = 1, .b = 2, .c = 3}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-11]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./struct_init.h:10:34: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: auto PassThreeFields(ThreeFields t) -> void; // CHECK:STDERR: ^ // CHECK:STDERR: Cpp.PassThreeFields({.a = 1, .b = 2, .c = 3}); - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+10]]:23: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct ThreeFields] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+11]]:23: error: cannot implicitly convert expression of type `{.a: i32, .b: i32, .c: i32}` to `Cpp.ThreeFields` [ConversionFailure] // CHECK:STDERR: Cpp.PassThreeFields(value); // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-22]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+8]]:23: note: type `{.a: i32, .b: i32, .c: i32}` does not implement interface `Core.ImplicitAs(Cpp.ThreeFields)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.PassThreeFields(value); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-24]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./struct_init.h:10:34: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: auto PassThreeFields(ThreeFields t) -> void; // CHECK:STDERR: ^ // CHECK:STDERR: Cpp.PassThreeFields(value); - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+10]]:23: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct ThreeFields] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+11]]:23: error: cannot implicitly convert expression of type `{.a: i32, .b: i32, .c: i32}` to `Cpp.ThreeFields` [ConversionFailure] // CHECK:STDERR: Cpp.PassThreeFields(reference); // CHECK:STDERR: ^~~~~~~~~ - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-34]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+8]]:23: note: type `{.a: i32, .b: i32, .c: i32}` does not implement interface `Core.ImplicitAs(Cpp.ThreeFields)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.PassThreeFields(reference); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-37]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./struct_init.h:10:34: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: auto PassThreeFields(ThreeFields t) -> void; // CHECK:STDERR: ^ // CHECK:STDERR: Cpp.PassThreeFields(reference); - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+10]]:23: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct ThreeFields] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+11]]:23: error: cannot implicitly convert expression of type `{.a: i32, .b: i32, .c: i32}` to `Cpp.ThreeFields` [ConversionFailure] // CHECK:STDERR: Cpp.PassThreeFields(MakeThreeFields()); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-46]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+8]]:23: note: type `{.a: i32, .b: i32, .c: i32}` does not implement interface `Core.ImplicitAs(Cpp.ThreeFields)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.PassThreeFields(MakeThreeFields()); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-50]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./struct_init.h:10:34: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: auto PassThreeFields(ThreeFields t) -> void; // CHECK:STDERR: ^ // CHECK:STDERR: Cpp.PassThreeFields(MakeThreeFields()); - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+10]]:23: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct ThreeFields] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+11]]:23: error: cannot implicitly convert expression of type `{.b: Core.IntLiteral, .c: Core.IntLiteral, .a: Core.IntLiteral}` to `Cpp.ThreeFields` [ConversionFailure] // CHECK:STDERR: Cpp.PassThreeFields({.b = 1, .c = 2, .a = 3}); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-58]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE+8]]:23: note: type `{.b: Core.IntLiteral, .c: Core.IntLiteral, .a: Core.IntLiteral}` does not implement interface `Core.ImplicitAs(Cpp.ThreeFields)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.PassThreeFields({.b = 1, .c = 2, .a = 3}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_struct_init_nonempty.carbon:[[@LINE-63]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./struct_init.h:10:34: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: auto PassThreeFields(ThreeFields t) -> void; // CHECK:STDERR: ^ @@ -598,12 +603,13 @@ library "[[@TEST_NAME]]"; import Cpp library "nested_structs.h"; fn F() { - // CHECK:STDERR: fail_todo_pass_nested_structs.carbon:[[@LINE+10]]:13: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct B] - // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: fail_todo_pass_nested_structs.carbon:[[@LINE+11]]:13: error: cannot implicitly convert expression of type `{.a: {.x: Core.IntLiteral, .y: Core.IntLiteral}, .n: Core.IntLiteral}` to `Cpp.B` [ConversionFailure] // CHECK:STDERR: Cpp.TakeB({.a = {.x = 1, .y = 2}, .n = 3}); // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_pass_nested_structs.carbon:[[@LINE-8]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_todo_pass_nested_structs.carbon:[[@LINE+8]]:13: note: type `{.a: {.x: Core.IntLiteral, .y: Core.IntLiteral}, .n: Core.IntLiteral}` does not implement interface `Core.ImplicitAs(Cpp.B)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: Cpp.TakeB({.a = {.x = 1, .y = 2}, .n = 3}); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_pass_nested_structs.carbon:[[@LINE-9]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./nested_structs.h:11:13: note: initializing function parameter [InCallToFunctionParam] // CHECK:STDERR: void TakeB(B); // CHECK:STDERR: ^ @@ -2542,6 +2548,8 @@ fn F() { // CHECK:STDOUT: %ThreeFields.elem: type = unbound_element_type %ThreeFields.942, %i32 [concrete] // CHECK:STDOUT: %.c77: type = custom_layout_type {size=12, align=4, .a@0: %i32, .b@4: %i32, .c@8: %i32} [concrete] // CHECK:STDOUT: %complete_type.702: = complete_type_witness %.c77 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %struct_type.b.c.a: type = struct_type {.b: Core.IntLiteral, .c: Core.IntLiteral, .a: Core.IntLiteral} [concrete] // CHECK:STDOUT: %struct.d34: %struct_type.b.c.a = struct_value (%int_1, %int_2, %int_3) [concrete] // CHECK:STDOUT: } @@ -2549,6 +2557,7 @@ fn F() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -2565,6 +2574,7 @@ fn F() { // CHECK:STDOUT: %t.param: %ptr.f81 = value_param call_param0 // CHECK:STDOUT: %t: %ptr.f81 = value_binding t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2646,44 +2656,44 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: fn @ThreeFields.loc8(%value.param: %struct_type.a.b.c.0b6, %reference.param: %struct_type.a.b.c.0b6) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc19: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %PassThreeFields.ref.loc19: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] -// CHECK:STDOUT: %int_1.loc19: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %int_2.loc19: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %int_3.loc19: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc19_46.1: %struct_type.a.b.c.90d = struct_literal (%int_1.loc19, %int_2.loc19, %int_3.loc19) [concrete = constants.%struct.ec0] -// CHECK:STDOUT: %.loc19_46.2: %ThreeFields.942 = converted %.loc19_46.1, [concrete = ] -// CHECK:STDOUT: %addr.loc19: %ptr.f81 = addr_of [concrete = ] -// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc19: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc19) -// CHECK:STDOUT: %Cpp.ref.loc31: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %PassThreeFields.ref.loc31: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] +// CHECK:STDOUT: %Cpp.ref.loc20: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %PassThreeFields.ref.loc20: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] +// CHECK:STDOUT: %int_1.loc20: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_2.loc20: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] +// CHECK:STDOUT: %int_3.loc20: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] +// CHECK:STDOUT: %.loc20_46.1: %struct_type.a.b.c.90d = struct_literal (%int_1.loc20, %int_2.loc20, %int_3.loc20) [concrete = constants.%struct.ec0] +// CHECK:STDOUT: %.loc20_46.2: %ThreeFields.942 = converted %.loc20_46.1, [concrete = ] +// CHECK:STDOUT: %addr.loc20: %ptr.f81 = addr_of [concrete = ] +// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc20: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc20) +// CHECK:STDOUT: %Cpp.ref.loc33: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %PassThreeFields.ref.loc33: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] // CHECK:STDOUT: %value.ref: %struct_type.a.b.c.0b6 = name_ref value, %value -// CHECK:STDOUT: %.loc31: %ThreeFields.942 = converted %value.ref, [concrete = ] -// CHECK:STDOUT: %addr.loc31: %ptr.f81 = addr_of [concrete = ] -// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc31: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc31) -// CHECK:STDOUT: %Cpp.ref.loc43: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %PassThreeFields.ref.loc43: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] +// CHECK:STDOUT: %.loc33: %ThreeFields.942 = converted %value.ref, [concrete = ] +// CHECK:STDOUT: %addr.loc33: %ptr.f81 = addr_of [concrete = ] +// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc33: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc33) +// CHECK:STDOUT: %Cpp.ref.loc46: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %PassThreeFields.ref.loc46: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] // CHECK:STDOUT: %reference.ref: ref %struct_type.a.b.c.0b6 = name_ref reference, %reference -// CHECK:STDOUT: %.loc43: %ThreeFields.942 = converted %reference.ref, [concrete = ] -// CHECK:STDOUT: %addr.loc43: %ptr.f81 = addr_of [concrete = ] -// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc43: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc43) -// CHECK:STDOUT: %Cpp.ref.loc55: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %PassThreeFields.ref.loc55: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] +// CHECK:STDOUT: %.loc46: %ThreeFields.942 = converted %reference.ref, [concrete = ] +// CHECK:STDOUT: %addr.loc46: %ptr.f81 = addr_of [concrete = ] +// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc46: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc46) +// CHECK:STDOUT: %Cpp.ref.loc59: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %PassThreeFields.ref.loc59: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] // CHECK:STDOUT: %MakeThreeFields.ref: %MakeThreeFields.type = name_ref MakeThreeFields, file.%MakeThreeFields.decl [concrete = constants.%MakeThreeFields] -// CHECK:STDOUT: %.loc55_39.1: ref %struct_type.a.b.c.0b6 = temporary_storage -// CHECK:STDOUT: %MakeThreeFields.call: init %struct_type.a.b.c.0b6 to %.loc55_39.1 = call %MakeThreeFields.ref() -// CHECK:STDOUT: %.loc55_39.2: %ThreeFields.942 = converted %MakeThreeFields.call, [concrete = ] -// CHECK:STDOUT: %addr.loc55: %ptr.f81 = addr_of [concrete = ] -// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc55: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc55) -// CHECK:STDOUT: %Cpp.ref.loc67: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %PassThreeFields.ref.loc67: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] -// CHECK:STDOUT: %int_1.loc67: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %int_2.loc67: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %int_3.loc67: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc67_46.1: %struct_type.b.c.a = struct_literal (%int_1.loc67, %int_2.loc67, %int_3.loc67) [concrete = constants.%struct.d34] -// CHECK:STDOUT: %.loc67_46.2: %ThreeFields.942 = converted %.loc67_46.1, [concrete = ] -// CHECK:STDOUT: %addr.loc67: %ptr.f81 = addr_of [concrete = ] -// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc67: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc67) +// CHECK:STDOUT: %.loc59_39.1: ref %struct_type.a.b.c.0b6 = temporary_storage +// CHECK:STDOUT: %MakeThreeFields.call: init %struct_type.a.b.c.0b6 to %.loc59_39.1 = call %MakeThreeFields.ref() +// CHECK:STDOUT: %.loc59_39.2: %ThreeFields.942 = converted %MakeThreeFields.call, [concrete = ] +// CHECK:STDOUT: %addr.loc59: %ptr.f81 = addr_of [concrete = ] +// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc59: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc59) +// CHECK:STDOUT: %Cpp.ref.loc72: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %PassThreeFields.ref.loc72: %PassThreeFields.cpp_overload_set.type = name_ref PassThreeFields, imports.%PassThreeFields.cpp_overload_set.value [concrete = constants.%PassThreeFields.cpp_overload_set.value] +// CHECK:STDOUT: %int_1.loc72: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_2.loc72: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] +// CHECK:STDOUT: %int_3.loc72: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] +// CHECK:STDOUT: %.loc72_46.1: %struct_type.b.c.a = struct_literal (%int_1.loc72, %int_2.loc72, %int_3.loc72) [concrete = constants.%struct.d34] +// CHECK:STDOUT: %.loc72_46.2: %ThreeFields.942 = converted %.loc72_46.1, [concrete = ] +// CHECK:STDOUT: %addr.loc72: %ptr.f81 = addr_of [concrete = ] +// CHECK:STDOUT: %PassThreeFields__carbon_thunk.call.loc72: init %empty_tuple.type = call imports.%PassThreeFields__carbon_thunk.decl(%addr.loc72) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -3314,11 +3324,14 @@ fn F() { // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] // CHECK:STDOUT: %.7b6: type = custom_layout_type {size=8, align=4, .x@0: %i32, .y@4: %i32} [concrete] // CHECK:STDOUT: %complete_type.1e0: = complete_type_witness %.7b6 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -3335,6 +3348,7 @@ fn F() { // CHECK:STDOUT: %_: %ptr.a04 = value_binding _, %_.param // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3384,10 +3398,10 @@ fn F() { // CHECK:STDOUT: %TakeB.ref: %TakeB.cpp_overload_set.type = name_ref TakeB, imports.%TakeB.cpp_overload_set.value [concrete = constants.%TakeB.cpp_overload_set.value] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc17_34: %struct_type.x.y = struct_literal (%int_1, %int_2) [concrete = constants.%struct.004] +// CHECK:STDOUT: %.loc18_34: %struct_type.x.y = struct_literal (%int_1, %int_2) [concrete = constants.%struct.004] // CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3] -// CHECK:STDOUT: %.loc17_43.1: %struct_type.a.n.988 = struct_literal (%.loc17_34, %int_3) [concrete = constants.%struct.516] -// CHECK:STDOUT: %.loc17_43.2: %B = converted %.loc17_43.1, [concrete = ] +// CHECK:STDOUT: %.loc18_43.1: %struct_type.a.n.988 = struct_literal (%.loc18_34, %int_3) [concrete = constants.%struct.516] +// CHECK:STDOUT: %.loc18_43.2: %B = converted %.loc18_43.1, [concrete = ] // CHECK:STDOUT: %addr: %ptr.a04 = addr_of [concrete = ] // CHECK:STDOUT: %TakeB__carbon_thunk.call: init %empty_tuple.type = call imports.%TakeB__carbon_thunk.decl(%addr) // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/interop/cpp/function/struct.carbon b/toolchain/check/testdata/interop/cpp/function/struct.carbon index 3d33219cf144..a175c2ddbad3 100644 --- a/toolchain/check/testdata/interop/cpp/function/struct.carbon +++ b/toolchain/check/testdata/interop/cpp/function/struct.carbon @@ -18,85 +18,66 @@ struct S; -auto foo(S) -> void; +auto foo1(S) -> void; +auto foo2(S) -> void; // --- fail_import_decl_value_param_type.carbon library "[[@TEST_NAME]]"; +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:4:6: error: argument type 'S' is incomplete [CppInteropParseError] +// CHECK:STDERR: 4 | auto foo1(S) -> void; +// CHECK:STDERR: | ^~~~ +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:2:8: note: forward declaration of 'S' [CppInteropParseNote] +// CHECK:STDERR: 2 | struct S; +// CHECK:STDERR: | ^ import Cpp library "decl_value_param_type.h"; -fn F() { - // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:11: error: invalid use of incomplete type `Cpp.S` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] +fn F(p: Cpp.S*) { + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-7]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:6: error: argument type 'S' is incomplete [CppInteropParseError] + // CHECK:STDERR: 5 | auto foo2(S) -> void; + // CHECK:STDERR: | ^~~~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-11]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:2:8: note: forward declaration of 'S' [CppInteropParseNote] + // CHECK:STDERR: 2 | struct S; + // CHECK:STDERR: | ^ + Cpp.foo1(*p); + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+28]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-5]]:12: error: forming value of incomplete type `Cpp.S` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-23]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: struct S; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-27]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:4:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo1(S) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - Cpp.foo({} as Cpp.S); -} - -// --- fail_import_decl_value_param_type_previously_imported.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE+12]]:10: error: binding pattern has incomplete type `S` in name binding declaration [IncompleteTypeInBindingDecl] - // CHECK:STDERR: let s: Cpp.S; - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:12: error: forming value of incomplete type `Cpp.S` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-35]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: struct S; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-39]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo2(S) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_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_import_double_decl_value_param_type.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "double_decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.S` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo1({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: struct S; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo1({} as Cpp.S); - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.S` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo2({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-15]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: struct S; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo2({} as Cpp.S); + Cpp.foo2(*p); } // ============================================================================ @@ -115,9 +96,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_no_data_members_value_param_type.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.S); + Cpp.foo(s); //@dump-sem-ir-end } @@ -151,13 +132,13 @@ library "[[@TEST_NAME]]"; // CHECK:STDERR: | ^ import Cpp library "non_copyable_param_type.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin // CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+4]]:3: note: in thunk for C++ function used here [InCppThunk] - // CHECK:STDERR: Cpp.foo({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: Cpp.foo(s); + // CHECK:STDERR: ^~~~~~~~~~ // CHECK:STDERR: - Cpp.foo({} as Cpp.S); + Cpp.foo(s); //@dump-sem-ir-end } @@ -175,21 +156,15 @@ struct S { auto foo(S) -> void; -// --- fail_todo_import_definition_single_data_member_value_param_type.carbon +// --- definition_single_data_member_value_param_type.carbon library "[[@TEST_NAME]]"; import Cpp library "definition_single_data_member_value_param_type.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_import_definition_single_data_member_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct S] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.S); + Cpp.foo(s); //@dump-sem-ir-end } @@ -209,21 +184,15 @@ struct S { auto foo(S) -> void; -// --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon +// --- definition_multiple_data_members_value_param_type.carbon library "[[@TEST_NAME]]"; import Cpp library "definition_multiple_data_members_value_param_type.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [struct S] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.S); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.S); + Cpp.foo(s); //@dump-sem-ir-end } @@ -243,9 +212,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_namespace_value_param_type.h"; -fn F() { +fn F(s: Cpp.N.S) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.N.S); + Cpp.foo(s); // Check that the parameter type was imported correctly. var x: Cpp.N.S; //@dump-sem-ir-end @@ -268,9 +237,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_relative_namespace_value_param_type.h"; -fn F() { +fn F(s: Cpp.N1.N2.S) { //@dump-sem-ir-begin - Cpp.N1.foo({} as Cpp.N1.N2.S); + Cpp.N1.foo(s); //@dump-sem-ir-end } @@ -292,9 +261,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_outer_definition.h"; -fn F() { +fn F(s: Cpp.O.S) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.O.S); + Cpp.foo(s); var x: Cpp.O; //@dump-sem-ir-end } @@ -317,10 +286,10 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin Cpp.S.bar(); - Cpp.foo({} as Cpp.S); + Cpp.foo(s); //@dump-sem-ir-end } @@ -330,9 +299,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(s: Cpp.S) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.S); + Cpp.foo(s); Cpp.S.bar(); //@dump-sem-ir-end } @@ -526,27 +495,22 @@ fn F() { // 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.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] // CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .S = %S.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -554,52 +518,36 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %S to %.loc8_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %S = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %S = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %S = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_14.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %S) = "no_op"; -// CHECK:STDOUT: // CHECK:STDOUT: --- fail_import_non_copyable_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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] // CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] // CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .S = %S.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -607,85 +555,88 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc24_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc24: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc24_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc24_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc24_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc24_12.3: init %S to %.loc24_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc24_12.4: ref %S = temporary %.loc24_12.2, %.loc24_12.3 -// CHECK:STDOUT: %.loc24_14.1: ref %S = converted %.loc24_12.1, %.loc24_12.4 -// CHECK:STDOUT: %.loc24_14.2: %S = acquire_value %.loc24_14.1 -// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%.loc24_14.2) -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc24_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc24_12.4) +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call imports.%foo.decl(%s.ref) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %S) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_import_definition_single_data_member_value_param_type.carbon +// CHECK:STDOUT: --- 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] +// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .S = %S.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc14_14: %S = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_import_definition_multiple_data_members_value_param_type.carbon +// CHECK:STDOUT: --- 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] +// CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .S = %S.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc14_14: %S = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -693,13 +644,10 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %S: type = class_type @S [concrete] +// CHECK:STDOUT: %pattern_type.cd8: type = pattern_type %S [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.cd8: type = pattern_type %S [concrete] // CHECK:STDOUT: %ptr.edf: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -709,16 +657,16 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N: = 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.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -726,21 +674,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N.ref.loc8: = name_ref N, imports.%N [concrete = imports.%N] -// CHECK:STDOUT: %S.ref.loc8: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %S to %.loc8_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %S = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %S = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %S = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.edf = addr_of %.loc8_14.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.edf = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.cd8 = ref_binding_pattern x [concrete] @@ -753,10 +693,8 @@ fn F() { // CHECK:STDOUT: %S.ref.loc10: type = name_ref S, imports.%S.decl [concrete = constants.%S] // CHECK:STDOUT: } // CHECK:STDOUT: %x: ref %S = ref_binding x, %x.var -// CHECK:STDOUT: %S.cpp_destructor.bound.loc10: = bound_method %x.var, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call.loc10: init %empty_tuple.type = call %S.cpp_destructor.bound.loc10(%x.var) -// CHECK:STDOUT: %S.cpp_destructor.bound.loc8: = bound_method %.loc8_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call.loc8: init %empty_tuple.type = call %S.cpp_destructor.bound.loc8(%.loc8_12.4) +// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %x.var, constants.%S.cpp_destructor +// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%x.var) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -766,17 +704,12 @@ fn F() { // 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.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] // CHECK:STDOUT: %ptr.887: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -785,16 +718,16 @@ fn F() { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %N1: = namespace [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N2: = 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.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -802,61 +735,42 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_6: = name_ref N1, imports.%N1 [concrete = imports.%N1] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %N1.ref.loc8: = name_ref N1, imports.%N1 [concrete = imports.%N1] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_20: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_23: = name_ref N1, imports.%N1 [concrete = imports.%N1] -// CHECK:STDOUT: %N2.ref: = name_ref N2, imports.%N2 [concrete = imports.%N2] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc8_15.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc8_15.3: init %S to %.loc8_15.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc8_15.4: ref %S = temporary %.loc8_15.2, %.loc8_15.3 -// CHECK:STDOUT: %.loc8_17.1: ref %S = converted %.loc8_15.1, %.loc8_15.4 -// CHECK:STDOUT: %.loc8_17.2: %S = acquire_value %.loc8_17.1 -// CHECK:STDOUT: %.loc8_17.3: ref %S = value_as_ref %.loc8_17.2 -// CHECK:STDOUT: %addr: %ptr.887 = addr_of %.loc8_17.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.887 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc8_15.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc8_15.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %S) = "no_op"; -// 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %O: type = class_type @O [concrete] // CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %ptr.149: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.cff: type = pattern_type %O [concrete] // CHECK:STDOUT: %O.cpp_destructor.type: type = fn_type @O.cpp_destructor [concrete] // CHECK:STDOUT: %O.cpp_destructor: %O.cpp_destructor.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .O = %O.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %O.decl: type = class_decl @O [concrete = constants.%O] {} {} -// CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -864,21 +778,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %O.ref.loc8: type = name_ref O, imports.%O.decl [concrete = constants.%O] -// CHECK:STDOUT: %S.ref: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %S to %.loc8_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %S = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %S = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %S = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.149 = addr_of %.loc8_14.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.149 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.cff = ref_binding_pattern x [concrete] @@ -892,34 +798,25 @@ fn F() { // CHECK:STDOUT: %x: ref %O = ref_binding x, %x.var // CHECK:STDOUT: %O.cpp_destructor.bound: = bound_method %x.var, constants.%O.cpp_destructor // CHECK:STDOUT: %O.cpp_destructor.call: init %empty_tuple.type = call %O.cpp_destructor.bound(%x.var) -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc9(%self.param: %O) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc8(%self.param: %S) = "no_op"; +// CHECK:STDOUT: fn @DestroyOp(%self.param: %O) = "no_op"; // 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: %S.bar.cpp_overload_set.type: type = cpp_overload_set_type @S.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %S.bar.cpp_overload_set.value: %S.bar.cpp_overload_set.type = cpp_overload_set_value @S.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %S.bar.type: type = fn_type @S.bar [concrete] // CHECK:STDOUT: %S.bar: %S.bar.type = struct_value () [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] // CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -939,42 +836,28 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %S.ref.loc8: type = name_ref S, imports.%S.decl [concrete = constants.%S] // CHECK:STDOUT: %bar.ref: %S.bar.cpp_overload_set.type = name_ref bar, imports.%S.bar.cpp_overload_set.value [concrete = constants.%S.bar.cpp_overload_set.value] // CHECK:STDOUT: %S.bar.call: init %empty_tuple.type = call imports.%S.bar.decl() -// CHECK:STDOUT: %Cpp.ref.loc9_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc9_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc9_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref.loc9: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc9_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc9_12.3: init %S to %.loc9_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc9_12.4: ref %S = temporary %.loc9_12.2, %.loc9_12.3 -// CHECK:STDOUT: %.loc9_14.1: ref %S = converted %.loc9_12.1, %.loc9_12.4 -// CHECK:STDOUT: %.loc9_14.2: %S = acquire_value %.loc9_14.1 -// CHECK:STDOUT: %.loc9_14.3: ref %S = value_as_ref %.loc9_14.2 -// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc9_14.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc9: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc9 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc9_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc9_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %S) = "no_op"; -// 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %S: type = class_type @S [concrete] -// CHECK:STDOUT: %S.val: %S = struct_value () [concrete] // CHECK:STDOUT: %ptr.5c7: type = ptr_type %S [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -982,18 +865,16 @@ fn F() { // CHECK:STDOUT: %S.bar.cpp_overload_set.value: %S.bar.cpp_overload_set.type = cpp_overload_set_value @S.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %S.bar.type: type = fn_type @S.bar [concrete] // CHECK:STDOUT: %S.bar: %S.bar.type = struct_value () [concrete] -// CHECK:STDOUT: %S.cpp_destructor.type: type = fn_type @S.cpp_destructor [concrete] -// CHECK:STDOUT: %S.cpp_destructor: %S.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .S = %S.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %S.decl: type = class_decl @S [concrete = constants.%S] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -1003,32 +884,21 @@ fn F() { // CHECK:STDOUT: %S.bar.decl: %S.bar.type = fn_decl @S.bar [concrete = constants.%S.bar] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%s.param: %S) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %S.ref.loc8: type = name_ref S, imports.%S.decl [concrete = constants.%S] -// CHECK:STDOUT: %.loc8_12.2: ref %S = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %S to %.loc8_12.2 = class_init () [concrete = constants.%S.val] -// CHECK:STDOUT: %.loc8_12.4: ref %S = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %S = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %S = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %S = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8_14.3 +// CHECK:STDOUT: %s.ref: %S = name_ref s, %s +// CHECK:STDOUT: %.loc8: ref %S = value_as_ref %s.ref +// CHECK:STDOUT: %addr: %ptr.5c7 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %S.ref.loc9: type = name_ref S, imports.%S.decl [concrete = constants.%S] // CHECK:STDOUT: %bar.ref: %S.bar.cpp_overload_set.type = name_ref bar, imports.%S.bar.cpp_overload_set.value [concrete = constants.%S.bar.cpp_overload_set.value] // CHECK:STDOUT: %S.bar.call: init %empty_tuple.type = call imports.%S.bar.decl() -// CHECK:STDOUT: %S.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%S.cpp_destructor -// CHECK:STDOUT: %S.cpp_destructor.call: init %empty_tuple.type = call %S.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %S) = "no_op"; -// CHECK:STDOUT: // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interop/cpp/function/union.carbon b/toolchain/check/testdata/interop/cpp/function/union.carbon index 8c2ad2d57e6e..c5d5948ba2d8 100644 --- a/toolchain/check/testdata/interop/cpp/function/union.carbon +++ b/toolchain/check/testdata/interop/cpp/function/union.carbon @@ -18,87 +18,66 @@ union U; -auto foo(U) -> void; +auto foo1(U) -> void; +auto foo2(U) -> void; // --- fail_import_decl_value_param_type.carbon library "[[@TEST_NAME]]"; +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:4:6: error: argument type 'U' is incomplete [CppInteropParseError] +// CHECK:STDERR: 4 | auto foo1(U) -> void; +// CHECK:STDERR: | ^~~~ +// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude] +// CHECK:STDERR: ./decl_value_param_type.h:2:7: note: forward declaration of 'U' [CppInteropParseNote] +// CHECK:STDERR: 2 | union U; +// CHECK:STDERR: | ^ import Cpp library "decl_value_param_type.h"; -fn F() { - //@dump-sem-ir-begin - // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:11: error: invalid use of incomplete type `Cpp.U` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo({} as Cpp.U); - // CHECK:STDERR: ^~~~~~~~~~~ +fn F(p: Cpp.U*) { + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-7]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:6: error: argument type 'U' is incomplete [CppInteropParseError] + // CHECK:STDERR: 5 | auto foo2(U) -> void; + // CHECK:STDERR: | ^~~~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-11]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: forward declaration of 'U' [CppInteropParseNote] + // CHECK:STDERR: 2 | union U; + // CHECK:STDERR: | ^ + Cpp.foo1(*p); + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+28]]:3: note: in thunk for C++ function used here [InCppThunk] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~~~~~~~~~~~ + // CHECK:STDERR: + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-5]]:12: error: forming value of incomplete type `Cpp.U` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo1(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-23]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: union U; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-27]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:4:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo1(U) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - Cpp.foo({} as Cpp.U); - //@dump-sem-ir-end -} - -// --- fail_import_decl_value_param_type_previously_imported.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE+12]]:10: error: binding pattern has incomplete type `U` in name binding declaration [IncompleteTypeInBindingDecl] - // CHECK:STDERR: let u: Cpp.U; - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:12: error: forming value of incomplete type `Cpp.U` [IncompleteTypeInValueConversion] + // CHECK:STDERR: Cpp.foo2(*p); + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-35]]:10: in file included here [InCppInclude] // CHECK:STDERR: ./decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] // CHECK:STDERR: union U; // CHECK:STDERR: ^ + // CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-39]]:10: in file included here [InCppInclude] + // CHECK:STDERR: ./decl_value_param_type.h:5:12: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: auto foo2(U) -> void; + // CHECK:STDERR: ^ // CHECK:STDERR: - // CHECK:STDERR: fail_import_decl_value_param_type_previously_imported.carbon:[[@LINE+4]]:15: error: expected `=`; `let` declaration must have an initializer [ExpectedInitializerAfterLet] - // CHECK:STDERR: let u: Cpp.U; - // CHECK:STDERR: ^ - // CHECK:STDERR: - let u: Cpp.U; - Cpp.foo(u); -} - -// ============================================================================ -// Forward-declared union as parameter type imported twice -// ============================================================================ - -// --- double_decl_value_param_type.h - -union U; - -auto foo1(U) -> void; -auto foo2(U) -> void; - -// --- fail_import_double_decl_value_param_type.carbon - -library "[[@TEST_NAME]]"; - -import Cpp library "double_decl_value_param_type.h"; - -fn F() { - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.U` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo1({} as Cpp.U); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-6]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: union U; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo1({} as Cpp.U); - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE+8]]:12: error: invalid use of incomplete type `Cpp.U` [IncompleteTypeInConversion] - // CHECK:STDERR: Cpp.foo2({} as Cpp.U); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: fail_import_double_decl_value_param_type.carbon:[[@LINE-15]]:10: in file included here [InCppInclude] - // CHECK:STDERR: ./double_decl_value_param_type.h:2:7: note: class was forward declared here [ClassForwardDeclaredHere] - // CHECK:STDERR: union U; - // CHECK:STDERR: ^ - // CHECK:STDERR: - Cpp.foo2({} as Cpp.U); + Cpp.foo2(*p); } // ============================================================================ @@ -117,9 +96,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_no_data_members_value_param_type.h"; -fn F() { +fn F(u: Cpp.U) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.U); + Cpp.foo(u); //@dump-sem-ir-end } @@ -137,21 +116,15 @@ union U { auto foo(U) -> void; -// --- fail_import_definition_single_data_member_value_param_type.carbon +// --- 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() { +fn F(u: Cpp.U) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_import_definition_single_data_member_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [union U] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.U); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.U); + Cpp.foo(u); //@dump-sem-ir-end } @@ -171,21 +144,15 @@ union U { auto foo(U) -> void; -// --- fail_import_definition_multiple_data_members_value_param_type.carbon +// --- 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() { +fn F(u: Cpp.U) { //@dump-sem-ir-begin - // CHECK:STDERR: fail_import_definition_multiple_data_members_value_param_type.carbon:[[@LINE+6]]:11: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list aggregate initialization [union U] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo({} as Cpp.U); - // CHECK:STDERR: ^~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo({} as Cpp.U); + Cpp.foo(u); //@dump-sem-ir-end } @@ -205,9 +172,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_namespace_value_param_type.h"; -fn F() { +fn F(u: Cpp.N.U) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.N.U); + Cpp.foo(u); // Check that the parameter type was imported correctly. var x: Cpp.N.U; //@dump-sem-ir-end @@ -230,9 +197,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_relative_namespace_value_param_type.h"; -fn F() { +fn F(u: Cpp.N1.N2.U) { //@dump-sem-ir-begin - Cpp.N1.foo({} as Cpp.N1.N2.U); + Cpp.N1.foo(u); //@dump-sem-ir-end } @@ -255,9 +222,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_in_outer_definition.h"; -fn F() { +fn F(u: Cpp.O.U) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.O.U); + Cpp.foo(u); var x: Cpp.O; //@dump-sem-ir-end } @@ -280,10 +247,10 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(u: Cpp.U) { //@dump-sem-ir-begin Cpp.U.bar(); - Cpp.foo({} as Cpp.U); + Cpp.foo(u); //@dump-sem-ir-end } @@ -293,9 +260,9 @@ library "[[@TEST_NAME]]"; import Cpp library "definition_with_static_method.h"; -fn F() { +fn F(u: Cpp.U) { //@dump-sem-ir-begin - Cpp.foo({} as Cpp.U); + Cpp.foo(u); Cpp.U.bar(); //@dump-sem-ir-end } @@ -484,61 +451,26 @@ fn F() { //@dump-sem-ir-end } -// CHECK:STDOUT: --- fail_import_decl_value_param_type.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value -// CHECK:STDOUT: .U = %U.decl -// CHECK:STDOUT: import Cpp//... -// CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc16_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc16: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc16_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: -// CHECK:STDOUT: } -// CHECK:STDOUT: // 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: %U: type = class_type @U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] // CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %U.cpp_destructor.type: type = fn_type @U.cpp_destructor [concrete] -// CHECK:STDOUT: %U.cpp_destructor: %U.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .U = %U.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -546,87 +478,90 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %U to %.loc8_12.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc8_12.4: ref %U = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %U = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %U = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %U = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8_14.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %U) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: --- fail_import_definition_single_data_member_value_param_type.carbon +// 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: %U: type = class_type @U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] +// CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .U = %U.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc14_14: %U = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_import_definition_multiple_data_members_value_param_type.carbon +// 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: %U: type = class_type @U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] +// CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete] +// CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] +// CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .U = %U.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] +// CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc14_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc14_12: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc14_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc14_14: %U = converted %.loc14_12, [concrete = ] +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8 +// CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -634,13 +569,10 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %U: type = class_type @U [concrete] +// CHECK:STDOUT: %pattern_type.eb9: type = pattern_type %U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.eb9: type = pattern_type %U [concrete] // CHECK:STDOUT: %ptr.87e: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -650,16 +582,16 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N = %N +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N: = namespace [concrete] { // CHECK:STDOUT: .U = %U.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -667,21 +599,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N.ref.loc8: = name_ref N, imports.%N [concrete = imports.%N] -// CHECK:STDOUT: %U.ref.loc8: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %U to %.loc8_12.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc8_12.4: ref %U = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %U = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %U = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %U = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.87e = addr_of %.loc8_14.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.87e = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.eb9 = ref_binding_pattern x [concrete] @@ -694,10 +618,8 @@ fn F() { // CHECK:STDOUT: %U.ref.loc10: type = name_ref U, imports.%U.decl [concrete = constants.%U] // CHECK:STDOUT: } // CHECK:STDOUT: %x: ref %U = ref_binding x, %x.var -// CHECK:STDOUT: %U.cpp_destructor.bound.loc10: = bound_method %x.var, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call.loc10: init %empty_tuple.type = call %U.cpp_destructor.bound.loc10(%x.var) -// CHECK:STDOUT: %U.cpp_destructor.bound.loc8: = bound_method %.loc8_12.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call.loc8: init %empty_tuple.type = call %U.cpp_destructor.bound.loc8(%.loc8_12.4) +// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %x.var, constants.%U.cpp_destructor +// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%x.var) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -707,17 +629,12 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %U: type = class_type @U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] // CHECK:STDOUT: %ptr.8c1: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %U.cpp_destructor.type: type = fn_type @U.cpp_destructor [concrete] -// CHECK:STDOUT: %U.cpp_destructor: %U.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -726,16 +643,16 @@ fn F() { // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %N1: = namespace [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .N2 = %N2 +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %N2: = namespace [concrete] { // CHECK:STDOUT: .U = %U.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -743,61 +660,42 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_6: = name_ref N1, imports.%N1 [concrete = imports.%N1] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %N1.ref.loc8: = name_ref N1, imports.%N1 [concrete = imports.%N1] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_20: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %N1.ref.loc8_23: = name_ref N1, imports.%N1 [concrete = imports.%N1] -// CHECK:STDOUT: %N2.ref: = name_ref N2, imports.%N2 [concrete = imports.%N2] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc8_15.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc8_15.3: init %U to %.loc8_15.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc8_15.4: ref %U = temporary %.loc8_15.2, %.loc8_15.3 -// CHECK:STDOUT: %.loc8_17.1: ref %U = converted %.loc8_15.1, %.loc8_15.4 -// CHECK:STDOUT: %.loc8_17.2: %U = acquire_value %.loc8_17.1 -// CHECK:STDOUT: %.loc8_17.3: ref %U = value_as_ref %.loc8_17.2 -// CHECK:STDOUT: %addr: %ptr.8c1 = addr_of %.loc8_17.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.8c1 = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %.loc8_15.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%.loc8_15.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %U) = "no_op"; -// 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: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %O: type = class_type @O [concrete] // CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %ptr.a6c: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.cff: type = pattern_type %O [concrete] // CHECK:STDOUT: %O.cpp_destructor.type: type = fn_type @O.cpp_destructor [concrete] // CHECK:STDOUT: %O.cpp_destructor: %O.cpp_destructor.type = struct_value () [concrete] -// CHECK:STDOUT: %U.cpp_destructor.type: type = fn_type @U.cpp_destructor [concrete] -// CHECK:STDOUT: %U.cpp_destructor: %U.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .O = %O.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %O.decl: type = class_decl @O [concrete = constants.%O] {} {} -// CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -805,21 +703,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %O.ref.loc8: type = name_ref O, imports.%O.decl [concrete = constants.%O] -// CHECK:STDOUT: %U.ref: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %U to %.loc8_12.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc8_12.4: ref %U = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %U = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %U = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %U = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.a6c = addr_of %.loc8_14.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.a6c = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.cff = ref_binding_pattern x [concrete] @@ -833,34 +723,25 @@ fn F() { // CHECK:STDOUT: %x: ref %O = ref_binding x, %x.var // CHECK:STDOUT: %O.cpp_destructor.bound: = bound_method %x.var, constants.%O.cpp_destructor // CHECK:STDOUT: %O.cpp_destructor.call: init %empty_tuple.type = call %O.cpp_destructor.bound(%x.var) -// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc9(%self.param: %O) = "no_op"; -// CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp.loc8(%self.param: %U) = "no_op"; +// CHECK:STDOUT: fn @DestroyOp(%self.param: %O) = "no_op"; // 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: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %U.bar.cpp_overload_set.type: type = cpp_overload_set_type @U.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %U.bar.cpp_overload_set.value: %U.bar.cpp_overload_set.type = cpp_overload_set_value @U.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %U.bar.type: type = fn_type @U.bar [concrete] // CHECK:STDOUT: %U.bar: %U.bar.type = struct_value () [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] // CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] -// CHECK:STDOUT: %U.cpp_destructor.type: type = fn_type @U.cpp_destructor [concrete] -// CHECK:STDOUT: %U.cpp_destructor: %U.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -880,42 +761,28 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %U.ref.loc8: type = name_ref U, imports.%U.decl [concrete = constants.%U] // CHECK:STDOUT: %bar.ref: %U.bar.cpp_overload_set.type = name_ref bar, imports.%U.bar.cpp_overload_set.value [concrete = constants.%U.bar.cpp_overload_set.value] // CHECK:STDOUT: %U.bar.call: init %empty_tuple.type = call imports.%U.bar.decl() -// CHECK:STDOUT: %Cpp.ref.loc9_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc9_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc9_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref.loc9: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc9_12.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc9_12.3: init %U to %.loc9_12.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc9_12.4: ref %U = temporary %.loc9_12.2, %.loc9_12.3 -// CHECK:STDOUT: %.loc9_14.1: ref %U = converted %.loc9_12.1, %.loc9_12.4 -// CHECK:STDOUT: %.loc9_14.2: %U = acquire_value %.loc9_14.1 -// CHECK:STDOUT: %.loc9_14.3: ref %U = value_as_ref %.loc9_14.2 -// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc9_14.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc9: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc9 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) -// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %.loc9_12.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%.loc9_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %U) = "no_op"; -// 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: %U: type = class_type @U [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.type: type = cpp_overload_set_type @foo.cpp_overload_set [concrete] // CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %U: type = class_type @U [concrete] -// CHECK:STDOUT: %U.val: %U = struct_value () [concrete] // CHECK:STDOUT: %ptr.86f: type = ptr_type %U [concrete] // CHECK:STDOUT: %foo__carbon_thunk.type: type = fn_type @foo__carbon_thunk [concrete] // CHECK:STDOUT: %foo__carbon_thunk: %foo__carbon_thunk.type = struct_value () [concrete] @@ -923,18 +790,16 @@ fn F() { // CHECK:STDOUT: %U.bar.cpp_overload_set.value: %U.bar.cpp_overload_set.type = cpp_overload_set_value @U.bar.cpp_overload_set [concrete] // CHECK:STDOUT: %U.bar.type: type = fn_type @U.bar [concrete] // CHECK:STDOUT: %U.bar: %U.bar.type = struct_value () [concrete] -// CHECK:STDOUT: %U.cpp_destructor.type: type = fn_type @U.cpp_destructor [concrete] -// CHECK:STDOUT: %U.cpp_destructor: %U.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: .U = %U.decl +// CHECK:STDOUT: .foo = %foo.cpp_overload_set.value // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } -// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %U.decl: type = class_decl @U [concrete = constants.%U] {} {} +// CHECK:STDOUT: %foo.cpp_overload_set.value: %foo.cpp_overload_set.type = cpp_overload_set_value @foo.cpp_overload_set [concrete = constants.%foo.cpp_overload_set.value] // CHECK:STDOUT: %foo__carbon_thunk.decl: %foo__carbon_thunk.type = fn_decl @foo__carbon_thunk [concrete = constants.%foo__carbon_thunk] { // CHECK:STDOUT: // CHECK:STDOUT: } { @@ -944,32 +809,21 @@ fn F() { // CHECK:STDOUT: %U.bar.decl: %U.bar.type = fn_decl @U.bar [concrete = constants.%U.bar] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: fn @F(%u.param: %U) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %Cpp.ref.loc8_3: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %foo.ref: %foo.cpp_overload_set.type = name_ref foo, imports.%foo.cpp_overload_set.value [concrete = constants.%foo.cpp_overload_set.value] -// CHECK:STDOUT: %.loc8_12.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] -// CHECK:STDOUT: %Cpp.ref.loc8_17: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %U.ref.loc8: type = name_ref U, imports.%U.decl [concrete = constants.%U] -// CHECK:STDOUT: %.loc8_12.2: ref %U = temporary_storage -// CHECK:STDOUT: %.loc8_12.3: init %U to %.loc8_12.2 = class_init () [concrete = constants.%U.val] -// CHECK:STDOUT: %.loc8_12.4: ref %U = temporary %.loc8_12.2, %.loc8_12.3 -// CHECK:STDOUT: %.loc8_14.1: ref %U = converted %.loc8_12.1, %.loc8_12.4 -// CHECK:STDOUT: %.loc8_14.2: %U = acquire_value %.loc8_14.1 -// CHECK:STDOUT: %.loc8_14.3: ref %U = value_as_ref %.loc8_14.2 -// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8_14.3 +// CHECK:STDOUT: %u.ref: %U = name_ref u, %u +// CHECK:STDOUT: %.loc8: ref %U = value_as_ref %u.ref +// CHECK:STDOUT: %addr: %ptr.86f = addr_of %.loc8 // CHECK:STDOUT: %foo__carbon_thunk.call: init %empty_tuple.type = call imports.%foo__carbon_thunk.decl(%addr) // CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %U.ref.loc9: type = name_ref U, imports.%U.decl [concrete = constants.%U] // CHECK:STDOUT: %bar.ref: %U.bar.cpp_overload_set.type = name_ref bar, imports.%U.bar.cpp_overload_set.value [concrete = constants.%U.bar.cpp_overload_set.value] // CHECK:STDOUT: %U.bar.call: init %empty_tuple.type = call imports.%U.bar.decl() -// CHECK:STDOUT: %U.cpp_destructor.bound: = bound_method %.loc8_12.4, constants.%U.cpp_destructor -// CHECK:STDOUT: %U.cpp_destructor.call: init %empty_tuple.type = call %U.cpp_destructor.bound(%.loc8_12.4) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @DestroyOp(%self.param: %U) = "no_op"; -// CHECK:STDOUT: // CHECK:STDOUT: --- import_decl_pointer_param_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon b/toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon index 961d37fdedff..01bfa4d04b98 100644 --- a/toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon +++ b/toolchain/check/testdata/interop/cpp/impls/implicit_as.carbon @@ -236,13 +236,40 @@ fn IntConstructorTest(u: u32) { //@dump-sem-ir-end } +// --- default_constructor.h + +struct DefaultConstructor { + DefaultConstructor(); +}; + +// --- default_constructor.carbon + +library "[[TEST_NAME]]"; + +import Cpp library "default_constructor.h"; + +fn DefaultConstructorTest() { + //@dump-sem-ir-begin + // OK, empty tuple maps to `{}` initializer list. + let _: Cpp.DefaultConstructor = (); + + // OK: empty struct maps to `{}` initializer list, which is an acceptable + // constructor call, even though a non-empty struct would not be. + let _: Cpp.DefaultConstructor = {}; + //@dump-sem-ir-end +} + // --- multi_argument.h struct Two { Two(int, int); }; -// --- fail_todo_construct_multi_argument.carbon +struct ThreeWithDefault { + ThreeWithDefault(int, int, int = 0); +}; + +// --- construct_multi_argument.carbon library "[[@TEST_NAME]]"; @@ -250,13 +277,140 @@ import Cpp library "multi_argument.h"; fn ImplicitConvert() { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_construct_multi_argument.carbon:[[@LINE+6]]:20: error: semantics TODO: `Unsupported initialization sequence: - // CHECK:STDERR: Normal sequence: list initialization via constructor [struct Two] - // CHECK:STDERR: ` [SemanticsTodo] - // CHECK:STDERR: let _: Cpp.Two = (1, 2); - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: let _: Cpp.Two = (1, 2); + + let _: Cpp.ThreeWithDefault = (1, 2); + + let _: Cpp.ThreeWithDefault = (1, 2, 3); + //@dump-sem-ir-end +} + +// --- aggregate.h + +struct Aggregate { + int x = 0; + int y = 0; +}; + +struct NonAggregate { + NonAggregate(int x = 0, int y = 0); +}; + +// --- fail_todo_aggregate_from_tuple.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "aggregate.h"; + +fn InitFromTuple() { + //@dump-sem-ir-begin + // CHECK:STDERR: fail_todo_aggregate_from_tuple.carbon:[[@LINE+6]]:26: error: semantics TODO: `Unsupported initialization sequence: + // CHECK:STDERR: Normal sequence: list aggregate initialization [struct Aggregate] + // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: let _: Cpp.Aggregate = (); + // CHECK:STDERR: ^~ + // CHECK:STDERR: + let _: Cpp.Aggregate = (); + // CHECK:STDERR: fail_todo_aggregate_from_tuple.carbon:[[@LINE+6]]:26: error: semantics TODO: `Unsupported initialization sequence: + // CHECK:STDERR: Normal sequence: list aggregate initialization [struct Aggregate] + // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: let _: Cpp.Aggregate = (1,); + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: + let _: Cpp.Aggregate = (1,); + // CHECK:STDERR: fail_todo_aggregate_from_tuple.carbon:[[@LINE+6]]:26: error: semantics TODO: `Unsupported initialization sequence: + // CHECK:STDERR: Normal sequence: list aggregate initialization [struct Aggregate] + // CHECK:STDERR: ` [SemanticsTodo] + // CHECK:STDERR: let _: Cpp.Aggregate = (1, 2); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: + let _: Cpp.Aggregate = (1, 2); + //@dump-sem-ir-end +} + +// --- fail_todo_aggregate_from_struct.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "aggregate.h"; + +fn InitFromStruct() { + //@dump-sem-ir-begin + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+7]]:26: error: cannot implicitly convert expression of type `{}` to `Cpp.Aggregate` [ConversionFailure] + // CHECK:STDERR: let _: Cpp.Aggregate = {}; + // CHECK:STDERR: ^~ + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+4]]:26: note: type `{}` does not implement interface `Core.ImplicitAs(Cpp.Aggregate)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: let _: Cpp.Aggregate = {}; + // CHECK:STDERR: ^~ + // CHECK:STDERR: + let _: Cpp.Aggregate = {}; + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+7]]:26: error: cannot implicitly convert expression of type `{.x: Core.IntLiteral}` to `Cpp.Aggregate` [ConversionFailure] + // CHECK:STDERR: let _: Cpp.Aggregate = {.x = 1}; + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+4]]:26: note: type `{.x: Core.IntLiteral}` does not implement interface `Core.ImplicitAs(Cpp.Aggregate)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: let _: Cpp.Aggregate = {.x = 1}; + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + let _: Cpp.Aggregate = {.x = 1}; + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+7]]:26: error: cannot implicitly convert expression of type `{.x: Core.IntLiteral, .y: Core.IntLiteral}` to `Cpp.Aggregate` [ConversionFailure] + // CHECK:STDERR: let _: Cpp.Aggregate = {.x = 1, .y = 2}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_todo_aggregate_from_struct.carbon:[[@LINE+4]]:26: note: type `{.x: Core.IntLiteral, .y: Core.IntLiteral}` does not implement interface `Core.ImplicitAs(Cpp.Aggregate)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: let _: Cpp.Aggregate = {.x = 1, .y = 2}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: + let _: Cpp.Aggregate = {.x = 1, .y = 2}; + //@dump-sem-ir-end +} + +// --- non_aggregate_from_tuple.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "aggregate.h"; + +fn InitFromStruct() { + //@dump-sem-ir-begin + let _: Cpp.NonAggregate = (); + let _: Cpp.NonAggregate = (1,); + let _: Cpp.NonAggregate = (1, 2); + //@dump-sem-ir-end +} + +// --- todo_fail_non_aggregate_from_empty_struct.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "aggregate.h"; + +// TODO: This should be rejected; we should only support initialization from a +// struct for an aggregate class. + +fn InitFromStruct() { + //@dump-sem-ir-begin + let _: Cpp.NonAggregate = {}; + //@dump-sem-ir-end +} + +// --- fail_non_aggregate_from_struct.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "aggregate.h"; + +fn InitFromStruct() { + //@dump-sem-ir-begin + let _: Cpp.NonAggregate = {}; + // CHECK:STDERR: fail_non_aggregate_from_struct.carbon:[[@LINE+4]]:29: error: cannot initialize class with 0 fields from struct with 1 field [StructInitElementCountMismatch] + // CHECK:STDERR: let _: Cpp.NonAggregate = {.x = 1}; + // CHECK:STDERR: ^~~~~~~~ + // CHECK:STDERR: + let _: Cpp.NonAggregate = {.x = 1}; + // CHECK:STDERR: fail_non_aggregate_from_struct.carbon:[[@LINE+4]]:29: error: cannot initialize class with 0 fields from struct with 2 fields [StructInitElementCountMismatch] + // CHECK:STDERR: let _: Cpp.NonAggregate = {.x = 1, .y = 2}; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: + let _: Cpp.NonAggregate = {.x = 1, .y = 2}; //@dump-sem-ir-end } @@ -815,39 +969,673 @@ fn ImplicitConvert() { // CHECK:STDOUT: // CHECK:STDOUT: fn @DestroyOp(%self.param: %IntConstructor) = "no_op"; // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_construct_multi_argument.carbon +// CHECK:STDOUT: --- default_constructor.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %DefaultConstructor: type = class_type @DefaultConstructor [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %pattern_type.b66: type = pattern_type %DefaultConstructor [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %ptr.3f7: type = ptr_type %DefaultConstructor [concrete] +// CHECK:STDOUT: %DefaultConstructor__carbon_thunk.type: type = fn_type @DefaultConstructor__carbon_thunk [concrete] +// CHECK:STDOUT: %DefaultConstructor__carbon_thunk: %DefaultConstructor__carbon_thunk.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultConstructor.val: %DefaultConstructor = struct_value () [concrete] +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor.type: type = fn_type @DefaultConstructor.cpp_destructor [concrete] +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor: %DefaultConstructor.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .DefaultConstructor = %DefaultConstructor.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %DefaultConstructor.decl: type = class_decl @DefaultConstructor [concrete = constants.%DefaultConstructor] {} {} +// CHECK:STDOUT: %DefaultConstructor__carbon_thunk.decl: %DefaultConstructor__carbon_thunk.type = fn_decl @DefaultConstructor__carbon_thunk [concrete = constants.%DefaultConstructor__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DefaultConstructorTest() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc9: %pattern_type.b66 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc9_36.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc9_13: type = splice_block %DefaultConstructor.ref.loc9 [concrete = constants.%DefaultConstructor] { +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %DefaultConstructor.ref.loc9: type = name_ref DefaultConstructor, imports.%DefaultConstructor.decl [concrete = constants.%DefaultConstructor] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc9_36.2: ref %DefaultConstructor = temporary_storage +// CHECK:STDOUT: %addr: %ptr.3f7 = addr_of %.loc9_36.2 +// CHECK:STDOUT: %DefaultConstructor__carbon_thunk.call: init %empty_tuple.type = call imports.%DefaultConstructor__carbon_thunk.decl(%addr) +// CHECK:STDOUT: %.loc9_36.3: init %DefaultConstructor to %.loc9_36.2 = in_place_init %DefaultConstructor__carbon_thunk.call +// CHECK:STDOUT: %.loc9_36.4: init %DefaultConstructor = converted %.loc9_36.1, %.loc9_36.3 +// CHECK:STDOUT: %.loc9_36.5: ref %DefaultConstructor = temporary %.loc9_36.2, %.loc9_36.4 +// CHECK:STDOUT: %.loc9_36.6: %DefaultConstructor = acquire_value %.loc9_36.5 +// CHECK:STDOUT: %_.loc9: %DefaultConstructor = value_binding _, %.loc9_36.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc13: %pattern_type.b66 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc13_36.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc13_13: type = splice_block %DefaultConstructor.ref.loc13 [concrete = constants.%DefaultConstructor] { +// CHECK:STDOUT: %Cpp.ref.loc13: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %DefaultConstructor.ref.loc13: type = name_ref DefaultConstructor, imports.%DefaultConstructor.decl [concrete = constants.%DefaultConstructor] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc13_36.2: ref %DefaultConstructor = temporary_storage +// CHECK:STDOUT: %.loc13_36.3: init %DefaultConstructor to %.loc13_36.2 = class_init () [concrete = constants.%DefaultConstructor.val] +// CHECK:STDOUT: %.loc13_36.4: ref %DefaultConstructor = temporary %.loc13_36.2, %.loc13_36.3 +// CHECK:STDOUT: %.loc13_36.5: ref %DefaultConstructor = converted %.loc13_36.1, %.loc13_36.4 +// CHECK:STDOUT: %.loc13_36.6: %DefaultConstructor = acquire_value %.loc13_36.5 +// CHECK:STDOUT: %_.loc13: %DefaultConstructor = value_binding _, %.loc13_36.6 +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor.bound.loc13: = bound_method %.loc13_36.4, constants.%DefaultConstructor.cpp_destructor +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor.call.loc13: init %empty_tuple.type = call %DefaultConstructor.cpp_destructor.bound.loc13(%.loc13_36.4) +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor.bound.loc9: = bound_method %.loc9_36.5, constants.%DefaultConstructor.cpp_destructor +// CHECK:STDOUT: %DefaultConstructor.cpp_destructor.call.loc9: init %empty_tuple.type = call %DefaultConstructor.cpp_destructor.bound.loc9(%.loc9_36.5) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp(%self.param: %DefaultConstructor) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: --- construct_multi_argument.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Two: type = class_type @Two [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Two [concrete] -// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] -// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] -// CHECK:STDOUT: %tuple.type: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] -// CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%int_1, %int_2) [concrete] +// CHECK:STDOUT: %pattern_type.4c2: type = pattern_type %Two [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.ad8: %tuple.type.f94 = tuple_value (%int_1.5b8, %int_2.ecc) [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %ptr.677: type = ptr_type %Two [concrete] +// CHECK:STDOUT: %Two__carbon_thunk.type: type = fn_type @Two__carbon_thunk [concrete] +// CHECK:STDOUT: %Two__carbon_thunk: %Two__carbon_thunk.type = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.3c2: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.6bc: = impl_witness imports.%ImplicitAs.impl_witness_table.74f, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e0d: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e0d = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.e8c = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.6bc) [concrete] +// CHECK:STDOUT: %.863: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method.38b: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [concrete] +// CHECK:STDOUT: %bound_method.646: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] +// CHECK:STDOUT: %ThreeWithDefault: type = class_type @ThreeWithDefault [concrete] +// CHECK:STDOUT: %pattern_type.ca7: type = pattern_type %ThreeWithDefault [concrete] +// CHECK:STDOUT: %ptr.ea4: type = ptr_type %ThreeWithDefault [concrete] +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.type.b64454.1: type = fn_type @ThreeWithDefault__carbon_thunk.1 [concrete] +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.fd88b7.1: %ThreeWithDefault__carbon_thunk.type.b64454.1 = struct_value () [concrete] +// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] +// CHECK:STDOUT: %tuple.type.37f: type = tuple_type (Core.IntLiteral, Core.IntLiteral, Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.2d5: %tuple.type.37f = tuple_value (%int_1.5b8, %int_2.ecc, %int_3.1ba) [concrete] +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.type.b64454.2: type = fn_type @ThreeWithDefault__carbon_thunk.2 [concrete] +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.fd88b7.2: %ThreeWithDefault__carbon_thunk.type.b64454.2 = struct_value () [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [concrete] +// CHECK:STDOUT: %bound_method.fa7: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor.type: type = fn_type @ThreeWithDefault.cpp_destructor [concrete] +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor: %ThreeWithDefault.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: %Two.cpp_destructor.type: type = fn_type @Two.cpp_destructor [concrete] +// CHECK:STDOUT: %Two.cpp_destructor: %Two.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { // CHECK:STDOUT: .Two = %Two.decl +// CHECK:STDOUT: .ThreeWithDefault = %ThreeWithDefault.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } // CHECK:STDOUT: %Two.decl: type = class_decl @Two [concrete = constants.%Two] {} {} +// CHECK:STDOUT: %Two__carbon_thunk.decl: %Two__carbon_thunk.type = fn_decl @Two__carbon_thunk [concrete = constants.%Two__carbon_thunk] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.42d: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.3c2)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.74f = impl_witness_table (%Core.import_ref.42d), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %ThreeWithDefault.decl: type = class_decl @ThreeWithDefault [concrete = constants.%ThreeWithDefault] {} {} +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.decl.482856.1: %ThreeWithDefault__carbon_thunk.type.b64454.1 = fn_decl @ThreeWithDefault__carbon_thunk.1 [concrete = constants.%ThreeWithDefault__carbon_thunk.fd88b7.1] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.decl.482856.2: %ThreeWithDefault__carbon_thunk.type.b64454.2 = fn_decl @ThreeWithDefault__carbon_thunk.2 [concrete = constants.%ThreeWithDefault__carbon_thunk.fd88b7.2] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @ImplicitConvert() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %_.patt: %pattern_type = value_binding_pattern _ [concrete] +// CHECK:STDOUT: %_.patt.loc8: %pattern_type.4c2 = value_binding_pattern _ [concrete] // CHECK:STDOUT: } -// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] -// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] -// CHECK:STDOUT: %.loc14_25.1: %tuple.type = tuple_literal (%int_1, %int_2) [concrete = constants.%tuple] -// CHECK:STDOUT: %.loc14_13: type = splice_block %Two.ref [concrete = constants.%Two] { -// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %int_1.loc8: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc8: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc8_25.1: %tuple.type.f94 = tuple_literal (%int_1.loc8, %int_2.loc8) [concrete = constants.%tuple.ad8] +// CHECK:STDOUT: %.loc8_13: type = splice_block %Two.ref [concrete = constants.%Two] { +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %Two.ref: type = name_ref Two, imports.%Two.decl [concrete = constants.%Two] // CHECK:STDOUT: } -// CHECK:STDOUT: %.loc14_25.2: %Two = converted %.loc14_25.1, [concrete = ] -// CHECK:STDOUT: %_: %Two = value_binding _, [concrete = ] +// CHECK:STDOUT: %.loc8_25.2: ref %Two = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc8_21: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc8_21.1: = bound_method %int_1.loc8, %impl.elem0.loc8_21 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215] +// CHECK:STDOUT: %specific_fn.loc8_21: = specific_function %impl.elem0.loc8_21, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc8_21.2: = bound_method %int_1.loc8, %specific_fn.loc8_21 [concrete = constants.%bound_method.38b] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8_21: init %i32 = call %bound_method.loc8_21.2(%int_1.loc8) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc8_21.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8_21 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc8_21.2: %i32 = converted %int_1.loc8, %.loc8_21.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc8_24: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc8_24.1: = bound_method %int_2.loc8, %impl.elem0.loc8_24 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5] +// CHECK:STDOUT: %specific_fn.loc8_24: = specific_function %impl.elem0.loc8_24, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc8_24.2: = bound_method %int_2.loc8, %specific_fn.loc8_24 [concrete = constants.%bound_method.646] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8_24: init %i32 = call %bound_method.loc8_24.2(%int_2.loc8) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc8_24.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8_24 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc8_24.2: %i32 = converted %int_2.loc8, %.loc8_24.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %addr.loc8: %ptr.677 = addr_of %.loc8_25.2 +// CHECK:STDOUT: %Two__carbon_thunk.call: init %empty_tuple.type = call imports.%Two__carbon_thunk.decl(%.loc8_21.2, %.loc8_24.2, %addr.loc8) +// CHECK:STDOUT: %.loc8_25.3: init %Two to %.loc8_25.2 = in_place_init %Two__carbon_thunk.call +// CHECK:STDOUT: %.loc8_25.4: init %Two = converted %.loc8_25.1, %.loc8_25.3 +// CHECK:STDOUT: %.loc8_25.5: ref %Two = temporary %.loc8_25.2, %.loc8_25.4 +// CHECK:STDOUT: %.loc8_25.6: %Two = acquire_value %.loc8_25.5 +// CHECK:STDOUT: %_.loc8: %Two = value_binding _, %.loc8_25.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc10: %pattern_type.ca7 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc10: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc10: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc10_38.1: %tuple.type.f94 = tuple_literal (%int_1.loc10, %int_2.loc10) [concrete = constants.%tuple.ad8] +// CHECK:STDOUT: %.loc10_13: type = splice_block %ThreeWithDefault.ref.loc10 [concrete = constants.%ThreeWithDefault] { +// CHECK:STDOUT: %Cpp.ref.loc10: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %ThreeWithDefault.ref.loc10: type = name_ref ThreeWithDefault, imports.%ThreeWithDefault.decl [concrete = constants.%ThreeWithDefault] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc10_38.2: ref %ThreeWithDefault = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc10_34: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc10_34.1: = bound_method %int_1.loc10, %impl.elem0.loc10_34 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215] +// CHECK:STDOUT: %specific_fn.loc10_34: = specific_function %impl.elem0.loc10_34, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_34.2: = bound_method %int_1.loc10, %specific_fn.loc10_34 [concrete = constants.%bound_method.38b] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_34: init %i32 = call %bound_method.loc10_34.2(%int_1.loc10) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc10_34.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_34 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc10_34.2: %i32 = converted %int_1.loc10, %.loc10_34.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc10_37: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc10_37.1: = bound_method %int_2.loc10, %impl.elem0.loc10_37 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5] +// CHECK:STDOUT: %specific_fn.loc10_37: = specific_function %impl.elem0.loc10_37, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_37.2: = bound_method %int_2.loc10, %specific_fn.loc10_37 [concrete = constants.%bound_method.646] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_37: init %i32 = call %bound_method.loc10_37.2(%int_2.loc10) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc10_37.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_37 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc10_37.2: %i32 = converted %int_2.loc10, %.loc10_37.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %addr.loc10: %ptr.ea4 = addr_of %.loc10_38.2 +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.call.loc10: init %empty_tuple.type = call imports.%ThreeWithDefault__carbon_thunk.decl.482856.1(%.loc10_34.2, %.loc10_37.2, %addr.loc10) +// CHECK:STDOUT: %.loc10_38.3: init %ThreeWithDefault to %.loc10_38.2 = in_place_init %ThreeWithDefault__carbon_thunk.call.loc10 +// CHECK:STDOUT: %.loc10_38.4: init %ThreeWithDefault = converted %.loc10_38.1, %.loc10_38.3 +// CHECK:STDOUT: %.loc10_38.5: ref %ThreeWithDefault = temporary %.loc10_38.2, %.loc10_38.4 +// CHECK:STDOUT: %.loc10_38.6: %ThreeWithDefault = acquire_value %.loc10_38.5 +// CHECK:STDOUT: %_.loc10: %ThreeWithDefault = value_binding _, %.loc10_38.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc12: %pattern_type.ca7 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc12: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2.loc12: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba] +// CHECK:STDOUT: %.loc12_41.1: %tuple.type.37f = tuple_literal (%int_1.loc12, %int_2.loc12, %int_3) [concrete = constants.%tuple.2d5] +// CHECK:STDOUT: %.loc12_13: type = splice_block %ThreeWithDefault.ref.loc12 [concrete = constants.%ThreeWithDefault] { +// CHECK:STDOUT: %Cpp.ref.loc12: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %ThreeWithDefault.ref.loc12: type = name_ref ThreeWithDefault, imports.%ThreeWithDefault.decl [concrete = constants.%ThreeWithDefault] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc12_41.2: ref %ThreeWithDefault = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc12_34: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc12_34.1: = bound_method %int_1.loc12, %impl.elem0.loc12_34 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215] +// CHECK:STDOUT: %specific_fn.loc12_34: = specific_function %impl.elem0.loc12_34, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc12_34.2: = bound_method %int_1.loc12, %specific_fn.loc12_34 [concrete = constants.%bound_method.38b] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_34: init %i32 = call %bound_method.loc12_34.2(%int_1.loc12) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc12_34.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_34 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc12_34.2: %i32 = converted %int_1.loc12, %.loc12_34.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc12_37: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc12_37.1: = bound_method %int_2.loc12, %impl.elem0.loc12_37 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5] +// CHECK:STDOUT: %specific_fn.loc12_37: = specific_function %impl.elem0.loc12_37, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc12_37.2: = bound_method %int_2.loc12, %specific_fn.loc12_37 [concrete = constants.%bound_method.646] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_37: init %i32 = call %bound_method.loc12_37.2(%int_2.loc12) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc12_37.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_37 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc12_37.2: %i32 = converted %int_2.loc12, %.loc12_37.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %impl.elem0.loc12_40: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc12_40.1: = bound_method %int_3, %impl.elem0.loc12_40 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.061] +// CHECK:STDOUT: %specific_fn.loc12_40: = specific_function %impl.elem0.loc12_40, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc12_40.2: = bound_method %int_3, %specific_fn.loc12_40 [concrete = constants.%bound_method.fa7] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_40: init %i32 = call %bound_method.loc12_40.2(%int_3) [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc12_40.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc12_40 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %.loc12_40.2: %i32 = converted %int_3, %.loc12_40.1 [concrete = constants.%int_3.822] +// CHECK:STDOUT: %addr.loc12: %ptr.ea4 = addr_of %.loc12_41.2 +// CHECK:STDOUT: %ThreeWithDefault__carbon_thunk.call.loc12: init %empty_tuple.type = call imports.%ThreeWithDefault__carbon_thunk.decl.482856.2(%.loc12_34.2, %.loc12_37.2, %.loc12_40.2, %addr.loc12) +// CHECK:STDOUT: %.loc12_41.3: init %ThreeWithDefault to %.loc12_41.2 = in_place_init %ThreeWithDefault__carbon_thunk.call.loc12 +// CHECK:STDOUT: %.loc12_41.4: init %ThreeWithDefault = converted %.loc12_41.1, %.loc12_41.3 +// CHECK:STDOUT: %.loc12_41.5: ref %ThreeWithDefault = temporary %.loc12_41.2, %.loc12_41.4 +// CHECK:STDOUT: %.loc12_41.6: %ThreeWithDefault = acquire_value %.loc12_41.5 +// CHECK:STDOUT: %_.loc12: %ThreeWithDefault = value_binding _, %.loc12_41.6 +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor.bound.loc12: = bound_method %.loc12_41.5, constants.%ThreeWithDefault.cpp_destructor +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor.call.loc12: init %empty_tuple.type = call %ThreeWithDefault.cpp_destructor.bound.loc12(%.loc12_41.5) +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor.bound.loc10: = bound_method %.loc10_38.5, constants.%ThreeWithDefault.cpp_destructor +// CHECK:STDOUT: %ThreeWithDefault.cpp_destructor.call.loc10: init %empty_tuple.type = call %ThreeWithDefault.cpp_destructor.bound.loc10(%.loc10_38.5) +// CHECK:STDOUT: %Two.cpp_destructor.bound: = bound_method %.loc8_25.5, constants.%Two.cpp_destructor +// CHECK:STDOUT: %Two.cpp_destructor.call: init %empty_tuple.type = call %Two.cpp_destructor.bound(%.loc8_25.5) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp.loc12(%self.param: %ThreeWithDefault) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp.loc8(%self.param: %Two) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_aggregate_from_tuple.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Aggregate: type = class_type @Aggregate [concrete] +// CHECK:STDOUT: %pattern_type.235: type = pattern_type %Aggregate [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.378: %tuple.type.985 = tuple_value (%int_1) [concrete] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.ad8: %tuple.type.f94 = tuple_value (%int_1, %int_2) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .Aggregate = %Aggregate.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Aggregate.decl: type = class_decl @Aggregate [concrete = constants.%Aggregate] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @InitFromTuple() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc14: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc14_27.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc14_13: type = splice_block %Aggregate.ref.loc14 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc14: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc14: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc14_27.2: %Aggregate = converted %.loc14_27.1, [concrete = ] +// CHECK:STDOUT: %_.loc14: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc21: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc21: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %.loc21_29.1: %tuple.type.985 = tuple_literal (%int_1.loc21) [concrete = constants.%tuple.378] +// CHECK:STDOUT: %.loc21_13: type = splice_block %Aggregate.ref.loc21 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc21: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc21: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc21_29.2: %Aggregate = converted %.loc21_29.1, [concrete = ] +// CHECK:STDOUT: %_.loc21: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc28: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc28: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] +// CHECK:STDOUT: %.loc28_31.1: %tuple.type.f94 = tuple_literal (%int_1.loc28, %int_2) [concrete = constants.%tuple.ad8] +// CHECK:STDOUT: %.loc28_13: type = splice_block %Aggregate.ref.loc28 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc28: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc28: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc28_31.2: %Aggregate = converted %.loc28_31.1, [concrete = ] +// CHECK:STDOUT: %_.loc28: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_aggregate_from_struct.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Aggregate: type = class_type @Aggregate [concrete] +// CHECK:STDOUT: %pattern_type.235: type = pattern_type %Aggregate [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %struct_type.x: type = struct_type {.x: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %struct.147: %struct_type.x = struct_value (%int_1) [concrete] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %struct.004: %struct_type.x.y = struct_value (%int_1, %int_2) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .Aggregate = %Aggregate.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Aggregate.decl: type = class_decl @Aggregate [concrete = constants.%Aggregate] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @InitFromStruct() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc15: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc15_27.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc15_13: type = splice_block %Aggregate.ref.loc15 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc15: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc15: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc15_27.2: %Aggregate = converted %.loc15_27.1, [concrete = ] +// CHECK:STDOUT: %_.loc15: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc23: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc23: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %.loc23_33.1: %struct_type.x = struct_literal (%int_1.loc23) [concrete = constants.%struct.147] +// CHECK:STDOUT: %.loc23_13: type = splice_block %Aggregate.ref.loc23 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc23: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc23: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc23_33.2: %Aggregate = converted %.loc23_33.1, [concrete = ] +// CHECK:STDOUT: %_.loc23: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc31: %pattern_type.235 = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc31: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] +// CHECK:STDOUT: %.loc31_41.1: %struct_type.x.y = struct_literal (%int_1.loc31, %int_2) [concrete = constants.%struct.004] +// CHECK:STDOUT: %.loc31_13: type = splice_block %Aggregate.ref.loc31 [concrete = constants.%Aggregate] { +// CHECK:STDOUT: %Cpp.ref.loc31: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %Aggregate.ref.loc31: type = name_ref Aggregate, imports.%Aggregate.decl [concrete = constants.%Aggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc31_41.2: %Aggregate = converted %.loc31_41.1, [concrete = ] +// CHECK:STDOUT: %_.loc31: %Aggregate = value_binding _, [concrete = ] +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- non_aggregate_from_tuple.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %NonAggregate: type = class_type @NonAggregate [concrete] +// CHECK:STDOUT: %pattern_type.eac: type = pattern_type %NonAggregate [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %ptr.9b6: type = ptr_type %NonAggregate [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.type.8d64dd.1: type = fn_type @NonAggregate__carbon_thunk.1 [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.0020a5.1: %NonAggregate__carbon_thunk.type.8d64dd.1 = struct_value () [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %tuple.type.985: type = tuple_type (Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.378: %tuple.type.985 = tuple_value (%int_1.5b8) [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.type.8d64dd.2: type = fn_type @NonAggregate__carbon_thunk.2 [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.0020a5.2: %NonAggregate__carbon_thunk.type.8d64dd.2 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.e8c: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.3c2: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.6bc: = impl_witness imports.%ImplicitAs.impl_witness_table.74f, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e0d: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e0d = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.e8c = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.6bc) [concrete] +// CHECK:STDOUT: %.863: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method.38b: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] +// CHECK:STDOUT: %tuple.ad8: %tuple.type.f94 = tuple_value (%int_1.5b8, %int_2.ecc) [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.type.8d64dd.3: type = fn_type @NonAggregate__carbon_thunk.3 [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.0020a5.3: %NonAggregate__carbon_thunk.type.8d64dd.3 = struct_value () [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5 [concrete] +// CHECK:STDOUT: %bound_method.646: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor.type: type = fn_type @NonAggregate.cpp_destructor [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor: %NonAggregate.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .NonAggregate = %NonAggregate.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %NonAggregate.decl: type = class_decl @NonAggregate [concrete = constants.%NonAggregate] {} {} +// CHECK:STDOUT: %NonAggregate__carbon_thunk.decl.712b28.1: %NonAggregate__carbon_thunk.type.8d64dd.1 = fn_decl @NonAggregate__carbon_thunk.1 [concrete = constants.%NonAggregate__carbon_thunk.0020a5.1] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: %NonAggregate__carbon_thunk.decl.712b28.2: %NonAggregate__carbon_thunk.type.8d64dd.2 = fn_decl @NonAggregate__carbon_thunk.2 [concrete = constants.%NonAggregate__carbon_thunk.0020a5.2] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.42d: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.4e6) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.3c2)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.74f = impl_witness_table (%Core.import_ref.42d), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %NonAggregate__carbon_thunk.decl.712b28.3: %NonAggregate__carbon_thunk.type.8d64dd.3 = fn_decl @NonAggregate__carbon_thunk.3 [concrete = constants.%NonAggregate__carbon_thunk.0020a5.3] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @InitFromStruct() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc8: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_30.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc8_13: type = splice_block %NonAggregate.ref.loc8 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc8: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_30.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %addr.loc8: %ptr.9b6 = addr_of %.loc8_30.2 +// CHECK:STDOUT: %NonAggregate__carbon_thunk.call.loc8: init %empty_tuple.type = call imports.%NonAggregate__carbon_thunk.decl.712b28.1(%addr.loc8) +// CHECK:STDOUT: %.loc8_30.3: init %NonAggregate to %.loc8_30.2 = in_place_init %NonAggregate__carbon_thunk.call.loc8 +// CHECK:STDOUT: %.loc8_30.4: init %NonAggregate = converted %.loc8_30.1, %.loc8_30.3 +// CHECK:STDOUT: %.loc8_30.5: ref %NonAggregate = temporary %.loc8_30.2, %.loc8_30.4 +// CHECK:STDOUT: %.loc8_30.6: %NonAggregate = acquire_value %.loc8_30.5 +// CHECK:STDOUT: %_.loc8: %NonAggregate = value_binding _, %.loc8_30.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc9: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc9: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc9_32.1: %tuple.type.985 = tuple_literal (%int_1.loc9) [concrete = constants.%tuple.378] +// CHECK:STDOUT: %.loc9_13: type = splice_block %NonAggregate.ref.loc9 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc9: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc9_32.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc9: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc9_30.1: = bound_method %int_1.loc9, %impl.elem0.loc9 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215] +// CHECK:STDOUT: %specific_fn.loc9: = specific_function %impl.elem0.loc9, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc9_30.2: = bound_method %int_1.loc9, %specific_fn.loc9 [concrete = constants.%bound_method.38b] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9: init %i32 = call %bound_method.loc9_30.2(%int_1.loc9) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc9_30.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc9_30.2: %i32 = converted %int_1.loc9, %.loc9_30.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %addr.loc9: %ptr.9b6 = addr_of %.loc9_32.2 +// CHECK:STDOUT: %NonAggregate__carbon_thunk.call.loc9: init %empty_tuple.type = call imports.%NonAggregate__carbon_thunk.decl.712b28.2(%.loc9_30.2, %addr.loc9) +// CHECK:STDOUT: %.loc9_32.3: init %NonAggregate to %.loc9_32.2 = in_place_init %NonAggregate__carbon_thunk.call.loc9 +// CHECK:STDOUT: %.loc9_32.4: init %NonAggregate = converted %.loc9_32.1, %.loc9_32.3 +// CHECK:STDOUT: %.loc9_32.5: ref %NonAggregate = temporary %.loc9_32.2, %.loc9_32.4 +// CHECK:STDOUT: %.loc9_32.6: %NonAggregate = acquire_value %.loc9_32.5 +// CHECK:STDOUT: %_.loc9: %NonAggregate = value_binding _, %.loc9_32.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc10: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc10: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %.loc10_34.1: %tuple.type.f94 = tuple_literal (%int_1.loc10, %int_2) [concrete = constants.%tuple.ad8] +// CHECK:STDOUT: %.loc10_13: type = splice_block %NonAggregate.ref.loc10 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc10: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc10: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc10_34.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %impl.elem0.loc10_30: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc10_30.1: = bound_method %int_1.loc10, %impl.elem0.loc10_30 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.215] +// CHECK:STDOUT: %specific_fn.loc10_30: = specific_function %impl.elem0.loc10_30, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_30.2: = bound_method %int_1.loc10, %specific_fn.loc10_30 [concrete = constants.%bound_method.38b] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_30: init %i32 = call %bound_method.loc10_30.2(%int_1.loc10) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc10_30.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_30 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc10_30.2: %i32 = converted %int_1.loc10, %.loc10_30.1 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %impl.elem0.loc10_33: %.863 = impl_witness_access constants.%ImplicitAs.impl_witness.6bc, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.0b5] +// CHECK:STDOUT: %bound_method.loc10_33.1: = bound_method %int_2, %impl.elem0.loc10_33 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e5] +// CHECK:STDOUT: %specific_fn.loc10_33: = specific_function %impl.elem0.loc10_33, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_33.2: = bound_method %int_2, %specific_fn.loc10_33 [concrete = constants.%bound_method.646] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_33: init %i32 = call %bound_method.loc10_33.2(%int_2) [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc10_33.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10_33 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %.loc10_33.2: %i32 = converted %int_2, %.loc10_33.1 [concrete = constants.%int_2.ef8] +// CHECK:STDOUT: %addr.loc10: %ptr.9b6 = addr_of %.loc10_34.2 +// CHECK:STDOUT: %NonAggregate__carbon_thunk.call.loc10: init %empty_tuple.type = call imports.%NonAggregate__carbon_thunk.decl.712b28.3(%.loc10_30.2, %.loc10_33.2, %addr.loc10) +// CHECK:STDOUT: %.loc10_34.3: init %NonAggregate to %.loc10_34.2 = in_place_init %NonAggregate__carbon_thunk.call.loc10 +// CHECK:STDOUT: %.loc10_34.4: init %NonAggregate = converted %.loc10_34.1, %.loc10_34.3 +// CHECK:STDOUT: %.loc10_34.5: ref %NonAggregate = temporary %.loc10_34.2, %.loc10_34.4 +// CHECK:STDOUT: %.loc10_34.6: %NonAggregate = acquire_value %.loc10_34.5 +// CHECK:STDOUT: %_.loc10: %NonAggregate = value_binding _, %.loc10_34.6 +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc10: = bound_method %.loc10_34.5, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc10: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc10(%.loc10_34.5) +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc9: = bound_method %.loc9_32.5, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc9: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc9(%.loc9_32.5) +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc8: = bound_method %.loc8_30.5, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc8: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc8(%.loc8_30.5) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp(%self.param: %NonAggregate) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_non_aggregate_from_empty_struct.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %NonAggregate: type = class_type @NonAggregate [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %pattern_type.eac: type = pattern_type %NonAggregate [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %NonAggregate.val: %NonAggregate = struct_value () [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor.type: type = fn_type @NonAggregate.cpp_destructor [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor: %NonAggregate.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .NonAggregate = %NonAggregate.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %NonAggregate.decl: type = class_decl @NonAggregate [concrete = constants.%NonAggregate] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @InitFromStruct() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc11_30.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc11_13: type = splice_block %NonAggregate.ref [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc11_30.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %.loc11_30.3: init %NonAggregate to %.loc11_30.2 = class_init () [concrete = constants.%NonAggregate.val] +// CHECK:STDOUT: %.loc11_30.4: ref %NonAggregate = temporary %.loc11_30.2, %.loc11_30.3 +// CHECK:STDOUT: %.loc11_30.5: ref %NonAggregate = converted %.loc11_30.1, %.loc11_30.4 +// CHECK:STDOUT: %.loc11_30.6: %NonAggregate = acquire_value %.loc11_30.5 +// CHECK:STDOUT: %_: %NonAggregate = value_binding _, %.loc11_30.6 +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound: = bound_method %.loc11_30.4, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound(%.loc11_30.4) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp(%self.param: %NonAggregate) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_non_aggregate_from_struct.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %NonAggregate: type = class_type @NonAggregate [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %pattern_type.eac: type = pattern_type %NonAggregate [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %NonAggregate.val: %NonAggregate = struct_value () [concrete] +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %struct_type.x: type = struct_type {.x: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %struct.147: %struct_type.x = struct_value (%int_1) [concrete] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: Core.IntLiteral, .y: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %struct.004: %struct_type.x.y = struct_value (%int_1, %int_2) [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor.type: type = fn_type @NonAggregate.cpp_destructor [concrete] +// CHECK:STDOUT: %NonAggregate.cpp_destructor: %NonAggregate.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .NonAggregate = %NonAggregate.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %NonAggregate.decl: type = class_decl @NonAggregate [concrete = constants.%NonAggregate] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @InitFromStruct() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc8: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_30.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc8_13: type = splice_block %NonAggregate.ref.loc8 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc8: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_30.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %.loc8_30.3: init %NonAggregate to %.loc8_30.2 = class_init () [concrete = constants.%NonAggregate.val] +// CHECK:STDOUT: %.loc8_30.4: ref %NonAggregate = temporary %.loc8_30.2, %.loc8_30.3 +// CHECK:STDOUT: %.loc8_30.5: ref %NonAggregate = converted %.loc8_30.1, %.loc8_30.4 +// CHECK:STDOUT: %.loc8_30.6: %NonAggregate = acquire_value %.loc8_30.5 +// CHECK:STDOUT: %_.loc8: %NonAggregate = value_binding _, %.loc8_30.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc13: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc13: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %.loc13_36.1: %struct_type.x = struct_literal (%int_1.loc13) [concrete = constants.%struct.147] +// CHECK:STDOUT: %.loc13_13: type = splice_block %NonAggregate.ref.loc13 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc13: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc13: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc13_36.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %.loc13_36.3: ref %NonAggregate = temporary %.loc13_36.2, +// CHECK:STDOUT: %.loc13_36.4: ref %NonAggregate = converted %.loc13_36.1, %.loc13_36.3 +// CHECK:STDOUT: %.loc13_36.5: %NonAggregate = acquire_value %.loc13_36.4 +// CHECK:STDOUT: %_.loc13: %NonAggregate = value_binding _, %.loc13_36.5 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %_.patt.loc18: %pattern_type.eac = value_binding_pattern _ [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc18: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] +// CHECK:STDOUT: %.loc18_44.1: %struct_type.x.y = struct_literal (%int_1.loc18, %int_2) [concrete = constants.%struct.004] +// CHECK:STDOUT: %.loc18_13: type = splice_block %NonAggregate.ref.loc18 [concrete = constants.%NonAggregate] { +// CHECK:STDOUT: %Cpp.ref.loc18: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %NonAggregate.ref.loc18: type = name_ref NonAggregate, imports.%NonAggregate.decl [concrete = constants.%NonAggregate] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc18_44.2: ref %NonAggregate = temporary_storage +// CHECK:STDOUT: %.loc18_44.3: ref %NonAggregate = temporary %.loc18_44.2, +// CHECK:STDOUT: %.loc18_44.4: ref %NonAggregate = converted %.loc18_44.1, %.loc18_44.3 +// CHECK:STDOUT: %.loc18_44.5: %NonAggregate = acquire_value %.loc18_44.4 +// CHECK:STDOUT: %_.loc18: %NonAggregate = value_binding _, %.loc18_44.5 +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc18: = bound_method %.loc18_44.3, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc18: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc18(%.loc18_44.3) +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc13: = bound_method %.loc13_36.3, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc13: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc13(%.loc13_36.3) +// CHECK:STDOUT: %NonAggregate.cpp_destructor.bound.loc8: = bound_method %.loc8_30.4, constants.%NonAggregate.cpp_destructor +// CHECK:STDOUT: %NonAggregate.cpp_destructor.call.loc8: init %empty_tuple.type = call %NonAggregate.cpp_destructor.bound.loc8(%.loc8_30.4) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp(%self.param: %NonAggregate) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/lower/testdata/interop/cpp/constructor.carbon b/toolchain/lower/testdata/interop/cpp/constructor.carbon index ed2e99a90c6e..583df15b0e84 100644 --- a/toolchain/lower/testdata/interop/cpp/constructor.carbon +++ b/toolchain/lower/testdata/interop/cpp/constructor.carbon @@ -35,6 +35,10 @@ fn F() { let _: Cpp.C = Cpp.C.C(); } +fn G() { + let _: Cpp.C = (); +} + // ============================================================================ // Copy constructor // ============================================================================ @@ -80,6 +84,53 @@ fn F() { let _: Cpp.Derived = Cpp.Derived.Derived(); } +// ============================================================================ +// Multiple arguments +// ============================================================================ + +// --- multi_argument.h + +class C { + public: + C() {} + C(int) {} + C(int, int) {} + C(int, int, int, int = 0) {} +}; + +// --- call_multi_argument.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "multi_argument.h"; + +fn Zero() { + let _: Cpp.C = Cpp.C.C(); + let _: Cpp.C = (); + let _: Cpp.C = {}; +} + +fn One() { + let _: Cpp.C = Cpp.C.C(1); + let _: Cpp.C = 2; + let _: Cpp.C = (3,); +} + +fn Two() { + let _: Cpp.C = Cpp.C.C(1, 2); + let _: Cpp.C = (3, 4); +} + +fn Three() { + let _: Cpp.C = Cpp.C.C(1, 2, 3); + let _: Cpp.C = (4, 5, 6); +} + +fn Four() { + let _: Cpp.C = Cpp.C.C(1, 2, 3, 4); + let _: Cpp.C = (5, 6, 7, 8); +} + // CHECK:STDOUT: ; ModuleID = 'import_default.carbon' // CHECK:STDOUT: source_filename = "import_default.carbon" // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" @@ -112,6 +163,16 @@ fn F() { // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Ev.carbon_thunk_tuple(ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %0 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: call void @_ZN1CC2Ev(ptr noundef nonnull align 4 dereferenceable(8) %0) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define void @_CF.Main() #2 !dbg !18 { // CHECK:STDOUT: entry: @@ -121,9 +182,22 @@ fn F() { // CHECK:STDOUT: ret void, !dbg !22 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CG.Main() #2 !dbg !23 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc11_19.2.temp = alloca [8 x i8], align 1, !dbg !24 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc11_19.2.temp), !dbg !24 +// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk_tuple(ptr %.loc11_19.2.temp), !dbg !24 +// CHECK:STDOUT: ret void, !dbg !25 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3 // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @_ZN1CC2Ev, { 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #1 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } // CHECK:STDOUT: attributes #2 = { nounwind } @@ -156,6 +230,9 @@ fn F() { // CHECK:STDOUT: !20 = !{null} // CHECK:STDOUT: !21 = !DILocation(line: 7, column: 18, scope: !18) // CHECK:STDOUT: !22 = !DILocation(line: 6, column: 1, scope: !18) +// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "G", linkageName: "_CG.Main", scope: null, file: !7, line: 10, type: !19, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !24 = !DILocation(line: 11, column: 18, scope: !23) +// CHECK:STDOUT: !25 = !DILocation(line: 10, column: 1, scope: !23) // CHECK:STDOUT: ; ModuleID = 'call_copy.carbon' // CHECK:STDOUT: source_filename = "call_copy.carbon" // CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" @@ -327,3 +404,356 @@ fn F() { // CHECK:STDOUT: !19 = !{null} // CHECK:STDOUT: !20 = !DILocation(line: 7, column: 24, scope: !17) // CHECK:STDOUT: !21 = !DILocation(line: 6, column: 1, scope: !17) +// CHECK:STDOUT: ; ModuleID = 'call_multi_argument.carbon' +// CHECK:STDOUT: source_filename = "call_multi_argument.carbon" +// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu" +// CHECK:STDOUT: +// CHECK:STDOUT: $_ZN1CC2Ev = comdat any +// CHECK:STDOUT: +// CHECK:STDOUT: $_ZN1CC2Ei = comdat any +// CHECK:STDOUT: +// CHECK:STDOUT: $_ZN1CC2Eii = comdat any +// CHECK:STDOUT: +// CHECK:STDOUT: $_ZN1CC2Eiiii = comdat any +// CHECK:STDOUT: +// CHECK:STDOUT: @C.val.loc9_19.3 = internal constant {} zeroinitializer +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Ev.carbon_thunk(ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %0 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: call void @_ZN1CC2Ev(ptr noundef nonnull align 1 dereferenceable(1) %0) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Ev(ptr noundef nonnull align 1 dereferenceable(1) %this) unnamed_addr #1 comdat align 2 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Ev.carbon_thunk_tuple(ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %0 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: call void @_ZN1CC2Ev(ptr noundef nonnull align 1 dereferenceable(1) %0) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Ei.carbon_thunk(i32 noundef %0, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %1 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %2 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Ei(ptr noundef nonnull align 1 dereferenceable(1) %1, i32 noundef %2) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Ei(ptr noundef nonnull align 1 dereferenceable(1) %this, i32 noundef %0) unnamed_addr #1 comdat align 2 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !12 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %this1 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Ei.carbon_thunk_tuple(i32 noundef %0, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %1 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %2 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Ei(ptr noundef nonnull align 1 dereferenceable(1) %1, i32 noundef %2) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eii.carbon_thunk(i32 noundef %0, i32 noundef %1, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %2 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %3 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %4 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eii(ptr noundef nonnull align 1 dereferenceable(1) %2, i32 noundef %3, i32 noundef %4) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Eii(ptr noundef nonnull align 1 dereferenceable(1) %this, i32 noundef %0, i32 noundef %1) unnamed_addr #1 comdat align 2 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !12 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: %this2 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eii.carbon_thunk_tuple(i32 noundef %0, i32 noundef %1, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %2 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %3 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %4 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eii(ptr noundef nonnull align 1 dereferenceable(1) %2, i32 noundef %3, i32 noundef %4) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eiiii.carbon_thunk3(i32 noundef %0, i32 noundef %1, i32 noundef %2, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %.addr2 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %3 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %4 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %5 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: %6 = load i32, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eiiii(ptr noundef nonnull align 1 dereferenceable(1) %3, i32 noundef %4, i32 noundef %5, i32 noundef %6, i32 noundef 0) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable +// CHECK:STDOUT: define linkonce_odr dso_local void @_ZN1CC2Eiiii(ptr noundef nonnull align 1 dereferenceable(1) %this, i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) unnamed_addr #1 comdat align 2 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %this.addr = alloca ptr, align 8 +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %.addr2 = alloca i32, align 4 +// CHECK:STDOUT: %.addr3 = alloca i32, align 4 +// CHECK:STDOUT: store ptr %this, ptr %this.addr, align 8, !tbaa !12 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %3, ptr %.addr3, align 4, !tbaa !8 +// CHECK:STDOUT: %this4 = load ptr, ptr %this.addr, align 8 +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eiiii.carbon_thunk_tuple3(i32 noundef %0, i32 noundef %1, i32 noundef %2, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %.addr2 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %3 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %4 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %5 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: %6 = load i32, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eiiii(ptr noundef nonnull align 1 dereferenceable(1) %3, i32 noundef %4, i32 noundef %5, i32 noundef %6, i32 noundef 0) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eiiii.carbon_thunk(i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %.addr2 = alloca i32, align 4 +// CHECK:STDOUT: %.addr3 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %3, ptr %.addr3, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %4 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %5 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %6 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: %7 = load i32, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: %8 = load i32, ptr %.addr3, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eiiii(ptr noundef nonnull align 1 dereferenceable(1) %4, i32 noundef %5, i32 noundef %6, i32 noundef %7, i32 noundef %8) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable +// CHECK:STDOUT: define dso_local void @_ZN1CC1Eiiii.carbon_thunk_tuple(i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3, ptr noundef %return) #0 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.addr = alloca i32, align 4 +// CHECK:STDOUT: %.addr1 = alloca i32, align 4 +// CHECK:STDOUT: %.addr2 = alloca i32, align 4 +// CHECK:STDOUT: %.addr3 = alloca i32, align 4 +// CHECK:STDOUT: %return.addr = alloca ptr, align 8 +// CHECK:STDOUT: store i32 %0, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: store i32 %3, ptr %.addr3, align 4, !tbaa !8 +// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %4 = load ptr, ptr %return.addr, align 8, !tbaa !12 +// CHECK:STDOUT: %5 = load i32, ptr %.addr, align 4, !tbaa !8 +// CHECK:STDOUT: %6 = load i32, ptr %.addr1, align 4, !tbaa !8 +// CHECK:STDOUT: %7 = load i32, ptr %.addr2, align 4, !tbaa !8 +// CHECK:STDOUT: %8 = load i32, ptr %.addr3, align 4, !tbaa !8 +// CHECK:STDOUT: call void @_ZN1CC2Eiiii(ptr noundef nonnull align 1 dereferenceable(1) %4, i32 noundef %5, i32 noundef %6, i32 noundef %7, i32 noundef %8) +// CHECK:STDOUT: ret void +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CZero.Main() #2 !dbg !15 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc7_26.1.temp = alloca {}, align 8, !dbg !18 +// CHECK:STDOUT: %.loc8_19.2.temp = alloca {}, align 8, !dbg !19 +// CHECK:STDOUT: %.loc9_19.2.temp = alloca {}, align 8, !dbg !20 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_26.1.temp), !dbg !18 +// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk(ptr %.loc7_26.1.temp), !dbg !18 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_19.2.temp), !dbg !19 +// CHECK:STDOUT: call void @_ZN1CC1Ev.carbon_thunk_tuple(ptr %.loc8_19.2.temp), !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_19.2.temp), !dbg !20 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %.loc9_19.2.temp, ptr align 1 @C.val.loc9_19.3, i64 0, i1 false), !dbg !20 +// CHECK:STDOUT: ret void, !dbg !21 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_COne.Main() #2 !dbg !22 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc13_27.1.temp = alloca {}, align 8, !dbg !23 +// CHECK:STDOUT: %.loc14_18.1.temp = alloca {}, align 8, !dbg !24 +// CHECK:STDOUT: %.loc15_21.2.temp = alloca {}, align 8, !dbg !25 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc13_27.1.temp), !dbg !23 +// CHECK:STDOUT: call void @_ZN1CC1Ei.carbon_thunk(i32 1, ptr %.loc13_27.1.temp), !dbg !23 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc14_18.1.temp), !dbg !24 +// CHECK:STDOUT: call void @_ZN1CC1Ei.carbon_thunk(i32 2, ptr %.loc14_18.1.temp), !dbg !24 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc15_21.2.temp), !dbg !25 +// CHECK:STDOUT: call void @_ZN1CC1Ei.carbon_thunk_tuple(i32 3, ptr %.loc15_21.2.temp), !dbg !25 +// CHECK:STDOUT: ret void, !dbg !26 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CTwo.Main() #2 !dbg !27 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc19_30.1.temp = alloca {}, align 8, !dbg !28 +// CHECK:STDOUT: %.loc20_23.2.temp = alloca {}, align 8, !dbg !29 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc19_30.1.temp), !dbg !28 +// CHECK:STDOUT: call void @_ZN1CC1Eii.carbon_thunk(i32 1, i32 2, ptr %.loc19_30.1.temp), !dbg !28 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_23.2.temp), !dbg !29 +// CHECK:STDOUT: call void @_ZN1CC1Eii.carbon_thunk_tuple(i32 3, i32 4, ptr %.loc20_23.2.temp), !dbg !29 +// CHECK:STDOUT: ret void, !dbg !30 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CThree.Main() #2 !dbg !31 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc24_33.1.temp = alloca {}, align 8, !dbg !32 +// CHECK:STDOUT: %.loc25_26.2.temp = alloca {}, align 8, !dbg !33 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_33.1.temp), !dbg !32 +// CHECK:STDOUT: call void @_ZN1CC1Eiiii.carbon_thunk3(i32 1, i32 2, i32 3, ptr %.loc24_33.1.temp), !dbg !32 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc25_26.2.temp), !dbg !33 +// CHECK:STDOUT: call void @_ZN1CC1Eiiii.carbon_thunk_tuple3(i32 4, i32 5, i32 6, ptr %.loc25_26.2.temp), !dbg !33 +// CHECK:STDOUT: ret void, !dbg !34 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CFour.Main() #2 !dbg !35 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc29_36.1.temp = alloca {}, align 8, !dbg !36 +// CHECK:STDOUT: %.loc30_29.2.temp = alloca {}, align 8, !dbg !37 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc29_36.1.temp), !dbg !36 +// CHECK:STDOUT: call void @_ZN1CC1Eiiii.carbon_thunk(i32 1, i32 2, i32 3, i32 4, ptr %.loc29_36.1.temp), !dbg !36 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc30_29.2.temp), !dbg !37 +// CHECK:STDOUT: call void @_ZN1CC1Eiiii.carbon_thunk_tuple(i32 5, i32 6, i32 7, i32 8, ptr %.loc30_29.2.temp), !dbg !37 +// CHECK:STDOUT: ret void, !dbg !38 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #3 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #4 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @_ZN1CC2Ev, { 1, 0 } +// CHECK:STDOUT: uselistorder ptr @_ZN1CC2Ei, { 1, 0 } +// CHECK:STDOUT: uselistorder ptr @_ZN1CC2Eii, { 1, 0 } +// CHECK:STDOUT: uselistorder ptr @_ZN1CC2Eiiii, { 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #1 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +// CHECK:STDOUT: attributes #2 = { nounwind } +// CHECK:STDOUT: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #4 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4, !5} +// CHECK:STDOUT: !llvm.dbg.cu = !{!6} +// CHECK:STDOUT: !llvm.errno.tbaa = !{!8} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = !{i32 1, !"wchar_size", i32 4} +// CHECK:STDOUT: !3 = !{i32 8, !"PIC Level", i32 2} +// CHECK:STDOUT: !4 = !{i32 7, !"PIE Level", i32 2} +// CHECK:STDOUT: !5 = !{i32 7, !"uwtable", i32 2} +// CHECK:STDOUT: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !7, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !7 = !DIFile(filename: "call_multi_argument.carbon", directory: "") +// CHECK:STDOUT: !8 = !{!9, !9, i64 0} +// CHECK:STDOUT: !9 = !{!"int", !10, i64 0} +// CHECK:STDOUT: !10 = !{!"omnipotent char", !11, i64 0} +// CHECK:STDOUT: !11 = !{!"Simple C++ TBAA"} +// CHECK:STDOUT: !12 = !{!13, !13, i64 0} +// CHECK:STDOUT: !13 = !{!"p1 _ZTS1C", !14, i64 0} +// CHECK:STDOUT: !14 = !{!"any pointer", !10, i64 0} +// CHECK:STDOUT: !15 = distinct !DISubprogram(name: "Zero", linkageName: "_CZero.Main", scope: null, file: !7, line: 6, type: !16, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !16 = !DISubroutineType(types: !17) +// CHECK:STDOUT: !17 = !{null} +// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 18, scope: !15) +// CHECK:STDOUT: !19 = !DILocation(line: 8, column: 18, scope: !15) +// CHECK:STDOUT: !20 = !DILocation(line: 9, column: 18, scope: !15) +// CHECK:STDOUT: !21 = !DILocation(line: 6, column: 1, scope: !15) +// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "One", linkageName: "_COne.Main", scope: null, file: !7, line: 12, type: !16, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !23 = !DILocation(line: 13, column: 18, scope: !22) +// CHECK:STDOUT: !24 = !DILocation(line: 14, column: 18, scope: !22) +// CHECK:STDOUT: !25 = !DILocation(line: 15, column: 18, scope: !22) +// CHECK:STDOUT: !26 = !DILocation(line: 12, column: 1, scope: !22) +// CHECK:STDOUT: !27 = distinct !DISubprogram(name: "Two", linkageName: "_CTwo.Main", scope: null, file: !7, line: 18, type: !16, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !28 = !DILocation(line: 19, column: 18, scope: !27) +// CHECK:STDOUT: !29 = !DILocation(line: 20, column: 18, scope: !27) +// CHECK:STDOUT: !30 = !DILocation(line: 18, column: 1, scope: !27) +// CHECK:STDOUT: !31 = distinct !DISubprogram(name: "Three", linkageName: "_CThree.Main", scope: null, file: !7, line: 23, type: !16, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !32 = !DILocation(line: 24, column: 18, scope: !31) +// CHECK:STDOUT: !33 = !DILocation(line: 25, column: 18, scope: !31) +// CHECK:STDOUT: !34 = !DILocation(line: 23, column: 1, scope: !31) +// CHECK:STDOUT: !35 = distinct !DISubprogram(name: "Four", linkageName: "_CFour.Main", scope: null, file: !7, line: 28, type: !16, spFlags: DISPFlagDefinition, unit: !6) +// CHECK:STDOUT: !36 = !DILocation(line: 29, column: 18, scope: !35) +// CHECK:STDOUT: !37 = !DILocation(line: 30, column: 18, scope: !35) +// CHECK:STDOUT: !38 = !DILocation(line: 28, column: 1, scope: !35) diff --git a/toolchain/sem_ir/clang_decl.cpp b/toolchain/sem_ir/clang_decl.cpp index f14bab416faa..729c647d07e1 100644 --- a/toolchain/sem_ir/clang_decl.cpp +++ b/toolchain/sem_ir/clang_decl.cpp @@ -21,9 +21,17 @@ auto ClangDeclKey::Print(llvm::raw_ostream& out) const -> void { decl->print(decl_stream, policy); } - if (num_params != -1) { - out << "{decl: \"" << FormatEscaped(decl_stream.TakeStr()) - << "\", num_params: " << num_params << "}"; + if (signature.num_params != -1) { + out << "{decl: \"" << FormatEscaped(decl_stream.TakeStr()) << "\", kind: "; + switch (signature.kind) { + case ClangDeclKey::Signature::Normal: + out << "normal"; + break; + case ClangDeclKey::Signature::TuplePattern: + out << "tuple"; + break; + } + out << ", num_params: " << signature.num_params << "}"; } else { out << "\"" << FormatEscaped(decl_stream.TakeStr()) << "\""; } diff --git a/toolchain/sem_ir/clang_decl.h b/toolchain/sem_ir/clang_decl.h index aaa4158a9a4b..6b65d16233bd 100644 --- a/toolchain/sem_ir/clang_decl.h +++ b/toolchain/sem_ir/clang_decl.h @@ -24,58 +24,82 @@ namespace Carbon::SemIR { // A canonical declaration pointer is used so that we can perform direct address // comparisons and hash this structure based on its contents. struct ClangDeclKey : public Printable { + // Information about how to form the Carbon function signature from the Clang + // function declaration. + struct Signature { + enum Kind : int8_t { + // A normal function signature: each C++ parameter maps into a Carbon + // parameter. + Normal, + // A function signature taking a tuple pattern that contains the C++ + // parameters. This is used when importing a constructor that is used for + // list initialization from a Carbon tuple. + TuplePattern, + }; + // The kind of function signature being imported. + Kind kind = Normal; + // The number of parameters to import. This can be less than the number of + // parameters in the Clang declaration if the Clang declaration has default + // arguments. Excludes the implicit object parameter, if there is one. + int32_t num_params = -1; + + friend auto operator==(const Signature& lhs, const Signature& rhs) + -> bool = default; + }; + // For declaration classes that are unrelated to FunctionDecl, no parameter // count is expected. template requires(std::derived_from && !std::derived_from && !std::derived_from) - explicit ClangDeclKey(DeclT* decl) : ClangDeclKey(decl, -1, UncheckedTag()) {} + explicit ClangDeclKey(DeclT* decl) + : ClangDeclKey(decl, Signature{}, UncheckedTag()) {} // For declaration classes that are derived from FunctionDecl, a parameter // count is required. - static auto ForFunctionDecl(clang::FunctionDecl* decl, int num_params) + static auto ForFunctionDecl(clang::FunctionDecl* decl, Signature signature) -> ClangDeclKey { - return ClangDeclKey(decl, num_params, UncheckedTag()); + return ClangDeclKey(decl, signature, UncheckedTag()); } // Factory function for clang declaration that is dynamically known to not be // a function declaration. static auto ForNonFunctionDecl(clang::Decl* decl) -> ClangDeclKey { CARBON_CHECK(!isa(decl)); - return ClangDeclKey(decl, -1, UncheckedTag()); + return ClangDeclKey(decl, Signature{}, UncheckedTag()); } auto Print(llvm::raw_ostream& out) const -> void; auto operator==(const ClangDeclKey& rhs) const -> bool { - return decl == rhs.decl && num_params == rhs.num_params; + return decl == rhs.decl && signature == rhs.signature; } // Hashing for ClangDecl. See common/hashing.h. friend auto CarbonHashValue(const ClangDeclKey& value, uint64_t seed) -> HashCode { - // Manual hashing support is required because this type has tail padding in - // 64-bit compilations. - return HashValue(std::pair{value.decl, value.num_params}, seed); + // Manual hashing support is required because `Signature` has padding. + return HashValue(std::tuple{value.decl, value.signature.num_params, + value.signature.kind}, + seed); } // The Clang declaration pointing to the Clang AST. // TODO: Ensure we can easily serialize/deserialize this. Consider // `clang::LazyDeclPtr`. - clang::Decl* decl = nullptr; + clang::Decl* decl; - // The number of parameters to import for a function declaration. Excludes the - // implicit object parameter, if there is one. Always -1 for a non-function - // declaration. - int32_t num_params = -1; + // The parameters to import for a function declaration. Otherwise a + // default-constructed value. + Signature signature; private: struct UncheckedTag { explicit UncheckedTag() = default; }; - ClangDeclKey(clang::Decl* decl, int num_params, UncheckedTag /*_*/) - : decl(decl->getCanonicalDecl()), num_params(num_params) {} + ClangDeclKey(clang::Decl* decl, Signature signature, UncheckedTag /*_*/) + : decl(decl->getCanonicalDecl()), signature(signature) {} }; // A Clang declaration mapped to a Carbon instruction.