Files
carbon-lang/toolchain/lower/testdata/interop/cpp/fail_extern_c.carbon
T
Boaz Brickner 870c5380a0 C++ interop: Support importing binary operator+ (#5996)
Triggered by calling a binary operator with LHS being an imported C++
class type.

Not supported (yet):
* Multiple overloads.
* Other operators.

C++ Interop Demo:

```c++
// hello_world.h

class C {
 public:
  C(int x) : x_(x) {}
  auto x() const -> int { return x_; }

 private:
  int x_ = 0; 
};

auto operator+ (C c1, C c2) -> C;
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

auto operator+ (C c1, C c2) -> C {
  printf("Adding %d with %d\n", c1.x(), c2.x());
  return C(c1.x() + c2.x());
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  let c1 : Cpp.C = Cpp.C.C(7);
  let c2 : Cpp.C = Cpp.C.C(8);
  let c3 : Cpp.C = c1 + c2;
  let c4 : Cpp.C = c3 + c2;
  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
Adding 7 with 8
Adding 15 with 8
```

Part of #5995.
2025-09-03 12:01:20 +00:00

62 lines
2.1 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/full.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interop/cpp/fail_extern_c.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interop/cpp/fail_extern_c.carbon
// These tests were factored out of `extern_c.carbon` because we do not generate
// LLVM IR if any test contains errors. They should be moved back once they can
// successfully compile.
// ============================================================================
// extern "C" variable
// ============================================================================
// --- extern_c_variable.h
extern "C" int foo;
// --- fail_todo_import_extern_c_variable.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_todo_import_extern_c_variable.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
// CHECK:STDERR: ./extern_c_variable.h:2:16: error: semantics TODO: `Unsupported: Declaration type Var` [SemanticsTodo]
// CHECK:STDERR: extern "C" int foo;
// CHECK:STDERR: ^
import Cpp library "extern_c_variable.h";
fn MyF() -> i32 {
// CHECK:STDERR: fail_todo_import_extern_c_variable.carbon:[[@LINE+4]]:10: note: in `Cpp` name lookup for `foo` [InCppNameLookup]
// CHECK:STDERR: return Cpp.foo;
// CHECK:STDERR: ^~~~~~~
// CHECK:STDERR:
return Cpp.foo;
}
// ============================================================================
// extern "C" function with C++ special name
// ============================================================================
// --- extern_c_with_special_name.h
struct X {};
extern "C" X operator+(X, X);
// --- import_extern_c_with_special_name.carbon
library "[[@TEST_NAME]]";
import Cpp library "extern_c_with_special_name.h";
fn MyF(a: Cpp.X, b: Cpp.X) -> Cpp.X {
return a + b;
}