source: src/AST/Convert.cpp @ 0b73f0c

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 0b73f0c was 0b73f0c, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

More progress on the conversion pass

  • Property mode set to 100644
File size: 72.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Convert.cpp -- Convert between the new and old syntax trees.
8//
9// Author           : Thierry Delisle
10// Created On       : Thu May 09 15::37::05 2019
11// Last Modified By : Andrew Beach
12// Last Modified On : Thu May 06 19:51:00 2019
13// Update Count     : 10
14//
15
16#include "Convert.hpp"
17
18#include <unordered_map>
19
20#include "AST/Attribute.hpp"
21#include "AST/Decl.hpp"
22#include "AST/Expr.hpp"
23#include "AST/Init.hpp"
24#include "AST/Stmt.hpp"
25#include "AST/TypeSubstitution.hpp"
26
27#include "SymTab/Autogen.h"
28#include "SynTree/Attribute.h"
29#include "SynTree/Declaration.h"
30#include "SynTree/TypeSubstitution.h"
31
32#include "Validate/FindSpecialDecls.h"
33
34//================================================================================================
35// Utilities
36template<template <class...> class C>
37struct to {
38        template<typename T>
39        static auto from( T && v ) -> C< typename T::value_type > {
40                C< typename T::value_type > l;
41                std::move(std::begin(v), std::end(v), std::back_inserter(l));
42                return l;
43        }
44};
45
46//================================================================================================
47namespace {
48
49// This is to preserve the FindSpecialDecls hack. It does not (and perhaps should not)
50// allow us to use the same stratagy in the new ast.
51ast::Type * sizeType = nullptr;
52ast::FunctionDecl * dereferenceOperator = nullptr;
53ast::StructDecl   * dtorStruct = nullptr;
54ast::FunctionDecl * dtorStructDestroy = nullptr;
55
56}
57
58//================================================================================================
59class ConverterNewToOld : public ast::Visitor {
60        BaseSyntaxNode * node = nullptr;
61        using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >;
62        Cache cache;
63
64        template<typename T>
65        struct Getter {
66                ConverterNewToOld & visitor;
67
68                template<typename U, enum ast::Node::ref_type R>
69                T * accept1( const ast::ptr_base<U, R> & ptr ) {
70                        if ( ! ptr ) return nullptr;
71                        ptr->accept( visitor );
72                        T * ret = strict_dynamic_cast< T * >( visitor.node );
73                        visitor.node = nullptr;
74                        return ret;
75                }
76
77                template<typename U>
78                std::list< T * > acceptL( const U & container ) {
79                        std::list< T * > ret;
80                        for ( auto ptr : container ) {
81                                ret.emplace_back( accept1( ptr ) );
82                        }
83                        return ret;
84                }
85        };
86
87    template<typename T>
88    Getter<T> get() {
89        return Getter<T>{ *this };
90    }
91
92        Label makeLabel(Statement * labelled, const ast::Label& label) {
93                return Label(
94                        label.name,
95                        labelled,
96                        get<Attribute>().acceptL(label.attributes)
97                );
98        }
99
100        template<template <class...> class C>
101        std::list<Label> makeLabelL(Statement * labelled, const C<ast::Label>& labels) {
102                std::list<Label> ret;
103                for (auto label : labels) {
104                        ret.push_back( makeLabel(labelled, label) );
105                }
106                return ret;
107        }
108
109        /// get new qualifiers from old type
110        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
111
112        /// returns true and sets `node` if in cache
113        bool inCache( const ast::Node * node ) {
114                auto it = cache.find( node );
115                if ( it == cache.end() ) return false;
116                this->node = it->second;
117                return true;
118        }
119
120public:
121        Declaration * decl( const ast::Decl * declNode ) {
122                return get<Declaration>().accept1( ast::ptr<ast::Decl>( declNode ) );
123        }
124
125private:
126        void declPostamble( Declaration * decl, const ast::Decl * node ) {
127                decl->location = node->location;
128                // name comes from constructor
129                // linkage comes from constructor
130                decl->extension = node->extension;
131                decl->uniqueId = node->uniqueId;
132                // storageClasses comes from constructor
133                this->node = decl;
134        }
135
136        const ast::DeclWithType * declWithTypePostamble (
137                        DeclarationWithType * decl, const ast::DeclWithType * node ) {
138                cache.emplace( node, decl );
139                decl->mangleName = node->mangleName;
140                decl->scopeLevel = node->scopeLevel;
141                decl->asmName = get<Expression>().accept1( node->asmName );
142                // attributes comes from constructor
143                decl->isDeleted = node->isDeleted;
144                // fs comes from constructor
145                declPostamble( decl, node );
146                return nullptr;
147        }
148
149        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
150                auto&& bfwd = get<Expression>().accept1( node->bitfieldWidth );
151                auto&& type = get<Type>().accept1( node->type );
152                auto&& init = get<Initializer>().accept1( node->init );
153                auto&& attr = get<Attribute>().acceptL( node->attributes );
154                if ( inCache( node ) ) {
155                        if(node->name == "tmp") {
156                                std::cerr << (void*)node << "(new) in cache " << (void*)this->node << "(old)" << std::endl;
157                        }
158                        return nullptr;
159                }
160                auto decl = new ObjectDecl(
161                        node->name,
162                        Type::StorageClasses( node->storage.val ),
163                        LinkageSpec::Spec( node->linkage.val ),
164                        bfwd,
165                        type,
166                        init,
167                        attr,
168                        Type::FuncSpecifiers( node->funcSpec.val )
169                );
170                if(node->name == "tmp") {
171                        std::cerr << (void*)node << "(new) created " << (void*)decl << "(old)" << std::endl;
172                }
173                return declWithTypePostamble( decl, node );
174        }
175
176        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
177                if ( inCache( node ) ) return nullptr;
178                auto decl = new FunctionDecl(
179                        node->name,
180                        Type::StorageClasses( node->storage.val ),
181                        LinkageSpec::Spec( node->linkage.val ),
182                        get<FunctionType>().accept1( node->type ),
183                        {},
184                        get<Attribute>().acceptL( node->attributes ),
185                        Type::FuncSpecifiers( node->funcSpec.val )
186                );
187                cache.emplace( node, decl );
188                decl->statements = get<CompoundStmt>().accept1( node->stmts );
189                decl->withExprs = get<Expression>().acceptL( node->withExprs );
190                if ( dereferenceOperator == node ) {
191                        Validate::dereferenceOperator = decl;
192                }
193                if ( dtorStructDestroy == node ) {
194                        Validate::dtorStructDestroy = decl;
195                }
196                return declWithTypePostamble( decl, node );
197        }
198
199        const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
200                // base comes from constructor
201                decl->parameters = get<TypeDecl>().acceptL( node->params );
202                decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
203                declPostamble( decl, node );
204                return nullptr;
205        }
206
207        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
208                if ( inCache( node ) ) return nullptr;
209                auto decl = new TypeDecl(
210                        node->name,
211                        Type::StorageClasses( node->storage.val ),
212                        get<Type>().accept1( node->base ),
213                        (TypeDecl::Kind)(unsigned)node->kind,
214                        node->sized,
215                        get<Type>().accept1( node->init )
216                );
217                cache.emplace( node, decl );
218                return namedTypePostamble( decl, node );
219        }
220
221        const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
222                auto decl = new TypedefDecl(
223                        node->name,
224                        node->location,
225                        Type::StorageClasses( node->storage.val ),
226            get<Type>().accept1( node->base ),
227                        LinkageSpec::Spec( node->linkage.val )
228                );
229                return namedTypePostamble( decl, node );
230        }
231
232        const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
233                cache.emplace( node, decl );
234                decl->members = get<Declaration>().acceptL( node->members );
235                decl->parameters = get<TypeDecl>().acceptL( node->params );
236                decl->body = node->body;
237                // attributes come from constructor
238                decl->parent = get<AggregateDecl>().accept1( node->parent );
239                declPostamble( decl, node );
240                return nullptr;
241        }
242
243        const ast::Decl * visit( const ast::StructDecl * node ) override final {
244                if ( inCache( node ) ) return nullptr;
245                auto decl = new StructDecl(
246                        node->name,
247                        node->kind,
248                        get<Attribute>().acceptL( node->attributes ),
249                        LinkageSpec::Spec( node->linkage.val )
250                );
251
252                if ( dtorStruct == node ) {
253                        Validate::dtorStruct = decl;
254                }
255
256                return aggregatePostamble( decl, node );
257        }
258
259        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
260                if ( inCache( node ) ) return nullptr;
261                auto decl = new UnionDecl(
262                        node->name,
263                        get<Attribute>().acceptL( node->attributes ),
264                        LinkageSpec::Spec( node->linkage.val )
265                );
266                return aggregatePostamble( decl, node );
267        }
268
269        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
270                if ( inCache( node ) ) return nullptr;
271                auto decl = new EnumDecl(
272                        node->name,
273                        get<Attribute>().acceptL( node->attributes ),
274                        LinkageSpec::Spec( node->linkage.val )
275                );
276                return aggregatePostamble( decl, node );
277        }
278
279        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
280                if ( inCache( node ) ) return nullptr;
281                auto decl = new TraitDecl(
282                        node->name,
283                        {},
284                        LinkageSpec::Spec( node->linkage.val )
285                );
286                return aggregatePostamble( decl, node );
287        }
288
289        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
290                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
291                declPostamble( decl, node );
292                return nullptr;
293        }
294
295        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
296                auto decl = new StaticAssertDecl(
297                        get<Expression>().accept1( node->cond ),
298                        get<ConstantExpr>().accept1( node->msg )
299                );
300                declPostamble( decl, node );
301                return nullptr;
302        }
303
304        const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
305                cache.emplace( node, stmt );
306                stmt->location = node->location;
307                stmt->labels = makeLabelL( stmt, node->labels );
308                this->node = stmt;
309                return nullptr;
310        }
311
312        const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
313                if ( inCache( node ) ) return nullptr;
314                auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
315                stmtPostamble( stmt, node );
316                return nullptr;
317        }
318
319        const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
320                if ( inCache( node ) ) return nullptr;
321                auto stmt = new ExprStmt( nullptr );
322                cache.emplace( node, stmt );
323                stmt->expr = get<Expression>().accept1( node->expr );
324                return stmtPostamble( stmt, node );
325        }
326
327        const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
328                if ( inCache( node ) ) return nullptr;
329                auto stmt = new AsmStmt(
330                        node->isVolatile,
331                        get<Expression>().accept1( node->instruction ),
332                        get<Expression>().acceptL( node->output ),
333                        get<Expression>().acceptL( node->input ),
334                        get<ConstantExpr>().acceptL( node->clobber ),
335                        makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
336                );
337                return stmtPostamble( stmt, node );
338        }
339
340        const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
341                if ( inCache( node ) ) return nullptr;
342                auto stmt = new DirectiveStmt( node->directive );
343                return stmtPostamble( stmt, node );
344        }
345
346        const ast::Stmt * visit( const ast::IfStmt * node ) override final {
347                if ( inCache( node ) ) return nullptr;
348                auto stmt = new IfStmt(
349                        get<Expression>().accept1( node->cond ),
350                        get<Statement>().accept1( node->thenPart ),
351                        get<Statement>().accept1( node->elsePart ),
352                        get<Statement>().acceptL( node->inits )
353                );
354                return stmtPostamble( stmt, node );
355        }
356
357        const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
358                if ( inCache( node ) ) return nullptr;
359                auto stmt = new SwitchStmt(
360                        get<Expression>().accept1( node->cond ),
361                        get<Statement>().acceptL( node->stmts )
362                );
363                return stmtPostamble( stmt, node );
364        }
365
366        const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
367                if ( inCache( node ) ) return nullptr;
368                auto stmt = new CaseStmt(
369                        get<Expression>().accept1( node->cond ),
370                        get<Statement>().acceptL( node->stmts ),
371                        node->isDefault()
372                );
373                return stmtPostamble( stmt, node );
374        }
375
376        const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
377                if ( inCache( node ) ) return nullptr;
378                auto inits = get<Statement>().acceptL( node->inits );
379                auto stmt = new WhileStmt(
380                        get<Expression>().accept1( node->cond ),
381                        get<Statement>().accept1( node->body ),
382                        inits,
383                        node->isDoWhile
384                );
385                return stmtPostamble( stmt, node );
386        }
387
388        const ast::Stmt * visit( const ast::ForStmt * node ) override final {
389                if ( inCache( node ) ) return nullptr;
390                auto stmt = new ForStmt(
391                        get<Statement>().acceptL( node->inits ),
392                        get<Expression>().accept1( node->cond ),
393                        get<Expression>().accept1( node->inc ),
394                        get<Statement>().accept1( node->body )
395                );
396                return stmtPostamble( stmt, node );
397        }
398
399        const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
400                if ( inCache( node ) ) return nullptr;
401                BranchStmt * stmt;
402                if (node->computedTarget) {
403                        stmt = new BranchStmt( get<Expression>().accept1( node->computedTarget ),
404                                BranchStmt::Goto );
405                } else {
406                        BranchStmt::Type type;
407                        switch (node->kind) {
408                        #define CASE(n) \
409                        case ast::BranchStmt::n: \
410                                type = BranchStmt::n; \
411                                break
412                        CASE(Goto);
413                        CASE(Break);
414                        CASE(Continue);
415                        CASE(FallThrough);
416                        CASE(FallThroughDefault);
417                        #undef CASE
418                        default:
419                                assertf(false, "Invalid ast::BranchStmt::Kind: %d\n", node->kind);
420                        }
421
422                        // The labels here are also weird.
423                        stmt = new BranchStmt( makeLabel( nullptr, node->originalTarget ), type );
424                        stmt->target = makeLabel( stmt, node->target );
425                }
426                return stmtPostamble( stmt, node );
427        }
428
429        const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
430                if ( inCache( node ) ) return nullptr;
431                auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
432                return stmtPostamble( stmt, node );
433        }
434
435        const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
436                if ( inCache( node ) ) return nullptr;
437                ThrowStmt::Kind kind;
438                switch (node->kind) {
439                case ast::ExceptionKind::Terminate:
440                        kind = ThrowStmt::Terminate;
441                        break;
442                case ast::ExceptionKind::Resume:
443                        kind = ThrowStmt::Resume;
444                        break;
445                default:
446                        assertf(false, "Invalid ast::ThrowStmt::Kind: %d\n", node->kind);
447                }
448                auto stmt = new ThrowStmt(
449                        kind,
450                        get<Expression>().accept1( node->expr ),
451                        get<Expression>().accept1( node->target )
452                );
453                return stmtPostamble( stmt, node );
454        }
455
456        const ast::Stmt * visit( const ast::TryStmt * node ) override final {
457                if ( inCache( node ) ) return nullptr;
458                auto handlers = get<CatchStmt>().acceptL( node->handlers );
459                auto stmt = new TryStmt(
460                        get<CompoundStmt>().accept1( node->body ),
461                        handlers,
462                        get<FinallyStmt>().accept1( node->finally )
463                );
464                return stmtPostamble( stmt, node );
465        }
466
467        const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
468                if ( inCache( node ) ) return nullptr;
469                CatchStmt::Kind kind;
470                switch (node->kind) {
471                case ast::ExceptionKind::Terminate:
472                        kind = CatchStmt::Terminate;
473                        break;
474                case ast::ExceptionKind::Resume:
475                        kind = CatchStmt::Resume;
476                        break;
477                default:
478                        assertf(false, "Invalid ast::CatchStmt::Kind: %d\n", node->kind);
479                }
480                auto stmt = new CatchStmt(
481                        kind,
482                        get<Declaration>().accept1( node->decl ),
483                        get<Expression>().accept1( node->cond ),
484                        get<Statement>().accept1( node->body )
485                );
486                return stmtPostamble( stmt, node );
487        }
488
489        const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
490                if ( inCache( node ) ) return nullptr;
491                auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
492                return stmtPostamble( stmt, node );
493        }
494
495        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
496                if ( inCache( node ) ) return nullptr;
497                auto stmt = new WaitForStmt;
498                stmt->clauses.reserve( node->clauses.size() );
499                for ( auto clause : node->clauses ) {
500                        stmt->clauses.push_back({{
501                                        get<Expression>().accept1( clause.target.func ),
502                                        get<Expression>().acceptL( clause.target.args ),
503                                },
504                                get<Statement>().accept1( clause.stmt ),
505                                get<Expression>().accept1( clause.cond ),
506                        });
507                }
508                stmt->timeout = {
509                        get<Expression>().accept1( node->timeout.time ),
510                        get<Statement>().accept1( node->timeout.stmt ),
511                        get<Expression>().accept1( node->timeout.cond ),
512                };
513                stmt->orelse = {
514                        get<Statement>().accept1( node->orElse.stmt ),
515                        get<Expression>().accept1( node->orElse.cond ),
516                };
517                return stmtPostamble( stmt, node );
518        }
519
520        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
521                if ( inCache( node ) ) return nullptr;
522                auto stmt = new WithStmt(
523                        get<Expression>().acceptL( node->exprs ),
524                        get<Statement>().accept1( node->stmt )
525                );
526                return stmtPostamble( stmt, node );
527        }
528
529        const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
530                if ( inCache( node ) ) return nullptr;
531                auto stmt = new NullStmt();
532                stmtPostamble( stmt, node );
533                return nullptr;
534        }
535
536        const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
537                if ( inCache( node ) ) return nullptr;
538                auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
539                return stmtPostamble( stmt, node );
540        }
541
542        const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
543                if ( inCache( node ) ) return nullptr;
544                auto stmt = new ImplicitCtorDtorStmt{
545                        get<Statement>().accept1( node->callStmt )
546                };
547                return stmtPostamble( stmt, node );
548        }
549
550        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
551
552                if (!src) return nullptr;
553
554                TypeSubstitution *rslt = new TypeSubstitution();
555
556                for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
557                        rslt->add( src_i->first,
558                                   get<Type>().accept1(src_i->second) );
559                }
560
561                for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
562                        rslt->addVar( src_i->first,
563                                      get<Expression>().accept1(src_i->second) );
564                }
565
566                return rslt;
567        }
568
569        void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
570                                                   std::vector<UniqueId>         &tgtResnSlots,
571                                                   const ast::Expr::InferUnion   &srcInferred ) {
572
573                assert( tgtInferParams.empty() );
574                assert( tgtResnSlots.empty() );
575
576                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
577                        const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
578                        for (auto srcParam : srcParams) {
579                                tgtInferParams[srcParam.first] = ParamEntry(
580                                        srcParam.second.decl,
581                                        get<Type>().accept1(srcParam.second.actualType),
582                                        get<Type>().accept1(srcParam.second.formalType),
583                                        get<Expression>().accept1(srcParam.second.expr)
584                                );
585                        }
586                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
587                        const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
588                        for (auto srcSlot : srcSlots) {
589                                tgtResnSlots.push_back(srcSlot);
590                        }
591                }
592        }
593
594        Expression * visitBaseExpr_skipResultType(const ast::Expr * src, Expression * tgt) {
595
596                tgt->location  = src->location;
597                tgt->env       = convertTypeSubstitution(src->env);
598                tgt->extension = src->extension;
599
600                convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
601                return tgt;
602        }
603
604        Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
605
606                tgt->result = get<Type>().accept1(src->result);
607                return visitBaseExpr_skipResultType(src, tgt);
608        }
609
610        const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
611                auto expr = visitBaseExpr( node,
612                        new ApplicationExpr(
613                                get<Expression>().accept1(node->func),
614                                get<Expression>().acceptL(node->args)
615                        )
616                );
617                this->node = expr;
618                return nullptr;
619        }
620
621        const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
622                auto expr = visitBaseExpr( node,
623                        new UntypedExpr(
624                                get<Expression>().accept1(node->func),
625                                get<Expression>().acceptL(node->args)
626                        )
627                );
628                this->node = expr;
629                return nullptr;
630        }
631
632        const ast::Expr * visit( const ast::NameExpr * node ) override final {
633                auto expr = visitBaseExpr( node,
634                        new NameExpr(
635                                node->name
636                        )
637                );
638                this->node = expr;
639                return nullptr;
640        }
641
642        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
643                auto expr = visitBaseExpr( node,
644                        new AddressExpr(
645                                get<Expression>().accept1(node->arg)
646                        )
647                );
648                this->node = expr;
649                return nullptr;
650        }
651
652        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
653                auto expr = visitBaseExpr( node,
654                        new LabelAddressExpr(
655                                makeLabel(nullptr, node->arg)
656                        )
657                );
658                this->node = expr;
659                return nullptr;
660        }
661
662        const ast::Expr * visit( const ast::CastExpr * node ) override final {
663                auto expr = visitBaseExpr( node,
664                        new CastExpr(
665                                get<Expression>().accept1(node->arg),
666                                (node->isGenerated == ast::GeneratedCast)
667                        )
668                );
669                this->node = expr;
670                return nullptr;
671        }
672
673        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
674                KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
675                switch (node->target) {
676                        case ast::KeywordCastExpr::Coroutine:
677                                castTarget = KeywordCastExpr::Coroutine;
678                                break;
679                        case ast::KeywordCastExpr::Thread:
680                                castTarget = KeywordCastExpr::Thread;
681                                break;
682                        case ast::KeywordCastExpr::Monitor:
683                                castTarget = KeywordCastExpr::Monitor;
684                                break;
685                        default:
686                                break;
687                }
688                assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
689                auto expr = visitBaseExpr( node,
690                        new KeywordCastExpr(
691                                get<Expression>().accept1(node->arg),
692                                castTarget
693                        )
694                );
695                this->node = expr;
696                return nullptr;
697        }
698
699        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
700                auto expr = visitBaseExpr_skipResultType( node,
701                        new VirtualCastExpr(
702                                get<Expression>().accept1(node->arg),
703                                get<Type>().accept1(node->result)
704                        )
705                );
706                this->node = expr;
707                return nullptr;
708        }
709
710        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
711                auto expr = visitBaseExpr( node,
712                        new UntypedMemberExpr(
713                                get<Expression>().accept1(node->member),
714                                get<Expression>().accept1(node->aggregate)
715                        )
716                );
717                this->node = expr;
718                return nullptr;
719        }
720
721        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
722                auto expr = visitBaseExpr( node,
723                        new MemberExpr(
724                                get<DeclarationWithType>().accept1(node->member),
725                                get<Expression>().accept1(node->aggregate)
726                        )
727                );
728                this->node = expr;
729                return nullptr;
730        }
731
732        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
733                auto expr = new VariableExpr();
734                visitBaseExpr( node, expr );
735                expr->var = get<DeclarationWithType>().accept1(node->var);
736                Type * type = expr->var->get_type()->clone();
737                if(FunctionType * ft = dynamic_cast<FunctionType*>(type)) {
738                        if(node->result.as<ast::PointerType>()) {
739                                type = new PointerType({}, ft);
740                        }
741                }
742
743                type->set_lvalue( true );
744                expr->result = type ;
745                this->node = expr;
746                return nullptr;
747        }
748
749        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
750                ConstantExpr *rslt = nullptr;
751                switch ( node->kind ) {
752                case ast::ConstantExpr::Integer:
753                        rslt = new ConstantExpr{Constant{
754                                get<Type>().accept1( node->result ),
755                                node->rep,
756                                (unsigned long long) node->intValue()
757                        }};
758                        break;
759                case ast::ConstantExpr::FloatingPoint:
760                        rslt = new ConstantExpr{Constant{
761                                get<Type>().accept1(node->result),
762                                node->rep,
763                                (double) node->floatValue()
764                        }};
765                        break;
766                case ast::ConstantExpr::String:
767                        rslt = new ConstantExpr{Constant{
768                                get<Type>().accept1( node->result ),
769                                node->rep,
770                                (long long unsigned int)0
771                        }};
772                        break;
773                }
774                assert(rslt);
775                auto expr = visitBaseExpr( node, rslt );
776                this->node = expr;
777                return nullptr;
778        }
779
780        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
781                assert (node->expr || node->type);
782                assert (! (node->expr && node->type));
783                SizeofExpr *rslt;
784                if (node->expr) {
785                        rslt = new SizeofExpr(
786                                get<Expression>().accept1(node->expr)
787                        );
788                        assert (!rslt->isType);
789                }
790                else {
791                        assert(node->type);
792                        rslt = new SizeofExpr(
793                                get<Type>().accept1(node->type)
794                        );
795                        assert (rslt->isType);
796                }
797                auto expr = visitBaseExpr( node, rslt );
798                this->node = expr;
799                return nullptr;
800        }
801
802        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
803                assert (node->expr || node->type);
804                assert (! (node->expr && node->type));
805                AlignofExpr *rslt;
806                if (node->expr) {
807                        rslt = new AlignofExpr(
808                                get<Expression>().accept1(node->expr)
809                        );
810                        assert (!rslt->isType);
811                }
812                else {
813                        assert(node->type);
814                        rslt = new AlignofExpr(
815                                get<Type>().accept1(node->type)
816                        );
817                        assert (rslt->isType);
818                }
819                auto expr = visitBaseExpr( node, rslt );
820                this->node = expr;
821                return nullptr;
822        }
823
824        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
825                auto expr = visitBaseExpr( node,
826                        new UntypedOffsetofExpr(
827                                get<Type>().accept1(node->type),
828                                node->member
829                        )
830                );
831                this->node = expr;
832                return nullptr;
833        }
834
835        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
836                auto expr = visitBaseExpr( node,
837                        new OffsetofExpr(
838                                get<Type>().accept1(node->type),
839                                get<DeclarationWithType>().accept1(node->member)
840                        )
841                );
842                this->node = expr;
843                return nullptr;
844        }
845
846        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
847                auto expr = visitBaseExpr( node,
848                        new OffsetPackExpr(
849                                get<StructInstType>().accept1(node->type)
850                        )
851                );
852                this->node = expr;
853                return nullptr;
854        }
855
856        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
857                assert (node->isAnd == ast::LogicalFlag::AndExpr ||
858                                node->isAnd == ast::LogicalFlag::OrExpr );
859                auto expr = visitBaseExpr( node,
860                        new LogicalExpr(
861                                get<Expression>().accept1(node->arg1),
862                                get<Expression>().accept1(node->arg2),
863                                (node->isAnd == ast::LogicalFlag::AndExpr)
864                        )
865                );
866                this->node = expr;
867                return nullptr;
868        }
869
870        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
871                auto expr = visitBaseExpr( node,
872                        new ConditionalExpr(
873                                get<Expression>().accept1(node->arg1),
874                                get<Expression>().accept1(node->arg2),
875                                get<Expression>().accept1(node->arg3)
876                        )
877                );
878                this->node = expr;
879                return nullptr;
880        }
881
882        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
883                auto expr = visitBaseExpr( node,
884                        new CommaExpr(
885                                get<Expression>().accept1(node->arg1),
886                                get<Expression>().accept1(node->arg2)
887                        )
888                );
889                this->node = expr;
890                return nullptr;
891        }
892
893        const ast::Expr * visit( const ast::TypeExpr * node ) override final {
894                auto expr = visitBaseExpr( node,
895                        new TypeExpr(
896                                get<Type>().accept1(node->type)
897                        )
898                );
899                this->node = expr;
900                return nullptr;
901        }
902
903        const ast::Expr * visit( const ast::AsmExpr * node ) override final {
904                auto expr = visitBaseExpr( node,
905                        new AsmExpr(
906                                get<Expression>().accept1(node->inout),
907                                get<Expression>().accept1(node->constraint),
908                                get<Expression>().accept1(node->operand)
909                        )
910                );
911                this->node = expr;
912                return nullptr;
913        }
914
915        const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
916                auto rslt = new ImplicitCopyCtorExpr(
917                        get<ApplicationExpr>().accept1(node->callExpr)
918                );
919
920                auto expr = visitBaseExpr( node, rslt );
921                this->node = expr;
922                return nullptr;
923        }
924
925        const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
926                auto expr = visitBaseExpr( node,
927                        new ConstructorExpr(
928                                get<Expression>().accept1(node->callExpr)
929                        )
930                );
931                this->node = expr;
932                return nullptr;
933        }
934
935        const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
936                auto expr = visitBaseExpr_skipResultType( node,
937                        new CompoundLiteralExpr(
938                                get<Type>().accept1(node->result),
939                                get<Initializer>().accept1(node->init)
940                        )
941                );
942                this->node = expr;
943                return nullptr;
944        }
945
946        const ast::Expr * visit( const ast::RangeExpr * node ) override final {
947                auto expr = visitBaseExpr( node,
948                        new RangeExpr(
949                                get<Expression>().accept1(node->low),
950                                get<Expression>().accept1(node->high)
951                        )
952                );
953                this->node = expr;
954                return nullptr;
955        }
956
957        const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
958                auto expr = visitBaseExpr( node,
959                        new UntypedTupleExpr(
960                                get<Expression>().acceptL(node->exprs)
961                        )
962                );
963                this->node = expr;
964                return nullptr;
965        }
966
967        const ast::Expr * visit( const ast::TupleExpr * node ) override final {
968                auto expr = visitBaseExpr( node,
969                        new UntypedTupleExpr(
970                                get<Expression>().acceptL(node->exprs)
971                        )
972                );
973                this->node = expr;
974                return nullptr;
975        }
976
977        const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
978                auto expr = visitBaseExpr( node,
979                        new TupleIndexExpr(
980                                get<Expression>().accept1(node->tuple),
981                                node->index
982                        )
983                );
984                this->node = expr;
985                return nullptr;
986        }
987
988        const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
989                auto expr = visitBaseExpr( node,
990                        new TupleAssignExpr(
991                                get<StmtExpr>().accept1(node->stmtExpr)
992                        )
993                );
994                this->node = expr;
995                return nullptr;
996        }
997
998        const ast::Expr * visit( const ast::StmtExpr * node ) override final {
999                auto rslt = new StmtExpr(
1000                        get<CompoundStmt>().accept1(node->stmts)
1001                );
1002
1003                rslt->returnDecls = get<ObjectDecl>().acceptL(node->returnDecls);
1004                rslt->dtors       = get<Expression>().acceptL(node->dtors);
1005
1006                auto expr = visitBaseExpr( node, rslt );
1007                this->node = expr;
1008                return nullptr;
1009        }
1010
1011        const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
1012                auto rslt = new UniqueExpr(
1013                        get<Expression>().accept1(node->expr)
1014                );
1015
1016                rslt->object = get<ObjectDecl>  ().accept1(node->object);
1017                rslt->var    = get<VariableExpr>().accept1(node->var);
1018
1019                auto expr = visitBaseExpr( node, rslt );
1020                this->node = expr;
1021                return nullptr;
1022        }
1023
1024        const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
1025                std::list<InitAlternative> initAlts;
1026                for (auto ia : node->initAlts) {
1027                        initAlts.push_back(InitAlternative(
1028                                get<Type>       ().accept1(ia.type),
1029                                get<Designation>().accept1(ia.designation)
1030                        ));
1031                }
1032                auto expr = visitBaseExpr( node,
1033                        new UntypedInitExpr(
1034                                get<Expression>().accept1(node->expr),
1035                                initAlts
1036                        )
1037                );
1038                this->node = expr;
1039                return nullptr;
1040        }
1041
1042        const ast::Expr * visit( const ast::InitExpr * node ) override final {
1043                auto expr = visitBaseExpr( node,
1044                        new InitExpr(
1045                                get<Expression>().accept1(node->expr),
1046                                get<Designation>().accept1(node->designation)
1047                        )
1048                );
1049                this->node = expr;
1050                return nullptr;
1051        }
1052
1053        const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
1054                auto expr = visitBaseExpr( node,
1055                        new DeletedExpr(
1056                                get<Expression>().accept1(node->expr),
1057                                inCache(node->deleteStmt) ?
1058                                        this->node :
1059                                        get<BaseSyntaxNode>().accept1(node->deleteStmt)
1060                        )
1061                );
1062                this->node = expr;
1063                return nullptr;
1064        }
1065
1066        const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
1067                auto expr = visitBaseExpr( node,
1068                        new DefaultArgExpr(
1069                                get<Expression>().accept1(node->expr)
1070                        )
1071                );
1072                this->node = expr;
1073                return nullptr;
1074        }
1075
1076        const ast::Expr * visit( const ast::GenericExpr * node ) override final {
1077                std::list<GenericExpr::Association> associations;
1078                for (auto association : node->associations) {
1079                        associations.push_back(GenericExpr::Association(
1080                                get<Type>      ().accept1(association.type),
1081                                get<Expression>().accept1(association.expr)
1082                        ));
1083                }
1084                auto expr = visitBaseExpr( node,
1085                        new GenericExpr(
1086                                get<Expression>().accept1(node->control),
1087                                associations
1088                        )
1089                );
1090                this->node = expr;
1091                return nullptr;
1092        }
1093
1094        const ast::Type * visit( const ast::VoidType * node ) override final {
1095                this->node = new VoidType{ cv( node ) };
1096                return nullptr;
1097        }
1098
1099        const ast::Type * visit( const ast::BasicType * node ) override final {
1100                auto type = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
1101                // I believe this should always be a BasicType.
1102                if ( sizeType == node ) {
1103                        Validate::SizeType = type;
1104                }
1105                this->node = type;
1106                return nullptr;
1107        }
1108
1109        const ast::Type * visit( const ast::PointerType * node ) override final {
1110                this->node = new PointerType{
1111                        cv( node ),
1112                        get<Type>().accept1( node->base ),
1113                        get<Expression>().accept1( node->dimension ),
1114                        (bool)node->isVarLen,
1115                        (bool)node->isStatic
1116                };
1117                return nullptr;
1118        }
1119
1120        const ast::Type * visit( const ast::ArrayType * node ) override final {
1121                this->node = new ArrayType{
1122                        cv( node ),
1123                        get<Type>().accept1( node->base ),
1124                        get<Expression>().accept1( node->dimension ),
1125                        (bool)node->isVarLen,
1126                        (bool)node->isStatic
1127                };
1128                return nullptr;
1129        }
1130
1131        const ast::Type * visit( const ast::ReferenceType * node ) override final {
1132                this->node = new ReferenceType{
1133                        cv( node ),
1134                        get<Type>().accept1( node->base )
1135                };
1136                return nullptr;
1137        }
1138
1139        const ast::Type * visit( const ast::QualifiedType * node ) override final {
1140                this->node = new QualifiedType{
1141                        cv( node ),
1142                        get<Type>().accept1( node->parent ),
1143                        get<Type>().accept1( node->child )
1144                };
1145                return nullptr;
1146        }
1147
1148        const ast::Type * visit( const ast::FunctionType * node ) override final {
1149                auto ty = new FunctionType {
1150                        cv( node ),
1151                        (bool)node->isVarArgs
1152                };
1153                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
1154                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
1155                ty->forall = get<TypeDecl>().acceptL( node->forall );
1156                this->node = ty;
1157                return nullptr;
1158        }
1159
1160        void postvisit( const ast::ReferenceToType * old, ReferenceToType * ty ) {
1161                ty->forall = get<TypeDecl>().acceptL( old->forall );
1162                ty->parameters = get<Expression>().acceptL( old->params );
1163                ty->hoistType = old->hoistType;
1164        }
1165
1166        const ast::Type * visit( const ast::StructInstType * node ) override final {
1167                StructInstType * ty;
1168                if ( node->base ) {
1169                        ty = new StructInstType{
1170                                cv( node ),
1171                                get<StructDecl>().accept1( node->base ),
1172                                get<Attribute>().acceptL( node->attributes )
1173                        };
1174                } else {
1175                        ty = new StructInstType{
1176                                cv( node ),
1177                                node->name,
1178                                get<Attribute>().acceptL( node->attributes )
1179                        };
1180                }
1181                postvisit( node, ty );
1182                this->node = ty;
1183                return nullptr;
1184        }
1185
1186        const ast::Type * visit( const ast::UnionInstType * node ) override final {
1187                UnionInstType * ty;
1188                if ( node->base ) {
1189                        ty = new UnionInstType{
1190                                cv( node ),
1191                                get<UnionDecl>().accept1( node->base ),
1192                                get<Attribute>().acceptL( node->attributes )
1193                        };
1194                } else {
1195                        ty = new UnionInstType{
1196                                cv( node ),
1197                                node->name,
1198                                get<Attribute>().acceptL( node->attributes )
1199                        };
1200                }
1201                postvisit( node, ty );
1202                this->node = ty;
1203                return nullptr;
1204        }
1205
1206        const ast::Type * visit( const ast::EnumInstType * node ) override final {
1207                EnumInstType * ty;
1208                if ( node->base ) {
1209                        ty = new EnumInstType{
1210                                cv( node ),
1211                                get<EnumDecl>().accept1( node->base ),
1212                                get<Attribute>().acceptL( node->attributes )
1213                        };
1214                } else {
1215                        ty = new EnumInstType{
1216                                cv( node ),
1217                                node->name,
1218                                get<Attribute>().acceptL( node->attributes )
1219                        };
1220                }
1221                postvisit( node, ty );
1222                this->node = ty;
1223                return nullptr;
1224        }
1225
1226        const ast::Type * visit( const ast::TraitInstType * node ) override final {
1227                TraitInstType * ty;
1228                if ( node->base ) {
1229                        ty = new TraitInstType{
1230                                cv( node ),
1231                                get<TraitDecl>().accept1( node->base ),
1232                                get<Attribute>().acceptL( node->attributes )
1233                        };
1234                } else {
1235                        ty = new TraitInstType{
1236                                cv( node ),
1237                                node->name,
1238                                get<Attribute>().acceptL( node->attributes )
1239                        };
1240                }
1241                postvisit( node, ty );
1242                this->node = ty;
1243                return nullptr;
1244        }
1245
1246        const ast::Type * visit( const ast::TypeInstType * node ) override final {
1247                TypeInstType * ty;
1248                if ( node->base ) {
1249                        ty = new TypeInstType{
1250                                cv( node ),
1251                                node->name,
1252                                get<TypeDecl>().accept1( node->base ),
1253                                get<Attribute>().acceptL( node->attributes )
1254                        };
1255                } else {
1256                        ty = new TypeInstType{
1257                                cv( node ),
1258                                node->name,
1259                                node->kind == ast::TypeVar::Ftype,
1260                                get<Attribute>().acceptL( node->attributes )
1261                        };
1262                }
1263                postvisit( node, ty );
1264                this->node = ty;
1265                return nullptr;
1266        }
1267
1268        const ast::Type * visit( const ast::TupleType * node ) override final {
1269                this->node = new TupleType{
1270                        cv( node ),
1271                        get<Type>().acceptL( node->types )
1272                        // members generated by TupleType c'tor
1273                };
1274                return nullptr;
1275        }
1276
1277        const ast::Type * visit( const ast::TypeofType * node ) override final {
1278                this->node = new TypeofType{
1279                        cv( node ),
1280                        get<Expression>().accept1( node->expr ),
1281                        (bool)node->kind
1282                };
1283                return nullptr;
1284        }
1285
1286        const ast::Type * visit( const ast::VarArgsType * node ) override final {
1287                this->node = new VarArgsType{ cv( node ) };
1288                return nullptr;
1289        }
1290
1291        const ast::Type * visit( const ast::ZeroType * node ) override final {
1292                this->node = new ZeroType{ cv( node ) };
1293                return nullptr;
1294        }
1295
1296        const ast::Type * visit( const ast::OneType * node ) override final {
1297                this->node = new OneType{ cv( node ) };
1298                return nullptr;
1299        }
1300
1301        const ast::Type * visit( const ast::GlobalScopeType * ) override final {
1302                this->node = new GlobalScopeType{};
1303                return nullptr;
1304        }
1305
1306        const ast::Designation * visit( const ast::Designation * node ) override final {
1307                auto designation = new Designation( get<Expression>().acceptL( node->designators ) );
1308                designation->location = node->location;
1309                this->node = designation;
1310                return nullptr;
1311        }
1312
1313        const ast::Init * visit( const ast::SingleInit * node ) override final {
1314                auto init = new SingleInit(
1315                        get<Expression>().accept1( node->value ),
1316                        ast::MaybeConstruct == node->maybeConstructed
1317                );
1318                init->location = node->location;
1319                this->node = init;
1320                return nullptr;
1321        }
1322
1323        const ast::Init * visit( const ast::ListInit * node ) override final {
1324                auto init = new ListInit(
1325                        get<Initializer>().acceptL( node->initializers ),
1326                        get<Designation>().acceptL( node->designations ),
1327                        ast::MaybeConstruct == node->maybeConstructed
1328                );
1329                init->location = node->location;
1330                this->node = init;
1331                return nullptr;
1332        }
1333
1334        const ast::Init * visit( const ast::ConstructorInit * node ) override final {
1335                auto init = new ConstructorInit(
1336                        get<Statement>().accept1( node->ctor ),
1337                        get<Statement>().accept1( node->dtor ),
1338                        get<Initializer>().accept1( node->init )
1339                );
1340                init->location = node->location;
1341                this->node = init;
1342                return nullptr;
1343        }
1344
1345        const ast::Attribute * visit( const ast::Attribute * node ) override final {
1346                auto attr = new Attribute(
1347                        node->name,
1348                        get<Expression>().acceptL(node->params)
1349                );
1350                this->node = attr;
1351                return nullptr;
1352        }
1353
1354        const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
1355                // Handled by convertTypeSubstitution helper instead.
1356                // TypeSubstitution is not a node in the old model, so the conversion result wouldn't fit in this->node.
1357                assert( 0 );
1358                (void)node;
1359                return nullptr;
1360        }
1361};
1362
1363std::list< Declaration * > convert( const std::list< ast::ptr< ast::Decl > > && translationUnit ) {
1364        ConverterNewToOld c;
1365        std::list< Declaration * > decls;
1366        for(auto d : translationUnit) {
1367                decls.emplace_back( c.decl( d ) );
1368        }
1369        return decls;
1370}
1371
1372//================================================================================================
1373
1374class ConverterOldToNew : public Visitor {
1375public:
1376        ast::Decl * decl() {
1377                return strict_dynamic_cast< ast::Decl * >( node );
1378        }
1379
1380        ConverterOldToNew() = default;
1381        ConverterOldToNew(const ConverterOldToNew &) = delete;
1382        ConverterOldToNew(ConverterOldToNew &&) = delete;
1383private:
1384        /// conversion output
1385        ast::Node * node = nullptr;
1386        /// cache of nodes that might be referenced by readonly<> for de-duplication
1387        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
1388
1389        // Local Utilities:
1390
1391        #define construct(T, key, ...) ({ \
1392                void * data = ::operator new(sizeof(T)); \
1393                cache.emplace( key, (T*)data ); \
1394                new (data) T( __VA_ARGS__ ); \
1395        })
1396
1397        template<typename NewT, typename OldT>
1398        NewT * getAccept1( OldT old ) {
1399                if ( ! old ) return nullptr;
1400                old->accept(*this);
1401                ast::Node * ret = node;
1402                node = nullptr;
1403                return strict_dynamic_cast< NewT * >( ret );
1404        }
1405
1406#       define GET_ACCEPT_1(child, type) \
1407                getAccept1< ast::type, decltype( old->child ) >( old->child )
1408
1409        template<typename NewT, typename OldC>
1410        std::vector< ast::ptr<NewT> > getAcceptV( OldC& old ) {
1411                std::vector< ast::ptr<NewT> > ret;
1412                ret.reserve( old.size() );
1413                for ( auto a : old ) {
1414                        a->accept( *this );
1415                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
1416                        node = nullptr;
1417                }
1418                return ret;
1419        }
1420
1421#       define GET_ACCEPT_V(child, type) \
1422                getAcceptV< ast::type, decltype( old->child ) >( old->child )
1423
1424        ast::Label make_label(Label* old) {
1425                return ast::Label(
1426                        old->labelled->location,
1427                        old->name,
1428                        GET_ACCEPT_V(attributes, Attribute)
1429                );
1430        }
1431
1432        template<template <class...> class C>
1433        C<ast::Label> make_labels(C<Label> olds) {
1434                C<ast::Label> ret;
1435                for (auto oldn : olds) {
1436                        ret.push_back( make_label( &oldn ) );
1437                }
1438                return ret;
1439        }
1440
1441#       define GET_LABELS_V(labels) \
1442                to<std::vector>::from( make_labels( std::move( labels ) ) )
1443
1444        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
1445
1446        /// returns true and sets `node` if in cache
1447        bool inCache( BaseSyntaxNode * old ) {
1448                auto it = cache.find( old );
1449                if ( it == cache.end() ) return false;
1450                node = it->second;
1451                return true;
1452        }
1453
1454        // Now all the visit functions:
1455
1456        virtual void visit( ObjectDecl * old ) override final {
1457                if( old->name == "tmp" ) {
1458                        std::cerr << "building parameters for" << (void*)old << std::endl;
1459                }
1460                auto&& type = GET_ACCEPT_1(type, Type);
1461                auto&& init = GET_ACCEPT_1(init, Init);
1462                auto&& bfwd = GET_ACCEPT_1(bitfieldWidth, Expr);
1463                auto&& attr = GET_ACCEPT_V(attributes, Attribute);
1464                if( old->name == "tmp" ) {
1465                        std::cerr << "checking cache for " << (void*)old << std::endl;
1466                }
1467                if ( inCache( old ) ) {
1468                        if( old->name == "tmp" ) {
1469                                std::cerr << (void*)old << "(old) in cache " << (void*)this->node << "(new)" << std::endl;
1470                        }
1471                        return;
1472                }
1473                auto decl = new ast::ObjectDecl(
1474                        old->location,
1475                        old->name,
1476                        type,
1477                        init,
1478                        { old->get_storageClasses().val },
1479                        { old->linkage.val },
1480                        bfwd,
1481                        std::move(attr),
1482                        { old->get_funcSpec().val }
1483                );
1484                cache.emplace(old, decl);
1485                if( old->name == "tmp" ) {
1486                        std::cerr << (void*)old << "(old) added to cache with " << (void*)decl << "(new)" << std::endl;
1487                }
1488                assert(cache.find( old ) != cache.end());
1489                decl->scopeLevel = old->scopeLevel;
1490                decl->mangleName = old->mangleName;
1491                decl->isDeleted  = old->isDeleted;
1492                decl->uniqueId   = old->uniqueId;
1493                decl->extension  = old->extension;
1494
1495                this->node = decl;
1496
1497                if( old->name == "tmp" ) {
1498                        std::cerr << (void*)old << "(old) created " << (void*)this->node << "(new)" << std::endl;
1499                }
1500        }
1501
1502        virtual void visit( FunctionDecl * old ) override final {
1503                if ( inCache( old ) ) return;
1504                auto decl = new ast::FunctionDecl{
1505                        old->location,
1506                        old->name,
1507                        GET_ACCEPT_1(type, FunctionType),
1508                        {},
1509                        { old->storageClasses.val },
1510                        { old->linkage.val },
1511                        GET_ACCEPT_V(attributes, Attribute),
1512                        { old->get_funcSpec().val }
1513                };
1514                cache.emplace( old, decl );
1515                decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
1516                decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
1517                decl->scopeLevel = old->scopeLevel;
1518                decl->mangleName = old->mangleName;
1519                decl->isDeleted  = old->isDeleted;
1520                decl->uniqueId   = old->uniqueId;
1521                decl->extension  = old->extension;
1522
1523                this->node = decl;
1524
1525                if ( Validate::dereferenceOperator == old ) {
1526                        dereferenceOperator = decl;
1527                }
1528
1529                if ( Validate::dtorStructDestroy == old ) {
1530                        dtorStructDestroy = decl;
1531                }
1532        }
1533
1534        virtual void visit( StructDecl * old ) override final {
1535                if ( inCache( old ) ) return;
1536                auto decl = new ast::StructDecl(
1537                        old->location,
1538                        old->name,
1539                        old->kind,
1540                        GET_ACCEPT_V(attributes, Attribute),
1541                        { old->linkage.val }
1542                );
1543                cache.emplace( old, decl );
1544                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1545                decl->body   = old->body;
1546                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1547                decl->members    = GET_ACCEPT_V(members, Decl);
1548                decl->extension  = old->extension;
1549                decl->uniqueId   = old->uniqueId;
1550                decl->storage    = { old->storageClasses.val };
1551
1552                this->node = decl;
1553
1554                if ( Validate::dtorStruct == old ) {
1555                        dtorStruct = decl;
1556                }
1557        }
1558
1559        virtual void visit( UnionDecl * old ) override final {
1560                if ( inCache( old ) ) return;
1561                auto decl = new ast::UnionDecl(
1562                        old->location,
1563                        old->name,
1564                        GET_ACCEPT_V(attributes, Attribute),
1565                        { old->linkage.val }
1566                );
1567                cache.emplace( old, decl );
1568                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1569                decl->body   = old->body;
1570                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1571                decl->members    = GET_ACCEPT_V(members, Decl);
1572                decl->extension  = old->extension;
1573                decl->uniqueId   = old->uniqueId;
1574                decl->storage    = { old->storageClasses.val };
1575
1576                this->node = decl;
1577        }
1578
1579        virtual void visit( EnumDecl * old ) override final {
1580                if ( inCache( old ) ) return;
1581                auto decl = new ast::EnumDecl(
1582                        old->location,
1583                        old->name,
1584                        GET_ACCEPT_V(attributes, Attribute),
1585                        { old->linkage.val }
1586                );
1587                cache.emplace( old, decl );
1588                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1589                decl->body   = old->body;
1590                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1591                decl->members    = GET_ACCEPT_V(members, Decl);
1592                decl->extension  = old->extension;
1593                decl->uniqueId   = old->uniqueId;
1594                decl->storage    = { old->storageClasses.val };
1595
1596                this->node = decl;
1597        }
1598
1599        virtual void visit( TraitDecl * old ) override final {
1600                if ( inCache( old ) ) return;
1601                auto decl = new ast::TraitDecl(
1602                        old->location,
1603                        old->name,
1604                        GET_ACCEPT_V(attributes, Attribute),
1605                        { old->linkage.val }
1606                );
1607                cache.emplace( old, decl );
1608                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1609                decl->body   = old->body;
1610                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1611                decl->members    = GET_ACCEPT_V(members, Decl);
1612                decl->extension  = old->extension;
1613                decl->uniqueId   = old->uniqueId;
1614                decl->storage    = { old->storageClasses.val };
1615
1616                this->node = decl;
1617        }
1618
1619        virtual void visit( TypeDecl * old ) override final {
1620                if ( inCache( old ) ) return;
1621                auto decl = new ast::TypeDecl{
1622                        old->location,
1623                        old->name,
1624                        { old->storageClasses.val },
1625                        GET_ACCEPT_1(base, Type),
1626                        (ast::TypeVar::Kind)(unsigned)old->kind,
1627                        old->sized,
1628                        GET_ACCEPT_1(init, Type)
1629                };
1630                cache.emplace( old, decl );
1631                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1632                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
1633                decl->extension  = old->extension;
1634                decl->uniqueId   = old->uniqueId;
1635
1636                this->node = decl;
1637        }
1638
1639        virtual void visit( TypedefDecl * old ) override final {
1640                auto decl = new ast::TypedefDecl(
1641                        old->location,
1642                        old->name,
1643                        { old->storageClasses.val },
1644                        GET_ACCEPT_1(base, Type),
1645                        { old->linkage.val }
1646                );
1647                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1648                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
1649                decl->extension  = old->extension;
1650                decl->uniqueId   = old->uniqueId;
1651                decl->storage    = { old->storageClasses.val };
1652
1653                this->node = decl;
1654        }
1655
1656        virtual void visit( AsmDecl * old ) override final {
1657                auto decl = new ast::AsmDecl{
1658                        old->location,
1659                        GET_ACCEPT_1(stmt, AsmStmt)
1660                };
1661                decl->extension  = old->extension;
1662                decl->uniqueId   = old->uniqueId;
1663                decl->storage    = { old->storageClasses.val };
1664
1665                this->node = decl;
1666        }
1667
1668        virtual void visit( StaticAssertDecl * old ) override final {
1669                auto decl = new ast::StaticAssertDecl{
1670                        old->location,
1671                        GET_ACCEPT_1(condition, Expr),
1672                        GET_ACCEPT_1(message, ConstantExpr)
1673                };
1674                decl->extension  = old->extension;
1675                decl->uniqueId   = old->uniqueId;
1676                decl->storage    = { old->storageClasses.val };
1677
1678                this->node = decl;
1679        }
1680
1681        virtual void visit( CompoundStmt * old ) override final {
1682                if ( inCache( old ) ) return;
1683                auto stmt = new ast::CompoundStmt(
1684                        old->location,
1685                        to<std::list>::from( GET_ACCEPT_V(kids, Stmt) ),
1686                        GET_LABELS_V(old->labels)
1687                );
1688
1689                this->node = stmt;
1690                cache.emplace( old, this->node );
1691        }
1692
1693        virtual void visit( ExprStmt * old ) override final {
1694                if ( inCache( old ) ) return;
1695                this->node = new ast::ExprStmt(
1696                        old->location,
1697                        GET_ACCEPT_1(expr, Expr),
1698                        GET_LABELS_V(old->labels)
1699                );
1700                cache.emplace( old, this->node );
1701        }
1702
1703        virtual void visit( AsmStmt * old ) override final {
1704                if ( inCache( old ) ) return;
1705                this->node = new ast::AsmStmt(
1706                        old->location,
1707                        old->voltile,
1708                        GET_ACCEPT_1(instruction, Expr),
1709                        GET_ACCEPT_V(output, Expr),
1710                        GET_ACCEPT_V(input, Expr),
1711                        GET_ACCEPT_V(clobber, ConstantExpr),
1712                        GET_LABELS_V(old->gotolabels),
1713                        GET_LABELS_V(old->labels)
1714                );
1715                cache.emplace( old, this->node );
1716        }
1717
1718        virtual void visit( DirectiveStmt * old ) override final {
1719                if ( inCache( old ) ) return;
1720                this->node = new ast::DirectiveStmt(
1721                        old->location,
1722                        old->directive,
1723                        GET_LABELS_V(old->labels)
1724                );
1725                cache.emplace( old, this->node );
1726        }
1727
1728        virtual void visit( IfStmt * old ) override final {
1729                if ( inCache( old ) ) return;
1730                this->node = new ast::IfStmt(
1731                        old->location,
1732                        GET_ACCEPT_1(condition, Expr),
1733                        GET_ACCEPT_1(thenPart, Stmt),
1734                        GET_ACCEPT_1(elsePart, Stmt),
1735                        GET_ACCEPT_V(initialization, Stmt),
1736                        GET_LABELS_V(old->labels)
1737                );
1738                cache.emplace( old, this->node );
1739        }
1740
1741        virtual void visit( SwitchStmt * old ) override final {
1742                if ( inCache( old ) ) return;
1743                this->node = new ast::SwitchStmt(
1744                        old->location,
1745                        GET_ACCEPT_1(condition, Expr),
1746                        GET_ACCEPT_V(statements, Stmt),
1747                        GET_LABELS_V(old->labels)
1748                );
1749                cache.emplace( old, this->node );
1750        }
1751
1752        virtual void visit( CaseStmt * old ) override final {
1753                if ( inCache( old ) ) return;
1754                this->node = new ast::CaseStmt(
1755                        old->location,
1756                        GET_ACCEPT_1(condition, Expr),
1757                        GET_ACCEPT_V(stmts, Stmt),
1758                        GET_LABELS_V(old->labels)
1759                );
1760                cache.emplace( old, this->node );
1761        }
1762
1763        virtual void visit( WhileStmt * old ) override final {
1764                if ( inCache( old ) ) return;
1765                this->node = new ast::WhileStmt(
1766                        old->location,
1767                        GET_ACCEPT_1(condition, Expr),
1768                        GET_ACCEPT_1(body, Stmt),
1769                        GET_ACCEPT_V(initialization, Stmt),
1770                        old->isDoWhile,
1771                        GET_LABELS_V(old->labels)
1772                );
1773                cache.emplace( old, this->node );
1774        }
1775
1776        virtual void visit( ForStmt * old ) override final {
1777                if ( inCache( old ) ) return;
1778                this->node = new ast::ForStmt(
1779                        old->location,
1780                        GET_ACCEPT_V(initialization, Stmt),
1781                        GET_ACCEPT_1(condition, Expr),
1782                        GET_ACCEPT_1(increment, Expr),
1783                        GET_ACCEPT_1(body, Stmt),
1784                        GET_LABELS_V(old->labels)
1785                );
1786                cache.emplace( old, this->node );
1787        }
1788
1789        virtual void visit( BranchStmt * old ) override final {
1790                if ( inCache( old ) ) return;
1791                if (old->computedTarget) {
1792                        this->node = new ast::BranchStmt(
1793                                old->location,
1794                                GET_ACCEPT_1(computedTarget, Expr),
1795                                GET_LABELS_V(old->labels)
1796                        );
1797                } else {
1798                        ast::BranchStmt::Kind kind;
1799                        switch (old->type) {
1800                        #define CASE(n) \
1801                        case BranchStmt::n: \
1802                                kind = ast::BranchStmt::n; \
1803                                break
1804                        CASE(Goto);
1805                        CASE(Break);
1806                        CASE(Continue);
1807                        CASE(FallThrough);
1808                        CASE(FallThroughDefault);
1809                        #undef CASE
1810                        default:
1811                                assertf(false, "Invalid BranchStmt::Type %d\n", old->type);
1812                        }
1813
1814                        Label label = old->originalTarget;
1815                        auto stmt = new ast::BranchStmt(
1816                                old->location,
1817                                kind,
1818                                make_label(&label),
1819                                GET_LABELS_V(old->labels)
1820                        );
1821                        stmt->target = make_label(&old->target);
1822                        this->node = stmt;
1823                }
1824                cache.emplace( old, this->node );
1825        }
1826
1827        virtual void visit( ReturnStmt * old ) override final {
1828                if ( inCache( old ) ) return;
1829                this->node = new ast::ReturnStmt(
1830                        old->location,
1831                        GET_ACCEPT_1(expr, Expr),
1832                        GET_LABELS_V(old->labels)
1833                );
1834                cache.emplace( old, this->node );
1835        }
1836
1837        virtual void visit( ThrowStmt * old ) override final {
1838                if ( inCache( old ) ) return;
1839                ast::ExceptionKind kind;
1840                switch (old->kind) {
1841                case ThrowStmt::Terminate:
1842                        kind = ast::ExceptionKind::Terminate;
1843                        break;
1844                case ThrowStmt::Resume:
1845                        kind = ast::ExceptionKind::Resume;
1846                        break;
1847                default:
1848                        assertf(false, "Invalid ThrowStmt::Kind %d\n", old->kind);
1849                }
1850
1851                this->node = new ast::ThrowStmt(
1852                        old->location,
1853                        kind,
1854                        GET_ACCEPT_1(expr, Expr),
1855                        GET_ACCEPT_1(target, Expr),
1856                        GET_LABELS_V(old->labels)
1857                );
1858                cache.emplace( old, this->node );
1859        }
1860
1861        virtual void visit( TryStmt * old ) override final {
1862                if ( inCache( old ) ) return;
1863                this->node = new ast::TryStmt(
1864                        old->location,
1865                        GET_ACCEPT_1(block, CompoundStmt),
1866                        GET_ACCEPT_V(handlers, CatchStmt),
1867                        GET_ACCEPT_1(finallyBlock, FinallyStmt),
1868                        GET_LABELS_V(old->labels)
1869                );
1870                cache.emplace( old, this->node );
1871        }
1872
1873        virtual void visit( CatchStmt * old ) override final {
1874                if ( inCache( old ) ) return;
1875                ast::ExceptionKind kind;
1876                switch (old->kind) {
1877                case CatchStmt::Terminate:
1878                        kind = ast::ExceptionKind::Terminate;
1879                        break;
1880                case CatchStmt::Resume:
1881                        kind = ast::ExceptionKind::Resume;
1882                        break;
1883                default:
1884                        assertf(false, "Invalid CatchStmt::Kind %d\n", old->kind);
1885                }
1886
1887                this->node = new ast::CatchStmt(
1888                        old->location,
1889                        kind,
1890                        GET_ACCEPT_1(decl, Decl),
1891                        GET_ACCEPT_1(cond, Expr),
1892                        GET_ACCEPT_1(body, Stmt),
1893                        GET_LABELS_V(old->labels)
1894                );
1895                cache.emplace( old, this->node );
1896        }
1897
1898        virtual void visit( FinallyStmt * old ) override final {
1899                if ( inCache( old ) ) return;
1900                this->node = new ast::FinallyStmt(
1901                        old->location,
1902                        GET_ACCEPT_1(block, CompoundStmt),
1903                        GET_LABELS_V(old->labels)
1904                );
1905                cache.emplace( old, this->node );
1906        }
1907
1908        virtual void visit( WaitForStmt * old ) override final {
1909                if ( inCache( old ) ) return;
1910                ast::WaitForStmt * stmt = new ast::WaitForStmt(
1911                        old->location,
1912                        GET_LABELS_V(old->labels)
1913                );
1914
1915                stmt->clauses.reserve( old->clauses.size() );
1916                for (size_t i = 0 ; i < old->clauses.size() ; ++i) {
1917                        stmt->clauses.push_back({
1918                                ast::WaitForStmt::Target{
1919                                        GET_ACCEPT_1(clauses[i].target.function, Expr),
1920                                        GET_ACCEPT_V(clauses[i].target.arguments, Expr)
1921                                },
1922                                GET_ACCEPT_1(clauses[i].statement, Stmt),
1923                                GET_ACCEPT_1(clauses[i].condition, Expr)
1924                        });
1925                }
1926                stmt->timeout = {
1927                        GET_ACCEPT_1(timeout.time, Expr),
1928                        GET_ACCEPT_1(timeout.statement, Stmt),
1929                        GET_ACCEPT_1(timeout.condition, Expr),
1930                };
1931                stmt->orElse = {
1932                        GET_ACCEPT_1(timeout.statement, Stmt),
1933                        GET_ACCEPT_1(timeout.condition, Expr),
1934                };
1935
1936                this->node = stmt;
1937                cache.emplace( old, this->node );
1938        }
1939
1940        virtual void visit( WithStmt * old ) override final {
1941                if ( inCache( old ) ) return;
1942                this->node = new ast::WithStmt(
1943                        old->location,
1944                        GET_ACCEPT_V(exprs, Expr),
1945                        GET_ACCEPT_1(stmt, Stmt),
1946                        GET_LABELS_V(old->labels)
1947                );
1948                cache.emplace( old, this->node );
1949        }
1950
1951        virtual void visit( NullStmt * old ) override final {
1952                if ( inCache( old ) ) return;
1953                this->node = new ast::NullStmt(
1954                        old->location,
1955                        GET_LABELS_V(old->labels)
1956                );
1957                cache.emplace( old, this->node );
1958        }
1959
1960        virtual void visit( DeclStmt * old ) override final {
1961                if ( inCache( old ) ) return;
1962                this->node = new ast::DeclStmt(
1963                        old->location,
1964                        GET_ACCEPT_1(decl, Decl),
1965                        GET_LABELS_V(old->labels)
1966                );
1967                cache.emplace( old, this->node );
1968        }
1969
1970        virtual void visit( ImplicitCtorDtorStmt * old ) override final {
1971                if ( inCache( old ) ) return;
1972                auto stmt = new ast::ImplicitCtorDtorStmt(
1973                        old->location,
1974                        nullptr,
1975                        GET_LABELS_V(old->labels)
1976                );
1977                cache.emplace( old, stmt );
1978                stmt->callStmt = GET_ACCEPT_1(callStmt, Stmt);
1979                this->node = stmt;
1980        }
1981
1982        ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
1983
1984                if (!old) return nullptr;
1985
1986                ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
1987
1988                for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
1989                        rslt->add( old_i->first,
1990                                   getAccept1<ast::Type>(old_i->second) );
1991                }
1992
1993                for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
1994                        rslt->addVar( old_i->first,
1995                                      getAccept1<ast::Expr>(old_i->second) );
1996                }
1997
1998                return rslt;
1999        }
2000
2001        void convertInferUnion(ast::Expr::InferUnion               &newInferred,
2002                                                   const std::map<UniqueId,ParamEntry> &oldInferParams,
2003                                                   const std::vector<UniqueId>         &oldResnSlots) {
2004
2005                assert( oldInferParams.empty() || oldResnSlots.empty() );
2006                assert( newInferred.mode == ast::Expr::InferUnion::Empty );
2007
2008                if ( !oldInferParams.empty() ) {
2009                        ast::InferredParams &tgt = newInferred.inferParams();
2010                        for (auto old : oldInferParams) {
2011                                tgt[old.first] = ast::ParamEntry(
2012                                        old.second.decl,
2013                                        getAccept1<ast::Type>(old.second.actualType),
2014                                        getAccept1<ast::Type>(old.second.formalType),
2015                                        getAccept1<ast::Expr>(old.second.expr)
2016                                );
2017                        }
2018                } else if ( !oldResnSlots.empty() ) {
2019                        ast::ResnSlots &tgt = newInferred.resnSlots();
2020                        for (auto old : oldResnSlots) {
2021                                tgt.push_back(old);
2022                        }
2023                }
2024        }
2025
2026        ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
2027
2028                nw->env    = convertTypeSubstitution(old->env);
2029
2030                nw->extension = old->extension;
2031                convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
2032
2033                return nw;
2034        }
2035
2036        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
2037
2038                nw->result = GET_ACCEPT_1(result, Type);
2039                return visitBaseExpr_SkipResultType(old, nw);;
2040        }
2041
2042        virtual void visit( ApplicationExpr * old ) override final {
2043                this->node = visitBaseExpr( old,
2044                        new ast::ApplicationExpr(
2045                                old->location,
2046                                GET_ACCEPT_1(function, Expr),
2047                                GET_ACCEPT_V(args, Expr)
2048                        )
2049                );
2050        }
2051
2052        virtual void visit( UntypedExpr * old ) override final {
2053                this->node = visitBaseExpr( old,
2054                        new ast::UntypedExpr(
2055                                old->location,
2056                                GET_ACCEPT_1(function, Expr),
2057                                GET_ACCEPT_V(args, Expr)
2058                        )
2059                );
2060        }
2061
2062        virtual void visit( NameExpr * old ) override final {
2063                this->node = visitBaseExpr( old,
2064                        new ast::NameExpr(
2065                                old->location,
2066                                old->get_name()
2067                        )
2068                );
2069        }
2070
2071        virtual void visit( CastExpr * old ) override final {
2072                this->node = visitBaseExpr( old,
2073                        new ast::CastExpr(
2074                                old->location,
2075                                GET_ACCEPT_1(arg, Expr),
2076                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
2077                        )
2078                );
2079        }
2080
2081        virtual void visit( KeywordCastExpr * old) override final {
2082                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
2083                switch (old->target) {
2084                        case KeywordCastExpr::Coroutine:
2085                                castTarget = ast::KeywordCastExpr::Coroutine;
2086                                break;
2087                        case KeywordCastExpr::Thread:
2088                                castTarget = ast::KeywordCastExpr::Thread;
2089                                break;
2090                        case KeywordCastExpr::Monitor:
2091                                castTarget = ast::KeywordCastExpr::Monitor;
2092                                break;
2093                        default:
2094                                break;
2095                }
2096                assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
2097                this->node = visitBaseExpr( old,
2098                        new ast::KeywordCastExpr(
2099                                old->location,
2100                                GET_ACCEPT_1(arg, Expr),
2101                                castTarget
2102                        )
2103                );
2104        }
2105
2106        virtual void visit( VirtualCastExpr * old ) override final {
2107                this->node = visitBaseExpr_SkipResultType( old,
2108                        new ast::VirtualCastExpr(
2109                                old->location,
2110                                GET_ACCEPT_1(arg, Expr),
2111                                GET_ACCEPT_1(result, Type)
2112                        )
2113                );
2114        }
2115
2116        virtual void visit( AddressExpr * old ) override final {
2117                this->node = visitBaseExpr( old,
2118                        new ast::AddressExpr(
2119                                old->location,
2120                                GET_ACCEPT_1(arg, Expr)
2121                        )
2122                );
2123        }
2124
2125        virtual void visit( LabelAddressExpr * old ) override final {
2126                this->node = visitBaseExpr( old,
2127                        new ast::LabelAddressExpr(
2128                                old->location,
2129                                make_label(&old->arg)
2130                        )
2131                );
2132        }
2133
2134        virtual void visit( UntypedMemberExpr * old ) override final {
2135                this->node = visitBaseExpr( old,
2136                        new ast::UntypedMemberExpr(
2137                                old->location,
2138                                GET_ACCEPT_1(member, Expr),
2139                                GET_ACCEPT_1(aggregate, Expr)
2140                        )
2141                );
2142        }
2143
2144        virtual void visit( MemberExpr * old ) override final {
2145                this->node = visitBaseExpr( old,
2146                        new ast::MemberExpr(
2147                                old->location,
2148                                GET_ACCEPT_1(member, DeclWithType),
2149                                GET_ACCEPT_1(aggregate, Expr)
2150                        )
2151                );
2152        }
2153
2154        virtual void visit( VariableExpr * old ) override final {
2155                auto expr = new ast::VariableExpr(
2156                        old->location
2157                );
2158
2159                visitBaseExpr_SkipResultType( old,
2160                        expr
2161                );
2162
2163                expr->var = GET_ACCEPT_1(var, DeclWithType);
2164                expr->result = expr->var->get_type();
2165                if(const ast::FunctionType * ft = expr->result.as<ast::FunctionType>()) {
2166                        if(dynamic_cast<PointerType *>(old->result)) {
2167                                expr->result = new ast::PointerType(ft);
2168                        }
2169                }
2170                add_qualifiers( expr->result, ast::CV::Lvalue );
2171                this->node = expr;
2172        }
2173
2174        bool isIntlikeConstantType(const Type *t) {
2175                if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
2176                        if ( basicType->isInteger() ) {
2177                                return true;
2178                        }
2179                } else if ( dynamic_cast< const OneType * >( t ) ) {
2180                        return true;
2181                } else if ( dynamic_cast< const ZeroType * >( t ) ) {
2182                        return true;
2183                } else if ( dynamic_cast< const PointerType * >( t ) ) {
2184                        // null pointer constants, with zero int-values
2185                        return true;
2186                }
2187                return false;
2188        }
2189
2190        int isFloatlikeConstantType(const Type *t) {
2191                if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
2192                        if ( ! bty->isInteger() ) {
2193                                return true;
2194                        }
2195                }
2196                return false;
2197        }
2198
2199        int isStringlikeConstantType(const Type *t) {
2200                if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
2201                        if ( const BasicType * bty = dynamic_cast< const BasicType * >( aty->base ) ) {
2202                           if ( bty->kind == BasicType::Kind::Char ) {
2203                                   return true;
2204                           }
2205                        }
2206                }
2207                return false;
2208        }
2209
2210        virtual void visit( ConstantExpr * old ) override final {
2211                ast::ConstantExpr *rslt = nullptr;
2212                if (isIntlikeConstantType(old->result)) {
2213                        rslt = new ast::ConstantExpr(
2214                                old->location,
2215                                GET_ACCEPT_1(result, Type),
2216                                old->constant.get_value(),
2217                                (unsigned long long) old->intValue(),
2218                                ast::ConstantExpr::Kind::Integer
2219                        );
2220                } else if (isFloatlikeConstantType(old->result)) {
2221                        rslt = new ast::ConstantExpr(
2222                                old->location,
2223                                GET_ACCEPT_1(result, Type),
2224                                old->constant.get_value(),
2225                                (double) old->constant.get_dval()
2226                        );
2227                } else if (isStringlikeConstantType(old->result)) {
2228                        rslt = new ast::ConstantExpr(
2229                                old->location,
2230                                GET_ACCEPT_1(result, Type),
2231                                old->constant.get_value(),
2232                                0,
2233                                ast::ConstantExpr::Kind::String
2234                        );
2235                }
2236                assert(rslt);
2237                this->node = visitBaseExpr( old, rslt );
2238        }
2239
2240        virtual void visit( SizeofExpr * old ) override final {
2241                assert (old->expr || old->type);
2242                assert (! (old->expr && old->type));
2243                ast::SizeofExpr *rslt;
2244                if (old->expr) {
2245                        assert(!old->isType);
2246                        rslt = new ast::SizeofExpr(
2247                                old->location,
2248                                GET_ACCEPT_1(expr, Expr)
2249                        );
2250                }
2251                if (old->type) {
2252                        assert(old->isType);
2253                        rslt = new ast::SizeofExpr(
2254                                old->location,
2255                                GET_ACCEPT_1(type, Type)
2256                        );
2257                }
2258                this->node = visitBaseExpr( old, rslt );
2259        }
2260
2261        virtual void visit( AlignofExpr * old ) override final {
2262                assert (old->expr || old->type);
2263                assert (! (old->expr && old->type));
2264                ast::AlignofExpr *rslt;
2265                if (old->expr) {
2266                        assert(!old->isType);
2267                        rslt = new ast::AlignofExpr(
2268                                old->location,
2269                                GET_ACCEPT_1(expr, Expr)
2270                        );
2271                }
2272                if (old->type) {
2273                        assert(old->isType);
2274                        rslt = new ast::AlignofExpr(
2275                                old->location,
2276                                GET_ACCEPT_1(type, Type)
2277                        );
2278                }
2279                this->node = visitBaseExpr( old, rslt );
2280        }
2281
2282        virtual void visit( UntypedOffsetofExpr * old ) override final {
2283                this->node = visitBaseExpr( old,
2284                        new ast::UntypedOffsetofExpr(
2285                                old->location,
2286                                GET_ACCEPT_1(type, Type),
2287                                old->member
2288                        )
2289                );
2290        }
2291
2292        virtual void visit( OffsetofExpr * old ) override final {
2293                this->node = visitBaseExpr( old,
2294                        new ast::OffsetofExpr(
2295                                old->location,
2296                                GET_ACCEPT_1(type, Type),
2297                                GET_ACCEPT_1(member, DeclWithType)
2298                        )
2299                );
2300        }
2301
2302        virtual void visit( OffsetPackExpr * old ) override final {
2303                this->node = visitBaseExpr( old,
2304                        new ast::OffsetPackExpr(
2305                                old->location,
2306                                GET_ACCEPT_1(type, StructInstType)
2307                        )
2308                );
2309        }
2310
2311        virtual void visit( LogicalExpr * old ) override final {
2312                this->node = visitBaseExpr( old,
2313                        new ast::LogicalExpr(
2314                                old->location,
2315                                GET_ACCEPT_1(arg1, Expr),
2316                                GET_ACCEPT_1(arg2, Expr),
2317                                old->get_isAnd() ?
2318                                        ast::LogicalFlag::AndExpr :
2319                                        ast::LogicalFlag::OrExpr
2320                        )
2321                );
2322        }
2323
2324        virtual void visit( ConditionalExpr * old ) override final {
2325                this->node = visitBaseExpr( old,
2326                        new ast::ConditionalExpr(
2327                                old->location,
2328                                GET_ACCEPT_1(arg1, Expr),
2329                                GET_ACCEPT_1(arg2, Expr),
2330                                GET_ACCEPT_1(arg3, Expr)
2331                        )
2332                );
2333        }
2334
2335        virtual void visit( CommaExpr * old ) override final {
2336                this->node = visitBaseExpr( old,
2337                        new ast::CommaExpr(
2338                                old->location,
2339                                GET_ACCEPT_1(arg1, Expr),
2340                                GET_ACCEPT_1(arg2, Expr)
2341                        )
2342                );
2343        }
2344
2345        virtual void visit( TypeExpr * old ) override final {
2346                this->node = visitBaseExpr( old,
2347                        new ast::TypeExpr(
2348                                old->location,
2349                                GET_ACCEPT_1(type, Type)
2350                        )
2351                );
2352        }
2353
2354        virtual void visit( AsmExpr * old ) override final {
2355                this->node = visitBaseExpr( old,
2356                        new ast::AsmExpr(
2357                                old->location,
2358                                GET_ACCEPT_1(inout, Expr),
2359                                GET_ACCEPT_1(constraint, Expr),
2360                                GET_ACCEPT_1(operand, Expr)
2361                        )
2362                );
2363        }
2364
2365        virtual void visit( ImplicitCopyCtorExpr * old ) override final {
2366                auto rslt = new ast::ImplicitCopyCtorExpr(
2367                        old->location,
2368                        GET_ACCEPT_1(callExpr, ApplicationExpr)
2369                );
2370
2371                this->node = visitBaseExpr( old, rslt );
2372        }
2373
2374        virtual void visit( ConstructorExpr * old ) override final {
2375                this->node = visitBaseExpr( old,
2376                        new ast::ConstructorExpr(
2377                                old->location,
2378                                GET_ACCEPT_1(callExpr, Expr)
2379                        )
2380                );
2381        }
2382
2383        virtual void visit( CompoundLiteralExpr * old ) override final {
2384                this->node = visitBaseExpr_SkipResultType( old,
2385                        new ast::CompoundLiteralExpr(
2386                                old->location,
2387                                GET_ACCEPT_1(result, Type),
2388                                GET_ACCEPT_1(initializer, Init)
2389                        )
2390                );
2391        }
2392
2393        virtual void visit( RangeExpr * old ) override final {
2394                this->node = visitBaseExpr( old,
2395                        new ast::RangeExpr(
2396                                old->location,
2397                                GET_ACCEPT_1(low, Expr),
2398                                GET_ACCEPT_1(high, Expr)
2399                        )
2400                );
2401        }
2402
2403        virtual void visit( UntypedTupleExpr * old ) override final {
2404                this->node = visitBaseExpr( old,
2405                        new ast::UntypedTupleExpr(
2406                                old->location,
2407                                GET_ACCEPT_V(exprs, Expr)
2408                        )
2409                );
2410        }
2411
2412        virtual void visit( TupleExpr * old ) override final {
2413                this->node = visitBaseExpr( old,
2414                        new ast::TupleExpr(
2415                                old->location,
2416                                GET_ACCEPT_V(exprs, Expr)
2417                        )
2418                );
2419        }
2420
2421        virtual void visit( TupleIndexExpr * old ) override final {
2422                this->node = visitBaseExpr( old,
2423                        new ast::TupleIndexExpr(
2424                                old->location,
2425                                GET_ACCEPT_1(tuple, Expr),
2426                                old->index
2427                        )
2428                );
2429        }
2430
2431        virtual void visit( TupleAssignExpr * old ) override final {
2432                this->node = visitBaseExpr_SkipResultType( old,
2433                        new ast::TupleAssignExpr(
2434                                old->location,
2435                                GET_ACCEPT_1(result, Type),
2436                                GET_ACCEPT_1(stmtExpr, StmtExpr)
2437                        )
2438                );
2439        }
2440
2441        virtual void visit( StmtExpr * old ) override final {
2442                auto rslt = new ast::StmtExpr(
2443                        old->location,
2444                        GET_ACCEPT_1(statements, CompoundStmt)
2445                );
2446                rslt->returnDecls = GET_ACCEPT_V(returnDecls, ObjectDecl);
2447                rslt->dtors       = GET_ACCEPT_V(dtors      , Expr);
2448
2449                this->node = visitBaseExpr_SkipResultType( old, rslt );
2450        }
2451
2452        virtual void visit( UniqueExpr * old ) override final {
2453                auto rslt = new ast::UniqueExpr(
2454                        old->location,
2455                        GET_ACCEPT_1(expr, Expr)
2456                );
2457                rslt->object = GET_ACCEPT_1(object, ObjectDecl);
2458                rslt->var    = GET_ACCEPT_1(var   , VariableExpr);
2459
2460                this->node = visitBaseExpr( old, rslt );
2461        }
2462
2463        virtual void visit( UntypedInitExpr * old ) override final {
2464                std::vector<ast::InitAlternative> initAlts;
2465                for (auto ia : old->initAlts) {
2466                        initAlts.push_back(ast::InitAlternative(
2467                                getAccept1< ast::Type, Type * >( ia.type ),
2468                                getAccept1< ast::Designation, Designation * >( ia.designation )
2469                        ));
2470                }
2471                this->node = visitBaseExpr( old,
2472                        new ast::UntypedInitExpr(
2473                                old->location,
2474                                GET_ACCEPT_1(expr, Expr),
2475                                std::move(initAlts)
2476                        )
2477                );
2478        }
2479
2480        virtual void visit( InitExpr * old ) override final {
2481                this->node = visitBaseExpr( old,
2482                        new ast::InitExpr(
2483                                old->location,
2484                                GET_ACCEPT_1(expr, Expr),
2485                                GET_ACCEPT_1(designation, Designation)
2486                        )
2487                );
2488        }
2489
2490        virtual void visit( DeletedExpr * old ) override final {
2491                this->node = visitBaseExpr( old,
2492                        new ast::DeletedExpr(
2493                                old->location,
2494                                GET_ACCEPT_1(expr, Expr),
2495                                inCache(old->deleteStmt) ?
2496                                        this->node :
2497                                        GET_ACCEPT_1(deleteStmt, Node)
2498                        )
2499                );
2500        }
2501
2502        virtual void visit( DefaultArgExpr * old ) override final {
2503                this->node = visitBaseExpr( old,
2504                        new ast::DefaultArgExpr(
2505                                old->location,
2506                                GET_ACCEPT_1(expr, Expr)
2507                        )
2508                );
2509        }
2510
2511        virtual void visit( GenericExpr * old ) override final {
2512                std::vector<ast::GenericExpr::Association> associations;
2513                for (auto association : old->associations) {
2514                        associations.push_back(ast::GenericExpr::Association(
2515                                getAccept1< ast::Type, Type * >( association.type ),
2516                                getAccept1< ast::Expr, Expression * >( association.expr )
2517                        ));
2518                }
2519                this->node = visitBaseExpr( old,
2520                        new ast::GenericExpr(
2521                                old->location,
2522                                GET_ACCEPT_1(control, Expr),
2523                                std::move(associations)
2524                        )
2525                );
2526        }
2527
2528        virtual void visit( VoidType * old ) override final {
2529                this->node = new ast::VoidType{ cv( old ) };
2530        }
2531
2532        virtual void visit( BasicType * old ) override final {
2533                auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
2534                // I believe this should always be a BasicType.
2535                if ( Validate::SizeType == old ) {
2536                        sizeType = type;
2537                }
2538                this->node = type;
2539        }
2540
2541        virtual void visit( PointerType * old ) override final {
2542                this->node = new ast::PointerType{
2543                        GET_ACCEPT_1( base, Type ),
2544                        GET_ACCEPT_1( dimension, Expr ),
2545                        (ast::LengthFlag)old->isVarLen,
2546                        (ast::DimensionFlag)old->isStatic,
2547                        cv( old )
2548                };
2549        }
2550
2551        virtual void visit( ArrayType * old ) override final {
2552                this->node = new ast::ArrayType{
2553                        GET_ACCEPT_1( base, Type ),
2554                        GET_ACCEPT_1( dimension, Expr ),
2555                        (ast::LengthFlag)old->isVarLen,
2556                        (ast::DimensionFlag)old->isStatic,
2557                        cv( old )
2558                };
2559        }
2560
2561        virtual void visit( ReferenceType * old ) override final {
2562                this->node = new ast::ReferenceType{
2563                        GET_ACCEPT_1( base, Type ),
2564                        cv( old )
2565                };
2566        }
2567
2568        virtual void visit( QualifiedType * old ) override final {
2569                this->node = new ast::QualifiedType{
2570                        GET_ACCEPT_1( parent, Type ),
2571                        GET_ACCEPT_1( child, Type ),
2572                        cv( old )
2573                };
2574        }
2575
2576        virtual void visit( FunctionType * old ) override final {
2577                auto ty = new ast::FunctionType {
2578                        (ast::ArgumentFlag)old->isVarArgs,
2579                        cv( old )
2580                };
2581                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
2582                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
2583                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2584                this->node = ty;
2585        }
2586
2587        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
2588                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2589                ty->params = GET_ACCEPT_V( parameters, Expr );
2590                ty->hoistType = old->hoistType;
2591        }
2592
2593        virtual void visit( StructInstType * old ) override final {
2594                ast::StructInstType * ty;
2595                if ( old->baseStruct ) {
2596                        ty = new ast::StructInstType{
2597                                GET_ACCEPT_1( baseStruct, StructDecl ),
2598                                cv( old ),
2599                                GET_ACCEPT_V( attributes, Attribute )
2600                        };
2601                } else {
2602                        ty = new ast::StructInstType{
2603                                old->name,
2604                                cv( old ),
2605                                GET_ACCEPT_V( attributes, Attribute )
2606                        };
2607                }
2608                postvisit( old, ty );
2609                this->node = ty;
2610        }
2611
2612        virtual void visit( UnionInstType * old ) override final {
2613                ast::UnionInstType * ty;
2614                if ( old->baseUnion ) {
2615                        ty = new ast::UnionInstType{
2616                                GET_ACCEPT_1( baseUnion, UnionDecl ),
2617                                cv( old ),
2618                                GET_ACCEPT_V( attributes, Attribute )
2619                        };
2620                } else {
2621                        ty = new ast::UnionInstType{
2622                                old->name,
2623                                cv( old ),
2624                                GET_ACCEPT_V( attributes, Attribute )
2625                        };
2626                }
2627                postvisit( old, ty );
2628                this->node = ty;
2629        }
2630
2631        virtual void visit( EnumInstType * old ) override final {
2632                ast::EnumInstType * ty;
2633                if ( old->baseEnum ) {
2634                        ty = new ast::EnumInstType{
2635                                GET_ACCEPT_1( baseEnum, EnumDecl ),
2636                                cv( old ),
2637                                GET_ACCEPT_V( attributes, Attribute )
2638                        };
2639                } else {
2640                        ty = new ast::EnumInstType{
2641                                old->name,
2642                                cv( old ),
2643                                GET_ACCEPT_V( attributes, Attribute )
2644                        };
2645                }
2646                postvisit( old, ty );
2647                this->node = ty;
2648        }
2649
2650        virtual void visit( TraitInstType * old ) override final {
2651                ast::TraitInstType * ty;
2652                if ( old->baseTrait ) {
2653                        ty = new ast::TraitInstType{
2654                                GET_ACCEPT_1( baseTrait, TraitDecl ),
2655                                cv( old ),
2656                                GET_ACCEPT_V( attributes, Attribute )
2657                        };
2658                } else {
2659                        ty = new ast::TraitInstType{
2660                                old->name,
2661                                cv( old ),
2662                                GET_ACCEPT_V( attributes, Attribute )
2663                        };
2664                }
2665                postvisit( old, ty );
2666                this->node = ty;
2667        }
2668
2669        virtual void visit( TypeInstType * old ) override final {
2670                ast::TypeInstType * ty;
2671                if ( old->baseType ) {
2672                        ty = new ast::TypeInstType{
2673                                old->name,
2674                                GET_ACCEPT_1( baseType, TypeDecl ),
2675                                cv( old ),
2676                                GET_ACCEPT_V( attributes, Attribute )
2677                        };
2678                } else {
2679                        ty = new ast::TypeInstType{
2680                                old->name,
2681                                old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
2682                                cv( old ),
2683                                GET_ACCEPT_V( attributes, Attribute )
2684                        };
2685                }
2686                postvisit( old, ty );
2687                this->node = ty;
2688        }
2689
2690        virtual void visit( TupleType * old ) override final {
2691                this->node = new ast::TupleType{
2692                        GET_ACCEPT_V( types, Type ),
2693                        // members generated by TupleType c'tor
2694                        cv( old )
2695                };
2696        }
2697
2698        virtual void visit( TypeofType * old ) override final {
2699                this->node = new ast::TypeofType{
2700                        GET_ACCEPT_1( expr, Expr ),
2701                        (ast::TypeofType::Kind)old->is_basetypeof,
2702                        cv( old )
2703                };
2704        }
2705
2706        virtual void visit( AttrType * ) override final {
2707                assertf( false, "AttrType deprecated in new AST." );
2708        }
2709
2710        virtual void visit( VarArgsType * old ) override final {
2711                this->node = new ast::VarArgsType{ cv( old ) };
2712        }
2713
2714        virtual void visit( ZeroType * old ) override final {
2715                this->node = new ast::ZeroType{ cv( old ) };
2716        }
2717
2718        virtual void visit( OneType * old ) override final {
2719                this->node = new ast::OneType{ cv( old ) };
2720        }
2721
2722        virtual void visit( GlobalScopeType * ) override final {
2723                this->node = new ast::GlobalScopeType{};
2724        }
2725
2726        virtual void visit( Designation * old ) override final {
2727                this->node = new ast::Designation(
2728                        old->location,
2729                        GET_ACCEPT_V(designators, Expr)
2730                );
2731        }
2732
2733        virtual void visit( SingleInit * old ) override final {
2734                this->node = new ast::SingleInit(
2735                        old->location,
2736                        GET_ACCEPT_1(value, Expr),
2737                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2738                );
2739        }
2740
2741        virtual void visit( ListInit * old ) override final {
2742                this->node = new ast::ListInit(
2743                        old->location,
2744                        GET_ACCEPT_V(initializers, Init),
2745                        GET_ACCEPT_V(designations, Designation),
2746                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2747                );
2748        }
2749
2750        virtual void visit( ConstructorInit * old ) override final {
2751                this->node = new ast::ConstructorInit(
2752                        old->location,
2753                        GET_ACCEPT_1(ctor, Stmt),
2754                        GET_ACCEPT_1(dtor, Stmt),
2755                        GET_ACCEPT_1(init, Init)
2756                );
2757        }
2758
2759        virtual void visit( Constant * ) override final {
2760                // Handled in visit( ConstantEpxr * ).
2761                // In the new tree, Constant fields are inlined into containing ConstantExpression.
2762                assert( 0 );
2763        }
2764
2765        virtual void visit( Attribute * old ) override final {
2766                this->node = new ast::Attribute(
2767                        old->name,
2768                        GET_ACCEPT_V( parameters, Expr )
2769                );
2770        }
2771
2772        virtual void visit( AttrExpr * ) override final {
2773                assertf( false, "AttrExpr deprecated in new AST." );
2774        }
2775};
2776
2777#undef GET_LABELS_V
2778#undef GET_ACCEPT_V
2779#undef GET_ACCEPT_1
2780
2781std::list< ast::ptr< ast::Decl > > convert( const std::list< Declaration * > && translationUnit ) {
2782        ConverterOldToNew c;
2783        std::list< ast::ptr< ast::Decl > > decls;
2784        for(auto d : translationUnit) {
2785                d->accept( c );
2786                decls.emplace_back( c.decl() );
2787        }
2788        deleteAll(translationUnit);
2789        return decls;
2790}
Note: See TracBrowser for help on using the repository browser.