mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 17:01:04 +01:00
Add support for using C++ double type in imported function declarations (#5868)
Carbon only supports f64, so only double can be mapped. https://github.com/carbon-language/carbon-lang/blob/30f0ddab71bda71f8789080962b1fe8a5938e327/toolchain/check/type.cpp#L54 C++ Interop Demo: ```c++ // hello_world.h auto hello_world(double x) -> void; ``` ```c++ // hello_world.cpp #include "hello_world.h" #include <cstdio> auto hello_world(double x) -> void { printf("double: %f\n", x); } ``` ```carbon // main.carbon library "Main"; import Cpp library "hello_world.h"; fn Run() -> i32 { Cpp.hello_world(0.25); return 0; } ``` ```shell $ clang -c hello_world.cpp $ bazel-bin/toolchain/carbon compile main.carbon $ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo $ $ ./demo double: 0.250000 ``` Before this change: ```shell $ bazel-bin/toolchain/carbon compile main.carbon main.carbon:8:3: error: semantics TODO: `Unsupported: parameter type: double` Cpp.hello_world(0.25); ^~~~~~~~~~~~~~~ main.carbon:8:3: note: in `Cpp` name lookup for `hello_world` Cpp.hello_world(0.25); ^~~~~~~~~~~~~~~ ``` Part of #5263.
This commit is contained in:
+90
-16
@@ -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: <elided>
|
||||
// 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> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .foo = %foo.decl
|
||||
// CHECK:STDOUT: import Cpp//...
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo.ref: %foo.type = name_ref foo, imports.%foo.decl [concrete = constants.%foo]
|
||||
// CHECK:STDOUT: %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: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- import_bool_return.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -1155,22 +1205,46 @@ fn F() {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// 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> = namespace file.%Cpp.import_cpp, [concrete] {
|
||||
// CHECK:STDOUT: .foo_float = <error>
|
||||
// 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: <elided>
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: <elided>
|
||||
// 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: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_float.ref: <error> = name_ref foo_float, <error> [concrete = <error>]
|
||||
// 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: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
|
||||
Reference in New Issue
Block a user