Instantiate C++ templates at end of file. (#6084)

Mark C++ functions as used when overload resolution selects them, and
trigger Clang's end-of-TU processing at the end of the Carbon
compilation to perform instantiation and other pending cleanup steps.
This commit is contained in:
Richard Smith
2025-09-17 01:06:47 +00:00
committed by GitHub
parent 6086d6eef2
commit 65a7e50037
9 changed files with 144 additions and 18 deletions
@@ -134,16 +134,21 @@ fn F() {
static auto foo() -> void;
// --- import_static.carbon
// --- todo_fail_import_static.carbon
library "[[@TEST_NAME]]";
// TODO: Promote this warning to an error by default.
// CHECK:STDERR: todo_fail_import_static.carbon:[[@LINE+5]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./static.h:2:13: warning: function 'foo' has internal linkage but is not defined [CppInteropParseWarning]
// CHECK:STDERR: 2 | static auto foo() -> void;
// CHECK:STDERR: | ^
// CHECK:STDERR:
import Cpp library "static.h";
fn F() {
//@dump-sem-ir-begin
// TODO: We should eventually warn or error that `Cpp.foo` has internal
// linkage but is not defined.
// TODO: Produce a note pointing here.
Cpp.foo();
//@dump-sem-ir-end
}
@@ -283,7 +288,7 @@ fn G() -> i32 {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- import_static.carbon
// CHECK:STDOUT: --- todo_fail_import_static.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
+13 -7
View File
@@ -42,11 +42,17 @@ inline void foo();
library "[[@TEST_NAME]]";
// TODO: Promote this warning to an error by default.
// CHECK:STDERR: todo_fail_import_without_definition.carbon:[[@LINE+5]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./without_definition.h:2:13: warning: inline function 'foo' is not defined [CppInteropParseWarning]
// CHECK:STDERR: 2 | inline void foo();
// CHECK:STDERR: | ^
// CHECK:STDERR:
import Cpp library "without_definition.h";
fn MyF() {
//@dump-sem-ir-begin
// TODO: Error on using an inline function without definition.
// TODO: Produce a note pointing here.
Cpp.foo();
// Don't error on repeated calls.
@@ -126,12 +132,12 @@ fn MyF() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @MyF() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Cpp.ref.loc9: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref.loc9: %.c5d = name_ref foo, imports.%.a21 [concrete = constants.%empty_struct]
// CHECK:STDOUT: %foo.call.loc9: init %empty_tuple.type = call imports.%foo.decl()
// CHECK:STDOUT: %Cpp.ref.loc12: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref.loc12: %.c5d = name_ref foo, imports.%.a21 [concrete = constants.%empty_struct]
// CHECK:STDOUT: %foo.call.loc12: init %empty_tuple.type = call imports.%foo.decl()
// CHECK:STDOUT: %Cpp.ref.loc15: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref.loc15: %.c5d = name_ref foo, imports.%.a21 [concrete = constants.%empty_struct]
// CHECK:STDOUT: %foo.call.loc15: init %empty_tuple.type = call imports.%foo.decl()
// CHECK:STDOUT: %Cpp.ref.loc18: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
// CHECK:STDOUT: %foo.ref.loc18: %.c5d = name_ref foo, imports.%.a21 [concrete = constants.%empty_struct]
// CHECK:STDOUT: %foo.call.loc18: init %empty_tuple.type = call imports.%foo.decl()
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: