Use it to dump the AST that includes a generated C++ thunk.
Based on #5917.
Also added printing of the full actual text when check fails to make
debugging easier.
Changed line replacement to allow removing complete lines.
Part of #5514.
I was thinking about this for destruction, which I may not be able to
use it for, but still think this may be a good change to keep features
consistent.
toolchain/check/testdata/builtins/char/basics.carbon and
toolchain/lower/testdata/builtins/char.carbon are probably the most
interesting tests here. The parse tests is required because this adds a
new node kind, and we need coverage of it; but the attached info is
minor. There's a fair amount of test churn here because I'm adding the
Core.Char and Core.CharLiteral types as new singletons.
My intent here is that `CharId` is always a unicode code point, even
when the type is a `Char` and thus must be a single UTF-8 code unit
(single byte). This mainly means the stored value of a `CharValue` can
be printed internally without knowing the type.
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Similar to 26ec78ec00 - vtable entries
can't be unattached symbolic constants, because if they are they can't
be `GetValueInSpecific`d because they lack the context for their
generic/specific.
Importing mostly wants to make/import things as unattached constants -
but `ImportRef` supports attached constants, so use those - but we don't
need the laziness, so use `LoadedImportRef`.
When the C++ function has a parameter that is not a pointer and not a
signed integer of 32 or 64 bits, generate a thunk.
Terminology:
* Callee function: The C++ function we actually want to call.
* Thunk function: The C++ function we generated that calls the callee
function.
* A simple ABI type, for now, is one of:
* A pointer
* signed integer with 32 bits
* signed integer with 64 bits
The thunk function is marked `always_inline` and uses the `asm`
attribute to set its mangled to the callee function mangled name
suffixed with `".carbon_thunk"`.
When importing a C++ function, we decide whether calling it requires a
thunk and if so we generate it and import it as well, which is currently
a recursive call.
When calling the thunk function, we initialize a temporary storage for
each non simple ABI parameter type and take its address. This can be
optimized when the variable is already in storage.
Not supported yet:
* Functions with non void return values.
* Member methods.
Moved unsigned int param test from `arithmetic_types_direct.carbon` to
`arithmetic_types_bridged.carbon`, since only signed integers aren't
bridged using a thunk.
C++ Interop Demo:
```c++
// hello_world.h
struct S {
S() {}
S(const S&) { x = 1; }
int x;
};
void hello_world(S s);
```
```c++
// hello_world.cpp
#include "hello_world.h"
#include <cstdio>
void hello_world2(S s) { printf("hello_world2: %d\n", s.x); }
void hello_world(S s) {
printf("hello_world: %d\n", s.x);
hello_world2(s);
}
```
```carbon
// main.carbon
library "Main";
import Cpp library "hello_world.h";
fn Run() -> i32 {
var s : Cpp.S;
Cpp.hello_world(s);
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
hello_world: 1
hello_world2: 1
```
Before this change (no thunk - copy constructor not called when calling
`hello_world()`):
```shell
$ ./demo
hello_world: -1219172304
hello_world2: 1
```
This adds support for importing C++ code directly from source rather
than via a `#include`.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
In preparation for `FloatValue` being used more generally, and not only
for literals.
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This is from a quick discussion with zygoloid. There's a mix of uses,
we're both comfortable with a "minimum syntax" decision here to use ADL.
Note this doesn't touch llvm::cast uses in yaml_test_helpers, but ADL
doesn't work there (because the objects are in a `llvm::yaml`
namespace). This gets to another choice made here: if we specify a
namespace, prefer `llvm::` because it's shorter. `clang` has a using of
them, but it's probably better to point at the canonical version if
we're being explicit about it.
Although this focused on `Destroy` support, some choices here around
`implicit_type_impls` are because copy/move will likely follow a similar
approach. I'm trying not to predict too much about how we'll structure
those, but I'm putting `Destroy` impl logic in a file that could perhaps
be shared with those. They'd likely be interested in similar things,
e.g. traversing members of types (particularly class, struct literal,
tuple literal).
At present this sets the destroy function as `no_op` which is consistent
with current logic, but has a TODO to correctly define.
Constant importing for functions changes slightly due to some issues I
was having with `GetFunctionType`. zygoloid suggested this approach to
avoid `EvalInst` logic.
Adds a flag for controlling whether to generating these impls. While
this does generation for `class`, as noted above this'll also need to be
done for tuples and struct literals, which would leave the `none.carbon`
min_prelude unable to use any types. Note if destruction *would* occur,
it'll still look up `Core.Destroy` for that and fail, but that's already
true of any test using `none.carbon`. I'm trying to use the flag to see
if we can keep `none.carbon` working mostly-consistently.
I'd tried separating out the flag to #5852, but that got a lot of
pushback over whether the behavior was appropriate. I'm hoping that the
interactions here make it clearer why the particular approach -- the
goal is not to enable advanced testing, or create some new end-user
behavior that we really support, it's just to keep no-prelude tests
functional. The main question raised there was why not just keep
generating `impl T as Core.Destroy` if `fn destroy` is present -- but I
think here it should be apparent that would require additional
complexity, as the generation of `impl T as Core.Destroy` is not
currently conditioned based on the implementation of `fn destroy`. I'd
rather add complexity to this flag only if it's enabling interesting
test functionality.
---------
Co-authored-by: Geoff Romer <gromer@google.com>
Add documentation describing the problem and algorithm for coalescing
the LLVM functions generated from Carbon generic functions into fewer
LLVM functions, where the LLVM types permit it.
Adapts `StringLiteral` to lex characters. Adds a `CharLiteral` token,
which contains a `CharLiteralValue` which is a straight unicode code
point (suggested by zygoloid).
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
In order to verify rewrite constraints at the end of
`LookupImplWitness()` we need to replace references to associated
constants in the query facet type with values that come from the query's
self. To do this, we find any `ImplWitnessAccess` that is a reference to
`.Self` and replace its witness with the witness found through the impl
lookup process, if the interfaces match. This allows the
`ImplWitnessAccess` to resolve to a concrete value if that witness was
concrete. Then we just need to compare that for each rewrite constraint
the lhs and rhs are the same constant value. If they differ, the self
provided a different value for one side (either through its own facet
value constraints or through an associated impl), or the self did not
provide a value at all.
For now, only .Self references in the top-level facet type are
rewritten. Nested facet types are not, even if they contain a .Self
reference up to the top level facet value. This will be addressed by
adding numbering to the EntityName of of .Self in a BindSymbolicName.
See the third model in
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0
for the plan. For now, there is a TODO addressing this.
- A parameter binding can be marked `ref` instead of `var` or the
default. It will bind to reference argument expressions in the caller
and produces a reference expression in the callee.
- Unlike pointers, a `ref` binding can't be rebound to a different
object.
- This replaces `addr`, and is not restricted to the `self` parameter.
- A `ref` binding, like a value binding, can't be used in fields of
classes or structs.
- When calling functions, arguments to non-`self` `ref` parameters are
also marked with `ref`.
- The return of a function can optionally be marked `ref`, `val`, or
`var`. These control the category of the call expression invoking the
function, and how the return expression is returned.
- These may be mixed for functions returning tuple or struct forms.
- The address of a `ref` binding is `nocapture` and `noalias`.
- We mark parameters of a function that may be referenced by the return
value with `bound`.
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Iterate over arrays by producing their elements in the obvious way. We
use `i32` as the cursor type because that's the type that check converts
array indexes to. This may need revisiting if we support arrays with
more than 2Bi elements.
Also includes a fix for an import crash bug that's triggered by this
change, borrowed from #5873.
Instead of taking the complete text of the Clang diagnostic and using it
as the message portion of a Carbon diagnostic, generate the individual
pieces separately and pass them into the Carbon diagnostic
infrastructure.
* Clang's context lines are generated by running a custom "diagnostic
renderer" and tracking which lines it wants to print as context for a
given source location. When mapping from a C++ source location back to a
Carbon location, the Carbon `Loc` structure is now fully populated,
including filling in the context line and the column number.
* Clang's snippet is generated by running a custom diagnostic renderer
that is a cut-down version of the full text diagnostic renderer that
only prints a snippet. This is then attached to the Carbon diagnostic
manually as an override for the snippet we'd usually create.
We no longer repeat the file location twice on each diagnostic, and no
longer produce a bogus "in import" line for all locations coming from
clang that point arbitrarily to the first C++ import in the Carbon file.
The `[diagnostic kind]` marker is now displayed at the end of the
diagnostic message, not on a line of its own after the snippet.
When attempting to import a definition of a class with virtual bases,
diagnose the point of use instead of the point of definition of the
class.
---------
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
When importing a class definition, ask Clang to complete it first. This
causes class template specializations to get instantiated as needed when
the type-checking of Carbon requires a C++ class to be complete. It also
allows Clang to implement things like modules-aware definition
visibility checking.
Don't reject importing a class with a virtual base if it's never
required to be complete. Instead, defer diagnosing until the definition
is required.
This also removes the recursion from `MapType`, as mapping a class type
no longer maps its definition.
In order to get diagnostics from instantiation failures, fix a bug that
caused any Clang diagnostics produced after the initial building of the
`ASTUnit` to get discarded. This exposed some duplicate diagnostic
issues in `ImportNameFromCpp` which are fixed here too.
Previously we would drop these diagnostics; now periodically flush them
to Carbon's diagnostics emitter. We flush them at the end of checking,
and also immediately before changing the set of diagnostic annotation
scopes, so that Clang diagnostics get properly annotated.
This exposes some double diagnostics being produced in situations where
Clang's name lookup logic would produce a diagnostic and we also
produced one. For access control issues, use the Carbon diagnostic, in
order to properly handle protected access. For ambiguity issues, use the
Clang diagnostic that produces helpful notes.
Also fix rendering of note diagnostics produced by Clang, by attaching
them to the prior error / warning diagnostic.
---------
Co-authored-by: Boaz Brickner <brickner@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Per discussion at
https://github.com/carbon-language/carbon-lang/pull/5875#issuecomment-3137288037,
a different approach to the same solution.
A key difference is that whereas #5875 would build a `TypeStructure`
containing `ConcreteType{error}`, this instead just returns nothing.
This means impls with errors can't be compared in the same way, though
I'm not sure how much impact that'll really have (I've added a test here
to show a case where it seemed interesting to see what effect it'd have,
and it seems to have none).
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Also document why these are expected on `CARBON_KIND`. In
`kind_switch_test.cpp`, drop the `str` variable.
My recollection of the original discussion of `CARBON_KIND` is that it
should always have braces due to the risk of confusion for statement
interpretation, similar to a typical `if`/`else` but more subtle due to
the macro.
For example:
```
case CARBON_KIND(int n):
str << "int = " << n;
return str.TakeStr();
```
is equivalent to:
```
case CARBON_KIND(int n): {
str << "int = " << n;
}
return str.TakeStr();
```
This happens to work in context because `str` isn't scoped, but a
trivial refactoring to move `RawStringOstream str;` the first statement
of the `case` would probably have non-obvious results. For example:
```
case CARBON_KIND(int n):
RawStringOstream str; // Valid name shadowing, destructed without use.
str << "int = " << n; // Name lookup error on `n`.
return str.TakeStr();
```
Dropping this in with basic.carbon as an aspirational way to encourage
more tests there.
This currently crashes because `CollectCandidateImplsForQuery` tries
building a type structure which cannot contain `ErrorInst`.
A rewrite constraint like `.X = .Y.Z and .Y = .Self and .Z = ()` has a
nested `ImplWitnessAccess` `.Y.Z` (technically `(.Self.Y).Z`). The inner
access `.Self.Y` needs to be resolved (in this case to `.Self`) before
the outer `???.Z` can be resolved as `.Self.Z` which is `()`.
Dedupe rewrite constraints by consuming them by their LHS from the map
of rewrite values, and dropping any LHS that we see more than once. This
essentially uses the map to track which LHS we have seen in place of
sorting the rewrite constraints by the LHS.
Make Subst perform "recursion" on the RHS instructions as they are
replaced, effectively doing a depth-first traversal through the rewrite
constraints doing replacements. This allows us to fully compute
individual associated constants in the minimal amount of work, and cache
the results so they can be reused cheaply in cases where the rewrite
constraints generate an exponential number of references to associated
constants.
Fixes https://github.com/carbon-language/carbon-lang/issues/5672
In open discussion[1] we decided that "identical" rewrites would mean
that for a given LHS value, all RHS have the same value (after
evaluation), rather than requiring the RHS to all have the same
syntactic value. This means the following is valid, since the value of
`.Y` is known to be `()` while resolving the rewrite constraints of `T`.
So both rewrites of `.X` are resolved to `.X = ()`:
```
fn Identical(T:! I where .X = () and .X = .Y and .Y = ()) {}
```
The implementation of this clarification, along with test cases encoding
it, is done in https://github.com/carbon-language/carbon-lang/pull/5686.
Clarify this in the language design documents, and improve some other
clarity while we're there:
- The prose talks about a facet `T`, but the examples were using `A` as
its name. Change the facet to be `T`. This means changing the `.T`
associated constant (and `.U` and `.V`) to be `.X` (and `.Y` and `.Z`).
While doing this, use `I` for the interface name instead of `C`, which
we use more commonly for a class type name.
- Correct the comments in the cycle example that claim we find `.Y then
.Y* then .Y**`. In this example `.Y = .Z* and .Z = .Y*` which adds _two_
levels of pointers when evaluating `.Y`: `.Y => .Z* => (.Y*)* => .Y**`
[1]
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.qti4vn50zwy
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Otherwise these end up as unattached constants (see the baseline test
changes) and can't be resolved by `GetConstantValueInSpecific` in
lowering or in further derived vtables.
If the class is non-generic, then it's fine for the vtable entry for
some function inherited from a generic base is represented as an
unattached constant, since the specific in that specific_function is
already fully resolved.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>