This updates lower/testdata to use _ instead of proper names, in order
to avoid the "unused binding" warnings from #2022 which are being
implemented. These changes do not depend on the implementation which
should make everything easier to review.
See #6460 with part 1 of the implementation. It was split upon request
in order to make reviewing easier, the original state of the PR was
updating hundreds of test cases.
The PR has thus been split, part 2 including test cases changes can be
viewed at
https://github.com/burakemir/carbon-lang/tree/unused_pattern_bindings_p2022_impl_part2
... many tests need to be updated, so it seems best to get those tests
out of the way that are not interesting.
These are not all tests in lower/testdata - a few of them are
interesting in the sense that they cannot use '_' because it leads to
failed redeclaration check. This is exactly the scenario described in
#3763 which requires the 'unused' marker. Those are left untouched here
but are updated in
https://github.com/burakemir/carbon-lang/tree/unused_pattern_bindings_p2022_impl_part2
This adds just enough debug info for i32/int parameters and return
values, with a path forward for adding DWARF type metadata for other
types.
As it happens, return type information is carried separately from
parameter information:
* Return type information is carried in the `type` of the `DISubprogram`
(as a `DISubroutineType` - which does carry parameter type information
as well, but that's unused when the DWARF is emitted by LLVM)
* Parameter information is carried by `DILocalVariable`s with a non-zero
`arg` value (representing the order of function parameters)
In the absence of locations for the parameters (future work), nothing
would usually keep the `DILocalVariable` live/reachable when emitting
DWARF - so for cases where this can happen (for clang, this happens in
optimized builds where all references to the parameter variable might be
optimized away) the variables can be "retained" in a list on the
`DISubprogram` - achieved by passing `AlwaysPreserve` parameter to
`createParameterVariable` (adds them to a list, then that list gets
attached to the `DISubprogram` when it's finalized later)
For now, any unsupported types are emitted as `void*` (except void
return, which is implemented as void) as a placeholder.
Given this example:
```
import Core library "io";
class MyClass {
}
fn Unsupported(v: MyClass) {
}
fn Ret() -> i32 {
return 42;
}
fn Arg(x: i32) {
Core.Print(x);
}
fn Run() {
}
```
this is the resulting DWARF:
```
DW_TAG_compile_unit
DW_AT_name ("test.carbon")
DW_TAG_subprogram
DW_AT_name ("Unsupported")
DW_TAG_formal_parameter
DW_AT_type (0x00000066 "void *")
DW_TAG_subprogram
DW_AT_name ("Ret")
DW_AT_type (0x00000062 "int")
DW_TAG_subprogram
DW_AT_name ("Arg")
DW_TAG_formal_parameter
DW_AT_type (0x00000062 "int")
DW_TAG_subprogram
DW_AT_name ("Run")
DW_TAG_base_type
DW_AT_name ("int")
DW_TAG_pointer_type
```
And the debugger:
```
(gdb) p Ret()
$1 = 42
(gdb) p Arg(4)
4
$2 = void
```
I'm not sure if there's a way this logic should be merged with the logic
for making the `llvm::Function` type (which the `DISubroutineType`
building code was inspired by/copied from) - since they're done at
different times/places, I don't think there's an easy way to do it in
one pass, but maybe the code can be shared (even if it's run twice) in
some generic `SemIR::Function` type walker.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
This helps at least lldb handle calling functions (currently the debug
info describes every function as `void()`, so no parameters or return
values are supported) - seems gdb and lldb both depend on demangling to
varying degrees in C code (marking a function as "prototyped" in C in
DWARF does seem to also address this problem).
Given:
```
fn PrintThree() {
Core.Print(3);
}
```
Before:
```
(lldb) p PrintThree()
error: Couldn't look up symbols:
PrintThree
Hint: The expression tried to call a function that is not present in
the target, perhaps because it was optimized out by the compiler.
```
After:
```
(lldb) p PrintThree()
3
(lldb)
```
Adds a flag `--optimize=<mode>` that specifies what to optimize for:
* `--optimize=none` turns off the optimizer as much as possible, but
still respects always_inline.
* `--optimize=debug` aims to be the equivalent of `-Og` / `-O1`, and
provides optimizations that don't affect the ability to debug the
program. This is the default.
* `--optimize=size` optimizes for the size of the produced program, and
aims to be the equivalent of `-Oz`.
* `--optimize=speed` optimizes for the execution time of the produced
program, and aims to be the equivalent of `-O3`.
Following the approach taken by Clang, the optimization level feeds into
both the configuration of the LLVM pass pipeline and the attributes
added to function definitions generated by the frontend.
Optimization is performed in a new phase, `optimize`, which runs between
`lower` and `codegen`.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
For now, map C++ reference types to const-qualified Carbon pointer types
rather than picking between a (non-const) pointer or a value type. This
fixes misbehavior in lowering for reference members in classes and
reference return types.
Update the special-case handling for references as function parameters
so that it continues to map const reference parameters to Carbon
pass-by-value, and unify the code paths for `self` parameters and other
parameters, which were mostly doing the same thing but had some subtle
differences.
Add references to the list of types that we can pass to and from C++
directly, without needing an additional layer of thunks.
Remove duplication between determining whether a parameter needs custom
thunk mapping and whether a function needs a thunk. Now a function needs
a thunk if any parameter or the return type does.
This fixes some inconsistencies; previously:
- We would not require a thunk when passing an `unsigned int`, but if we
had a thunk we'd pass `unsigned int` indirectly.
- We would always require a thunk for an enum parameter, even though
we'd actually pass it directly if its underlying type is a 32- or
64-bit integer.
- We would require a thunk for a nullable pointer, even though
we arrange for all pointer types to have the same ABI in Carbon and
C++, including nullable pointers / Optional(T*).
This also causes us to use a thunk for rvalue reference return types,
which we used to miscompile.
Depends on #6276.
This is a follow up of #6082, which added support for reference types,
but not for return types.
C++ Interop Demo:
```carbon
// main.carbon
library "Main";
import Core library "io";
import Cpp inline '''
struct C {
auto Inc() -> void { ++x; }
int x = 0;
};
auto GetC() -> C& {
static C c;
return c;
}
''';
fn Run() -> i32 {
Core.Print(Cpp.GetC()->x);
Cpp.GetC()->Inc();
Core.Print(Cpp.GetC()->x);
Cpp.GetC()->Inc();
Core.Print(Cpp.GetC()->x);
return 0;
}
```
```shell
$ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon && bazel-bin/toolchain/carbon link main.o --output=demo && ./demo
0
1
2
```
**Without this change**:
```shell
main.carbon:19:14: error: semantics TODO: `Unsupported: return type: C &`
Core.Print(Cpp.GetC()->x);
^~~~~~~~~~
```
Part of #6148.
The general strategy here is to force use of a thunk when we want to use
default arguments, and have Clang generate uses of the default arguments
on its side of the thunk.
To support this, change the key type used in `clang_decls` from being
just a `Decl*` to being a pair of `Decl*` and number of parameters in
the case of function decls. Import distinct `SemIR::Function`s for each
number of parameters that's used, and corresponding distinct thunks.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
For now this works as follows:
* `T&&` is mapped to a by-value `param: T` parameter.
* `T&` is mapped to an `addr param: T*` parameter.
In either case, we will generate a thunk, which will internally pass the
parameter as a pointer.