Commit Graph
71 Commits
Author SHA1 Message Date
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
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 12d66be1cd Delete files that were moved in #5716 but got undeleted in #5678 (#5768) 2025-07-03 10:33:25 +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 4aa62bf5cd Switch Destroy to addr self (#5748)
Pointed out by zygoloid on #toolchain, just taking care of this now.
2025-06-28 00:50:47 +00:00
Jon Ross-Perkins 0722dab0ef Reimplement destroy as an interface (#5678)
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.
2025-06-27 21:57:14 +00:00
Boaz Brickner 11a75d1de1 Move function_ test files to be in function dir and remove the function_ prefix (#5716)
Follow up of
https://github.com/carbon-language/carbon-lang/pull/5645#discussion_r2153064236
and #5607.
2025-06-24 12:53:33 +00:00
Boaz Brickner 20f44e0a92 Support a C++ class as a parameter or return by value, similar to a C++ struct (#5709)
Add tests for C++ `union`.
Also fix some typos in `class` tests and remove SemIR ranges from tests
that should diagnose an error.

Part of #5533.
2025-06-23 19:30:56 +00:00
Boaz Brickner 8aedcbcabd Remove TODOs from the test of a declared but not defined struct as a by value parameter/return value (#5708)
These TODOs should have been removed in
https://github.com/carbon-language/carbon-lang/pull/5538 which adds
support for struct by value parameters and return values.

Part of #5533.
2025-06-23 14:45:06 +00:00
Boaz Brickner c025f96894 Replace EXTRA-ARGS: --no-prelude-import with INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon (#5707)
Follow up https://github.com/carbon-language/carbon-lang/pull/5538 to be
consistent with the practice introduced in
https://github.com/carbon-language/carbon-lang/pull/5694.
2025-06-23 13:57:47 +00:00
Boaz Brickner cc698d78f5 When using a C++ struct as a parameter, map its type to a Carbon class type (#5538)
This doesn't support actually passing the value of the struct, which is
planned to be implemented using thunks.

`ClangDeclId` value is now `ClangDecl` which includes the mapped Carbon
instruction in addition to the Clang declaration. This allows finding
the Carbon instruction for a given Clang declaration, which is necessary
for mapping a Clang struct parameter type to the Carbon class without
doing name lookup. We don't take the instruction as part of the hash
key, as discussed in
[Discord](https://discord.com/channels/655572317891461132/768530752592805919/1380575881050718469).

To map the type, we also need to map namespaces. To avoid recursion for
inner namespaces, we use a vector.

Note that the first commit just changes the order of functions in the
file to make review easier.

C++ Interop Demo (that shows missing behavior):

```c++
// hello_world.h

struct 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: -1108224096
hello_world2: 1
```

Part of #5533.
2025-06-20 16:51:58 +00:00
Dana JansensandJon Ross-Perkins 76cdbd8a5a Introduce the none.carbon min-prelude (#5694)
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>
2025-06-18 20:45:46 +00:00
Boaz Brickner 64ad57adef Update toolchain/check/testdata/interop/cpp/function_param_int*.carbon and toolchain/check/testdata/interop/cpp/function_return.carbon tests to use sem ir ranges (#5645)
Follow up of #5594.

Trying to compromise SemIR size, having enough information and
complexity of tests, I've duplicated representative tests to a separate
test file with `--dump-sem-ir-ranges=if-present`.
2025-06-18 07:50:44 +00:00
Dana Jansens 07aec169e1 Add min-preludes to more slow tests (#5681)
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 7s to about 6s.

For a few files that are clearly only testing diagnostics, we drop the
if-present semir ranges and the associated TODO.
2025-06-17 20:55:48 +00:00
Richard SmithandGeoff Romer 80529aaef9 Convert the scrutinee of a binding pattern to the right category. (#5662)
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>
2025-06-17 16:45:19 +00:00
Jon Ross-Perkins 1c09de9b87 Add min_prelude/convert.carbon to tests missing ImplicitAs (#5677)
import_use_generic.carbon has the comment "// We're just checking that
this doesn't crash. It's not expected to compile." Because it involves
import behavior by name, I'm not touching it. Other than that, while
maybe it's better to test with less, the `ImplicitAs` errors at best
feel difficult to understand, and at worst could be masking an issue.
2025-06-16 23:50:45 +00:00
Richard Smith 344f0b7550 Support for heterogeneous operators. (#5653)
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.
2025-06-13 01:55:24 +00:00
Ivana Ivanovska c7afc85541 Rename splits for intN_t tests (#5615)
Renaming the splits in the tests for `int16_t` and `int32_t` to
emphasize testing typedefs.

Part of #5263 .
2025-06-12 16:05:38 +00:00
Jon Ross-Perkins 122800881b Remove redundant ranges=only flag settings (#5648) 2025-06-11 16:47:40 +00:00
Boaz Brickner 29d4aae722 Update most toolchain/check/testdata/interop/cpp tests to use sem ir ranges (#5594)
All except
`toolchain/check/testdata/interop/cpp/function_param_int*.carbon` and
`toolchain/check/testdata/interop/cpp/function_return.carbon`.

Don't output SemIR for cases that are intended to fail.
2025-06-11 12:35:55 +00:00
Ivana Ivanovska 3d603fced7 Fix C++ function params and return values printed in SemIR (#5468)
Fix `pattern_block_id` and `call_params_id` for C++ function decl
import, to get the correct SemIR printout for the C++ functions i.e.

1) Fill in missing parameter info in the function decls:
```
// CHECK:STDOUT:   %foo.decl: %foo.type = fn_decl @foo [concrete = constants.%foo] {
// CHECK:STDOUT:     %a.patt: %pattern_type.2f8 = binding_pattern a [concrete]
// CHECK:STDOUT:     %a.param_patt: %pattern_type.2f8 = value_param_pattern %a.patt, call_param0 [concrete]
// CHECK:STDOUT:   } {
// CHECK:STDOUT:     %a.param: %i16 = value_param call_param0
// CHECK:STDOUT:     %.1: type = splice_block %i16 [concrete = constants.%i16] {
// CHECK:STDOUT:       %int_16: Core.IntLiteral = int_value 16 [concrete = constants.%int_16]
// CHECK:STDOUT:       %i16: type = class_type @Int, @Int(constants.%int_16) [concrete = constants.%i16]
// CHECK:STDOUT:     }
// CHECK:STDOUT:     %a: %i16 = bind_name a, %a.param
// CHECK:STDOUT:   }
```
2) Print the params and return values:

```
// CHECK:STDOUT: fn @foo_short() -> %i16;
```

```
// CHECK:STDOUT: fn @foo(%a.param: %i16);
```

Closes #5449
2025-06-10 17:17:19 +00:00
Boaz Brickner ec97ec9664 Use InImport pointing to C++ imports in ConvertLocInFile() instead of adding a separate InCppImport when emitting (#5614)
I believe we will need to eventually add the specific C++ import
information in `LocId`.

This also seems to fix the `LanguageServerDiagnosticInWrongFile` issue
(#5604).

We're still not in the state we want to be according to
https://github.com/carbon-language/carbon-lang/pull/5246#issuecomment-2784301206.
Will look into removing the location part from the `"In file included
from ..."` line.

Part of #5245.
2025-06-10 09:02:45 +00:00
Jon Ross-Perkins 9b1a0729a1 Move imported C++ entities to the import block (#5616)
This mirrors how imports work in general, that the imported declarations
shouldn't belong to the first referencing scope (particularly apparent
when referenced across multiple scopes). I think this was just an
oversight here.
2025-06-05 18:44:27 +00:00
Jon Ross-Perkins 04d534abee Remove the no_prelude directory, using --no-prelude-import directly (#5607)
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.
2025-06-04 16:56:03 +00:00
Boaz Brickner 5435877745 Simplify the test that accesses LangOptions due to handling diagnostic with FixItHints and clarify the test if for diagnostic with FixItHints (#5596)
Followup of #5586.
Part of #5176.
2025-06-04 06:32:12 +00:00
Jon Ross-Perkins 26093656de Removes no-longer-needed --dump-sem-ir-ranges=only args (#5600)
The default was flipped by #5587.
2025-06-03 19:58:55 +00:00
Boaz Brickner 1899a6b285 Add C++ struct parameter tests with data members (#5540)
Also, add ranges.

Part of #5533.
2025-06-03 16:53:36 +00:00
Boaz Brickner 464ee76b9b Fix stack-use-after-scope issue by making LangOptions parameter non temporary (#5586)
The parameter is kept by reference.
Added a test that accesses `LangOptions` and crashes without this fix.

Part of #5176.
2025-06-02 14:28:36 +00:00
Boaz Brickner ae454bb48c Test C++ structs as parameters and return types as declarations and definitions (#5537)
Move all function tests to a dedicated directory and all `struct`
function tests to a dedicated file in this directory.

Part of #5533.
2025-05-30 21:52:26 +00:00
a23631f360 Support for lowering references to imported vars. (#5513)
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>
2025-05-29 19:48:16 +00:00
Jon Ross-Perkins 560b5734a4 Add range flag settings to interop files (#5564)
Where `--no-dump-sem-ir` is used, change to `--dump-sem-ir-ranges=only`.
Otherwise, add `--dump-sem-ir-ranges=if-present` with a TODO to change
to `only`.
2025-05-29 18:46:37 +00:00
Boaz Brickner 0a5dc9a9cc Use C++ trailing return type in toolchain/check/testdata/interop/cpp/no_prelude/function.carbon (#5541) 2025-05-27 16:20:00 +00:00
Richard Smith 5b884ae14d Improve lowering for global variables. (#5492)
- 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.
2025-05-21 00:09:10 +00:00
Boaz Brickner c39efe321e Refactor toolchain/check/testdata/interop/cpp/no_prelude/function_decl.carbon (#5477)
Rename file and shard files to shorter name given context.
Add `todo_` to file shards where appropriate.
Add shard files section comments.
2025-05-20 16:15:49 +00:00
Boaz Brickner 8e666cea3e Add section descriptions in toolchain/check/testdata/interop/cpp/no_prelude/cpp_diagnostics.carbon as agreed in #5467 (#5497)
Part of #4666.
2025-05-19 21:39:57 +00:00
Boaz Brickner 04d2643fd7 Reformat banner comments in toolchain/check/testdata/interop/cpp/function_param_*.carbon , following the agreed format in #5467 (#5498)
I've decided to keep `int` and similar as low case, as it refers to an
actual type.

Part of #5436
2025-05-19 21:17:23 +00:00
Boaz Brickner 6842c51fd1 Rename toolchain/check/testdata/interop/cpp/no_prelude/function_decl_inline.carbon and its shard files to simpler names (#5476)
Part of #5405.
2025-05-18 23:30:47 +00:00
Boaz Brickner 42f4d20e36 Improve toolchain/check/testdata/interop/cpp/no_prelude/namespace.carbon (#5478)
* Add // === headlines on group of file shards.
* Rename shard files to shorten given the file context them and add
`todo` where appropriate and group them together..
2025-05-17 15:17:41 +00:00
Boaz Brickner 4071372677 Improve toolchain/check/testdata/interop/cpp/no_prelude/{class,struct,union}.carbon (#5467)
* Add // === headlines on group of file shards.
* Rename shard files to shorten given the file context them and add
`todo` where appropriate.

Not splitting this file for now.

Part of #5150.
2025-05-15 09:01:18 +00:00
Boaz Brickner 2b48033da7 Refactor toolchain/check/testdata/interop/cpp/function_decl.carbon (#5457)
* Split to 4 files: `function_param_int16`, `function_param_int32`,
`function_param_unsupported.carbon`, `function_return`.
* Add // === headlines on group of file shards.
* Rename shard files to shorten them and make them more consistent given
the file context.
* Deduplicate identical .h files and group their tests.

Potential future improvements:
* Split further. For example, pointers and references might be somewhat
separate from int primitives.
* Remove `import_` shard file prefix, as it repeats itself, but leaving
for now as it makes it more explicit.

Part of #5263
2025-05-14 16:00:27 +00:00
Boaz Brickner 2cb0df42e0 Add C++ interop inline function tests (#5406)
This shows that `inline` is ignored and the function definition is not
generated.

Demo:

```c++
// hello_world.h

inline void 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
ld.lld: error: undefined symbol: hello_world()
>>> referenced by main.carbon:8
>>>               main.o:(main)
error: linker command failed with exit code 1 (use -v to see invocation)
```

Part of #5405.
2025-05-09 16:33:16 +00:00
Ivana Ivanovska f8443ae09e [Carbon/C++ interop] Add support for C++ type short (#5393)
Added support for `short`/`int16_t`. Both function parameters and return
values this type will be supported.

Demo:

```c++
// hello_short.h

#include <cstdint>
auto foo_short(int16_t a) -> int16_t;
```

```c++
// hello_short.cpp

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

auto foo_short(int16_t a) -> int16_t {
    printf("a = %i \n", a);
    return a;
}
```

```c++
// main.carbon

library "Main";

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

fn Run() -> i32 {
  var a: i16 = 3;
  Cpp.foo_short(a);
  return 0;
}
```

```
$ clang -c hello_short.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_short.o main.o --output=demo
$ ./demo
a = 3 
```

Part of #5263
2025-05-09 08:51:46 +00:00
Ivana Ivanovska afea14d14d [Carbon/C++ interop] Add more tests for int function params support (#5392)
Added tests for `signed int`, `signed`, `std::int32_t` and `const int&`.
This is an addition to PR #5197.

Part of #5064
2025-05-08 13:57:34 +00:00
Richard Smith 797b14eb8e Import ImplWitnessTable into the imports block instead of the constants block. (#5374)
Don't import `ImplWitnessTable` into the `constants` block, because we
generally don't put `Unique` constants there. This matches the handling
of the other kinds of `Unique` constants. In order to keep the
instruction visible in formatted SemIR, add it to the `imports` block
instead.

Also fix a bug in the instruction formatter that resulted in
instructions in the `imports` block being omitted from the output if
they were only referenced by earlier instructions in the `imports` block
and by instructions in the `constants` block. This was already resulting
in some referenced instructions being omitted from the output, but also
occurred frequently for `impl_witness_table` instructions after this
change because it is common for the only reference to those instructions
to be from `impl_witness` instructions in the `constants` block.
2025-05-01 00:08:43 +00:00
Geoff Romer 34887403ab Model patterns as constant values (#5385)
This will enable us to simplify support for parameter and return
patterns in import, which operates primarily on constants.
2025-04-30 22:32:41 +00:00
Geoff Romer 7c85397f8b Stop treating symbolic binding patterns as constants (#5361)
This was originally needed to support constant evaluation of name
expressions, but that's now done in a different way.

This is actually a step toward treating all patterns as constants. The
upcoming change will do so in a slightly different way, and so it will
simplify the review to start from a baseline where patterns are never
constant.
2025-04-28 23:45:15 +00:00
Geoff Romer fafb655d39 Separate pattern types from expression types (#5360)
This is a step toward treating patterns as compile-time constants, so
that we can import them more easily.
2025-04-28 16:54:37 +00:00
Boaz Brickner 609ccefd18 Introduce a Clang diagnostic instruction and use it to point to C++ source locations on Clang errors and warnings (#5262)
Introduce `ImportIRId::Cpp` and refer to clang source location in its
`ImportIRInst`.

Part of #5245.
2025-04-25 13:05:45 +00:00
Richard Smith ca8df34d0d Format the call parameters of a function, not the patterns. (#5342)
This makes the parameters printed in a SemIR `fn` declaration match the
arguments printed in a SemIR `call` instruction.
2025-04-22 18:52:21 +00:00
Richard Smith b5ae988a08 Add builtins for compound assignment operators. (#5335)
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.
2025-04-21 20:38:11 +00:00