source: src/AST/Convert.cpp @ b869ec5

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

Conversion caching for AggregateDecl?, DeclWithType?, TypeDecl?

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