source: src/AST/Convert.cpp@ b869ec5

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since b869ec5 was b869ec5, checked in by Aaron Moss <a3moss@…>, 7 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.