Thank you @JohnReagan .
Macro expansion is a part of OpenVMS listing file implementation in OpenVMS C++ compiler.
OpenVMS listing file is a generated file which shows the module(source file) it is generated from, its modification time, the compiler version, compilation time, the content of main file and its included files ( #include directives, in an expanded form), diagnostic messages, expanded macros, the command line, predefined macros on compilation time, etc…
The listing file generation and inclusion of some parts of it is controlled by command line option and flags.
I want to give few more examples of macro expansion:
1093 #define ADD_ONE(X) ((X) + 1)
1094 #define ADD_TWO(X) (ADD_ONE(X) + 1)
1095 #define ADD_THREE(X) ((X) + 3)
1096 #define ADD_FIVE(X) (ADD_TWO(X) + ADD_THREE(X))
1097
1098 #if __clang__
E #if 1
1099 #define ADD_TEN(Y) (ADD_FIVE(Y) + 5)
1100 int gl = ADD_TEN(10);
E ( ( ( ( ( 10 ) + 1 ) + 1 ) + ( ( 10 ) + 3 ) ) + 5 )
10 #if __cplusplus
E #if 201703L
11
12 #if __has_feature(cxx_alignas)
E #if 1
7 #define ADD_TEN(Y) (Y + 10)
8 #define foo(u) 42
9 #define bar(x, y) x(y)
10 #define EMPTYY
11 #define EMPTY() EMPTYY
12 #define DEFER(...) __VA_ARGS__ EMPTY()
13
14 int main() {
15 int f = DEFER(ADD_TEN(bar(foo, -4)));
E ( 42 + 10 )
16 return 0;
17 }
A shallow description of macro expansion implementation:
I added struct ListingFileGeneratorPPCallback derived from PPCallbacks class. This struct holds a lot of current information needed to generate the listing file, and the macro expansion is a part of it. I added new function virtual void MacroExpandsForListing(StringRef MacroExpansionStr) in the class PPCallbackswhich already has virtual function MacroExpands()`. This new PP callback is registered in CompilerInstance::createPreprocessor() function, which actually creates the Preprocessor, by the member object of class ListingFileGenerator.
The function MacroExpandsForListing() is called in Preprocessor’s static functions CLK_Lexer, CLK_TokenLexer, Preprocessor::HandleMacroExpandedIdentifier, Preprocessor::ExpandBuiltinMacro functions under certain conditions.
New calls to the function MacroExpands() are not added.
The Preprocessor has new member std::string ListingExpansion;which holds currently expanding string. This member is passed to the function MacroExpandsForListing() and is clear()ed right after the call. This function finalizes macro expansion string and writes into the listing file.
The Preprocess has new void AddListingExpansion(StringRef str); which gathers(appends) currently expanding macro/string in many different places, like EvaluateDefined(), EvaluateValue(), EvaluateDirectiveSubExpr(), Preprocessor::HandleMacroExpandedIdentifier(), Preprocessor::ExpandBuiltinMacro(), CLK_TokenLexer().
OpenVMS C++ compiler is not publicly visible, so I can’t point you to our implementation.