source: src/AST/Convert.cpp @ 05d55ff

arm-ehenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 05d55ff was 05d55ff, checked in by Aaron Moss <a3moss@…>, 4 years ago

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

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