source: src/AST/Convert.cpp @ d60780c

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

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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