diff --git a/toolchain/check/handle_literal.cpp b/toolchain/check/handle_literal.cpp index c71384850876..02edd203e1a1 100644 --- a/toolchain/check/handle_literal.cpp +++ b/toolchain/check/handle_literal.cpp @@ -12,6 +12,7 @@ #include "toolchain/check/name_lookup.h" #include "toolchain/check/type.h" #include "toolchain/diagnostics/format_providers.h" +#include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { @@ -147,9 +148,8 @@ auto HandleParseNode(Context& context, Parse::FloatTypeLiteralId node_id) } auto tok_id = context.parse_tree().node_token(node_id); auto size_id = context.tokens().GetTypeLiteralSize(tok_id); - auto width_id = MakeIntLiteral(context, node_id, size_id); - auto fn_inst_id = LookupNameInCore(context, node_id, "Float"); - auto type_inst_id = PerformCall(context, node_id, fn_inst_id, {width_id}); + auto type_inst_id = + MakeFloatTypeLiteral(context, node_id, SemIR::FloatKind::None, size_id); context.node_stack().Push(node_id, type_inst_id); return true; } diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index cee1da4272ec..d98db54c5532 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -794,6 +794,15 @@ static auto MapBuiltinType(Context& context, clang::QualType qual_type, return MakeIntType(context, context.ints().Add(width), is_signed); } // TODO: Handle integer types that map to named aliases. + } else if (type.isDoubleType()) { + // TODO: Handle other floating point types when Carbon supports fN where N + // != 64. + CARBON_CHECK(ast_context.getTypeSize(qual_type) == 64); + CARBON_CHECK(ast_context.hasSameType(qual_type, ast_context.DoubleTy)); + return ExprAsType( + context, Parse::NodeId::None, + MakeFloatTypeLiteral(context, Parse::NodeId::None, + SemIR::FloatKind::None, context.ints().Add(64))); } return {.inst_id = SemIR::TypeInstId::None, .type_id = SemIR::TypeId::None}; diff --git a/toolchain/check/literal.cpp b/toolchain/check/literal.cpp index ef66607cb75d..1c3e12f0049f 100644 --- a/toolchain/check/literal.cpp +++ b/toolchain/check/literal.cpp @@ -9,6 +9,7 @@ #include "toolchain/check/convert.h" #include "toolchain/check/name_lookup.h" #include "toolchain/check/type.h" +#include "toolchain/sem_ir/ids.h" namespace Carbon::Check { @@ -35,4 +36,13 @@ auto MakeIntType(Context& context, Parse::NodeId node_id, return ExprAsType(context, node_id, type_inst_id).type_id; } +auto MakeFloatTypeLiteral(Context& context, Parse::NodeId node_id, + SemIR::FloatKind float_kind, IntId size_id) + -> SemIR::InstId { + CARBON_CHECK(float_kind == SemIR::FloatKind::None); + auto width_id = MakeIntLiteral(context, node_id, size_id); + auto fn_inst_id = LookupNameInCore(context, node_id, "Float"); + return PerformCall(context, node_id, fn_inst_id, {width_id}); +} + } // namespace Carbon::Check diff --git a/toolchain/check/literal.h b/toolchain/check/literal.h index 36f6903bc2a5..d96b19d94ddc 100644 --- a/toolchain/check/literal.h +++ b/toolchain/check/literal.h @@ -24,6 +24,11 @@ auto MakeIntTypeLiteral(Context& context, Parse::NodeId node_id, auto MakeIntType(Context& context, Parse::NodeId node_id, SemIR::IntKind int_kind, IntId size_id) -> SemIR::TypeId; +// Forms a floating point type expression for `fN` literal. +auto MakeFloatTypeLiteral(Context& context, Parse::NodeId node_id, + SemIR::FloatKind float_kind, IntId size_id) + -> SemIR::InstId; + } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_LITERAL_H_ 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 8ab078641479..8abfc059eca3 100644 --- a/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon +++ b/toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon @@ -358,6 +358,26 @@ fn F() { //@dump-sem-ir-end } +// ============================================================================ +// double param +// ============================================================================ + +// --- double_param.h + +auto foo(double a) -> void; + +// --- import_double_param.carbon + +library "[[@TEST_NAME]]"; + +import Cpp library "double_param.h"; + +fn F() { + //@dump-sem-ir-begin + Cpp.foo(0.8 as f64); + //@dump-sem-ir-end +} + // ============================================================================ // bool return // ============================================================================ @@ -399,29 +419,22 @@ fn F() { } // ============================================================================ -// float return +// double return // ============================================================================ -// --- float_return.h +// --- double_return.h -auto foo_float() -> float; +auto foo_double() -> double; -// --- fail_todo_import_float_return.carbon +// --- import_double_return.carbon library "[[@TEST_NAME]]"; -import Cpp library "float_return.h"; +import Cpp library "double_return.h"; fn F() { //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_import_float_return.carbon:[[@LINE+7]]:3: error: semantics TODO: `Unsupported: return type: float` [SemanticsTodo] - // CHECK:STDERR: Cpp.foo_float(); - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_import_float_return.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `foo_float` [InCppNameLookup] - // CHECK:STDERR: Cpp.foo_float(); - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: - Cpp.foo_float(); + let x: f64 = Cpp.foo_double(); //@dump-sem-ir-end } @@ -1074,6 +1087,43 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- import_double_param.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete] +// CHECK:STDOUT: %Float.type: type = fn_type @Float [concrete] +// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete] +// CHECK:STDOUT: %foo.type: type = fn_type @foo [concrete] +// CHECK:STDOUT: %foo: %foo.type = struct_value () [concrete] +// CHECK:STDOUT: %float: f64 = float_literal 0.80000000000000004 [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: %float: f64 = float_literal 0.80000000000000004 [concrete = constants.%float] +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %Float.call: init type = call constants.%Float(%int_64) [concrete = f64] +// CHECK:STDOUT: %.loc8_18.1: type = value_of_initializer %Float.call [concrete = f64] +// CHECK:STDOUT: %.loc8_18.2: type = converted %Float.call, %.loc8_18.1 [concrete = f64] +// CHECK:STDOUT: %foo.call: init %empty_tuple.type = call %foo.ref(%float) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- import_bool_return.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1155,22 +1205,46 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_import_float_return.carbon +// CHECK:STDOUT: --- import_double_return.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete] +// CHECK:STDOUT: %Float.type: type = fn_type @Float [concrete] +// CHECK:STDOUT: %Float: %Float.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.3de: type = pattern_type f64 [concrete] +// CHECK:STDOUT: %foo_double.type: type = fn_type @foo_double [concrete] +// CHECK:STDOUT: %foo_double: %foo_double.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { -// CHECK:STDOUT: .foo_float = +// CHECK:STDOUT: .foo_double = %foo_double.decl // CHECK:STDOUT: import Cpp//... // CHECK:STDOUT: } +// CHECK:STDOUT: %foo_double.decl: %foo_double.type = fn_decl @foo_double [concrete = constants.%foo_double] { +// 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.3de = binding_pattern x [concrete] +// CHECK:STDOUT: } // CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %foo_float.ref: = name_ref foo_float, [concrete = ] +// CHECK:STDOUT: %foo_double.ref: %foo_double.type = name_ref foo_double, imports.%foo_double.decl [concrete = constants.%foo_double] +// CHECK:STDOUT: %foo_double.call: init f64 = call %foo_double.ref() +// CHECK:STDOUT: %.loc8_10.1: type = splice_block %.loc8_10.3 [concrete = f64] { +// CHECK:STDOUT: %int_64: Core.IntLiteral = int_value 64 [concrete = constants.%int_64] +// CHECK:STDOUT: %Float.call: init type = call constants.%Float(%int_64) [concrete = f64] +// CHECK:STDOUT: %.loc8_10.2: type = value_of_initializer %Float.call [concrete = f64] +// CHECK:STDOUT: %.loc8_10.3: type = converted %Float.call, %.loc8_10.2 [concrete = f64] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8_31.1: f64 = value_of_initializer %foo_double.call +// CHECK:STDOUT: %.loc8_31.2: f64 = converted %foo_double.call, %.loc8_31.1 +// CHECK:STDOUT: %x: f64 = bind_name x, %.loc8_31.2 // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: