source: src/AST/Convert.cpp@ 2c04369

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 2c04369 was 2c04369, checked in by Andrew Beach <ajbeach@…>, 6 years ago

Fixed some problems in convert. One of which was better solved by removing the FindSpecialDeclarations hack.

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