diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index c755b1e233e9..afe754f6c06b 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -752,12 +752,18 @@ static auto MakeIntType(Context& context, IntId size_id, bool is_signed) // TODO: Support more builtin types. static auto MapBuiltinType(Context& context, clang::QualType qual_type, const clang::BuiltinType& type) -> TypeExpr { + clang::ASTContext& ast_context = context.ast_context(); + if (type.isBooleanType()) { + CARBON_CHECK(ast_context.hasSameType(qual_type, ast_context.BoolTy)); + return ExprAsType(context, Parse::NodeId::None, + context.types().GetInstId(GetSingletonType( + context, SemIR::BoolType::TypeInstId))); + } if (type.isInteger()) { - auto width = context.ast_context().getIntWidth(qual_type); + auto width = ast_context.getIntWidth(qual_type); bool is_signed = type.isSignedInteger(); - auto int_n_type = - context.ast_context().getIntTypeForBitwidth(width, is_signed); - if (context.ast_context().hasSameType(qual_type, int_n_type)) { + auto int_n_type = ast_context.getIntTypeForBitwidth(width, is_signed); + if (ast_context.hasSameType(qual_type, int_n_type)) { return MakeIntType(context, context.ints().Add(width), is_signed); } // TODO: Handle integer types that map to named aliases. diff --git a/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon b/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon index 919ba4c4db06..8ab078641479 100644 --- a/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon +++ b/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon @@ -2,7 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon // // AUTOUPDATE // TIP: To test this file alone, run: @@ -15,6 +15,38 @@ // calling convention. // TODO: Create thunks for these cases. +// ============================================================================ +// bool param +// ============================================================================ + +// --- bool_param.h + +auto foo(bool a) -> void; + +// --- import_bool_param_true.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "bool_param.h"; + +fn F() { + //@dump-sem-ir-begin + Cpp.foo(true); + //@dump-sem-ir-end +} + +// --- import_bool_param_false.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "bool_param.h"; + +fn F() { + //@dump-sem-ir-begin + Cpp.foo(false); + //@dump-sem-ir-end +} + // ============================================================================ // short param // ============================================================================ @@ -326,6 +358,26 @@ fn F() { //@dump-sem-ir-end } +// ============================================================================ +// bool return +// ============================================================================ + +// --- bool_return.h + +auto foo_bool() -> bool; + +// --- import_bool_return.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "bool_return.h"; + +fn F() { + //@dump-sem-ir-begin + let x: bool = Cpp.foo_bool(); + //@dump-sem-ir-end +} + // ============================================================================ // short return // ============================================================================ @@ -373,6 +425,67 @@ fn F() { //@dump-sem-ir-end } + +// CHECK:STDOUT: --- import_bool_param_true.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] +// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] +// CHECK:STDOUT: %true: bool = bool_literal true [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = %foo.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo] +// CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true] +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%true) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- import_bool_param_false.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] +// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] +// CHECK:STDOUT: %false: bool = bool_literal false [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo = %foo.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo] +// CHECK:STDOUT: %false: bool = bool_literal false [concrete = constants.%false] +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%false) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- import_short_param.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -961,6 +1074,47 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- import_bool_return.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] +// CHECK:STDOUT: %Bool: %Bool.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete] +// CHECK:STDOUT: %foo_bool.type: type = fn_type @foo_bool [concrete] +// CHECK:STDOUT: %foo_bool: %foo_bool.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .foo_bool = %foo_bool.decl +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %foo_bool.decl: %foo_bool.type = fn_decl @foo_bool [concrete = constants.%foo_bool] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %pattern_type.831 = binding_pattern x [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %foo_bool.ref: %foo_bool.type = name_ref foo_bool, imports.%foo_bool.decl [concrete = constants.%foo_bool] +// CHECK:STDOUT: %foo_bool.call: init bool = call %foo_bool.ref() +// CHECK:STDOUT: %.loc8_10.1: type = splice_block %.loc8_10.3 [concrete = bool] { +// CHECK:STDOUT: %Bool.call: init type = call constants.%Bool() [concrete = bool] +// CHECK:STDOUT: %.loc8_10.2: type = value_of_initializer %Bool.call [concrete = bool] +// CHECK:STDOUT: %.loc8_10.3: type = converted %Bool.call, %.loc8_10.2 [concrete = bool] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_30.1: bool = value_of_initializer %foo_bool.call +// CHECK:STDOUT: %.loc8_30.2: bool = converted %foo_bool.call, %.loc8_30.1 +// CHECK:STDOUT: %x: bool = bind_name x, %.loc8_30.2 +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- import_short_return.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants {