source: src/AST/Convert.cpp @ 6355ba7

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

Removed debugging prints which are no longer useful

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