Include notes listing the candidates and explaining why they didn't
work. Rather than duplicating the (substantial) logic for this, use the
Clang machinery to generate these diagnostics.
In order to support this, add a mechanism to map `SemIR::LocId`s to
`clang::SourceLocation`s. This works by creating source buffers in Clang
that refer into the Carbon source file so that `SourceLocation`s can
point into them.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Multiple overloads for the same operator are now resolved using overload
resolution.
This change doesn't try to solve all issues with operator lookup.
Moved the operator lookup logic from `import` to `operators` and changed
it to take the args into account.
Use `Sema::LookupOverloadedBinOp()` (with ADL) when looking up operator
functions to create an overload set.
Verified all demos in #6017, #6020 and #6024 still work.
C++ Interop Demo:
```c++
// my_number.h
class MyNumber {
public:
explicit MyNumber(int value) : value_(value) {}
auto value() const -> int { return value_; }
private:
int value_;
};
class NotMyNumber {};
auto operator+(MyNumber lhs, MyNumber rhs) -> MyNumber;
auto operator+(NotMyNumber lhs, NotMyNumber rhs) -> NotMyNumber;
```
```c++
// my_number.cpp
#include "my_number.h"
auto operator+(MyNumber lhs, MyNumber rhs) -> MyNumber {
return MyNumber(lhs.value() + rhs.value());
}
auto operator+(NotMyNumber lhs, NotMyNumber /*rhs*/) -> NotMyNumber {
return lhs;
}
```
```carbon
// main.carbon
library "Main";
import Core library "io";
import Cpp library "my_number.h";
fn Run() -> i32 {
// Arithmetic
var num1: Cpp.MyNumber = Cpp.MyNumber.MyNumber(14);
var num2: Cpp.MyNumber = Cpp.MyNumber.MyNumber(5);
Core.Print(num1.value());
Core.Print(num2.value());
Core.Print((num1 + num2).value());
return 0;
}
```
**After this change:**
```shell
$ clang -c my_number.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link my_number.o main.o --output=demo
$ ./demo
14
5
19
```
**Before this change**
```shell
$ bazel-bin/toolchain/carbon compile main.carbon
main.carbon:14:15: error: semantics TODO: `Unsupported: Lookup succeeded but couldn't find a single result; LookupResultKind: 3`
Core.Print((num1 + num2).value());
^~~~~~~~~~~
main.carbon:14:15: note: in `Cpp` operator `AddWith` lookup
Core.Print((num1 + num2).value());
^~~~~~~~~~~
```
Part of https://github.com/carbon-language/carbon-lang/issues/5995.
Only do the lookup when the class is complete.
Before this change we crash in `Sema::LookupQualifiedName()` on
`Declaration context must already be complete!`.
This is Itanium-specific for now (explicitly downcasting to the itanium
vtable handling code in Clang) - though it doesn't look like it'd be a
big stretch to either have conditional/two codepaths down Itanium and
MSVC in Carbon, or maybe add a virtual function in clang to avoid
needing to conditional+downcast in Carbon.
Here's a working example:
`dynamic_type.h`:
```
#ifndef TEST_H
#define TEST_H
struct A {
virtual auto virt0() -> int;
virtual auto virt1() -> int;
};
auto GetVal() -> A* _Nonnull;
#endif
```
`test.carbon`:
```
library "test";
import Cpp library "dynamic_type.h";
import Core library "io";
fn Run() {
var a: Cpp.A* = Cpp.GetVal();
Core.Print(a->virt0());
Core.Print(a->virt1());
}
```
`dynamic_type.cpp`:
```
#include "dynamic_type.h"
auto A::virt0() -> int {
return 0;
}
auto A::virt1() -> int {
return 1;
}
struct B: A {
auto virt0() -> int override {
return 7;
}
auto virt1() -> int override {
return 42;
}
};
auto GetVal() -> A* _Nonnull {
static B b;
return &b;
}
```
```
$ ./bazel-bin/toolchain/carbon compile test.carbon
$ clang++-tot -g dynamic_type.cpp test.o --output=a.out
$ ./a.out
7
42
```
(linking with `carbon link` failed because we aren't linking to the C++
runtime yet, it seems, so: `ld.lld: error: undefined symbol: vtable for
__cxxabiv1::__class_type_info`)
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>