Files
carbon-lang/toolchain/check/testdata/interop/cpp/class/export/field.carbon
T
Richard Smith c06165d3e0 Require exported field types to be complete in the clang AST. (#7653)
It's not enough for field types of Carbon classes to be complete in
SemIR. If the field is exported to Clang, we also need the type to be
complete in Clang's AST, since Clang assumes it has a definition
available for the types of all fields of a complete class.
2026-08-19 17:45:34 +00:00

185 lines
4.3 KiB
Plaintext

// 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/int.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/class/export/field.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/class/export/field.carbon
// --- field.carbon
library "[[@TEST_NAME]]";
import Cpp;
class A {
var x: i32;
var y: i32;
}
inline Cpp '''
void F() {
Carbon::A a;
a.x = 12;
a.y = 34;
}
''';
// --- field_inheritence.carbon
library "[[@TEST_NAME]]";
import Cpp;
base class A {
var x: i32;
}
class B {
extend base: A;
var y: i32;
}
inline Cpp '''
void F() {
Carbon::B b;
b.x = 12;
b.y = 34;
}
''';
// --- class_field.carbon
library "[[@TEST_NAME]]";
import Cpp;
class ClassField {}
class ClassWithClassField {
var c: ClassField;
}
inline Cpp '''
void g() {
// In order for this to work, we need both class definitions to be exported to
// Clang.
Carbon::ClassWithClassField c;
}
''';
// --- fail_nonexistent_field.carbon
library "[[@TEST_NAME]]";
import Cpp;
class A {}
inline Cpp '''
void F() {
Carbon::A a;
// CHECK:STDERR: fail_nonexistent_field.carbon:[[@LINE+4]]:5: error: no member named 'x' in 'Carbon::A' [CppInteropParseError]
// CHECK:STDERR: 13 | a.x = 12;
// CHECK:STDERR: | ~ ^
// CHECK:STDERR:
a.x = 12;
// CHECK:STDERR: fail_nonexistent_field.carbon:[[@LINE+4]]:5: error: no member named 'y' in 'Carbon::A' [CppInteropParseError]
// CHECK:STDERR: 18 | a.y = 34;
// CHECK:STDERR: | ~ ^
// CHECK:STDERR:
a.y = 34;
}
''';
// --- fail_unsupported_field_type.carbon
library "[[@TEST_NAME]]";
import Cpp;
class A {
// CHECK:STDERR: fail_unsupported_field_type.carbon:[[@LINE+4]]:7: error: semantics TODO: `failed to map Carbon type to C++` [SemanticsTodo]
// CHECK:STDERR: var x: ();
// CHECK:STDERR: ^~~~~
// CHECK:STDERR:
var x: ();
// CHECK:STDERR: fail_unsupported_field_type.carbon:[[@LINE+4]]:7: error: semantics TODO: `failed to map Carbon type to C++` [SemanticsTodo]
// CHECK:STDERR: var y: ();
// CHECK:STDERR: ^~~~~
// CHECK:STDERR:
var y: ();
}
inline Cpp '''
void F() {
Carbon::A a;
// CHECK:STDERR: fail_unsupported_field_type.carbon:[[@LINE+4]]:5: error: no member named 'x' in 'Carbon::A' [CppInteropParseError]
// CHECK:STDERR: 24 | a.x;
// CHECK:STDERR: | ~ ^
// CHECK:STDERR:
a.x;
// CHECK:STDERR: fail_unsupported_field_type.carbon:[[@LINE+4]]:5: error: no member named 'y' in 'Carbon::A' [CppInteropParseError]
// CHECK:STDERR: 29 | a.y;
// CHECK:STDERR: | ~ ^
// CHECK:STDERR:
a.y;
}
''';
// --- fail_adapter.carbon
library "[[@TEST_NAME]]";
import Cpp;
class A {
adapt ();
}
inline Cpp '''
void F() {
Carbon::A a;
// CHECK:STDERR: fail_adapter.carbon:[[@LINE+4]]:5: error: no member named 'x' in 'Carbon::A' [CppInteropParseError]
// CHECK:STDERR: 15 | a.x = 12;
// CHECK:STDERR: | ~ ^
// CHECK:STDERR:
a.x = 12;
}
''';
// --- fail_invalid.carbon
library "[[@TEST_NAME]]";
import Cpp;
// This should not cause a crash.
class A {
// CHECK:STDERR: fail_invalid.carbon:[[@LINE+4]]:16: error: name `Whoops` not found [NameNotFound]
// CHECK:STDERR: extend base: Whoops;
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
extend base: Whoops;
}
inline Cpp '''
Carbon::A x;
''';
// --- fail_private_field.carbon
library "[[@TEST_NAME]]";
import Cpp;
class C {
fn Make() -> C {
return {.x = 123};
}
private var x: i32;
}
inline Cpp '''
int F() {
auto c = Carbon::C::Make();
// CHECK:STDERR: fail_private_field.carbon:[[@LINE+7]]:12: error: 'x' is a private member of 'Carbon::C' [CppInteropParseError]
// CHECK:STDERR: 22 | return c.x;
// CHECK:STDERR: | ^
// CHECK:STDERR: fail_private_field.carbon:[[@LINE-9]]:16: note: implicitly declared private here [CppInteropParseNote]
// CHECK:STDERR: 9 | private var x: i32;
// CHECK:STDERR: | ^
// CHECK:STDERR:
return c.x;
}
''';