source: src/AST/Convert.cpp @ 28f8f15

ADT
Last change on this file since 28f8f15 was 28f8f15, checked in by JiadaL <j82liang@…>, 13 months ago

Save progress

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