source: src/AST/Convert.cpp @ 546e712

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

Fix for 1 bug of N

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