source: src/AST/Convert.cpp @ 6a1dfda

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 6a1dfda was 6896548, checked in by Michael Brooks <mlbrooks@…>, 5 years ago

Fixed convert-convert issues with strings, when conversion happens after resolve. Three specific issues fixed.

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