@@ -62,6 +62,9 @@ export function new_ast_rewriter_cc({
6262 emit ( ) ;
6363 emit ( ` struct ASTRewriter::${ className } Visitor {` ) ;
6464 emit ( ` ${ opName } & rewrite;` ) ;
65+ emit (
66+ ` [[nodiscard]] auto translationUnit() const -> TranslationUnit* { return rewrite.unit_; }`
67+ ) ;
6568 emit ( ) ;
6669 emit (
6770 ` [[nodiscard]] auto arena() const -> Arena* { return rewrite.arena(); }`
@@ -88,8 +91,20 @@ export function new_ast_rewriter_cc({
8891 }
8992 case "node-list" : {
9093 emit ( ) ;
94+
95+ // check the base type has a context that must be passed
96+ switch ( m . type ) {
97+ case "SpecifierAST" :
98+ emit ( ` DeclSpecs ${ m . name } Ctx{translationUnit()};` ) ;
99+ break ;
100+
101+ default :
102+ break ;
103+ } // switch
104+
91105 emit ( ` if (auto it = ast->${ m . name } ) {` ) ;
92106 emit ( ` auto out = ©->${ m . name } ;` ) ;
107+
93108 emit ( ` for (auto node : ListView{ast->${ m . name } }) {` ) ;
94109 emit ( ` auto value = ${ visitor } (node);` ) ;
95110 if ( isBase ( m . type ) ) {
@@ -98,6 +113,17 @@ export function new_ast_rewriter_cc({
98113 emit ( `*out = new (arena()) List(ast_cast<${ m . type } >(value));` ) ;
99114 }
100115 emit ( ` out = &(*out)->next;` ) ;
116+
117+ // update the context if needed
118+ switch ( m . type ) {
119+ case "SpecifierAST" :
120+ emit ( `${ m . name } Ctx.accept(value);` ) ;
121+ break ;
122+
123+ default :
124+ break ;
125+ } // switch
126+
101127 emit ( ` }` ) ;
102128 emit ( ` }` ) ;
103129 emit ( ) ;
@@ -118,21 +144,34 @@ export function new_ast_rewriter_cc({
118144 by_base . forEach ( ( nodes , base ) => {
119145 if ( base === "AST" ) return ;
120146 emit ( ) ;
121- if ( base == "ExpressionAST" ) {
122- emit ( `auto ${ opName } ::operator()(${ base } * ast) -> ${ base } * {` ) ;
123- emit ( ` if (!ast) return {};` ) ;
124- emit ( ` auto expr = visit(${ chopAST ( base ) } Visitor{*this}, ast);` ) ;
125- emit ( ` if (expr) typeChecker_->check(expr);` ) ;
126- emit ( ` return expr;` ) ;
127- emit ( `}` ) ;
128- } else {
129- emit ( `auto ${ opName } ::operator()(${ base } * ast) -> ${ base } * {` ) ;
130- emit ( ` if (ast)` ) ;
131- emit ( ` return visit(${ chopAST ( base ) } Visitor{*this}, ast);` ) ;
132- emit ( ` return {};` ) ;
133- emit ( `}` ) ;
134- }
147+
148+ switch ( base ) {
149+ case "ExpressionAST" :
150+ emit ( `auto ${ opName } ::operator()(${ base } * ast) -> ${ base } * {` ) ;
151+ emit ( ` if (!ast) return {};` ) ;
152+ emit ( ` auto expr = visit(${ chopAST ( base ) } Visitor{*this}, ast);` ) ;
153+ emit ( ` if (expr) typeChecker_->check(expr);` ) ;
154+ emit ( ` return expr;` ) ;
155+ emit ( `}` ) ;
156+ break ;
157+
158+ case "SpecifierAST" :
159+ emit ( `auto ${ opName } ::operator()(${ base } * ast) -> ${ base } * {` ) ;
160+ emit ( ` if (!ast) return {};` ) ;
161+ emit ( ` auto specifier = visit(${ chopAST ( base ) } Visitor{*this}, ast);` ) ;
162+ emit ( ` return specifier;` ) ;
163+ emit ( `}` ) ;
164+ break ;
165+
166+ default :
167+ emit ( `auto ${ opName } ::operator()(${ base } * ast) -> ${ base } * {` ) ;
168+ emit ( ` if (!ast) return {};` ) ;
169+ emit ( ` return visit(${ chopAST ( base ) } Visitor{*this}, ast);` ) ;
170+ emit ( `}` ) ;
171+ break ;
172+ } // switch
135173 } ) ;
174+
136175 by_base . get ( "AST" ) ?. forEach ( ( { name, members } ) => {
137176 emit ( ) ;
138177 emit ( `auto ${ opName } ::operator()(${ name } * ast) -> ${ name } * {` ) ;
@@ -176,6 +215,7 @@ export function new_ast_rewriter_cc({
176215#include <cxx/control.h>
177216#include <cxx/translation_unit.h>
178217#include <cxx/type_checker.h>
218+ #include <cxx/decl_specs.h>
179219
180220namespace cxx {
181221
0 commit comments