On 4/9/24 01:27, Stephan T. Lavavej wrote:
[Andrey Semashev]
Why changing compiler options affects C++ AST?
Increasing /std:c++20 to /std:c++latest (or /std:c++23, /std:c++26, etc. in the future) causes lots of stuff to appear, some stuff to disappear, some stuff to be marked as deprecated, more stuff to be marked as constexpr, and some stuff simply changes form (return types have been changed from void to non-void in the past, classes have gained typedefs, etc.).
Changing between static linking and dynamic linking (/MT versus /MD) affects whether things are declared as __declspec(dllimport).
Changing between release and debug (/MT or /MD versus /MTd or /MDd) massively affects the representations of classes, and the code that they execute.
The calling convention options (/Gd /Gr /Gv /Gz) affect whether functions are treated as __cdecl, __stdcall, __fastcall, __vectorcall, etc.
The /Zp option (affecting packing) affects the layout of classes. The STL defends itself against this one, but most code doesn't bother.
There are many escape hatches for Standard behavior that affect semantics:
The accursed /Zc:wchar_t- affects whether wchar_t is a real type or a fake unsigned short.
/Zc:noexceptTypes- affects whether noexcept participates in the type system, which the STL has to occasionally react to by omitting noexcept from function pointer typedefs.
/Zc:char8_t- removes char8_t from the type system, and the STL has to react accordingly.
And on, and on, and on. I haven't even mentioned the macro modes we support (like controlling deprecations, restoring removed machinery, etc.). Shipping all possible combinations of these settings is impossible.
Many of the things you mentioned above have no effect on the AST. For example, it doesn't matter which calling convention or struct packing the user chooses, it doesn't affect the function or class definitions. It affects code generation, yes, but that does not take place when modules are compiled. Even wchar_t, char8_t, noexcept being part of the type system and deprecation markup (presumably, using __declspec) should not matter since the AST should contain these tokens either way. The different options control *interpretation* of these tokens, and will only affect template instantiations, overload resolution, name mangling and code generation, none of which happens during module compilation. So, of the options you mentioned, only the C++ version, static/shared linking and debug/release version are the options that may in fact affect AST. This seems manageable.