hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.56k stars 248 forks source link

refactor(to_cpp1): decentralize lowering of special member functions #1295

Open JohelEGP opened 1 month ago

JohelEGP commented 1 month ago

Title: refactor(to_cpp1): decentralize lowering of special member functions.

Description:

Since the dawn of Cpp2 user-defined types, there have been bugs in the lowered Cpp1 special member functions. The focus of this issue is Cpp2 code that in any other context lowers correctly.

There are some issues and fixing PRs for (some of) those, some resolved or merged, and others still open. You can navigate those in this quote to reach some of them:

478 fixes #422 by generating a default constructor.

to_cpp1.h takes care of lowering a default constructor that both uses the NSDMIs and #lines to their .cpp2 source.

operator=s could also be generated. [emit_special_member_function], on top of lowering member initializer lists, simulates the generation during lowering. That has resulted in bugs because some logic isn't repeated for the member-wise assignments. For example, #487 didn't work in the member-wise assignments, so #680 had to add a special case for it. Another example might be #822.

-- https://github.com/hsutter/cppfront/issues/844#issuecomment-1829023060.

cppfront::emit_special_member_function, in to_cpp1.h, centralizes the lowering of special member functions. Its duplication of logic is a source of bugs. In order to uproot present and future issues, I think we should decentralize it. We should strive to leave ever more to the lowering functions that already work, and focus ever more on handling only that which makes lowering special member functions unique.

JohelEGP commented 1 month ago

The quoted https://github.com/hsutter/cppfront/issues/844#issuecomment-1829023060 also includes a worthwhile suggestion:

operator=s could also be generated.

One of the things emit_special_member_function does is lowering up to 4 Cpp1 declarations from a single Cpp2 operator=. Arguably, this makes it hard to refactor, since the other lowering functions are unable to do so.

Instead of determining what an operator= generates at to_cpp1 time, we could generate them with a built-in metafunction that runs last. For starters, that would greatly simplify emit_special_member_function, which will then need to emit only one declaration at a time.

JohelEGP commented 1 month ago

operator=s could also be generated.

This necessitates expanding the reflection API to reflect on function bodies.