Use `full.carbon` min-prelude for any tests using the full prelude. A
few tests were using it unnecessarily and are changed to a more minimal
one in the process.
Any test which does not include some min-prelude will now fail with an
error.
For example, this would allow using `std::string::size`, which is
templated because it's a member of the class template
`std::basic_string`, but isn't itself a function template.
Create a `self` parameter when importing a C++ non-static member
function. That seems to be all we need to get basic method calls
working! For now, `const` methods have by-value self parameters, and
non-`const` methods get an `addr self: Self*` parameter.
Some specific features:
* Use `SpecificFunction` for vtable entries for generic classes.
* Create specific constants for vtable entries in classes derived from
generic classes to reference the appropriate specific of the function
in the context of such a derived class.
* Create specific constants for vtable_ptrs for uses of specific generic
classes.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This changes `Destroy` to use an interface for its implementation.
Note that this change includes a lot of test updates. Even when
`Destroy` is a no-op, it still causes code generation as part of
determining that.
Originally I was trying to use ranges to cut down the scope of this, and
to a degree I think they have. But a flipside here is that cases where
no destructors should be generated -- particularly globals -- would be
needed to completely remove destructor calls. Even for ranges, the range
can often include the destructor placement. So I've shifted
frame-of-thought a little: accept a bunch of destructor churn, because
destructors are needed and will be prevalent. The verbosity is a feature
of the design to make desugaring apparent in IR, not a bug.
The goal was/is to reduce the overhead for vtables in generics - the
previous representation/prior to this patch caused a new vtable to be
created in every specific which isn't generally what we want for Carbon
generics (the whole specific/generic thing is meant to avoid creating
specific versions for things that can be a generic form parameterized by
a specific instead of manifest as a unique entity per specific)
So this moves vtables to a top level object (like functions, classes,
etc). Each dynamic class will have a vtable in this list.
Classes have a `vtable_ptr` instruction in them that points to the
vtable.
The actual generic support hasn't been implemented in this patch, as
I've been struggling with just getting this part of the migration going
& wanted to get it flushed out before adding the additional
complications.
It's possible more laziness when doing cross-file importing would be
suitable - for instance if we only need to reference the vtable from
another file, but don't need to know its individual contents, it may be
beneficial for the functions in the vtable to be import_refs (or to add
another layer of indirection - so it can be a single import_ref
all-or-nothing for the functions in the vtable).
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Suggested by zygoloid while looking at #5678
```
CHECK failure at toolchain/lower/context.cpp:62: !llvm::verifyModule(*llvm_module_, &errs): Verifier errors: Instruction does not dominate all uses!
%.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
%tuple.elem0.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 0, !dbg !13
Instruction does not dominate all uses!
%.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
%tuple.elem1.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 1, !dbg !13
Instruction does not dominate all uses!
%.loc17_46.1.temp = alloca { i1, i32, i32 }, align 8, !dbg !13
%tuple.elem2.loc17_46.2.tuple.elem = getelementptr inbounds nuw { i1, i32, i32 }, ptr %.loc17_46.1.temp, i32 0, i32 2, !dbg !13
```
Adds a `--llvm-verifier` flag to be able to turn this off easily,
particularly for debugging the LLVM IR.
The call workaround is due to a verifier requirement `inlinable function
call in a function with debug info must have a !dbg location`. It
specifically comes up for the `++x` case, with `%1 = call i32
@"_CConvert.8b3d5d6a6c17be04:ImplicitAs.Core.b88d1103f417c6d4"(i32
%other)`. I think #5397 is in the direction of a fix for that, but #5397
was set aside because it puts the debug info in too many places.
Instead, address this by adding a stub location for calls that don't
have a good location. I'm deliberately putting this next to the TODO so
that it's easier to understand the association.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Add check support for `for` loops following #1885. This also adds a
basic `Optional` type to the prelude, as that's necessary to support the
new `Iterate` interface.
Depends on #5688, #5697. Those PRs aren't stacked here, but this change
will crash until they land.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Previously we created allocas for temporaries at whatever point in the
output LLVM function we'd reached. This would result in these being
dynamic allocas (performing a dynamic stack allocation), which is
inefficent and can lead to a stack overflow if it happens in a loop.
Switch to putting the allocas in the entry block instead, and instead
generate a lifetime start marker when we reach the point where the
temporary is introduced. We already did this for local variables; this
is just factoring out and reusing that code.
- Update all the llvm::Function pointers after function replacement.
Some were previously left in an inconsistent state.
- Only do function replacement once, after converging on the canonical
specific to use.
The `full.carbon` prelude just sets a flag indicating an explicit intent
to include the full prelude. Once all tests include some prelude file,
an error can be enabled (currently it's commented out) that requires an
`INCLUDE-FILE` of some min-prelude to be present in all `check/` and
`lower/` file tests.
Update remaining parts of lowering, in particular the lowering of
aggregates, to handle lowering within a specific from a different file
than its generic. Look up information about a type in the current
specific and in its file rather than performing lookups for the type in
the generic and its file.
Remove or fix all remaining uses of raw `TypeId` in
lower/function_context and lower/handle*, so that the type from the
specific is consistently always used when lowering a specific function.
---------
Co-authored-by: Geoff Romer <gromer@google.com>
This drops file_test runtime from about 3s to 2.5s on my machine, which
is now ~30% faster than before #5653 slowed things down by adding a lot
of stuff to the production prelude.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
The none.carbon min-prelude is not just an empty prelude, it also
prevents any prelude from being imported at all. So no import machinery
runs before the test, only the `package` statement from the prelude
would run.
Use the none.carbon min-prelude in a few tests that were specifying
`--no-prelude-import` to give it a trial run.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Adds min-preludes more tests which were seen as slow and their
surrounding neighbours. This drops the file_test runtime on my machine
from about 6s to about 4.5s.
For a few files that are clearly only testing diagnostics, we drop the
if-present semir ranges and the associated TODO.
Adds min-preludes to a few more slowest tests, and adds them to most of
the lowering tests, with a few exceptions that make use of operators.
This take the runtime of file_test down from about 8s to about 7s on my
machine.
We add support for Negate on uints in the min-preludes.
This drops the wall clock time for running file_test from 10s to 8s on
my machine. There's many more tests to convert, as each one takes the
test from ~1s to ~100ms. Compiling the full prelude is a bit slow now
since #5653, and before that file_test was taking about 3.5s.
We introduce a few more flavours of min_prelude to support more tests.
Remove use of i32/bool when a builtin type or test-define class type can
work. Make `Sub` user-defines in a test that is testing builtin
functions and not trying to test the prelude, in the same way that it
defines its own Negate. Reduce use of the + operator when it isn't
contributing to the test's coverage, since the + operator needs the full
prelude. Remove use of Core.Print when it's not required for the test.
Move `deduce_nested_facet_value.carbon` to its own file since it uses
TypeAnd, and the rest of deduce.carbon does not, but uses i32. This
means they can each use a different min-prelude.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
When the binding pattern appears within a `var` pattern, convert to a
reference. Otherwise, convert to a value.
This gets the advent of code examples to produce the right answers again
:)
---------
Co-authored-by: Geoff Romer <gromer@google.com>
Replace the binary `Operation` interfaces with the `OperationWith(T:!
type)` interfaces described in the design, and add a `Result` associated
type for both unary and binary operations. Update the `impl`s in the
prelude for integer types to use the new form, including supporting
implicit conversion of either operand.
I've tried to split this PR up into commits focused on distinct changes
for review convenience. It may be simplest to review it one commit at a
time.
This preserves the constant values of the arguments to the thunk, which
is important if the thunk requires conversion of an `IntLiteral` to some
other type. This should become unnecessary once we have form support,
but avoiding the indirection through a thunk function seems valuable
even once that support is in place.
To support this, track whether a function is a thunk on the Function
object, and if so, what the callee of the thunk is. This information is
also included in formatted SemIR when dumping the thunk.
Build a `SpecificConstant` (if needed) and `NameRef` instruction when
referencing the thunk target from a thunk. The former is necessary if
the impl is generic in order to call the right version of the thunk
target. This previously caused a crash in lowering.
Also add some more check testing for the interaction of thunks and
generics. This testing uncovered an unrelated bug with thunks for
generic interface functions for which I've added a TODO.
People seemed receptive [on
#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1379196447827689553),
so proceeding.
For the two name conflicts, I've set it up so that there's a
"foo.carbon" and "foo_with_prelude.carbon", to indicate that the
no-prelude approach is preferred (with a shorter name).
Note min_prelude will require a little more work/thought, I want to
avoid adding `--custom-core` etc.
Adds minimal defaults for codegen so that those tests don't need to
specify the full command line.
Moves driver/testdata/compile to check/testdata/basics/raw_sem_ir, which
seems like it better reflects the focus. Removes the textual IR test
because we have plenty of those now.
Moves a multiline token diagnostic test to parse because (a) diagnostics
doesn't have other tests and (b) this is really testing the way that
parse structures the location.
Drops `--include-diagnostic-kind` from some driver tests that aren't
testing a diagnostic, so the flag felt a bit like noise (even before
this change, there are a few tests that don't specify it because they're
not intended to test an emitted diagnostic, just high-level diagnostic
behaviors).
Adds some comments to reflect my understanding of why a test exists,
when I was pausing to think about it.
Modifies the stdin test to do more dumps; which happens to expose we
currently misbehave.
When lowering a specific function whose generic was defined in a
different file, switch to that other file's `FileContext` and lower the
generic there. Also pass the `FileContext` corresponding to the specific
into the `FunctionContext`, and use that `FileContext` for resolving
requests for constants and types from the specific.
The same specific function will (eventually) be emitted as part of
lowering multiple different source files, so don't give them unique
external linkage.
Previously we walked the global variables defined by the current file
and emitted an LLVM global variable definition for each of them. Now
instead, when emitting a constant reference to a global variable, we
emit an LLVM global variable declaration, and we then subsequently walk
the global variables defined by the current file and convert each of
them from a declaration to a definition.
In order to make import of names of global variables work, add support
for import of `var`, as well as support for importing `tuple_access` and
`tuple_pattern` in the case where the `var` has a tuple pattern in its
declaration. Also treat `bind_name`s that are reference bindings to
`var`s as having the same constant reference value as their `var` so
that we can properly import and lower them.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Entities, such as `Function`s may be created during phase 2 and need to
read the `Class`'s `scope_id` at that point, so it must be made
available earlier (in phase 2, rather than 3) when importing.
(thanks @zygoloid for explaining this all to me)
I'll look into other instances of this 3 phase lookup to see if they
have
similar bugs/if I can create test cases to tickle them as follow-ups.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
In LLVM, CLANG_DEFAULT_PIE_ON_LINUX is
[configurable](https://github.com/llvm/llvm-project/blob/main/clang/test/CMakeLists.txt#L8),
so change lowering to specify a value.
Also, adjust how the target is set so that function_decl.carbon isn't
trying to overload every flag, and so that the target isn't forgotten
elsewhere.
This is fixing issues introduced by #5427; note #5520 is also a related
fix.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This requires:
* Making `FunctionDecl` mutable since generating code
(`HandleTopLevelDecl()`) requires a mutable declaration and since we
manually add `used` attribute to force code generation.
* Passing the file system to `Lower` since it's needed by Clang code
generation.
* Creating an internal Clang LLVM module and link it against the Carbon
LLVM module.
Demo:
```c++
// hello_world.h
extern int puts;
inline void hello_world() {
((int (*)(const char*))&puts)("hello world");
}
```
```carbon
// main.carbon
library "Main";
import Cpp library "hello_world.h";
fn Run() -> i32 {
Cpp.hello_world();
return 0;
}
```
```shell
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link main.o --output=demo
$ ./demo
hello world
```
Based on https://github.com/carbon-language/carbon-lang/pull/5406.
Part of #5405.
- Track the `VarPattern` instruction on the `VarStorage` instruction so
that it's available for name mangling.
- Mangle global variables based on the first binding name within their
pattern.
- Give global variables external rather than internal linkage, except if
they have no bindings whatsoever in their pattern.
- To support lowering references to bindings nested within a global var,
such as for `var (x: i32, b: i32)`, add some basic initial support for
reference constant expressions. Treat a global `var` as a reference
constant, and treat an aggregate access into a reference constant as a
reference constant.
If a function contains instructions whose locations are in another file,
skip providing debug locations for those instructions rather than
CHECK-failing.
This happens when emitting a thunk where the signature is declared in
one file and the call target is in another file: some parts of the thunk
use the original signature as their locations, whereas other parts of it
use the location of the call target.
`IRBuilderBase::SetInsertPoint` weirdly replaces our debug location with
one copied from the new insertion point, so undo its damage after
calling it.
Also included: a couple of cleanups I made while tracking this down.
These will need to be emitted lazily, as we do for functions - this
addresses the crash/removes the impossible (because we don't have a
specific) non-lazy path.
We eliminate the `FacetAccessWitness` instruction, which would sometimes
immediately evaluate to a concrete `ImplWitness`, and sometimes remain
symbolic. This instruction is now replaced by `LookupImplWitness` in all
cases. To support the same use cases, when it is evaluated,
`LookupImplWitness` will look in the self value if it's a facet value,
and attempt to return a concrete `ImplWitness` from it before looking
for an `impl` statement.
The `LookupImplWitness` instruction's value is now canonical, even when
it evaluates to a symbolic `LookupImplWitness` instruction, by
canonicalizing the self value of the lookup query. This canonicalization
unwraps `FacetAccessType` and `FacetValue` instructions to get to an
underlying canonical facet value. However we must preserve and use the
non-canonical query while evaluating the instruction in order to look
for a concrete `ImplWitness` if the query self value was a concrete
`FacetValue`. The canonicalization ensures that symbolic witnesses
obtained from a facet value are compatible with those obtained from an
impl statement, as long as the self types originate from the same
canonical facet value though they may have been narrowed.
Member access now unconditionally does a `LookupImplWitness()`
operation, instead of only sometimes doing the lookup for a final impl
declaration.
`EvalImplLookupResult` is marked `[[nodiscard]]` so that we don't
construct it and forget to return it. This was a mistake made at one
point during the creation of this PR. And the `has_concrete_value()`
method no longer has a precondition that `has_value()` is true, since we
want to look for a concrete result only in the new use of
`EvalImplLookupResult` returned from lookup into the query self facet
value.
The TODO from `FacetAccessWitness` evaluation is addressed by ensuring
the index of the witness in the `FacetValue` comes from the required
interfaces of the `FacetValue`'s type, and that the type (a `FacetType`)
is the same facet type used in the query to construct the `FacetValue`'s
witness block. This is made possible by eliminating the
`FacetAccessWitness` indirection. The lookup into a `FacetValue` happens
while evaluating `LookupImplWitness` and it does so directly on the self
value. This gives a consistent view of the witness set and the facet
type, as they both come from the same instruction.
All of this with 400 less lines of code. :)
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Provide builtins for compound assignments instead of defining them in
the prelude as a use of a binary operator and an assignment. This allows
us to lower compound assignment directly to LLVM operations instead of
producing a function call. In the short term this also allows us to
define a type-generic compound assignment in the prelude.
Adds a `virtual_index` to `SemIR::Function` used to determine which
vtable slot
to use when calling the given function.
Then use that to lower the function call to use the vtable and
specifically the
relative vtable ABI to match the vtable entries.