`PerformCppOverloadResolution` computes an overload set from a
`CppOverloadSetId`, but the compiler sometimes needs to synthesise a
local overload set for witnesses. `PerformCppOverloadResolution` now
requires callers to produce the `CppOverloadSet` to address this
problem.
Treat the initial sequence ofarguments in a call to a C++ function up to
and including the last argument that is a type or template as being the
explicit template arguments for the call, rather than rejecting them
because they can't be converted to the parameter types.
Implements the current direction on leads issue #6768, except that no
syntax for explicitly annotating an argument as being a template
argument is provided.
---------
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Mainly because "sorting_diagnostic_consumer" is legacy, since
`SortingDiagnosticConsumer` became `SortingConsumer`. Also better
reflecting contents of these files.
Where I'm not renaming, I'm less positive about dropping "diagnostics"
from "file_diagnostics" and "null_diagnostics" (which contain both a
consumer and emitter, and "null.h" seems like poor naming), so not doing
that here. Also "diagnostic.h" contains `struct Diagnostic`, so is a
decent fit.
Assisted-by: Google Antigravity with Gemini 3 Flash
The general strategy here is to import the constructor with a signature
that directly matches the argument. The intent is that the imported
function will eventually be usable directly as the `ImplicitAs.Convert`
function in a generated `impl`.
For initialization from a tuple, for example `(1, 2)`, we import the
selected constructor with a signature that takes a tuple pattern:
`fn Class.Class((a: i32, b: i32)) -> Class;`
In order to support that, this PR also adds support in general for tuple
patterns in function signatures. It turns out the implementation was
already very close to allowing this.
Assisted-by: Gemini 3 Pro via Antigravity
When performing impl lookup for `Core.Copy` for a C++ class type, look
for a copy constructor. If we find one, synthesize an impl witness that
calls the constructor.
This adds initial support for impl lookup to delegate to the C++ interop
logic for queries involving C++ types. For now, we don't implement the
rules from #6166 that compare a synthesized type structure for the C++
impl against the best Carbon type structure, but the framework for
building that support is established here.
Currently there is no caching of the lookup here, and we build unique
`ImplWitnessTable`s for each lookup, which leads to each impl lookup
producing a distinct facet value. This results in some errors in generic
contexts; this will be addressed in follow-up changes. This PR aims only
to support the non-generic case.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Don't attempt to defer overload resolution by creating a
`CppOverloadSet`; this was incorrect as we weren't saving the complete
clang::OverloadCandidateSet, resulting in template candidates not being
found. Moreover, saving the overload candidate set would be expensive,
as the representation is surprisingly large, and is unnecessary since
we're about to build a call.
In passing, improve the diagnostics for overload resolution failure to
use Clang's operator overload resolution messages rather than its call
overload resolution messages.
This fixes calls to templated operator overloads, which is the final
piece needed for us to successfully compile an iostream-based "Hello
world" program.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This allows to find the spaceship `operator<=>` when a comparison
operator is not available, and `operator==` when `operator!=` is not
available.
Support added to both lookup and overload resolution, by adding
`OperatorRewriteInfo` and propagating it in `CppOverloadSet`.
In case overload resolution chooses to use an operator which requires
rewriting, we emit a `TODO` since rewriting is not yet supported.
Part of #6170.
Instead of calling `PerformCppOverloadResolution()` and use the complex
return value to call `PerformCallToFunction()`, we call
`PerformCallToCppFunction()` which will call both
`PerformCppOverloadResolution()` and `PerformCallToFunction()`.
Followup of #6112.
Part of #5995.
This turns out to be quite important, as several important standard
library types (such as `std::string`) have mixed-access overload sets
for their constructors as an implementation detail. The overall approach
here is:
- Use the most permissive access to determine the access of the overload
set itself. This affects whether name lookup finds the member name at
all.
- After overload resolution, re-check the access of the selected member,
if it's protected or private.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
The general strategy here is to force use of a thunk when we want to use
default arguments, and have Clang generate uses of the default arguments
on its side of the thunk.
To support this, change the key type used in `clang_decls` from being
just a `Decl*` to being a pair of `Decl*` and number of parameters in
the case of function decls. Import distinct `SemIR::Function`s for each
number of parameters that's used, and corresponding distinct thunks.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
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.