Commit Graph
154 Commits
Author SHA1 Message Date
David Blaikie f45a632d77 Implement virtual call dispatch (#5308)
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.
2025-04-17 14:42:30 +00:00
Jon Ross-Perkins 401c72a5c3 Allow no-op functions to have unused arguments (#5318)
For example, we might want `[self: Self]` to be ignored.
2025-04-16 22:03:21 +00:00
Jon Ross-PerkinsandChandler Carruth b49e89e97e Add a no-op builtin function which shouldn't generate code. (#5306)
This is part of a broader plan to have noop destructor functions for
trivial destruction.

Note this emits a SemIR call (`%no_op: init %empty_tuple.type = call
%NoOp.ref() [concrete = constants.%empty_tuple]`), but not LLVM IR. My
thought was this was probably okay, since even though it'll be a little
spammy with destructor calls, the flipside is there'll probably already
be a fair amount for the name reference, and this at least shows when
the call is injected (and discarded).

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-04-15 00:33:39 +00:00
Alina Sbirlea 02e9ac21bf Fix type when lowering associated constants. (#5295)
Get type in specific when lowering associated constants. This resolves
crash when getting type for type_id is not found, when the query is for
a specific.
Note: Currently lowering only supports mangling of impls that can viewed
as a single interface (single ImplConstraint).
2025-04-14 15:55:12 +00:00
Dana JansensandRichard Smith 0e8d354567 Split the witness table into a separate ImplWitnessTable instruction (#5272)
This allows us to import the table for a given impl only once, while we
can import many ImplWitness instructions with different specifics for a
generic impl.

For example in convert_facet_value_to_narrowed_facet_type.carbon we see
that a single witness table is imported for the BitAnd interface, with
multiple witnesses (for different specifics) imported and sharing the
same table.

The ImplWitnessTable now contains a back-link to the Impl the witness is
for, allowing inst namer to name that interface in the textual semir,
and allowing the interface to be found when debugging from a witness.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-11 20:30:04 +00:00
Alina Sbirlea 7da972b773 Create a single global for the PrintInt format string. (#5275)
Create a single global for the PrintInt format string. Cleaner tests.
2025-04-09 16:47:32 +00:00
Alina Sbirlea 694a329bdd Reuse LLVM global constants. (#5273)
Reuse LLVM global constants: do not generate a new llvm::Global constant
for a pointer to a global constant for the same Carbon const_inst_id,
reuse already generated one.
2025-04-09 16:36:42 +00:00
Alina Sbirlea 3ccb0b82f8 Add/update lowering tests. (#5254)
Add lowering tests for future redesign.
2025-04-08 17:26:16 +00:00
David Blaikie 8e7bb2f953 Initialize vptrs to point to vtables (#5244)
Adds a mapping to keep track of vtable LLVM IR decls/defs for use.
Adds the vtable_id to the vtable_ptr initialize instruction for lookup.
Adds emission of vtable declarations for use outside the file that
defines the vtable. (this isn't done lazily, it's done for any imported
class - it could be done lazily & maybe eventually has to be lazy to
handle generics)
2025-04-05 06:11:34 +00:00
Dana Jansens 164310c6b8 Facet values (like type values) can be copied around at runtime (#5242)
Give them a value representation of copy, and allow conversions between
two facet values of the same type to work.

Convert was assuming that facet values are compile time constants, but
thye can also be runtime values. In that case, we have no support for
converting to a different facet value of a different facet type. But if
the types are equal then it's all fine.

In theory it seems that we should be able to convert if the target facet
type can be found through the source value's FacetType. But currently
that happens through impl lookup and it requires constant values. Adding
a test for this.

Related to #5241
2025-04-03 19:34:54 +00:00
Alina Sbirlea 077cf56a8a Emit function definitions in check, for all specifics seen. (#5090)
Emitting definitions in check. This resolves the crash in lowering which
necessitated definitions be emitted.
Some of the test changes need further review.
2025-04-02 21:51:25 +00:00
David Blaikie 8847178242 Emit (relative) vtables (#5231)
One of the remaining three steps for proof-of-concept virtual function
lowering (the other two being: initializing vptrs to point to these
tables, and using the vptr+table at call sites).

Introduces a (placeholder?) mangling of vtables as ".$vtable" at the end
of the mangling of the class name.

Uses a scheme similar to clang's relative vtables - though those are
relative to the vtable slot, and this is relative to the start of the
vtable (seemed simpler? though I haven't looked at it in detail, perhaps
in lowering call sites I'll find the relative-to-vtable-slot is nicer,
easy enough to change).
2025-04-02 17:59:08 +00:00
David Blaikie 4739828cca Generalize non-const ClassInit lowering beyond only InitializeFrom insts (#5199)
Fixes #5186

With @zygoloid's kind assistance, this generalizes the existing
non-const lowering of ClassInit, that had previously only handled
InitializeFrom, to find other cases - such as a nested ClassInit used to
initialize a class member.

This refactors the `FindReturnSlotArgForInitializer` from
`check/convert.cpp` into `sem_ir/file.{h,cpp}` for use from lowering
(since lower doesn't depend on check, which I assume is an intentional
layering constraint - so figured it made sense to move it to sem_ir, and
found one or two similar-ish utility functions in `sem_ir/file.{h,cpp}`,
so figured that was a good spot)
2025-04-01 18:45:07 +00:00
David BlaikieandRichard Smith 45d042cab8 Fix crash in lowering vptr initialization (#5184)
Seems the instructions got emitted out of order & that caused problems
for lowering. This was because most of the initialization instructions
were added to a PendingBlock, but the vptr initialization instructions
were added to the (non-pending) block directly.

(I don't fully understand the pending stuff (is there a different test I
could/should write that demonstrates the vptr init instructions not
being discarded because they didn't go in the pending block (before this
patch)), or the out of order instruction problem (could we add more
robust checking for instruction ordering?) - but perhaps this is
adequate understanding for this bug fix at least)

Fixes #5094

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-03-26 21:52:16 +00:00
David Blaikie 4f0a0819c5 Minor test updates to out of date comments (#5161)
These two cases seem to work correctly now - must've forgot to clean
them up at some point.
2025-03-21 00:01:15 +00:00
Richard Smith 4d2cca48c7 Compute a correct SpecificFunction when resolving an indirect call to an impl function (#5116)
When performing a call through an impl witness, the callee that we
type-check against is the function in the interface, so we form a
specific for that callee. However, once the impl witness access
resolves, the eventual callee is a different function -- the function in
the impl -- so this would cause us to form a `SpecificFunction` where
the callee is one function but the specific refers to a different
function.

Address this by adding another instruction, `SpecificImplFunction`, that
takes a function in an impl and a specific for the corresponding
function in the interface, and computes and returns a `SpecificFunction`
referring to the corresponding specific function in the impl, or returns
a direct reference to the function in the `impl` if it's not a generic
function.
2025-03-18 21:26:52 +00:00
Alina Sbirlea fdedbb037d Add some tests for lowering generics. (#5131)
Adding some tests that show current lowering and limitations.
2025-03-15 05:44:18 +00:00
Alina Sbirlea 7fd54eded0 Reverse nesting of BoundMethod and SpecificFunction. (#5079)
During SemIR, when identifying a specific in a specific context, we'd
have to either look through a specific or through a bound method.
Canonicalize which one to look through first, by having the BoundMethod
created around a SpecificFunction instead.
This changes a lot of check tests.

TODO: As the SemIr does not currently allow removal (access to insts()
is intentionally const), the bound instruction created prior to finding
the specific is not removed from the instructions.
Options: (1) leave as is, (2) add a way to remove the previous bound,
(3) rethink how/when the BoundMethod inst is created.
2025-03-08 01:34:06 +00:00
Alina Sbirlea d3869a529b Continue: emit function definitions for specifics. (#5068)
Resolve instruction id depending on the context from which a function is
called.

Calling a function in a function context that does not have a definition
emitted before reaching lowering will cause a crash. This needs a change
in check/eval layer.
2025-03-06 17:40:35 +00:00
Boaz Brickner 156ab889f8 Support mangling imported C++ functions using Clang's MangleContext (#5062)
Keep a pointer to the Clang declaration in Carbon's function declaration
and use it in Carbon mangling by calling Clang mangling.
Create Clang's `MangleContext` once on demand.

Part of #4666.

C++ Interop Demo:

```c++
// hello_world.h

void hello_world();
```

```c++
// hello_world.cpp

#include <cstdio>

void hello_world() { printf("Hello World!\n"); }
```

```
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.hello_world();
  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!
```
2025-03-06 09:51:01 +00:00
David Blaikie e71d5942bc Function decl lowering for incomplete parameter/return types (#5038) (#5066)
While current examples of this could also be addressed by emitting
declarations on use (by which stage the associated types would have to
be complete by construction) - it's expected that future examples
(vtables, function pointers) will need to work in this case anyway, so
might as well implement this feature.
2025-03-05 20:02:14 +00:00
Alina Sbirlea 4e21c0c1fc Basic lowering generic function definitions. (#5016)
Resolve the specific type for the callee, to lower the proper specific
function called.
2025-03-04 18:41:29 +00:00
Alina Sbirlea 1f5e5a7b44 Add basic lowering of generic function definitions. (#5015)
Very basic (incomplete) lowering of function definitions for generics.
2025-02-27 21:17:46 +00:00
f97f1a3e11 Add error for virtual member function without self (#5005)
This tripped over a lowering crash when a member function with self was
declared-but-not-defined, so that's why some test cases were updated to
have (empty) function definitions.

I'll follow-up with/look into a fix for the
self-declared-but-not-defined cases separately.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2025-02-27 17:01:29 +00:00
3ebd098597 Completing a type no longer ignores facet types (#5004)
Make facet types complete like other types. This means that in the body
of an interface, the type of `Self` is incomplete. This involved fixing
an issue where eval of a specific_id that was already canonical was not
resolving the specific declaration, which could occur as part of
substituting into a facet type.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-02-22 21:40:43 +00:00
Dana Jansensandzygoloid 24bde46181 Change array syntax from [T; N] to array(T, N) (#4981)
In line with the proposal in #4682, this changes the array syntax to be
array(T, N). `array` is a builtin keyword which must be followed by
parens containing two expressions and a separating comma.

The array type expression is still fully builtin, it does not forward to
a Core.Array library type yet. It merely adds the `ArrayType`
instruction, as was done with the previous syntax.

Followup work will change the instruction to reference to Core.Array,
once the library type exists and can be used directly.

---------

Co-authored-by: zygoloid <richard@metafoo.co.uk>
2025-02-20 22:42:47 +00:00
Jon Ross-Perkins 2929254168 Update LLVM version, fix breaks (#4886)
- The actual reason I started this: minor lowering updates in the golden
LLVM IR
- Process.inc changed enough to need a patch context update.
- https://github.com/llvm/llvm-project/pull/123126 added `proto_library`
uses without a `load`, which is broken in bazel 8
- Just commenting these out because we don't use them. I'll follow up
separately about a possible fix, but continuing to use `WORKSPACE` is a
bigger issue LLVM probably should address.
- Note this update is also triggering removal of `migrate_cpp`, in #4887
2025-02-04 18:13:29 +00:00
Jon Ross-PerkinsandChandler Carruth 7befe2ce9f Switch custom error stream output to diagnostic (#4846)
This switches most error printing to use diagnostics instead of direct
stream writes, even when not a specific file diagnostic. I'm allowing
empty filenames for this use-case.

This allows a little more specific testing to validate coverage of
output using the diagnostic coverage test. I'm adding a few tests to
cover things that weren't previously tested.

Separately, this also forces a little more standardization in format...
considering how changes like #4568 show effort being spent to _mirror_
diagnostic style, my thought is now to just use diagnostic code where
possible.

Note this also allows incrementally better testing of the language
server; I'm changing the crash fix from #4847 in favor of diagnostic
testing.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-01-30 01:58:07 +00:00
Geoff RomerandRichard Smith 13434f0e8a Model var as a pattern operator (#4720)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-01-17 17:51:34 +00:00
David BlaikieandJon Ross-Perkins e6c1f0630a Add a newline after diagnostic output when testing (#4818)
This removes some churn when adding new diagnostic cases to test files
(where previous to this change the newly added newline would cause the
previous diagnostic CHECKs to be updated including changes to the line
number because the CHECK for the blank line meant an extra line between
CHECK and source line).

A few alternatives discussed here:
https://discord.com/channels/655572317891461132/655578254970716160/1329573358475673723

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-01-16 23:23:57 +00:00
Richard Smith b1230218d5 Make fingerprinting stable across compatible source changes. (#4789)
Include the index rather than the name in the fingerprint of a symbolic
binding. While both the index and the name contribute to the canonical
identity, using either one of them in the fingerprint is sufficient to
ensure that distinct entities get different fingerprints. Changing the
name of a symbolic binding should ideally not result in fingerprint
changes, so exclude the name from the fingerprint when we have an index.

Use the canonical type and constraint when fingerprinting an impl, so
that uses of names in `name_ref` instructions aren't considered, only
the entity the name resolves to, and different ways of spelling the same
type have the same fingerprint. This similarly allows compatible changes
to be made to impls without changing the fingerprint.

Exclude the declaration block when determining the fingerprint of a
declaration. The declaration block contains the declarations of
parameters of the declaration, which do affect whether two declarations
are identical, but not whether they denote the same entity, because it
would be invalid to have different declaration blocks for declarations
with the same name in the same scope. Therefore changes to the
declaration block are compatible, and it's useful for such changes to
not affect the fingerprint.

This is not easy to test in isolation with our current testing
machinery. However, a follow-on PR will change the name of a parameter
in the prelude, and with this in place, will not cause any changes to
occur elsewhere in the toolchain tests.
2025-01-10 22:30:22 +00:00
Richard Smith 9a5f2d734b Include a fingerprint of the specific arguments in mangled names. (#4771)
Instead of including the raw index of the specific, which is unstable
across files and across unrelated changes, use a fingerprint of the
constant values of the specific arguments. This is a placeholder until
we decide on how we want to mangle specific functions.
2025-01-08 20:23:12 +00:00
Richard Smith 246ec785df Add support for converting between integer types (#4753)
Add a builtin `"int.convert"` supporting unchecked conversions between
different integer types. This performs a truncation, zero-extension, or
sign-extension, depending on the widths of the operands and the
signedness of the source type. Add explicit `As` support to the prelude.
No implicit conversions are supported yet as we don't have a way to
express the constraint that we can only implicitly convert to wider
types.
2025-01-08 08:25:20 +00:00
Richard SmithandDana Jansens 19182f08aa Compute a fingerprint for constants and import_ref instructions. (#4763)
Use it in the instruction namer to make instruction names more stable
across unrelated changes to the toolchain or the prelude.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-01-07 20:41:44 +00:00
Richard Smith 4a7aefefaa Add support for operators on Core.IntLiteral. (#4716)
Fixes integer builtins to produce the correct values (and not
CHECK-fail) when used on integer literals. Also adds impls to the
prelude to use the new builtins to perform operations on integer
literals.

Perhaps most importantly, this allows directly initializing `i32` values
with negative numbers, as the negation operation on integer literals now
works.

For testing I've added tests for use of literals with one operator in
each class (addition, multiplication, ordering, bitwise, etc) for which
there are distinct rules or overflow behavior, rather than exhaustively
testing all the combinations. This is aimed at finding a good tradeoff
between maintainability of the tests and thorough test coverage.

Also fixes lowering of heterogeneous shifts and comparisons. These are
currently disabled when one of the operands is an integer literal, but
we may want to allow that when the integer literal operand has a known
constant value.
2024-12-31 06:36:43 +00:00
Richard Smith 7d8d59cb7e Make snegate / unegate overflow handling consistent with other builtins. (#4744)
Make `int.snegate` ignore the signedness of its operand and
unconditionally check for signed overflow like all the other `int.s*`
builtins do. Fix the prelude implementation of unary `-` for `Core.UInt`
to use `int.unegate` instead of `int.snegate`.

Fix the test for unsigned negate to actually test negating unsigned
integers, and add some tests that unary `-` also works.
2024-12-26 22:07:47 +00:00
Dana Jansens 9290ee2bcf Use unsigned arithmetic builtins for UInt(N) operations (#4740)
We were mistakenly using the signed builtins, which produce the same
lowering for add/multiply right now, but don't for division and modulus.

When manually flipping SignedOverflowIsUB on, the signed version of add
gains the nsw (no signed wrap) flag, while the unsigned version
(correctly after this change) does not:
```
// CHECK:STDOUT: define i32 @_Cadd_i32.Main(i32 %a, i32 %b) !dbg !4 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT:   %int.sadd = add nsw i32 %a, %b, !dbg !7
// CHECK:STDOUT:   ret i32 %int.sadd, !dbg !8
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @_Cadd_u32.Main(i32 %a, i32 %b) !dbg !9 {
// CHECK:STDOUT: entry:
// CHECK:STDOUT:   %int.uadd = add i32 %a, %b, !dbg !10
// CHECK:STDOUT:   ret i32 %int.uadd, !dbg !11
// CHECK:STDOUT: }
```
2024-12-26 00:36:33 +00:00
Dana Jansensandjonmeow 6cb660f5ad Avoid recursion in InstNamer::CollectNamesInBlock (#4706)
Use a deque to maintain the set of instructions to be walked over. so
that the loop can append more instructions (with their related scope)
during iteration without requiring recursion.

---------

Co-authored-by: jonmeow <jperkins@google.com>
2024-12-20 16:12:06 +00:00
Richard Smith 6fe8e0b5aa Provide generic impls for Core.Int and Core.UInt operations. (#4693)
Instead of providing operations only for `i32`, provide them for all
`iN` and `uN` types.

For now, this excludes the `*Assign`, `Inc` and `Dec` interfaces,
because the implementations for those are defined as Carbon functions
rather than builtins, and we can't yet lower definitions for specific
functions, so converting those to be generic breaks the build for our
examples.
2024-12-19 22:02:18 +00:00
Richard Smith b54a27e9e7 Fix incorrect lowering of mixed constant / non-constant aggregate initialization. (#4704)
We defer lowering initialization with constant values, because the use
of the constant can itself be part of a larger constant that we don't
want to emit. However, when the initialization is for an element of a
non-constant aggregate, we do need to initialize the constant portion.
2024-12-19 01:13:29 +00:00
Richard Smith c1590f886a Add equality comparison support for bool. (#4701) 2024-12-18 00:47:03 +00:00
David Blaikie 4d0a6db49b Abort checking when encountering an invalid parse node (#4700)
Short term solution/block for #4689
2024-12-18 00:19:12 +00:00
Richard Smith c04d62a7d1 Ensure that all allocas are created in the entry block. (#4685)
Non-entry-block allocas will allocate new stack memory each time they're
reached, resulting in leaking stack memory over time for allocas in a
loop. Move all such allocas to the entry block instead, and use an LLVM
intrinsic to mark when the lifetime of the variable actually begins.
2024-12-17 00:55:06 +00:00
Richard Smith 3645143e27 Add solutions for advent of code 2024 day 1 to examples/. (#4673)
In order to support these examples, this adds two new builtins to the
toolchain: `print.char` and `read.char`, which map to the libc functions
`putchar` and `getchar`.
2024-12-17 00:47:51 +00:00
Richard Smith a10c79569e Model Core.Int as a class type (#4644)
Instead of treating `Core.Int` as the toolchain's builtin `IntType`,
model it as a class that adapts the builtin type. This aligns us better
with the intended language model, gives an associated library for
`impl`s involving `Core.Int` to live within, and opens the door adding
member functions to `Core.Int` if we decide that is desirable.
Remarkably it also seems to make the formatted SemIR a little smaller,
because a call to a generic class generates less IR than a call to a
function.
2024-12-16 22:19:23 +00:00
Richard Smith 7b45a28a82 Fix lowering of array indexing with an int literal. (#4686)
Such indexing operations are created by array initialization. Since we
switched integer literals to be of type IntLiteral we've been attempting
to index arrays with the (empty) representation of an IntLiteral rather
than with an actual integer value.
2024-12-14 04:47:32 +00:00
Richard Smith 3e0fdd04eb Lower global variables as global definitions, not global declarations. (#4674) 2024-12-12 22:23:00 +00:00
David Blaikie a2c939a2a2 Add an instruction for vptr initialization (#4633)
This fixes a crash in lowering, at least (though only initializes the
vptr to
null for now) - certainly open to naming feedback on the instruction, or
the
exact semantics (we could have a global vptr instruction that's
referenced from
the existing instructions for reading globals, for instance).

I guess we'll want one type parameter for the vptr_init instruction,
which is
the type that this is a vptr for? (can do that here or in a follow-on
patch)
2024-12-06 18:51:36 +00:00
David Blaikie 5719687438 Fix crash in lowering use of a global variable (#4631)
Actually presenting two options in this one review - if you look at the
specific
commits in this PR, the first commit represents my first attempt - and
if you
look at the overall PR change for the second attempt.

But I'm totally open to completely different approaches/ideas - these
were just
my rough guesses.
2024-12-06 17:34:29 +00:00
Richard Smith 1b13125d19 Avoid relying on an implicit conversion in builtin lowering test. (#4630)
This test is trying to explicitly test builtin functions, so use an
explicit call to a builtin function for the conversion too.
2024-12-05 01:33:42 +00:00