source: src/AST/Convert.cpp @ a83044fb

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

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

  • Property mode set to 100644
File size: 43.8 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 : Tue May 21 15:30:00 2019
13// Update Count     : 5
14//
15
16#include "Convert.hpp"
17
18#include <unordered_map>
19
20#include "AST/Attribute.hpp"
21#include "AST/Decl.hpp"
22#include "AST/Expr.hpp"
23#include "AST/Init.hpp"
24#include "AST/Stmt.hpp"
25#include "AST/TypeSubstitution.hpp"
26
27#include "SynTree/Attribute.h"
28#include "SynTree/Declaration.h"
29#include "SynTree/TypeSubstitution.h"
30
31//================================================================================================
32// Utilities
33template<template <class...> class C>
34struct to {
35        template<typename T>
36        static auto from( T && v ) -> C< typename T::value_type > {
37                C< typename T::value_type > l;
38                std::move(std::begin(v), std::end(v), std::back_inserter(l));
39                return l;
40        }
41};
42
43//================================================================================================
44class ConverterNewToOld : public ast::Visitor {
45        BaseSyntaxNode * node = nullptr;
46        std::unordered_map< ast::Node *, BaseSyntaxNode * > cache;
47
48        template<typename T>
49        struct Getter {
50                ConverterNewToOld & visitor;
51
52                template<typename U>
53                T * accept1( const ast::ptr<U> & ptr ) {
54                        if ( ! ptr ) return nullptr;
55                        ptr->accept( visitor );
56                        T * ret = strict_dynamic_cast< T * >( visitor.node );
57                        visitor.node = nullptr;
58                        return ret;
59                }
60
61                template<typename U>
62                std::list< T * > acceptL( const U & container ) {
63                        std::list< T * > ret;
64                        for (auto ptr : container ) {
65                                ret.emplace_back( accept1( ptr ) );
66                        }
67                        return ret;
68                }
69        };
70
71    template<typename T>
72    Getter<T> get() {
73        return Getter<T>{ *this };
74    }
75
76        Label makeLabel(Statement * labelled, const ast::Label& label) {
77                return Label(
78                        label.name,
79                        labelled,
80                        get<Attribute>().acceptL(label.attributes)
81                );
82        }
83
84        template<template <class...> class C>
85        std::list<Label> makeLabelL(Statement * labelled, const C<ast::Label>& labels) {
86                std::list<Label> ret;
87                for (auto label : labels) {
88                        ret.push_back( makeLabel(labelled, label) );
89                }
90                return ret;
91        }
92
93        /// get new qualifiers from old type
94        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
95
96        template<typename NewT, typename OldT>
97        NewT * cached( OldT * old ) {
98                auto it = cache.find( old );
99                // doesn't update cache, that should be handled by the accept function
100                ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
101                return strict_dynamic_cast< NewT * >( nw );
102        }
103
104public:
105        Declaration * decl( const ast::Decl * declNode ) {
106                return get<Declaration>().accept1( ast::ptr<ast::Decl>( declNode ) );
107        }
108
109private:
110        void declPostamble( Declaration * decl, const ast::Decl * node ) {
111                decl->location = node->location;
112                // name comes from constructor
113                // linkage comes from constructor
114                decl->extension = node->extension;
115                decl->uniqueId = node->uniqueId;
116                // storageClasses comes from constructor
117                this->node = decl;
118        }
119
120        const ast::DeclWithType * declWithTypePostamble (
121                        DeclarationWithType * decl, const ast::DeclWithType * node ) {
122                declPostamble( decl, node );
123                decl->mangleName = node->mangleName;
124                decl->scopeLevel = node->scopeLevel;
125                decl->asmName = get<Expression>().accept1( node->asmName );
126                // attributes comes from constructor
127                decl->isDeleted = node->isDeleted;
128                // fs comes from constructor
129                return nullptr;
130        }
131
132        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
133                auto decl = new ObjectDecl(
134                        node->name,
135                        Type::StorageClasses( node->storage.val ),
136                        LinkageSpec::Spec( node->linkage.val ),
137                        get<Expression>().accept1( node->bitfieldWidth ),
138                        get<Type>().accept1( node->type ),
139                        get<Initializer>().accept1( node->init ),
140                        get<Attribute>().acceptL( node->attributes ),
141                        Type::FuncSpecifiers( node->funcSpec.val )
142                );
143                return declWithTypePostamble( decl, node );
144        }
145
146        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
147                auto decl = new FunctionDecl(
148                        node->name,
149                        Type::StorageClasses( node->storage.val ),
150                        LinkageSpec::Spec( node->linkage.val ),
151                        get<FunctionType>().accept1( node->type ),
152                        get<CompoundStmt>().accept1( node->stmts ),
153                        get<Attribute>().acceptL( node->attributes ),
154                        Type::FuncSpecifiers( node->funcSpec.val )
155                );
156                decl->withExprs = get<Expression>().acceptL( node->withExprs );
157                return declWithTypePostamble( decl, node );
158        }
159
160        // NamedTypeDecl
161        const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
162                declPostamble( decl, node );
163                // base comes from constructor
164                decl->parameters = get<TypeDecl>().acceptL( node->params );
165                decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
166                return nullptr;
167        }
168
169        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
170                TypeDecl::Kind kind;
171                switch (node->kind) {
172                case ast::TypeVar::Dtype:
173                        kind = TypeDecl::Dtype;
174                        break;
175                case ast::TypeVar::Ftype:
176                        kind = TypeDecl::Ftype;
177                        break;
178                case ast::TypeVar::Ttype:
179                        kind = TypeDecl::Ttype;
180                        break;
181                default:
182                        assertf(false, "Invalid ast::TypeVar::Kind: %d\n", node->kind);
183                };
184                auto decl = new TypeDecl(
185                        node->name,
186                        Type::StorageClasses( node->storage.val ),
187                        get<Type>().accept1( node->base ),
188                        kind,
189                        node->sized,
190                        get<Type>().accept1( node->init )
191                );
192                return namedTypePostamble( decl, node );
193        }
194
195        const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
196                auto decl = new TypedefDecl(
197                        node->name,
198                        node->location,
199                        Type::StorageClasses( node->storage.val ),
200            get<Type>().accept1( node->base ),
201                        LinkageSpec::Spec( node->linkage.val )
202                );
203                return namedTypePostamble( decl, node );
204        }
205
206        const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
207                decl->members = get<Declaration>().acceptL( node->members );
208                decl->parameters = get<TypeDecl>().acceptL( node->params );
209                decl->body = node->body;
210                // attributes come from constructor
211                // TODO: Need caching for: decl->parent = node->parent;
212                return nullptr;
213        }
214
215        const ast::Decl * visit( const ast::StructDecl * node ) override final {
216                auto decl = new StructDecl(
217                        node->name,
218                        node->kind,
219                        get<Attribute>().acceptL( node->attributes ),
220                        LinkageSpec::Spec( node->linkage.val )
221                );
222                return aggregatePostamble( decl, node );
223        }
224
225        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
226                auto decl = new UnionDecl(
227                        node->name,
228                        get<Attribute>().acceptL( node->attributes ),
229                        LinkageSpec::Spec( node->linkage.val )
230                );
231                return aggregatePostamble( decl, node );
232        }
233
234        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
235                auto decl = new EnumDecl(
236                        node->name,
237                        get<Attribute>().acceptL( node->attributes ),
238                        LinkageSpec::Spec( node->linkage.val )
239                );
240                return aggregatePostamble( decl, node );
241        }
242
243        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
244                auto decl = new TraitDecl(
245                        node->name,
246                        {},
247                        LinkageSpec::Spec( node->linkage.val )
248                );
249                return aggregatePostamble( decl, node );
250        }
251
252        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
253                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
254                declPostamble( decl, node );
255                return nullptr;
256        }
257
258        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
259                auto decl = new StaticAssertDecl(
260                        get<Expression>().accept1( node->cond ),
261                        get<ConstantExpr>().accept1( node->msg )
262                );
263                declPostamble( decl, node );
264                return nullptr;
265        }
266
267        const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
268                stmt->location = node->location;
269                stmt->labels = makeLabelL( stmt, node->labels );
270                this->node = stmt;
271                return nullptr;
272        }
273
274        const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
275                auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
276                stmtPostamble( stmt, node );
277                return nullptr;
278        }
279
280        const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
281                auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) );
282                return stmtPostamble( stmt, node );
283        }
284
285        const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
286                auto stmt = new AsmStmt(
287                        node->isVolatile,
288                        get<Expression>().accept1( node->instruction ),
289                        get<Expression>().acceptL( node->output ),
290                        get<Expression>().acceptL( node->input ),
291                        get<ConstantExpr>().acceptL( node->clobber ),
292                        makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
293                );
294                return stmtPostamble( stmt, node );
295        }
296
297        const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
298                auto stmt = new DirectiveStmt( node->directive );
299                return stmtPostamble( stmt, node );
300        }
301
302        const ast::Stmt * visit( const ast::IfStmt * node ) override final {
303                auto stmt = new IfStmt(
304                        get<Expression>().accept1( node->cond ),
305                        get<Statement>().accept1( node->thenPart ),
306                        get<Statement>().accept1( node->elsePart ),
307                        get<Statement>().acceptL( node->inits )
308                );
309                return stmtPostamble( stmt, node );
310        }
311
312        const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
313                auto stmt = new SwitchStmt(
314                        get<Expression>().accept1( node->cond ),
315                        get<Statement>().acceptL( node->stmts )
316                );
317                return stmtPostamble( stmt, node );
318        }
319
320        const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
321                auto stmt = new CaseStmt(
322                        get<Expression>().accept1( node->cond ),
323                        get<Statement>().acceptL( node->stmts ),
324                        node->isDefault()
325                );
326                return stmtPostamble( stmt, node );
327        }
328
329        const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
330                auto inits = get<Statement>().acceptL( node->inits );
331                auto stmt = new WhileStmt(
332                        get<Expression>().accept1( node->cond ),
333                        get<Statement>().accept1( node->body ),
334                        inits,
335                        node->isDoWhile
336                );
337                return stmtPostamble( stmt, node );
338        }
339
340        const ast::Stmt * visit( const ast::ForStmt * node ) override final {
341                auto stmt = new ForStmt(
342                        get<Statement>().acceptL( node->inits ),
343                        get<Expression>().accept1( node->cond ),
344                        get<Expression>().accept1( node->inc ),
345                        get<Statement>().accept1( node->body )
346                );
347                return stmtPostamble( stmt, node );
348        }
349
350        const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
351                BranchStmt * stmt;
352                if (node->computedTarget) {
353                        stmt = new BranchStmt( get<Expression>().accept1( node->computedTarget ),
354                                BranchStmt::Goto );
355                } else {
356                        BranchStmt::Type type;
357                        switch (node->kind) {
358                        #define CASE(n) \
359                        case ast::BranchStmt::n: \
360                                type = BranchStmt::n; \
361                                break
362                        CASE(Goto);
363                        CASE(Break);
364                        CASE(Continue);
365                        CASE(FallThrough);
366                        CASE(FallThroughDefault);
367                        #undef CASE
368                        default:
369                                assertf(false, "Invalid ast::BranchStmt::Kind: %d\n", node->kind);
370                        }
371
372                        // The labels here are also weird.
373                        stmt = new BranchStmt( makeLabel( nullptr, node->originalTarget ), type );
374                        stmt->target = makeLabel( stmt, node->target );
375                }
376                return stmtPostamble( stmt, node );
377        }
378
379        const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
380                auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
381                return stmtPostamble( stmt, node );
382        }
383
384        const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
385                ThrowStmt::Kind kind;
386                switch (node->kind) {
387                case ast::ThrowStmt::Terminate:
388                        kind = ThrowStmt::Terminate;
389                        break;
390                case ast::ThrowStmt::Resume:
391                        kind = ThrowStmt::Resume;
392                        break;
393                default:
394                        assertf(false, "Invalid ast::ThrowStmt::Kind: %d\n", node->kind);
395                }
396                auto stmt = new ThrowStmt(
397                        kind,
398                        get<Expression>().accept1( node->expr ),
399                        get<Expression>().accept1( node->target )
400                );
401                return stmtPostamble( stmt, node );
402        }
403
404        const ast::Stmt * visit( const ast::TryStmt * node ) override final {
405                auto handlers = get<CatchStmt>().acceptL( node->handlers );
406                auto stmt = new TryStmt(
407                        get<CompoundStmt>().accept1( node->body ),
408                        handlers,
409                        get<FinallyStmt>().accept1( node->finally )
410                );
411                return stmtPostamble( stmt, node );
412        }
413
414        const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
415                CatchStmt::Kind kind;
416                switch (node->kind) {
417                case ast::CatchStmt::Terminate:
418                        kind = CatchStmt::Terminate;
419                        break;
420                case ast::CatchStmt::Resume:
421                        kind = CatchStmt::Resume;
422                        break;
423                default:
424                        assertf(false, "Invalid ast::CatchStmt::Kind: %d\n", node->kind);
425                }
426                auto stmt = new CatchStmt(
427                        kind,
428                        get<Declaration>().accept1( node->decl ),
429                        get<Expression>().accept1( node->cond ),
430                        get<Statement>().accept1( node->body )
431                );
432                return stmtPostamble( stmt, node );
433        }
434
435        const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
436                auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
437                return stmtPostamble( stmt, node );
438        }
439
440        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
441                auto stmt = new WaitForStmt;
442                stmt->clauses.reserve( node->clauses.size() );
443                for ( auto clause : node->clauses ) {
444                        stmt->clauses.push_back({{
445                                        get<Expression>().accept1( clause.target.func ),
446                                        get<Expression>().acceptL( clause.target.args ),
447                                },
448                                get<Statement>().accept1( clause.stmt ),
449                                get<Expression>().accept1( clause.cond ),
450                        });
451                }
452                stmt->timeout = {
453                        get<Expression>().accept1( node->timeout.time ),
454                        get<Statement>().accept1( node->timeout.stmt ),
455                        get<Expression>().accept1( node->timeout.cond ),
456                };
457                stmt->orelse = {
458                        get<Statement>().accept1( node->orElse.stmt ),
459                        get<Expression>().accept1( node->orElse.cond ),
460                };
461                return stmtPostamble( stmt, node );
462        }
463
464        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
465                auto stmt = new WithStmt(
466                        get<Expression>().acceptL( node->exprs ),
467                        get<Statement>().accept1( node->stmt )
468                );
469                return stmtPostamble( stmt, node );
470        }
471
472        const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
473                auto stmt = new NullStmt();
474                stmtPostamble( stmt, node );
475                return nullptr;
476        }
477
478        const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
479                auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
480                return stmtPostamble( stmt, node );
481        }
482
483        const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
484                (void)node;
485                return nullptr;
486        }
487
488        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
489
490                TypeSubstitution *rslt = new TypeSubstitution();
491
492                for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
493                        rslt->add( src_i->first,
494                                   get<Type>().accept1(src_i->second) );
495                }
496
497                for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
498                        rslt->addVar( src_i->first,
499                                      get<Expression>().accept1(src_i->second) );
500                }
501
502                return rslt;
503        }
504
505        void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
506                                                   std::vector<UniqueId>         &tgtResnSlots,
507                                                   const ast::Expr::InferUnion   &srcInferred ) {
508
509                assert( tgtInferParams.empty() );
510                assert( tgtResnSlots.empty() );
511
512                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
513                        const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
514                        for (auto srcParam : srcParams) {
515                                tgtInferParams[srcParam.first] = ParamEntry(
516                                        srcParam.second.decl,
517                                        get<Type>().accept1(srcParam.second.actualType),
518                                        get<Type>().accept1(srcParam.second.formalType),
519                                        get<Expression>().accept1(srcParam.second.expr)
520                                );
521                        }
522                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
523                        const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
524                        for (auto srcSlot : srcSlots) {
525                                tgtResnSlots.push_back(srcSlot);
526                        }
527                }
528        }
529
530        Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
531
532                tgt->location = src->location;
533
534                tgt->result = get<Type>().accept1(src->result);
535                tgt->env    = convertTypeSubstitution(src->env);
536
537                tgt->extension = src->extension;
538                convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
539
540                return tgt;
541        }
542
543        const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
544                auto expr = visitBaseExpr( node,
545                        new ApplicationExpr(
546                                get<Expression>().accept1(node->func),
547                                get<Expression>().acceptL(node->args)
548                        )
549                );
550                this->node = expr;
551                return nullptr;
552        }
553
554        const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
555                auto expr = visitBaseExpr( node,
556                        new UntypedExpr(
557                                get<Expression>().accept1(node->func),
558                                get<Expression>().acceptL(node->args)
559                        )
560                );
561                this->node = expr;
562                return nullptr;
563        }
564
565        const ast::Expr * visit( const ast::NameExpr * node ) override final {
566                auto expr = visitBaseExpr( node,
567                        new NameExpr(
568                                node->name
569                        )
570                );
571                this->node = expr;
572                return nullptr;
573        }
574
575        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
576                (void)node;
577                return nullptr;
578        }
579
580        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
581                (void)node;
582                return nullptr;
583        }
584
585        const ast::Expr * visit( const ast::CastExpr * node ) override final {
586                (void)node;
587                return nullptr;
588        }
589
590        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
591                (void)node;
592                return nullptr;
593        }
594
595        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
596                (void)node;
597                return nullptr;
598        }
599
600        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
601                (void)node;
602                return nullptr;
603        }
604
605        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
606                (void)node;
607                return nullptr;
608        }
609
610        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
611                (void)node;
612                return nullptr;
613        }
614
615        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
616                (void)node;
617                return nullptr;
618        }
619
620        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
621                (void)node;
622                return nullptr;
623        }
624
625        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
626                (void)node;
627                return nullptr;
628        }
629
630        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
631                (void)node;
632                return nullptr;
633        }
634
635        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
636                (void)node;
637                return nullptr;
638        }
639
640        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
641                (void)node;
642                return nullptr;
643        }
644
645        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
646                (void)node;
647                return nullptr;
648        }
649
650        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
651                (void)node;
652                return nullptr;
653        }
654
655        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
656                (void)node;
657                return nullptr;
658        }
659
660        const ast::Expr * visit( const ast::TypeExpr * node ) override final {
661                (void)node;
662                return nullptr;
663        }
664
665        const ast::Expr * visit( const ast::AsmExpr * node ) override final {
666                (void)node;
667                return nullptr;
668        }
669
670        const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
671                (void)node;
672                return nullptr;
673        }
674
675        const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
676                (void)node;
677                return nullptr;
678        }
679
680        const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
681                (void)node;
682                return nullptr;
683        }
684
685        const ast::Expr * visit( const ast::RangeExpr * node ) override final {
686                (void)node;
687                return nullptr;
688        }
689
690        const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
691                (void)node;
692                return nullptr;
693        }
694
695        const ast::Expr * visit( const ast::TupleExpr * node ) override final {
696                (void)node;
697                return nullptr;
698        }
699
700        const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
701                (void)node;
702                return nullptr;
703        }
704
705        const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
706                (void)node;
707                return nullptr;
708        }
709
710        const ast::Expr * visit( const ast::StmtExpr * node ) override final {
711                (void)node;
712                return nullptr;
713        }
714
715        const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
716                (void)node;
717                return nullptr;
718        }
719
720        const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
721                (void)node;
722                return nullptr;
723        }
724
725        const ast::Expr * visit( const ast::InitExpr * node ) override final {
726                (void)node;
727                return nullptr;
728        }
729
730        const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
731                (void)node;
732                return nullptr;
733        }
734
735        const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
736                (void)node;
737                return nullptr;
738        }
739
740        const ast::Expr * visit( const ast::GenericExpr * node ) override final {
741                (void)node;
742                return nullptr;
743        }
744
745        const ast::Type * visit( const ast::VoidType * node ) override final {
746                this->node = new VoidType{ cv( node ) };
747                return nullptr;
748        }
749
750        const ast::Type * visit( const ast::BasicType * node ) override final {
751                this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
752                return nullptr;
753        }
754
755        const ast::Type * visit( const ast::PointerType * node ) override final {
756                this->node = new PointerType{
757                        cv( node ),
758                        get<Type>().accept1( node->base ),
759                        get<Expression>().accept1( node->dimension ),
760                        node->isVarLen,
761                        node->isStatic
762                };
763                return nullptr;
764        }
765
766        const ast::Type * visit( const ast::ArrayType * node ) override final {
767                this->node = new ArrayType{
768                        cv( node ),
769                        get<Type>().accept1( node->base ),
770                        get<Expression>().accept1( node->dimension ),
771                        node->isVarLen,
772                        node->isStatic
773                };
774                return nullptr;
775        }
776
777        const ast::Type * visit( const ast::ReferenceType * node ) override final {
778                this->node = new ReferenceType{
779                        cv( node ),
780                        get<Type>().accept1( node->base )
781                };
782                return nullptr;
783        }
784
785        const ast::Type * visit( const ast::QualifiedType * node ) override final {
786                this->node = new QualifiedType{
787                        cv( node ),
788                        get<Type>().accept1( node->parent ),
789                        get<Type>().accept1( node->child )
790                };
791                return nullptr;
792        }
793
794        const ast::Type * visit( const ast::FunctionType * node ) override final {
795                auto ty = new FunctionType { cv( node ), node->isVarArgs };
796                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
797                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
798                ty->forall = get<TypeDecl>().acceptL( node->forall );
799                node = ty;
800                return nullptr;
801        }
802
803        const ast::Type * visit( const ast::StructInstType * node ) override final {
804                (void)node;
805                return nullptr;
806        }
807
808        const ast::Type * visit( const ast::UnionInstType * node ) override final {
809                (void)node;
810                return nullptr;
811        }
812
813        const ast::Type * visit( const ast::EnumInstType * node ) override final {
814                (void)node;
815                return nullptr;
816        }
817
818        const ast::Type * visit( const ast::TraitInstType * node ) override final {
819                (void)node;
820                return nullptr;
821        }
822
823        const ast::Type * visit( const ast::TypeInstType * node ) override final {
824                (void)node;
825                return nullptr;
826        }
827
828        const ast::Type * visit( const ast::TupleType * node ) override final {
829                (void)node;
830                return nullptr;
831        }
832
833        const ast::Type * visit( const ast::TypeofType * node ) override final {
834                (void)node;
835                return nullptr;
836        }
837
838        const ast::Type * visit( const ast::VarArgsType * node ) override final {
839                (void)node;
840                return nullptr;
841        }
842
843        const ast::Type * visit( const ast::ZeroType * node ) override final {
844                (void)node;
845                return nullptr;
846        }
847
848        const ast::Type * visit( const ast::OneType * node ) override final {
849                (void)node;
850                return nullptr;
851        }
852
853        const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
854                (void)node;
855                return nullptr;
856        }
857
858        const ast::Designation * visit( const ast::Designation * node ) override final {
859                (void)node;
860                return nullptr;
861        }
862
863        const ast::Init * visit( const ast::SingleInit * node ) override final {
864                (void)node;
865                return nullptr;
866        }
867
868        const ast::Init * visit( const ast::ListInit * node ) override final {
869                (void)node;
870                return nullptr;
871        }
872
873        const ast::Init * visit( const ast::ConstructorInit * node ) override final {
874                (void)node;
875                return nullptr;
876        }
877
878        const ast::Attribute * visit( const ast::Attribute * node ) override final {
879                (void)node;
880                return nullptr;
881        }
882
883        const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
884                (void)node;
885                return nullptr;
886        }
887};
888
889std::list< Declaration * > convert( std::list< ast::ptr< ast::Decl > > && translationUnit ) {
890        ConverterNewToOld c;
891        std::list< Declaration * > decls;
892        for(auto d : translationUnit) {
893                decls.emplace_back( c.decl( d ) );
894                delete d;
895        }
896        return decls;
897}
898
899//================================================================================================
900
901class ConverterOldToNew : public Visitor {
902public:
903        ast::Decl * decl() {
904                return strict_dynamic_cast< ast::Decl * >( node );
905        }
906private:
907        /// conversion output
908        ast::Node * node;
909        /// cache of nodes that might be referenced by readonly<> for de-duplication
910        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;
911
912        // Local Utilities:
913
914        template<typename NewT, typename OldT>
915        NewT * getAccept1( OldT old ) {
916                if ( ! old ) return nullptr;
917                old->accept(*this);
918                return strict_dynamic_cast< NewT * >( node );
919        }
920
921#       define GET_ACCEPT_1(child, type) \
922                getAccept1< ast::type, decltype( old->child ) >( old->child )
923
924        template<typename NewT, typename OldC>
925        std::vector< ast::ptr<NewT> > getAcceptV( OldC& old ) {
926                std::vector< ast::ptr<NewT> > ret;
927                ret.reserve( old.size() );
928                for ( auto a : old ) {
929                        a->accept( *this );
930                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
931                }
932                return ret;
933        }
934
935#       define GET_ACCEPT_V(child, type) \
936                getAcceptV< ast::type, decltype( old->child ) >( old->child )
937
938        ast::Label make_label(Label* old) {
939                return ast::Label(
940                        old->labelled->location,
941                        old->name,
942                        GET_ACCEPT_V(attributes, Attribute)
943                );
944        }
945
946        template<template <class...> class C>
947        C<ast::Label> make_labels(C<Label> olds) {
948                C<ast::Label> ret;
949                for (auto oldn : olds) {
950                        ret.push_back( make_label( &oldn ) );
951                }
952                return ret;
953        }
954
955#       define GET_LABELS_V(labels) \
956                to<std::vector>::from( make_labels( std::move( labels ) ) )
957       
958        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
959
960        template<typename NewT, typename OldT>
961        NewT * cached( OldT * old ) {
962                auto it = cache.find( old );
963                // doesn't update cache, that should be handled by the accept function
964                ast::Node * nw = it == cache.end() ? getAccept1< NewT >( old ) : it->second;
965                return strict_dynamic_cast< NewT * >( nw );
966        }
967
968        // Now all the visit functions:
969
970        virtual void visit( ObjectDecl * old ) override final {
971                auto decl = new ast::ObjectDecl(
972                        old->location,
973                        old->name,
974                        GET_ACCEPT_1(type, Type),
975                        GET_ACCEPT_1(init, Init),
976                        { old->get_storageClasses().val },
977                        { old->linkage.val },
978                        GET_ACCEPT_1(bitfieldWidth, Expr),
979                        GET_ACCEPT_V(attributes, Attribute),
980                        { old->get_funcSpec().val }
981                );
982                decl->scopeLevel = old->scopeLevel;
983                decl->mangleName = old->mangleName;
984                decl->isDeleted  = old->isDeleted;
985                decl->uniqueId   = old->uniqueId;
986                decl->extension  = old->extension;
987
988                this->node = decl;
989        }
990
991        virtual void visit( FunctionDecl * ) override final {
992
993        }
994
995        virtual void visit( StructDecl * old ) override final {
996                auto decl = new ast::StructDecl(
997                        old->location,
998                        old->name,
999                        old->kind,
1000                        GET_ACCEPT_V(attributes, Attribute),
1001                        { old->linkage.val }
1002                );
1003                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1004                decl->body   = old->body;
1005                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1006                decl->members    = GET_ACCEPT_V(members, Decl);
1007                decl->extension  = old->extension;
1008                decl->uniqueId   = old->uniqueId;
1009                decl->storage    = { old->storageClasses.val };
1010
1011                this->node = decl;
1012        }
1013
1014        virtual void visit( UnionDecl * old ) override final {
1015                auto decl = new ast::UnionDecl(
1016                        old->location,
1017                        old->name,
1018                        GET_ACCEPT_V(attributes, Attribute),
1019                        { old->linkage.val }
1020                );
1021                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1022                decl->body   = old->body;
1023                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1024                decl->members    = GET_ACCEPT_V(members, Decl);
1025                decl->extension  = old->extension;
1026                decl->uniqueId   = old->uniqueId;
1027                decl->storage    = { old->storageClasses.val };
1028
1029                this->node = decl;
1030        }
1031
1032        virtual void visit( EnumDecl * old ) override final {
1033                auto decl = new ast::UnionDecl(
1034                        old->location,
1035                        old->name,
1036                        GET_ACCEPT_V(attributes, Attribute),
1037                        { old->linkage.val }
1038                );
1039                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1040                decl->body   = old->body;
1041                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1042                decl->members    = GET_ACCEPT_V(members, Decl);
1043                decl->extension  = old->extension;
1044                decl->uniqueId   = old->uniqueId;
1045                decl->storage    = { old->storageClasses.val };
1046
1047                this->node = decl;
1048        }
1049
1050        virtual void visit( TraitDecl * old ) override final {
1051                auto decl = new ast::UnionDecl(
1052                        old->location,
1053                        old->name,
1054                        GET_ACCEPT_V(attributes, Attribute),
1055                        { old->linkage.val }
1056                );
1057                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1058                decl->body   = old->body;
1059                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1060                decl->members    = GET_ACCEPT_V(members, Decl);
1061                decl->extension  = old->extension;
1062                decl->uniqueId   = old->uniqueId;
1063                decl->storage    = { old->storageClasses.val };
1064
1065                this->node = decl;
1066        }
1067
1068        virtual void visit( TypeDecl * ) override final {
1069
1070        }
1071
1072        virtual void visit( TypedefDecl * old ) override final {
1073                auto decl = new ast::TypedefDecl(
1074                        old->location,
1075                        old->name,
1076                        { old->storageClasses.val },
1077                        GET_ACCEPT_1(base, Type),
1078                        { old->linkage.val }
1079                );
1080                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1081                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
1082                decl->extension  = old->extension;
1083                decl->uniqueId   = old->uniqueId;
1084                decl->storage    = { old->storageClasses.val };
1085
1086                this->node = decl;
1087        }
1088
1089        virtual void visit( AsmDecl * ) override final {
1090
1091        }
1092
1093        virtual void visit( StaticAssertDecl * ) override final {
1094
1095        }
1096
1097        virtual void visit( CompoundStmt * old ) override final {
1098                auto stmt = new ast::CompoundStmt(
1099                        old->location,
1100                        to<std::list>::from( GET_ACCEPT_V(kids, Stmt) ),
1101                        GET_LABELS_V(old->labels)
1102                );
1103
1104                this->node = stmt;
1105        }
1106
1107        virtual void visit( ExprStmt * old ) override final {
1108                this->node = new ast::ExprStmt(
1109                        old->location,
1110                        GET_ACCEPT_1(expr, Expr),
1111                        GET_LABELS_V(old->labels)
1112                );
1113        }
1114
1115        virtual void visit( AsmStmt * old ) override final {
1116                this->node = new ast::AsmStmt(
1117                        old->location,
1118                        old->voltile,
1119                        GET_ACCEPT_1(instruction, Expr),
1120                        GET_ACCEPT_V(output, Expr),
1121                        GET_ACCEPT_V(input, Expr),
1122                        GET_ACCEPT_V(clobber, ConstantExpr),
1123                        GET_LABELS_V(old->gotolabels),
1124                        GET_LABELS_V(old->labels)
1125                );
1126        }
1127
1128        virtual void visit( DirectiveStmt * old ) override final {
1129                this->node = new ast::DirectiveStmt(
1130                        old->location,
1131                        old->directive,
1132                        GET_LABELS_V(old->labels)
1133                );
1134        }
1135
1136        virtual void visit( IfStmt * old ) override final {
1137                this->node = new ast::IfStmt(
1138                        old->location,
1139                        GET_ACCEPT_1(condition, Expr),
1140                        GET_ACCEPT_1(thenPart, Stmt),
1141                        GET_ACCEPT_1(elsePart, Stmt),
1142                        GET_ACCEPT_V(initialization, Stmt),
1143                        GET_LABELS_V(old->labels)
1144                );
1145        }
1146
1147        virtual void visit( SwitchStmt * old ) override final {
1148                this->node = new ast::SwitchStmt(
1149                        old->location,
1150                        GET_ACCEPT_1(condition, Expr),
1151                        GET_ACCEPT_V(statements, Stmt),
1152                        GET_LABELS_V(old->labels)
1153                );
1154        }
1155
1156        virtual void visit( CaseStmt * old ) override final {
1157                this->node = new ast::CaseStmt(
1158                        old->location,
1159                        GET_ACCEPT_1(condition, Expr),
1160                        GET_ACCEPT_V(stmts, Stmt),
1161                        GET_LABELS_V(old->labels)
1162                );
1163        }
1164
1165        virtual void visit( WhileStmt * old ) override final {
1166                this->node = new ast::WhileStmt(
1167                        old->location,
1168                        GET_ACCEPT_1(condition, Expr),
1169                        GET_ACCEPT_1(body, Stmt),
1170                        GET_ACCEPT_V(initialization, Stmt),
1171                        old->isDoWhile,
1172                        GET_LABELS_V(old->labels)
1173                );
1174        }
1175
1176        virtual void visit( ForStmt * old ) override final {
1177                this->node = new ast::ForStmt(
1178                        old->location,
1179                        GET_ACCEPT_V(initialization, Stmt),
1180                        GET_ACCEPT_1(condition, Expr),
1181                        GET_ACCEPT_1(increment, Expr),
1182                        GET_ACCEPT_1(body, Stmt),
1183                        GET_LABELS_V(old->labels)
1184                );
1185        }
1186
1187        virtual void visit( BranchStmt * old ) override final {
1188                if (old->computedTarget) {
1189                        this->node = new ast::BranchStmt(
1190                                old->location,
1191                                GET_ACCEPT_1(computedTarget, Expr),
1192                                GET_LABELS_V(old->labels)
1193                        );
1194                } else {
1195                        ast::BranchStmt::Kind kind;
1196                        switch (old->type) {
1197                        #define CASE(n) \
1198                        case BranchStmt::n: \
1199                                kind = ast::BranchStmt::n; \
1200                                break
1201                        CASE(Goto);
1202                        CASE(Break);
1203                        CASE(Continue);
1204                        CASE(FallThrough);
1205                        CASE(FallThroughDefault);
1206                        #undef CASE
1207                        default:
1208                                assertf(false, "Invalid BranchStmt::Type %d\n", old->type);
1209                        }
1210
1211                        Label label = old->originalTarget;
1212                        auto stmt = new ast::BranchStmt(
1213                                old->location,
1214                                kind,
1215                                make_label(&label),
1216                                GET_LABELS_V(old->labels)
1217                        );
1218                        stmt->target = make_label(&old->target);
1219                        this->node = stmt;
1220                }
1221        }
1222
1223        virtual void visit( ReturnStmt * old ) override final {
1224                this->node = new ast::ReturnStmt(
1225                        old->location,
1226                        GET_ACCEPT_1(expr, Expr),
1227                        GET_LABELS_V(old->labels)
1228                );
1229        }
1230
1231        virtual void visit( ThrowStmt * old ) override final {
1232                ast::ThrowStmt::Kind kind;
1233                switch (old->kind) {
1234                case ThrowStmt::Terminate:
1235                        kind = ast::ThrowStmt::Terminate;
1236                        break;
1237                case ThrowStmt::Resume:
1238                        kind = ast::ThrowStmt::Resume;
1239                        break;
1240                default:
1241                        assertf(false, "Invalid ThrowStmt::Kind %d\n", old->kind);
1242                }
1243
1244                this->node = new ast::ThrowStmt(
1245                        old->location,
1246                        kind,
1247                        GET_ACCEPT_1(expr, Expr),
1248                        GET_ACCEPT_1(target, Expr),
1249                        GET_LABELS_V(old->labels)
1250                );
1251        }
1252
1253        virtual void visit( TryStmt * old ) override final {
1254                this->node = new ast::TryStmt(
1255                        old->location,
1256                        GET_ACCEPT_1(block, CompoundStmt),
1257                        GET_ACCEPT_V(handlers, CatchStmt),
1258                        GET_ACCEPT_1(finallyBlock, FinallyStmt),
1259                        GET_LABELS_V(old->labels)
1260                );
1261        }
1262
1263        virtual void visit( CatchStmt * old ) override final {
1264                ast::CatchStmt::Kind kind;
1265                switch (old->kind) {
1266                case CatchStmt::Terminate:
1267                        kind = ast::CatchStmt::Terminate;
1268                        break;
1269                case CatchStmt::Resume:
1270                        kind = ast::CatchStmt::Resume;
1271                        break;
1272                default:
1273                        assertf(false, "Invalid CatchStmt::Kind %d\n", old->kind);
1274                }
1275
1276                this->node = new ast::CatchStmt(
1277                        old->location,
1278                        kind,
1279                        GET_ACCEPT_1(decl, Decl),
1280                        GET_ACCEPT_1(cond, Expr),
1281                        GET_ACCEPT_1(body, Stmt),
1282                        GET_LABELS_V(old->labels)
1283                );
1284        }
1285
1286        virtual void visit( FinallyStmt * old ) override final {
1287                this->node = new ast::FinallyStmt(
1288                        old->location,
1289                        GET_ACCEPT_1(block, CompoundStmt),
1290                        GET_LABELS_V(old->labels)
1291                );
1292        }
1293
1294        virtual void visit( WaitForStmt * old ) override final {
1295                ast::WaitForStmt * stmt = new ast::WaitForStmt(
1296                        old->location,
1297                        GET_LABELS_V(old->labels)
1298                );
1299
1300                stmt->clauses.reserve( old->clauses.size() );
1301                for (size_t i = 0 ; i < old->clauses.size() ; ++i) {
1302                        stmt->clauses.push_back({
1303                                ast::WaitForStmt::Target{
1304                                        GET_ACCEPT_1(clauses[i].target.function, Expr),
1305                                        GET_ACCEPT_V(clauses[i].target.arguments, Expr)
1306                                },
1307                                GET_ACCEPT_1(clauses[i].statement, Stmt),
1308                                GET_ACCEPT_1(clauses[i].condition, Expr)
1309                        });
1310                }
1311                stmt->timeout = {
1312                        GET_ACCEPT_1(timeout.time, Expr),
1313                        GET_ACCEPT_1(timeout.statement, Stmt),
1314                        GET_ACCEPT_1(timeout.condition, Expr),
1315                };
1316                stmt->orElse = {
1317                        GET_ACCEPT_1(timeout.statement, Stmt),
1318                        GET_ACCEPT_1(timeout.condition, Expr),
1319                };
1320
1321                this->node = stmt;
1322        }
1323
1324        virtual void visit( WithStmt * old ) override final {
1325                this->node = new ast::WithStmt(
1326                        old->location,
1327                        GET_ACCEPT_V(exprs, Expr),
1328                        GET_ACCEPT_1(stmt, Stmt),
1329                        GET_LABELS_V(old->labels)
1330                );
1331        }
1332
1333        virtual void visit( NullStmt * old ) override final {
1334                this->node = new ast::NullStmt(
1335                        old->location,
1336                        GET_LABELS_V(old->labels)
1337                );
1338        }
1339
1340        virtual void visit( DeclStmt * old ) override final {
1341                this->node = new ast::DeclStmt(
1342                        old->location,
1343                        GET_ACCEPT_1(decl, Decl),
1344                        GET_LABELS_V(old->labels)
1345                );
1346        }
1347
1348        virtual void visit( ImplicitCtorDtorStmt * old ) override final {
1349                this->node = new ast::ImplicitCtorDtorStmt(
1350                        old->location,
1351                        GET_ACCEPT_1(callStmt, Stmt),
1352                        GET_LABELS_V(old->labels)
1353                );
1354        }
1355
1356        ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
1357
1358                ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
1359
1360                for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
1361                        rslt->add( old_i->first,
1362                                   getAccept1<ast::Type>(old_i->second) );
1363                }
1364
1365                for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
1366                        rslt->addVar( old_i->first,
1367                                      getAccept1<ast::Expr>(old_i->second) );
1368                }
1369
1370                return rslt;
1371        }
1372
1373        void convertInferUnion(ast::Expr::InferUnion               &newInferred,
1374                                                   const std::map<UniqueId,ParamEntry> &oldInferParams,
1375                                                   const std::vector<UniqueId>         &oldResnSlots) {
1376
1377                assert( oldInferParams.empty() || oldResnSlots.empty() );
1378                assert( newInferred.mode == ast::Expr::InferUnion::Empty );
1379
1380                if ( !oldInferParams.empty() ) {
1381                        ast::InferredParams &tgt = newInferred.inferParams();
1382                        for (auto old : oldInferParams) {
1383                                tgt[old.first] = ast::ParamEntry(
1384                                        old.second.decl,
1385                                        getAccept1<ast::Type>(old.second.actualType),
1386                                        getAccept1<ast::Type>(old.second.formalType),
1387                                        getAccept1<ast::Expr>(old.second.expr)
1388                                );
1389                        }
1390                } else if ( !oldResnSlots.empty() ) {
1391                        ast::ResnSlots &tgt = newInferred.resnSlots();
1392                        for (auto old : oldResnSlots) {
1393                                tgt.push_back(old);
1394                        }
1395                }
1396        }
1397
1398        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
1399
1400                nw->result = GET_ACCEPT_1(result, Type);
1401                nw->env    = convertTypeSubstitution(old->env);
1402
1403                nw->extension = old->extension;
1404                convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
1405
1406                return nw;
1407        }
1408
1409        virtual void visit( ApplicationExpr * old ) override final {
1410                this->node = visitBaseExpr( old,
1411                        new ast::ApplicationExpr(
1412                                old->location,
1413                                GET_ACCEPT_1(function, Expr),
1414                                GET_ACCEPT_V(args, Expr)
1415                        )
1416                );
1417        }
1418
1419        virtual void visit( UntypedExpr * old ) override final {
1420                this->node = visitBaseExpr( old,
1421                        new ast::UntypedExpr(
1422                                old->location,
1423                                GET_ACCEPT_1(function, Expr),
1424                                GET_ACCEPT_V(args, Expr)
1425                        )
1426                );
1427        }
1428
1429        virtual void visit( NameExpr * old ) override final {
1430                this->node = visitBaseExpr( old,
1431                        new ast::NameExpr(
1432                                old->location,
1433                                old->get_name()
1434                        )
1435                );
1436        }
1437
1438        virtual void visit( CastExpr * old ) override final {
1439                this->node = visitBaseExpr( old,
1440                        new ast::CastExpr(
1441                                old->location,
1442                                nullptr, // cast's "to" type is expr's result type; converted in visitBaseExpr
1443                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
1444                        )
1445                );
1446        }
1447
1448        virtual void visit( KeywordCastExpr * ) override final {
1449
1450        }
1451
1452        virtual void visit( VirtualCastExpr * ) override final {
1453
1454        }
1455
1456        virtual void visit( AddressExpr * ) override final {
1457
1458        }
1459
1460        virtual void visit( LabelAddressExpr * ) override final {
1461
1462        }
1463
1464        virtual void visit( UntypedMemberExpr * ) override final {
1465
1466        }
1467
1468        virtual void visit( MemberExpr * ) override final {
1469
1470        }
1471
1472        virtual void visit( VariableExpr * ) override final {
1473
1474        }
1475
1476        virtual void visit( ConstantExpr * ) override final {
1477
1478        }
1479
1480        virtual void visit( SizeofExpr * ) override final {
1481
1482        }
1483
1484        virtual void visit( AlignofExpr * ) override final {
1485
1486        }
1487
1488        virtual void visit( UntypedOffsetofExpr * ) override final {
1489
1490        }
1491
1492        virtual void visit( OffsetofExpr * ) override final {
1493
1494        }
1495
1496        virtual void visit( OffsetPackExpr * ) override final {
1497
1498        }
1499
1500        virtual void visit( LogicalExpr * ) override final {
1501
1502        }
1503
1504        virtual void visit( ConditionalExpr * ) override final {
1505
1506        }
1507
1508        virtual void visit( CommaExpr * ) override final {
1509
1510        }
1511
1512        virtual void visit( TypeExpr * ) override final {
1513
1514        }
1515
1516        virtual void visit( AsmExpr * ) override final {
1517
1518        }
1519
1520        virtual void visit( ImplicitCopyCtorExpr * ) override final {
1521
1522        }
1523
1524        virtual void visit( ConstructorExpr *  ) override final {
1525
1526        }
1527
1528        virtual void visit( CompoundLiteralExpr * ) override final {
1529
1530        }
1531
1532        virtual void visit( RangeExpr * ) override final {
1533
1534        }
1535
1536        virtual void visit( UntypedTupleExpr * ) override final {
1537
1538        }
1539
1540        virtual void visit( TupleExpr * ) override final {
1541
1542        }
1543
1544        virtual void visit( TupleIndexExpr * ) override final {
1545
1546        }
1547
1548        virtual void visit( TupleAssignExpr * ) override final {
1549
1550        }
1551
1552        virtual void visit( StmtExpr *  ) override final {
1553
1554        }
1555
1556        virtual void visit( UniqueExpr *  ) override final {
1557
1558        }
1559
1560        virtual void visit( UntypedInitExpr *  ) override final {
1561
1562        }
1563
1564        virtual void visit( InitExpr *  ) override final {
1565
1566        }
1567
1568        virtual void visit( DeletedExpr * ) override final {
1569
1570        }
1571
1572        virtual void visit( DefaultArgExpr * ) override final {
1573
1574        }
1575
1576        virtual void visit( GenericExpr * ) override final {
1577
1578        }
1579
1580        virtual void visit( VoidType * old ) override final {
1581                this->node = new ast::VoidType{ cv( old ) };
1582        }
1583
1584        virtual void visit( BasicType * old ) override final {
1585                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
1586        }
1587
1588        virtual void visit( PointerType * old ) override final {
1589                this->node = new ast::PointerType{
1590                        GET_ACCEPT_1( base, Type ),
1591                        GET_ACCEPT_1( dimension, Expr ),
1592                        (ast::LengthFlag)old->isVarLen,
1593                        (ast::DimensionFlag)old->isStatic,
1594                        cv( old )
1595                };
1596        }
1597
1598        virtual void visit( ArrayType * old ) override final {
1599                this->node = new ast::ArrayType{
1600                        GET_ACCEPT_1( base, Type ),
1601                        GET_ACCEPT_1( dimension, Expr ),
1602                        (ast::LengthFlag)old->isVarLen,
1603                        (ast::DimensionFlag)old->isStatic,
1604                        cv( old )
1605                };
1606        }
1607
1608        virtual void visit( ReferenceType * old ) override final {
1609                this->node = new ast::ReferenceType{
1610                        GET_ACCEPT_1( base, Type ),
1611                        cv( old )
1612                };
1613        }
1614
1615        virtual void visit( QualifiedType * old ) override final {
1616                this->node = new ast::QualifiedType{
1617                        GET_ACCEPT_1( parent, Type ),
1618                        GET_ACCEPT_1( child, Type ),
1619                        cv( old )
1620                };
1621        }
1622
1623        virtual void visit( FunctionType * old ) override final {
1624                auto ty = new ast::FunctionType {
1625                        (ast::ArgumentFlag)old->isVarArgs,
1626                        cv( old )
1627                };
1628                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
1629                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
1630                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
1631                this->node = ty;
1632        }
1633
1634        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
1635                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
1636                ty->params = GET_ACCEPT_V( parameters, Expr );
1637                ty->hoistType = old->hoistType;
1638        }
1639
1640        virtual void visit( StructInstType * old ) override final {
1641                auto ty = new ast::StructInstType{
1642                        cached< ast::StructDecl >( old->baseStruct ),
1643                        cv( old ),
1644                        GET_ACCEPT_V( attributes, Attribute )
1645                };
1646                postvisit( old, ty );
1647                this->node = ty;
1648        }
1649
1650        virtual void visit( UnionInstType * old ) override final {
1651                auto ty = new ast::UnionInstType{
1652                        cached< ast::UnionDecl >( old->baseUnion ),
1653                        cv( old ),
1654                        GET_ACCEPT_V( attributes, Attribute )
1655                };
1656                postvisit( old, ty );
1657                this->node = ty;
1658        }
1659
1660        virtual void visit( EnumInstType * old ) override final {
1661                auto ty = new ast::EnumInstType{
1662                        cached< ast::EnumDecl >( old->baseEnum ),
1663                        cv( old ),
1664                        GET_ACCEPT_V( attributes, Attribute )
1665                };
1666                postvisit( old, ty );
1667                this->node = ty;
1668        }
1669
1670        virtual void visit( TraitInstType * old ) override final {
1671                auto ty = new ast::TraitInstType{
1672                        cached< ast::TraitDecl >( old->baseTrait ),
1673                        cv( old ),
1674                        GET_ACCEPT_V( attributes, Attribute )
1675                };
1676                postvisit( old, ty );
1677                this->node = ty;
1678        }
1679
1680        virtual void visit( TypeInstType * old ) override final {
1681                auto ty = new ast::TypeInstType{
1682                        cached< ast::TypeDecl >( old->baseStruct ),
1683                        cv( old ),
1684                        GET_ACCEPT_V( attributes, Attribute )
1685                };
1686                postvisit( old, ty );
1687                this->node = ty;
1688        }
1689
1690        virtual void visit( TupleType * ) override final {
1691
1692        }
1693
1694        virtual void visit( TypeofType * ) override final {
1695
1696        }
1697
1698        virtual void visit( AttrType * ) override final {
1699
1700        }
1701
1702        virtual void visit( VarArgsType * ) override final {
1703
1704        }
1705
1706        virtual void visit( ZeroType * ) override final {
1707
1708        }
1709
1710        virtual void visit( OneType * ) override final {
1711
1712        }
1713
1714        virtual void visit( GlobalScopeType * ) override final {
1715
1716        }
1717
1718        virtual void visit( Designation * ) override final {
1719
1720        }
1721
1722        virtual void visit( SingleInit * ) override final {
1723
1724        }
1725
1726        virtual void visit( ListInit * ) override final {
1727
1728        }
1729
1730        virtual void visit( ConstructorInit * ) override final {
1731
1732        }
1733
1734        virtual void visit( Constant * ) override final {
1735
1736        }
1737
1738        virtual void visit( Attribute * ) override final {
1739
1740        }
1741
1742        virtual void visit( AttrExpr * ) override final {
1743
1744                assert( 0 );
1745        }
1746};
1747
1748#undef GET_LABELS_V
1749#undef GET_ACCEPT_V
1750#undef GET_ACCEPT_1
1751
1752std::list< ast::ptr< ast::Decl > > convert( const std::list< Declaration * > && translationUnit ) {
1753        ConverterOldToNew c;
1754        std::list< ast::ptr< ast::Decl > > decls;
1755        for(auto d : translationUnit) {
1756                d->accept( c );
1757                decls.emplace_back( c.decl() );
1758                delete d;
1759        }
1760        return decls;
1761}
Note: See TracBrowser for help on using the repository browser.