source: src/AST/Convert.cpp @ 954c954

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since 954c954 was 954c954, checked in by Fangren Yu <f37yu@…>, 14 months ago

Move function argument and return variable declarations from FunctionType? to FunctionDecl?

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