Commit Graph
4188 Commits
Author SHA1 Message Date
David Blaikie c2a0ee98c5 Remove outdated comment about generic vtable inst naming (#5814)
Since vtables are generic over the class's specific, they don't have
their own generic/specific ids and so there's no generic insts that need
naming.
2025-07-17 18:32:36 +00:00
Jon Ross-Perkins a842162424 Make NameScope move constructor noexcept (#5812) 2025-07-17 18:29:49 +00:00
David BlaikieandJon Ross-Perkins 3bf98e9bc2 Implement correctly overriding dependent virtual functions (#5804)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-07-17 16:14:50 +00:00
Richard Smith 9f67fa4b0f Allow interop with templated but non-template functions. (#5809)
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.
2025-07-17 15:04:19 +00:00
Boaz Brickner dd76c9bd13 Merge i16 and i32 param and return test files (#5760)
This is instead of having one test file that has different return types
and two test files for `i16` and `i32` param tests, which doesn't seem
consistent.
First commit does file renames for easier review.

Part of #5063.
v0.0.0-0.nightly.2025.07.17
2025-07-16 12:53:05 +00:00
Boaz Brickner 4f8d0649d5 When importing a looked up name, reuse previously imported declaration instead of importing the same declaration again (#5789)
Added test coverage to demonstrate name lookup following import of a
type of a function parameter.
SemIR changes show that the same decl isn't imported multiple times.

Part of #5533.
2025-07-16 11:21:49 +00:00
Richard Smith f204bdf094 Basic support for calling class methods imported from C++. (#5796)
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.
v0.0.0-0.nightly.2025.07.16
2025-07-15 16:05:01 +00:00
David BlaikieandDana Jansens 83b2924432 Support importing vtables for generic classes (#5802)
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-07-15 14:06:51 +00:00
David Blaikie e6214b946a Remove out of date comment (#5805)
Lazy vtable_ptrs were implemented in
967a98f845
2025-07-15 14:03:41 +00:00
Jon Ross-Perkins be487bbeda Use declaration locations for formatting entities (#5799)
This is just trying to address the location TODO.
v0.0.0-0.nightly.2025.07.15
2025-07-14 23:27:03 +00:00
David Blaikie 16ab0b313a Remove out-of-date comment now that generic vtables are implemented (#5803) 2025-07-14 20:56:00 +00:00
Richard Smith a6acba9eab Support for importing const-qualified types from C++. (#5794)
Incidentally also supports import of pointers-to-pointers.

Imported const-qualified types aren't especially useful just yet,
because on the Carbon side we don't yet permit conversions from
non-const to const types, so most of the tests still fail, but for
different reasons now.
v0.0.0-0.nightly.2025.07.14 v0.0.0-0.nightly.2025.07.13
2025-07-12 02:22:24 +00:00
David BlaikieandRichard Smith 27be0973e7 Vtable support for generics (#5793)
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>
v0.0.0-0.nightly.2025.07.12
2025-07-11 22:29:10 +00:00
Jon Ross-Perkins 8cd1307711 Include the interface name in impl names (#5798)
i.e., `impl` -> `<interface>.impl`
2025-07-11 19:52:53 +00:00
Chandler Carruth 1a97021875 Enhance benchmark runner args and defaults (#5797)
There are some very useful default arguments, so teach the runner script
to directly provide them. They can be easily overridden if needed. As
part of this, change the default run count to 10 which much more often
produces statistically significant error bars and results.

Also, tweak the processing of the results to provide a stable order
based on the source order, even when randomized interleaving is enabled.
The randomized interleaving improves the statistical strength of the
benchmarks significantly, but displaying the results in the source order
is much more understandable. This should give roughly the best of both
worlds.
2025-07-11 16:54:51 +00:00
Jon Ross-Perkins a7dbd4ef62 Improve handling of carbon-busybox symlinks in bazel (#5795)
Trying to make the handling of `bazel build //toolchain; bazel clean;
bazel build //toolchain; ./bazel-bin/toolchain/carbon` work more
consistently.
v0.0.0-0.nightly.2025.07.11
2025-07-10 23:51:44 +00:00
Jon Ross-Perkins 2bb8e98849 Change SemIR formed for 'as' errors (#5792)
Direct use of an error means we can delay looking at the actual type,
and also use the `self_id` of the stored `ImplInfo` directly.

Note, I'm assuming we should be okay with this not always being a
`NameRef`. In error cases though, it seems like we shouldn't mind it
being an error instead of a name reference to an error.
2025-07-10 21:56:03 +00:00
Jon Ross-Perkins e855f38b8c Tag destruction as desugaring (#5790)
In `BuildUnaryOperator`, `GetOperatorOpFunction` is treated as
desugaring, but `PerformCompoundMemberAccess` and `PerformCall` are not.
This treats all of destruction as desugaring.

This leads to some instructions being elided, because of `GetOrAddInst`
behaviors:

> // If the instruction has a desugared location and a constant value,
returns
> // the constant value's instruction ID. Otherwise, same as AddInst.

This changes instructions that previously had a non-desugared location
to instead have a desugared location, so if they also have a constant
value then the constant value can be used directly.
2025-07-10 21:21:19 +00:00
Richard Smith 26e23eac10 Support import of typedefs. (#5787)
Unify code paths for importing classes by name and importing them
indirectly when their type is referenced. Switch to using the general
type import machinery to import all type declarations, which allows
typedef declarations naming importable types to be used too.

Fix up handling of error cases to consistently only produce an Error
InstId after actually producing an error message, so that we can produce
exactly one diagnostic in failure cases.

Remove TODO error for unions that previously was only produced when
importing them indirectly, not when importing them by name. Import of
unions is exactly as complete / incomplete as import of other class
types, so treating them differently doesn't seem necessary.
2025-07-10 20:46:46 +00:00
Jon Ross-Perkins 6ca4e2e089 Fix a small implicit/desugared reference (#5791)
Implicit is the old term, and could be confusing now.
2025-07-10 18:27:28 +00:00
Jon Ross-Perkins 6a53947c5c Handle destruction for return statements (#5785)
This just catches uses equivalent to `return;` and `return <expr>;`.
Note it's just extending the current implicit return logic, not really
adding much unique here.

I'm still delaying break and continue because those require partial
destruction, which is more work and I want to be careful to get it
right.
2025-07-10 16:32:39 +00:00
Boaz Brickner a5ddc3e3cd Support importing C++ _Nonnull pointers as function parameters or return values (#5773)
We avoid using canonical type before knowing it's not a pointer because
we need the nullability attribute.
No support for pointers to pointers, yet.

C++ Interop Demo:

```c++
// hello_world.h

auto hello_world_param(int* _Nonnull i) -> void;
auto hello_world_return() -> int* _Nonnull;
```

```c++
// hello_world.cpp

#include "hello_world.h"
#include <cstdio>

auto hello_world_param(int* _Nonnull i) -> void {
  printf("hello_world: %d\n", *i);
}

static int x = 5;
auto hello_world_return() -> int* _Nonnull { return &x; }
```

```carbon
// main.carbon

library "Main";

import Core library "io";
import Cpp library "hello_world.h";

fn Run() -> i32 {
  var i: i32 = 10;
  Cpp.hello_world_param(&i);

  let p: i32* = Cpp.hello_world_return();
  Core.Print(*p);

  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ ./bazel-bin/toolchain/install/prefix_root/bin/carbon compile main.carbon
$ ./bazel-bin/toolchain/install/prefix_root/bin/carbon link hello_world.o main.o --output=demo
$ ./demo
hello_world: 10
5
```

Part of #5772.
2025-07-10 08:00:37 +00:00
Jon Ross-Perkins 110af3bfe4 Set an explicit size for lexical lookup's vector (#5786) v0.0.0-0.nightly.2025.07.10 2025-07-09 22:42:27 +00:00
Jon Ross-Perkins d64ec883d5 Move BlockValueStore from sem_ir to base (#5779)
The other generic `ValueStore` types are in base; this is for
consistency, to make it easier to find. I think it's only in sem_ir for
historical reasons, since it was probably the first bespoke ValueStore
variant added.
2025-07-09 16:25:23 +00:00
Richard SmithandChandler Carruth 3776e464e0 Properly set up C++ include paths and similar environment settings when parsing imported C++. (#5767)
Stop using the clang tooling library to build an ASTUnit; that library
is set up to process clang frontend arguments, assuming that something
has already built frontend arguments from the compiler arguments. It is
also too encapsulated and doesn't let us inspect and modify the compiler
invocation before it's executed.

Instead, build the AST unit directly in two phases:

* FIrst, take a list of clang driver arguments and convert them into a
list of compiler arguments, using `clang::createInvocation`. Internally,
this uses the clang driver to build a frontend invocation, including
building system-specific include paths as needed.
* Then, directly build an ASTUnit from this compiler invocation.

I've factored this so that we can split out the `createInvocation` step,
with the intention that we may want to move it out of check and into the
carbon driver with the rest of the driver-level argument handling, and
we may want to customize some of the clang options before we invoke the
clang frontend with that set of options.

In order to make the invocation reusable, it no longer depends on the
name of the carbon file importing the C++ code. In place of synthesizing
a header file name as `<foo.carbon>.generated.cpp_imports.h`, we now
insert line marker directives into the generated header so that errors
in that header cause Clang to point a diagnostic back at the Carbon
source file itself. This results in a minor improvement in the
diagnostic output: we no longer refer to a nonexistent generated file.
But the snippet still contains text that doesn't match the source code,
so it remains imperfect.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-09 03:09:43 +00:00
Jon Ross-Perkins da99b940f5 Fix clangd-tidy to avoid blocking merges while testing (#5782)
What I'm trying to fix is visible at:

- PR: https://github.com/carbon-language/carbon-lang/pull/5779
- clangd-tidy run on merge:
https://github.com/carbon-language/carbon-lang/actions/runs/16155546033/job/45597095935
- Merge attempt:
https://github.com/carbon-language/carbon-lang/pull/5779#event-18534768919

That PR deletes block_value_store, so excluding deleted files here
(`added|modified`). But also, I think this is blocking merge just
because it's set for merge_group. Or it may be because of the clang-tidy
job name overlap -- I'm just going to address both.

Also trying to remove the base commit; I think dorny/paths-filter should
actually be calculating this reasonably well, and it was holdover from
where we set the commit explicitly elsewhere. There's a warning about it
being ignored in pull_request, visible
[here](https://github.com/carbon-language/carbon-lang/actions/runs/16155814211/job/45597903684).
v0.0.0-0.nightly.2025.07.09
2025-07-09 01:11:28 +00:00
Richard Smith f987504614 Track the location of the Cpp import for use in Clang diagnostics. (#5783)
When diagnosing a problem with C++ code imported from Carbon, include
the location of the specific `import Cpp` statement that imported the
C++ code as part of the backtrace, rather than providing a location in a
generated file that doesn't exist on disk.

Also fix handling in autoupdate of check lines that contain multiple
file name and line number pairs to use the matched file name for
remapping of locations rather than the first file name in the line.
2025-07-09 00:47:21 +00:00
Jon Ross-Perkins 6db13532ca Try using clangd-tidy (#5763)
Run clangd-tidy in parallel with clang-tidy, to experimentally see
whether it works reasonably well. These may produce slightly different
results, and it's not clear that clangd-tidy will be better, so being
cautious about switching.

A real possibility here is this is slower in some cases (building
compile commands takes ~6m below), but faster in the extremely slow
cases (when clang-tidy takes >10m).

For contrast:

- clang-tidy:
https://github.com/carbon-language/carbon-lang/actions/runs/16038096026/job/45254162180?pr=5763
- clangd-tidy:
https://github.com/carbon-language/carbon-lang/actions/runs/16038096427/job/45254164217?pr=5763
2025-07-08 14:00:15 +00:00
Boaz Brickner 9d0aaa740b When adding an imported C++ name, make sure that its clang::Decl is mapped if import failed (#5769)
When mapping parameter types, we assume that if the `clang::Decl` isn't
mapped, the name wasn't added, so this fixes a bug that triggers a crash
otherwise.

Part of #5533.
2025-07-08 13:12:32 +00:00
Dana Jansens cd14dca749 Document and test that structs with different field orders are different types for impl lookup (#5778)
This encodes the decision of #5413 in our tests.
v0.0.0-0.nightly.2025.07.08
2025-07-07 20:59:11 +00:00
Boaz Brickner ff9154b978 Push a decl name scope before calling CalleePatternMatch() (#5771)
Otherwise the return values of different functions collide.

Part of #5063.
2025-07-07 15:02:47 +00:00
Boaz Brickner 3f5b04f777 Use Core.Print instead of Carbon.Print in documentation (#5770) v0.0.0-0.nightly.2025.07.07 v0.0.0-0.nightly.2025.07.06 v0.0.0-0.nightly.2025.07.05 2025-07-04 08:05:11 +00:00
Jon Ross-Perkins b3866250db Remove prebuilt_binary from file_test rules (#5765)
Since explorer was removed, this is no longer in use.
v0.0.0-0.nightly.2025.07.04
2025-07-03 15:29:39 +00:00
Boaz Brickner 12d66be1cd Delete files that were moved in #5716 but got undeleted in #5678 (#5768) 2025-07-03 10:33:25 +00:00
Richard Smith c7886f4336 Ask Clang to mangle names, don't try to do it ourselves. (#5764)
Fixes mangling for `extern "C"` functions, as well as some other
uncommon cases like multi-version functions.
v0.0.0-0.nightly.2025.07.03
2025-07-02 23:25:52 +00:00
Jon Ross-Perkins 5b0ae6e784 Remove IdT from ValueStoreTypes (#5761)
`IdT` is no longer needed because `ValueT` is always supplied.
2025-07-02 22:09:09 +00:00
Jon Ross-PerkinsandRichard Smith b4b4d33789 Change CanonicalValueStore to take ValueT and KeyT as parameters (#5759)
`SpecificInterface` seems oddly placed. It appears to be in ids.h just
because it's used by typed_insts.h, but maybe that should be factored
differently? We typically aren't having typed_insts.h depend on non-ID
types. To that end, I'm splitting it out to its own file so that at
least I'm not adding a `ValueStore` dep inside ids.h

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-07-02 20:58:02 +00:00
David Blaikie 967a98f845 Import vtable_ptr lazily (#5762)
Ensure `vtable_ptr`s(and the vtables they refer to) aren't
imported if the type is imported but the vtable isn't
needed (no initialization of a value of that type is required).
2025-07-02 19:45:02 +00:00
Dana Jansens 6c6552ce57 Consistently return runtime phase if the operands contain a runtime (#5729)
Currently if the first operand contains an error, we will return error,
even though the second operands contains a runtime, and it has a
stronger priority (the phase always goes up if possible).

Import is only allowed on instructions with compile-time values, so we
crash if we ever try to import a runtime value. Importable instructions
must diagnose unexpected runtime values and produce errors in the semir
from which they would be imported so that runtime values are never
imported by another semir.

If we had an instruction where you had an error value from the first
operand, and runtime from the second, and we imported it:
- Before https://github.com/carbon-language/carbon-lang/pull/5728 we
would crash in import, but only because we treated errors as runtime
- After https://github.com/carbon-language/carbon-lang/pull/5728 we
would import ErrorInst because we propagate errors. This is desirable
for cases with compile-time values and errors present only.
- After this PR, we would crash again, cuz you're importing a runtime
thing.

This change means that instructions containing an
`InstConstantKind::Never` instruction like`ValueParam` will consistently
evaluate to a runtime value, even if there are errors present. This is
visible in the `BindName` instructions changing in the semir, where they
became constant `ErrorInst` values previously but no longer do.
2025-07-02 19:21:41 +00:00
Jon Ross-Perkins 002756b4cc Change BlockValueStore to take ElementT as a parameter (#5758)
Also modify CopyOnWriteBlock to just pull block type information from
the return type of the function it receives, rather than taking some as
a parameter.

I chose the `RefType`/`ConstRefType` names based on other similar
`ValueStore` uses which I think are equivalent.
2025-07-02 19:21:01 +00:00
Jon Ross-Perkins a65f4b89e2 Make ValueStore require a ValueT parameter (#5757)
This is reducing ValueStore inference of types from `using`, and removes
`using ValueType = ...` from affected id types.

I'm adding a number of `using FooStore = ValueStore<FooId, Foo>` because
I think it's a little repetitive otherwise; often 4 cases where I'm
doing this: getter, const getter, member, and getter on `Context`. Note
we also have a number of `-> decltype(auto)` that were added I think
mainly to avoid repeating the type, but I'm not sure whether there'll be
agreement on replacing those and so am not changing them here.

I'm placing these aliases with the value type in general, because I
think it's probably easier to view that way. An alternative would be to
put all the types on `File`, but:

- That would be inconsistent with things like `InstStore`, which are
very `ValueStore`-adjacent and put with their value type.
- `File` would have a _lot_ of using's, and the accessors are already
noisy -- I think it would just make the file harder to skim.

Note this is the heart of what I'd brought up [on
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1388199282250613019).
This PR still leaves CanonicalValueStore and BlockValueStore as things
to also add parameters to, but I thought it best to try breaking the set
of changes apart by type. Both of those rely on ValueStore, so
ValueStore needs to change first.
2025-07-02 18:07:55 +00:00
Jon Ross-Perkins 839a7b7c96 Refactor ValueStoreChunk and ValueStoreRange into ValueStore (#5756)
ValueStoreChunk and ValueStoreRange are implemented in a way that's
closely tied to ValueStore, and the separation makes for a lot of
additional template parameter passing, which seems easy to make mistakes
on. Combine types in order to make the close association more implicit.

I also considered passing `ValueT` everywhere, as an additional template
parameter. Note I believe the simplification is important. I'll
highlight four notes that I think favor this approach:

- `ValueStore`, with the chunk type in the same file, now has more of
the closely related implementation features in the same file. I think we
probably will want any chunking to continue to be done by `ValueStore`
itself, with related types using the implementation on `ValueStore` and
never creating their own.
- Making `ValueT` a template parameter on `ValueStore` -- my next step
-- will only change a couple lines of code on this type, instead of
sweeping changes. That should make it easier to be confident of the
correctness of those changes.
- Simpler to verify correctness. For example, `ValueStoreChunk` takes a
`ValueType` parameter that it doesn't forward; other functions assume
they can use `IdT::ValueType`. With the changes, this also no longer
benefits from separating out `IdHasValueType`, which was inconsistently
applied to related types (e.g., `ValueStoreRange` didn't use it).
- Template parameters often lead to `sizeof`, where we can't rely on
type checking to catch mistakes.
- The reduction of code is significant, with 8 `template<...>` removed
(including 1 forward declaration for `ValueStoreRange`), and also the
related `requires`. Correspondingly, places specifying template
parameters also decreased.
2025-07-02 16:19:32 +00:00
Jon Ross-Perkins 864e9cb4a2 Add a ValueT to RelationalValueStore (#5755)
RelationalValueStore is only used in one spot, so starting there.
v0.0.0-0.nightly.2025.07.02
2025-07-01 20:09:00 +00:00
Ivana Ivanovska 44b2f60c90 Carbon/C++ Interop: Primitive Types proposal (#5448)
A proposal for Primitive Types mapping between Carbon and C++.

Part of #5263
2025-07-01 18:17:02 +00:00
Jon Ross-Perkins b97646a890 Split value store related types to separate files (#5754)
As I'm looking at splitting value type setting out, this is to make it a
bit easier to see what's part of each type. Note, I expect
`ValueStoreTypes` to remain because of the `StringRef` logic it does --
I'm giving that its own file.
2025-07-01 17:38:56 +00:00
Jon Ross-Perkins 57ef976802 Move dumping into the phase factory functions (#5747)
By moving dumping, we can have dumping occur before verification that
might CHECK-fail (e.g. parse tree and llvm IR verification).

I'm dropping vlogging of raw semir. It was only done when dumping, so
`-v` would print zero copies and `-v --dump-raw-sem-ir` would print two
copies. The lack of complaints about this suggests it's not needed.

I'm making a small change to drop newlines between textual and raw
semir. This is an edge case so I don't expect people to really notice in
general, but it seemed unusually aware of what's on a stream, and it
made it harder to do the dump_stream/raw_dump_stream approach, which I
felt would be decent in general, since check is the only phase that can
emit two different things (which I could also just drop -- we don't
really use raw semir anymore, it doesn't seem like a big need to be able
to print it with textual semir, but I'm assuming to just maintain
existing behavior).

In parse, we were previously dumping the tree on verification errors.
I'm removing that because now `--dump-parse-tree` should work fine,
where previously it wouldn't.
2025-07-01 15:51:41 +00:00
Richard Smith 11d5ee5f3e Add partial to the precedence diagram. (#5749)
Following the decision in #5010.
v0.0.0-0.nightly.2025.07.01
2025-06-30 22:44:54 +00:00
Jon Ross-Perkins 6966b1879d A few more mermaid newline fixes (#5752)
Akin to #5751, found in two other files.
2025-06-30 22:43:03 +00:00
David Blaikie 0b53217372 Diagnose partial applied to final types. (#5744)
Is it worth having a distinct diagnostic or phrasing for non-class types
(like tuples, structs, pointers, etc), also for declared-but-not-defined
class types (where we can't tell if they're final or not)? Happy to add
it, but not sure how much detail to put in here at this stage at least.

I chose "non-final type" as somewhat vague wording so it sort of applies
even to pointers/tuples/structs.
2025-06-30 20:35:19 +00:00
Jon Ross-Perkins 72c3f8a6b5 Fix repeated newlines in expression mermaid (#5751)
A newline adds a br. The br tag is redundant, unless you really want two
newlines. Might stem from a mistake in #1089

We have a couple spots using br to keep text on a single line; changing
those for consistency.

Before:

![Screenshot 2025-06-30 at 1 01
51 PM](https://github.com/user-attachments/assets/29c16b0f-1180-4e91-a2f8-3889db4dd311)

After:

![Screenshot 2025-06-30 at 1 01
18 PM](https://github.com/user-attachments/assets/1b69356e-92b7-4db5-8e0d-9e838035a9f5)
2025-06-30 20:10:16 +00:00