Step build returned: 0
[1/5] Generating main.cpp
main.cpp2...
number: type =
{
_storage: std::aligned_storage_t<cpp2::max(sizeof(int), sizeof(double))> = ();
_discriminator: i8 = -1;
is_i:(in this) -> move bool = _discriminator == 0;
i:(in this) -> forward int
pre( is_i() ) = reinterpret_cast<* const int>(_storage&)*;
i:(inout this) -> forward int
pre( is_i() ) = reinterpret_cast<* int>(_storage&)*;
set_i:(
inout this,
in _value: int
) =
{
if !is_i()
{
_destroy();
std::construct_at(reinterpret_cast<* int>(_storage&), _value);
}
else
{
reinterpret_cast<* int>(_storage&)* = _value;
}
_discriminator = 0;
}
set_i:(
inout this,
forward _args...:
) =
{
if !is_i()
{
_destroy();
std::construct_at(reinterpret_cast<* int>(_storage&), _args...);
}
else
{
reinterpret_cast<* int>(_storage&)* = : int = (_args...);
}
_discriminator = 0;
}
is_d:(in this) -> move bool = _discriminator == 1;
d:(in this) -> forward double
pre( is_d() ) = reinterpret_cast<* const double>(_storage&)*;
d:(inout this) -> forward double
pre( is_d() ) = reinterpret_cast<* double>(_storage&)*;
set_d:(
inout this,
in _value: double
) =
{
if !is_d()
{
_destroy();
std::construct_at(reinterpret_cast<* double>(_storage&), _value);
}
else
{
reinterpret_cast<* double>(_storage&)* = _value;
}
_discriminator = 1;
}
set_d:(
inout this,
forward _args...:
) =
{
if !is_d()
{
_destroy();
std::construct_at(reinterpret_cast<* double>(_storage&), _args...);
}
else
{
reinterpret_cast<* double>(_storage&)* = : double = (_args...);
}
_discriminator = 1;
}
private _destroy:(inout this) =
{
if _discriminator == 0
{
std::destroy_at(reinterpret_cast<* int>(_storage&));
}
if _discriminator == 1
{
std::destroy_at(reinterpret_cast<* double>(_storage&));
}
_discriminator = -1;
}
operator=:(move this) =
{
_destroy();
}
operator=:(out this) =
{
}
operator=:(
out this,
in that
) =
{
_storage = ();
_discriminator = -1;
if that.is_i()
{
set_i(that.i());
}
if that.is_d()
{
set_d(that.d());
}
}
operator=:(
inout this,
in that
) =
{
_storage = _;
_discriminator = _;
if that.is_i()
{
set_i(that.i());
}
if that.is_d()
{
set_d(that.d());
}
}
}
ok (all Cpp2, passes safety checks)
[2/5] Scanning /app/build/main.cpp for CXX dependencies
[3/5] Generating CXX dyndep file CMakeFiles/main.dir/CXX.dd
[4/5] Building CXX object CMakeFiles/main.dir/main.cpp.o
main.cpp2:2:83: warning: 'using std::aligned_storage_t = union std::aligned_storage<8, 16>::type' is deprecated [-Wdeprecated-declarations]
In file included from /opt/compiler-explorer/gcc-trunk-20231120/include/c++/14.0.0/bits/stl_pair.h:60,
from /opt/compiler-explorer/gcc-trunk-20231120/include/c++/14.0.0/bits/stl_algobase.h:64,
from /opt/compiler-explorer/gcc-trunk-20231120/include/c++/14.0.0/algorithm:60,
from /app/raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:232,
from /app/cpp2util.h:1,
from /app/build/main.cpp:6:
/opt/compiler-explorer/gcc-trunk-20231120/include/c++/14.0.0/type_traits:2611:11: note: declared here
2611 | using aligned_storage_t _GLIBCXX23_DEPRECATED = typename aligned_storage<_Len, _Align>::type;
| ^~~~~~~~~~~~~~~~~
[5/5] Linking CXX executable main
Program returned: 0
Title: Poor debugging experience of generated code.
Description:
A lot of Cpp2 can be generated, not visible in the Cpp2 source code itself.
For example, generated constructors and assignments,
as well as member functions generated by metafunctions.
When debugging the reproducer,
until you step into a standard function,
attempting to step into generated code
This results in a poor user experience.
I think we can and should do better.
Minimal reproducer (https://cpp2.godbolt.org/z/P7ssbdoYe):
Commands:
cppfront main.cpp2 clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cppExpected result:
cppfrontto output a Cpp2 source file with the generated code.#linedirectives of generated code to point to the new file.Actual result and error: Stepping into generated code jumps to the EOF.
Cpp2 lowered to Cpp1:
Output: