source: src/AST/Convert.cpp@ e00c22f

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since e00c22f was 16ba4a6f, checked in by Fangren Yu <f37yu@…>, 5 years ago

factor out resolver calls in pre-resolution stage

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