source: src/AST/Print.cpp@ 085f67a

ADT ast-experimental
Last change on this file since 085f67a was 6e1e2d0, checked in by caparsons <caparson@…>, 2 years ago

resolved merge conflicts

  • Property mode set to 100644
File size: 40.1 KB
RevLine 
[461046f]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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//
[0351e9f]7// Print.cpp -- Print an AST (or sub-tree) to a stream.
[461046f]8//
9// Author : Thierry Delisle
10// Created On : Tue May 21 16:20:15 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#include "Print.hpp"
17
18#include "Decl.hpp"
19#include "Expr.hpp"
20#include "Stmt.hpp"
21#include "Type.hpp"
22#include "TypeSubstitution.hpp"
[b26144d]23#include "CompilationState.h"
[461046f]24
[a2e758e]25#include "Common/utility.h" // for group_iterate
26
[5902625]27using namespace std;
[461046f]28
29namespace ast {
30
[257a8f5]31namespace {
32
33template<typename C, typename... T>
34constexpr array<C, sizeof...(T)> make_array( T&&... values ) {
35 return array<C, sizeof...(T)>{ std::forward<T>( values )... };
36}
37
38namespace Names {
39 static constexpr auto FuncSpecifiers = make_array<const char*>(
40 "inline", "_Noreturn", "fortran"
41 );
42
43 static constexpr auto StorageClasses = make_array<const char*>(
44 "extern", "static", "auto", "register", "__thread", "_Thread_local"
45 );
46
47 static constexpr auto Qualifiers = make_array<const char*>(
48 "const", "restrict", "volatile", "mutex", "_Atomic"
49 );
50}
51
52template<typename bits_t, size_t N>
53void print( ostream & os, const bits_t & bits,
54 const array<const char *, N> & names ) {
55 if ( !bits.any() ) return;
56 for ( size_t i = 0 ; i < N ; i += 1 ) {
57 if ( bits[i] ) {
58 os << names[i] << ' ';
59 }
60 }
[461046f]61}
62
[e67991f]63class Printer final : public Visitor {
[461046f]64public:
[5902625]65 ostream & os;
[461046f]66 Indenter indent;
[5902625]67 bool short_mode;
[461046f]68
[5902625]69 Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
[461046f]70
71private:
72 template< typename C >
73 void printAll( const C & c ) {
74 for ( const auto & i : c ) {
75 if ( i ) {
76 os << indent;
77 i->accept( *this );
78 // need an endl after each element because it's not
79 // easy to know when each individual item should end
[5902625]80 os << endl;
[461046f]81 } // if
82 } // for
83 }
84
[20a5977]85 /// call if mandatory field is missing
86 void undefined() {
87 os << "UNDEFINED";
88 }
89
90 /// call for fields that should be mandatory
91 void safe_print( const ast::Node * n ) {
92 if ( n ) n->accept( *this );
93 else undefined();
94 }
95
96 /// call to print short form. Incorporates features of safe_print()
[6f4b7f2]97 void short_print( const ast::Decl * n ) {
[20a5977]98 if ( ! n ) { undefined(); return; }
99 bool old_short = short_mode; short_mode = true;
100 n->accept( *this );
101 short_mode = old_short;
102 }
103
[461046f]104 static const char* Names[];
105
[94b1f718]106 void print( const std::vector<ast::Label> & labels ) {
107 if ( labels.empty() ) return;
108 os << indent << "... Labels: {";
109 bool isFirst = true;
110 for ( const Label & l : labels ) {
111 if ( isFirst ) { isFirst = false; } else { os << ","; }
112 os << l;
113 }
114 os << "}" << endl;
115 }
116
[20a5977]117 void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) {
[79c907b]118 if (inferred.data.resnSlots && !inferred.data.resnSlots->empty()) {
119 os << indent << "with " << inferred.data.resnSlots->size()
[94b1f718]120 << " pending inference slots" << endl;
[20a5977]121 }
[79c907b]122 if (inferred.data.inferParams && !inferred.data.inferParams->empty()) {
[94b1f718]123 os << indent << "with inferred parameters " << level << ":" << endl;
[20a5977]124 ++indent;
[79c907b]125 for ( const auto & i : *inferred.data.inferParams ) {
[20a5977]126 os << indent;
[79c907b]127 short_print( i.second.declptr );
[94b1f718]128 os << endl;
[20a5977]129 print( i.second.expr->inferred, level+1 );
130 }
131 --indent;
132 }
133 }
134
[361bf01]135 void print( const ast::FunctionType::ForallList & forall ) {
[d908563]136 if ( forall.empty() ) return;
[94b1f718]137 os << "forall" << endl;
[b0ec971]138 ++indent;
139 printAll( forall );
140 os << indent;
141 --indent;
142 }
143
[3e5dd913]144 void print( const ast::FunctionType::AssertionList & assts ) {
145 if (assts.empty()) return;
146 os << "with assertions" << endl;
147 ++indent;
148 printAll(assts);
149 os << indent;
150 --indent;
151 }
152
[b0ec971]153 void print( const std::vector<ptr<Attribute>> & attrs ) {
154 if ( attrs.empty() ) return;
[94b1f718]155 os << "with attributes" << endl;
[b0ec971]156 ++indent;
157 printAll( attrs );
158 --indent;
159 }
160
161 void print( const std::vector<ptr<Expr>> & params ) {
162 if ( params.empty() ) return;
[94b1f718]163 os << endl << indent << "... with parameters" << endl;
[b0ec971]164 ++indent;
165 printAll( params );
166 --indent;
167 }
168
[5902625]169 void print( const ast::AggregateDecl * node ) {
[6f4b7f2]170 os << node->typeString() << " " << node->name;
[a7d50b6]171
[6f4b7f2]172 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
[5902625]173 os << " " << Linkage::name( node->linkage );
[6f4b7f2]174 }
[a7d50b6]175
[6f4b7f2]176 os << " " << (node->body ? "with" : "without") << " body";
[5902625]177
178 if ( ! node->params.empty() ) {
179 os << endl << indent << "... with parameters" << endl;
180 ++indent;
181 printAll( node->params );
182 --indent;
[6f4b7f2]183 }
184
185 if ( ! short_mode && ! node->members.empty() ) {
[5902625]186 os << endl << indent << "... with members" << endl;
187 ++indent;
188 printAll( node->members );
189 --indent;
[6f4b7f2]190 }
191
192 if ( ! short_mode && ! node->attributes.empty() ) {
[5902625]193 os << endl << indent << "... with attributes" << endl;
194 ++indent;
195 printAll( node->attributes );
196 --indent;
[6f4b7f2]197 }
198
[4559b34]199 auto ptrToEnum = dynamic_cast<const ast::EnumDecl *>(node);
200 if ( ! short_mode && ptrToEnum && ptrToEnum->base ) {
201 os << endl << indent << ".. with (enum) base" << endl;
202 ++indent;
203 ptrToEnum->base->accept( *this );
[ed9a1ae]204 --indent;
[4559b34]205 }
206
[5902625]207 os << endl;
208 }
209
[c86b08d]210 void print( const ast::WaitStmt * node ) {
211 if ( node->timeout_time ) {
212 os << indent-1 << "timeout of:" << endl;
213 node->timeout_time->accept( *this );
214
215 if ( node->timeout_stmt ) {
216 os << indent-1 << "... with statment:" << endl;
217 node->timeout_stmt->accept( *this );
218 }
219
220 if ( node->timeout_cond ) {
221 os << indent-1 << "... with condition:" << endl;
222 node->timeout_cond->accept( *this );
223 }
224 }
225
226 if ( node->else_stmt ) {
227 os << indent-1 << "else:" << endl;
228 node->else_stmt->accept( *this );
229
230 if ( node->else_cond ) {
231 os << indent-1 << "... with condition:" << endl;
232 node->else_cond->accept( *this );
233 }
234 }
235 }
236
[6f4b7f2]237 void preprint( const ast::NamedTypeDecl * node ) {
[cd6a6ff]238 if ( ! node->name.empty() ) {
[3e5dd913]239 os << node->name << ": ";
[cd6a6ff]240 }
[5902625]241
[6f4b7f2]242 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
[5902625]243 os << Linkage::name( node->linkage ) << " ";
[6f4b7f2]244 }
245
[257a8f5]246 ast::print( os, node->storage );
[5902625]247 os << node->typeString();
[a7d50b6]248
[5902625]249 if ( node->base ) {
250 os << " for ";
251 ++indent;
252 node->base->accept( *this );
253 --indent;
[6f4b7f2]254 }
255
[79c907b]256 if ( ! node->assertions.empty() ) {
[5902625]257 os << endl << indent << "... with assertions" << endl;
258 ++indent;
259 printAll( node->assertions );
260 --indent;
[6f4b7f2]261 }
[5902625]262 }
[b0ec971]263
[20a5977]264 void postprint( const ast::Expr * node ) {
265 print( node->inferred );
266
[ef9988b]267 if ( node->result ) {
[cd6a6ff]268 os << endl << indent << "... with resolved type:" << endl;
269 ++indent;
270 os << indent;
271 node->result->accept( *this );
272 --indent;
[ef9988b]273 }
274
[20a5977]275 if ( node->env ) {
[94b1f718]276 os << endl << indent << "... with environment:" << endl;
[20a5977]277 ++indent;
278 node->env->accept( *this );
279 --indent;
280 }
[a16e246]281
[20a5977]282 if ( node->extension ) {
[94b1f718]283 os << endl << indent << "... with extension";
[20a5977]284 }
285 }
286
287 void preprint( const ast::Type * node ) {
[257a8f5]288 ast::print( os, node->qualifiers );
[20a5977]289 }
290
[361bf01]291 void preprint( const ast::FunctionType * node ) {
[20a5977]292 print( node->forall );
[3e5dd913]293 print( node->assertions );
[257a8f5]294 ast::print( os, node->qualifiers );
[20a5977]295 }
296
[98e8b3b]297 void preprint( const ast::BaseInstType * node ) {
[20a5977]298 print( node->attributes );
[257a8f5]299 ast::print( os, node->qualifiers );
[20a5977]300 }
301
[461046f]302public:
[e67991f]303 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
[6f4b7f2]304 if ( ! node->name.empty() ) os << node->name << ": ";
[461046f]305
[6f4b7f2]306 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
[461046f]307 os << Linkage::name( node->linkage ) << " ";
[6f4b7f2]308 }
[461046f]309
[257a8f5]310 ast::print( os, node->storage );
[461046f]311
312 if ( node->type ) {
313 node->type->accept( *this );
314 } else {
[20a5977]315 os << "untyped entity";
[6f4b7f2]316 }
[461046f]317
[6f4b7f2]318 if ( ! short_mode && node->init ) {
319 ++indent;
[461046f]320 os << " with initializer (" << (
321 node->init->maybeConstructed
322 ? "maybe constructed"
323 : "not constructed"
[6f4b7f2]324 ) << ")" << endl << indent;
[461046f]325 node->init->accept( *this );
326 --indent;
[5902625]327 os << endl;
[6f4b7f2]328 }
[461046f]329
[6f4b7f2]330 if ( ! short_mode && ! node->attributes.empty() ) {
[5902625]331 os << endl << indent << "... with attributes:" << endl;
[461046f]332 ++indent;
333 printAll( node->attributes );
334 --indent;
335 }
336
337 if ( node->bitfieldWidth ) {
338 os << indent << " with bitfield width ";
339 node->bitfieldWidth->accept( *this );
[6f4b7f2]340 }
341
[461046f]342 return node;
343 }
344
[e67991f]345 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
[6f4b7f2]346 if ( !node->name.empty() ) os << node->name << ": ";
347
348 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
[5902625]349 os << Linkage::name( node->linkage ) << " ";
[6f4b7f2]350 }
[5902625]351
[6f4b7f2]352 if ( ! short_mode ) printAll( node->attributes );
[5902625]353
[257a8f5]354 ast::print( os, node->storage );
355 ast::print( os, node->funcSpec );
[451d958]356
357 if ( node->type && node->isTypeFixed ) {
[5902625]358 node->type->accept( *this );
359 } else {
[451d958]360 if (!node->type_params.empty()) {
361 os << "forall" << endl;
362 ++indent;
363 printAll(node->type_params);
364 os << indent;
365 --indent;
366
367 if (!node->assertions.empty()) {
368 os << "with assertions" << endl;
369 ++indent;
370 printAll(node->assertions);
371 os << indent;
372 --indent;
373 }
374 }
375
376 os << "function" << endl;
377 if ( ! node->params.empty() ) {
378 os << indent << "... with parameters" << endl;
379 ++indent;
380 printAll( node->params );
381 if ( node->type->isVarArgs ) {
382 os << indent << "and a variable number of other arguments" << endl;
383 }
384 --indent;
385 } else if ( node->type->isVarArgs ) {
386 os << indent+1 << "accepting unspecified arguments" << endl;
387 }
388
389 os << indent << "... returning";
390 if ( node->returns.empty() ) {
391 os << " nothing" << endl;
392 } else {
393 os << endl;
394 ++indent;
395 printAll( node->returns );
396 --indent;
397 }
[6f4b7f2]398 }
[5902625]399
[056bee8]400 if ( ! node->withExprs.empty() ) {
401 // Not with a clause, but the 'with clause'.
402 ++indent;
403 os << " with clause" << endl << indent;
404 printAll( node->withExprs );
405 --indent;
406 }
407
[6f4b7f2]408 if ( ! short_mode && node->stmts ) {
[5902625]409 ++indent;
[6f4b7f2]410 os << " with body" << endl << indent;
[5902625]411 node->stmts->accept( *this );
412 --indent;
[6f4b7f2]413 }
414
[461046f]415 return node;
416 }
417
[e67991f]418 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
[5902625]419 print(node);
[461046f]420 return node;
421 }
422
[71806e0]423 virtual const ast::DeclWithType * visit( const ast::InlineMemberDecl * node ) override final {
[e874605]424 os << "inline ";
425 if ( ! node->name.empty() ) os << node->name;
426
427 return node;
428 }
429
[e67991f]430 virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
[5902625]431 print(node);
[461046f]432 return node;
433 }
434
[e67991f]435 virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
[5902625]436 print(node);
[461046f]437 return node;
438 }
439
[e67991f]440 virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
[5902625]441 print(node);
[461046f]442 return node;
443 }
444
[e67991f]445 virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
[6f4b7f2]446 preprint( node );
447 if ( ! short_mode && node->init ) {
[5902625]448 os << endl << indent << "with type initializer: ";
449 ++indent;
450 node->init->accept( *this );
451 --indent;
452 }
[6f4b7f2]453
[461046f]454 return node;
455 }
456
[e67991f]457 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
[6f4b7f2]458 preprint( node );
[461046f]459 return node;
460 }
461
[e67991f]462 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
[6f4b7f2]463 safe_print( node->stmt );
[461046f]464 return node;
465 }
466
[2d019af]467 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final {
468 safe_print( node->stmt );
469 return node;
470 }
471
[e67991f]472 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
[5902625]473 os << "Static Assert with condition: ";
474 ++indent;
[6f4b7f2]475 safe_print( node->cond );
476 os << endl << indent-1 << "and message: ";
477 safe_print( node->msg );
[5902625]478 --indent;
479 os << endl;
[6f4b7f2]480
[461046f]481 return node;
482 }
483
[e67991f]484 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
[94b1f718]485 os << "Compound Statement:" << endl;
[5902625]486 ++indent;
487 printAll( node->kids );
488 --indent;
[461046f]489 return node;
490 }
491
[e67991f]492 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
[5902625]493 ++indent;
494 os << "Expression Statement:" << endl << indent;
[20a5977]495 safe_print( node->expr );
[5902625]496 --indent;
[461046f]497 return node;
498 }
499
[e67991f]500 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
[5902625]501 os << "Assembler Statement:" << endl;
502 ++indent;
[94b1f718]503 os << indent-1 << "instruction:" << endl << indent;
504 safe_print( node->instruction );
[5902625]505 if ( ! node->output.empty() ) {
[94b1f718]506 os << endl << indent << "output:" << endl;
[5902625]507 printAll( node->output );
508 } // if
509 if ( ! node->input.empty() ) {
[94b1f718]510 os << indent << "input:" << endl;
[5902625]511 printAll( node->input );
512 } // if
513 if ( ! node->clobber.empty() ) {
[94b1f718]514 os << indent << "clobber:" << endl;
[5902625]515 printAll( node->clobber );
516 } // if
517 --indent;
[461046f]518 return node;
519 }
520
[e67991f]521 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
[94b1f718]522 os << "GCC Directive: " << node->directive << endl;
[461046f]523 return node;
524 }
525
[e67991f]526 virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
[94b1f718]527 os << "If on condition:" << endl;
[5902625]528 ++indent;
[94b1f718]529 os << indent;
[20a5977]530 safe_print( node->cond );
[5902625]531 --indent;
532
[94b1f718]533 if ( ! node->inits.empty() ) {
534 os << indent << "... with initialization:" << endl;
[5902625]535 ++indent;
[94b1f718]536 for ( const ast::Stmt * stmt : node->inits ) {
[5902625]537 os << indent;
[94b1f718]538 safe_print( stmt );
[5902625]539 }
540 --indent;
541 os << endl;
542 }
543
[94b1f718]544 os << indent << "... then:" << endl;
[5902625]545
546 ++indent;
547 os << indent;
[3b0bc16]548 safe_print( node->then );
[5902625]549 --indent;
550
[3b0bc16]551 if ( node->else_ != 0 ) {
[94b1f718]552 os << indent << "... else:" << endl;
[5902625]553 ++indent;
554 os << indent;
[3b0bc16]555 node->else_->accept( *this );
[5902625]556 --indent;
557 } // if
[461046f]558 return node;
559 }
560
[3b0bc16]561 virtual const ast::Stmt * visit( const ast::WhileDoStmt * node ) override final {
[94b1f718]562 if ( node->isDoWhile ) { os << "Do-"; }
563 os << "While on condition:" << endl;
564 ++indent;
565 safe_print( node->cond );
566 os << indent-1 << "... with body:" << endl;
567 safe_print( node->body );
568
569 if ( ! node->inits.empty() ) {
570 os << indent-1 << "... with inits:" << endl;
571 printAll( node->inits );
572 }
573 --indent;
574
[461046f]575 return node;
576 }
577
[e67991f]578 virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
[94b1f718]579 os << "For Statement" << endl;
580
581 if ( ! node->inits.empty() ) {
582 os << indent << "... initialization:" << endl;
583 ++indent;
584 for ( const ast::Stmt * stmt : node->inits ) {
585 os << indent+1;
586 safe_print( stmt );
587 }
588 --indent;
589 }
590
591 if ( node->cond ) {
592 os << indent << "... condition:" << endl;
593 ++indent;
594 os << indent;
595 node->cond->accept( *this );
596 --indent;
597 }
598
599 if ( node->inc ) {
600 os << indent << "... increment:" << endl;
601 ++indent;
602 os << indent;
603 node->inc->accept( *this );
604 --indent;
605 }
606
607 if ( node->body ) {
608 os << indent << "... with body:" << endl;
609 ++indent;
610 os << indent;
611 node->body->accept( *this );
612 --indent;
613 }
614 os << endl;
615 print( node->labels );
616
[461046f]617 return node;
618 }
619
[e67991f]620 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
[94b1f718]621 os << "Switch on condition: ";
622 safe_print( node->cond );
623 os << endl;
624
625 ++indent;
[400b8be]626 for ( const ast::CaseClause * stmt : node->cases ) {
[94b1f718]627 stmt->accept( *this );
628 }
629 --indent;
630
[461046f]631 return node;
632 }
633
[400b8be]634 virtual const ast::CaseClause * visit( const ast::CaseClause * node ) override final {
[94b1f718]635 if ( node->isDefault() ) {
636 os << indent << "Default ";
637 } else {
638 os << indent << "Case ";
639 safe_print( node->cond );
640 } // if
641 os << endl;
642
643 ++indent;
644 for ( const ast::Stmt * stmt : node->stmts ) {
645 os << indent;
646 stmt->accept( *this );
647 }
648 --indent;
649
[461046f]650 return node;
651 }
652
[e67991f]653 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
[94b1f718]654 os << "Branch (" << node->kindName() << ")" << endl;
655 ++indent;
656 if ( ! node->target.empty() ) {
657 os << indent << "with target: " << node->target << endl;
658 }
659
660 if ( ! node->originalTarget.empty() ) {
661 os << indent << "with original target: " << node->originalTarget << endl;
662 }
663
664 if ( node->computedTarget ) {
665 os << indent << "with computed target: ";
666 node->computedTarget->accept( *this );
667 os << endl;
668 }
669 --indent;
670
[461046f]671 return node;
672 }
673
[e67991f]674 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
[94b1f718]675 os << "Return Statement, returning";
676 if ( node->expr ) {
677 ++indent;
678 os << ":" << endl << indent;
679 node->expr->accept( *this );
680 --indent;
681 } else {
682 os << " void";
683 }
684 os << endl;
685
[461046f]686 return node;
687 }
688
[e67991f]689 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
[6f4b7f2]690 if ( node->target ) os << "Non-Local ";
691
692 switch( node->kind ) {
693 case ast::ExceptionKind::Terminate: os << "Terminate "; break;
694 case ast::ExceptionKind::Resume: os << "Resume "; break;
695 }
696
697 ++indent;
698 os << "Throw Statement, raising: ";
699 safe_print( node->expr );
700 if ( node->target ) {
701 os << "... at: ";
702 node->target->accept( *this );
703 }
704 --indent;
705
[461046f]706 return node;
707 }
708
[e67991f]709 virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
[6f4b7f2]710 ++indent;
[a7d50b6]711 os << "Try Statement" << endl << indent-1
[6f4b7f2]712 << "... with block:" << endl << indent;
713 safe_print( node->body );
714
715 os << indent-1 << "... and handlers:" << endl;
[400b8be]716 for ( const ast::CatchClause * stmt : node->handlers ) {
[6f4b7f2]717 os << indent;
718 stmt->accept( *this );
719 }
720
721 if ( node->finally ) {
722 os << indent-1 << "... and finally:" << endl << indent;
723 node->finally->accept( *this );
724 }
725 --indent;
726
[461046f]727 return node;
728 }
729
[400b8be]730 virtual const ast::CatchClause * visit( const ast::CatchClause * node ) override final {
[6f4b7f2]731 os << "Catch ";
732 switch ( node->kind ) {
733 case ast::ExceptionKind::Terminate: os << "Terminate "; break;
734 case ast::ExceptionKind::Resume: os << "Resume "; break;
735 }
736 os << "Statement" << endl << indent;
737
738 ++indent;
739 os << "... catching: ";
740 short_print( node->decl );
741 os << endl;
742
743 if ( node->cond ) {
744 os << indent-1 << "... with conditional:" << endl << indent;
745 node->cond->accept( *this );
746 }
747
748 os << indent-1 << "... with block:" << endl << indent;
749 safe_print( node->body );
750 --indent;
[a7d50b6]751
[461046f]752 return node;
753 }
754
[400b8be]755 virtual const ast::FinallyClause * visit( const ast::FinallyClause * node ) override final {
[6f4b7f2]756 os << "Finally Statement" << endl;
757 os << indent << "... with block:" << endl;
758 ++indent;
759 os << indent;
760 safe_print( node->body );
761 --indent;
762
[461046f]763 return node;
764 }
765
[37cdd97]766 virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
767 os << "Suspend Statement";
[835d6e8]768 switch (node->kind) {
769 case ast::SuspendStmt::None : os << " with implicit target"; break;
770 case ast::SuspendStmt::Generator: os << " for generator"; break;
771 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
[37cdd97]772 }
773 os << endl;
774
775 ++indent;
776 if(node->then) {
777 os << indent << " with post statement :" << endl;
778 safe_print( node->then );
779 }
780 ++indent;
781
782 return node;
783 }
784
[c86b08d]785 virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
786 os << indent-1 << "target: ";
787 safe_print( node->target );
788
789 if ( node->stmt ) {
790 os << indent-1 << "... with statment:" << endl;
791 node->stmt->accept( *this );
792 }
793
794 if ( node->when_cond ) {
795 os << indent-1 << "... with when condition:" << endl;
796 node->when_cond->accept( *this );
797 }
798
799 return node;
800 }
801
[e67991f]802 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
[6f4b7f2]803 os << "Waitfor Statement" << endl;
804 indent += 2;
805 for( const auto & clause : node->clauses ) {
[f6e6a55]806 clause->accept( *this );
807 }
[a7d50b6]808
[f6e6a55]809 if ( node->timeout_time ) {
810 os << indent-1 << "timeout of:" << endl;
811 node->timeout_time->accept( *this );
[6f4b7f2]812
[f6e6a55]813 if ( node->timeout_stmt ) {
[6f4b7f2]814 os << indent-1 << "... with statment:" << endl;
[f6e6a55]815 node->timeout_stmt->accept( *this );
[6f4b7f2]816 }
817
[f6e6a55]818 if ( node->timeout_cond ) {
[6f4b7f2]819 os << indent-1 << "... with condition:" << endl;
[f6e6a55]820 node->timeout_cond->accept( *this );
[6f4b7f2]821 }
822 }
823
[f6e6a55]824 if ( node->else_stmt ) {
825 os << indent-1 << "else:" << endl;
826 node->else_stmt->accept( *this );
[6f4b7f2]827
[f6e6a55]828 if ( node->else_cond ) {
[6f4b7f2]829 os << indent-1 << "... with condition:" << endl;
[f6e6a55]830 node->else_cond->accept( *this );
[6f4b7f2]831 }
832 }
833
[f6e6a55]834 return node;
835 }
[6f4b7f2]836
[f6e6a55]837 virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
838 os << indent-1 << "target function: ";
[c86b08d]839 safe_print( node->target );
[f6e6a55]840
841 if ( !node->target_args.empty() ) {
842 os << endl << indent-1 << "... with arguments:" << endl;
843 for( const ast::Expr * arg : node->target_args ) {
844 arg->accept( *this );
[6f4b7f2]845 }
846 }
[f6e6a55]847
848 if ( node->stmt ) {
849 os << indent-1 << "... with statment:" << endl;
850 node->stmt->accept( *this );
851 }
852
[c86b08d]853 if ( node->when_cond ) {
[f6e6a55]854 os << indent-1 << "... with condition:" << endl;
[c86b08d]855 node->when_cond->accept( *this );
[f6e6a55]856 }
[6f4b7f2]857
[461046f]858 return node;
859 }
860
[c86b08d]861 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
862 os << "Waituntil Statement" << endl;
863 indent += 2;
864 for( const auto & clause : node->clauses ) {
865 clause->accept( *this );
866 }
867 print(node); // calls print( const ast::WaitStmt * node )
868 return node;
869 }
870
[e67991f]871 virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
[6f4b7f2]872 os << "With statement" << endl;
873 os << indent << "... with expressions:" << endl;
874 ++indent;
875 printAll( node->exprs );
876 os << indent-1 << "... with statement:" << endl << indent;
877 safe_print( node->stmt );
878 --indent;
879
[461046f]880 return node;
881 }
882
[e67991f]883 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
[94b1f718]884 os << "Null Statement" << endl;
885 print( node->labels );
886
[461046f]887 return node;
888 }
889
[e67991f]890 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
[6f4b7f2]891 os << "Declaration of ";
892 safe_print( node->decl );
893
[461046f]894 return node;
895 }
896
[e67991f]897 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
[6f4b7f2]898 os << "Implicit Ctor Dtor Statement" << endl;
899 os << indent << "... with Ctor/Dtor: ";
900 ++indent;
901 safe_print( node->callStmt );
902 --indent;
903 os << endl;
904
[461046f]905 return node;
906 }
907
[6cebfef]908 virtual const ast::Stmt * visit( const ast::MutexStmt * node ) override final {
909 os << "Mutex Statement" << endl;
910 os << indent << "... with Mutex Parameters: ";
911 ++indent;
912 printAll( node->mutexObjs );
913 --indent;
914 os << indent << "... with Statement: ";
915 ++indent;
916 safe_print( node->stmt );
917 --indent;
918 os << endl;
919
920 return node;
921 }
922
[e67991f]923 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
[20a5977]924 ++indent;
[94b1f718]925 os << "Application of" << endl << indent;
[20a5977]926 safe_print( node->func );
[94b1f718]927 os << endl;
[20a5977]928 if ( ! node->args.empty() ) {
[94b1f718]929 os << indent << "... to arguments" << endl;
[20a5977]930 printAll( node->args );
931 }
932 --indent;
933 postprint( node );
934
[461046f]935 return node;
936 }
937
[e67991f]938 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
[20a5977]939 ++indent;
[94b1f718]940 os << "Applying untyped:" << endl;
[20a5977]941 os << indent;
942 safe_print( node->func );
[94b1f718]943 os << endl << indent-1 << "...to:" << endl;
[20a5977]944 printAll( node->args );
945 --indent;
946 postprint( node );
947
[461046f]948 return node;
949 }
950
[e67991f]951 virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
[20a5977]952 os << "Name: " << node->name;
953 postprint( node );
[d908563]954
[461046f]955 return node;
956 }
957
[b0d9ff7]958 virtual const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final {
959 os << "QualifiedNameExpr: " << std::endl;
960 os << ++indent << "Type: ";
961 safe_print( node->type_decl );
962 os << std::endl;
963 os << indent << "Name: " << node->name << std::endl;
964 --indent;
965 postprint( node );
966 return node;
967 }
968
[e67991f]969 virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
[94b1f718]970 os << "Address of:" << endl;
[20a5977]971 ++indent;
972 os << indent;
973 safe_print( node->arg );
974
975 --indent;
976
[461046f]977 return node;
978 }
979
[e67991f]980 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
[20a5977]981 os << "Address of label:" << node->arg;
982
[461046f]983 return node;
984 }
985
[e67991f]986 virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
[20a5977]987 ++indent;
[a8ed717]988 os << (node->isGenerated ? "Generated" : "Explicit") << " Cast of:" << endl << indent;
[20a5977]989 safe_print( node->arg );
[94b1f718]990 os << endl << indent-1 << "... to:";
[20a5977]991 if ( ! node->result ) {
992 os << " ";
993 undefined();
994 } else if ( node->result->isVoid() ) {
995 os << " nothing";
996 } else {
[94b1f718]997 os << endl << indent;
[20a5977]998 node->result->accept( *this );
999 } // if
1000 --indent;
1001 postprint( node );
1002
[461046f]1003 return node;
1004 }
1005
[e67991f]1006 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
[20a5977]1007 ++indent;
[94b1f718]1008 os << "Keyword Cast of:" << endl << indent;
[20a5977]1009 safe_print( node->arg );
1010 --indent;
[94b1f718]1011 os << endl << indent << "... to: " << node->targetString();
[20a5977]1012 postprint( node );
1013
[461046f]1014 return node;
1015 }
1016
[e67991f]1017 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
[20a5977]1018 ++indent;
[94b1f718]1019 os << "Virtual Cast of:" << endl << indent;
[20a5977]1020 safe_print( node->arg );
[94b1f718]1021 os << endl << indent-1 << "... to:";
[20a5977]1022 if ( ! node->result ) {
1023 os << " unknown";
1024 } else {
[94b1f718]1025 os << endl << indent;
[20a5977]1026 node->result->accept( *this );
1027 }
1028 --indent;
1029 postprint( node );
1030
[461046f]1031 return node;
1032 }
1033
[e67991f]1034 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
[20a5977]1035 ++indent;
[94b1f718]1036 os << "Untyped Member Expression, with field: " << endl << indent;
[20a5977]1037 safe_print( node->member );
[94b1f718]1038 os << indent-1 << "... from aggregate:" << endl << indent;
[20a5977]1039 safe_print( node->aggregate );
1040 --indent;
1041 postprint( node );
1042
[461046f]1043 return node;
1044 }
1045
[e67991f]1046 virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
[20a5977]1047 ++indent;
[94b1f718]1048 os << "Member Expression, with field:" << endl << indent;
[20a5977]1049 safe_print( node->member );
[94b1f718]1050 os << endl << indent-1 << "... from aggregate:" << endl << indent;
[20a5977]1051 safe_print( node->aggregate );
1052 --indent;
1053 postprint( node );
1054
[461046f]1055 return node;
1056 }
1057
[e67991f]1058 virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
[20a5977]1059 os << "Variable Expression: ";
1060 short_print( node->var );
1061 postprint( node );
1062
[461046f]1063 return node;
1064 }
1065
[e67991f]1066 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
[20a5977]1067 os << "Constant Expression (" << node->rep;
1068 if ( node->result ) {
1069 os << ": ";
1070 node->result->accept( *this );
1071 }
1072 os << ")";
1073 postprint( node );
1074
[461046f]1075 return node;
1076 }
1077
[e67991f]1078 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
[a16e246]1079 os << "Sizeof Expression on: ";
1080 ++indent;
1081 if ( node->type ) node->type->accept( *this );
1082 else safe_print( node->expr );
1083 --indent;
1084 postprint( node );
1085
[461046f]1086 return node;
1087 }
1088
[e67991f]1089 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
[a16e246]1090 os << "Alignof Expression on: ";
1091 ++indent;
1092 if ( node->type ) node->type->accept( *this );
1093 else safe_print( node->expr );
1094 --indent;
1095 postprint( node );
[d908563]1096
[461046f]1097 return node;
1098 }
1099
[e67991f]1100 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
[a16e246]1101 os << "Untyped Offsetof Expression on member " << node->member << " of ";
1102 ++indent;
1103 safe_print( node->type );
1104 --indent;
1105 postprint( node );
1106
[461046f]1107 return node;
1108 }
1109
[e67991f]1110 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
[a16e246]1111 os << "Offsetof Expression on member " << node->member->name << " of ";
1112 ++indent;
1113 safe_print( node->type );
1114 --indent;
1115 postprint( node );
1116
[461046f]1117 return node;
1118 }
1119
[e67991f]1120 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
[a16e246]1121 os << "Offset Pack Expression on: ";
1122 ++indent;
1123 safe_print( node->type );
1124 --indent;
1125 postprint( node );
1126
[461046f]1127 return node;
1128 }
1129
[e67991f]1130 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
[a16e246]1131 os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
1132 safe_print( node->arg1 );
1133 os << " and ";
1134 safe_print( node->arg2 );
1135 postprint( node );
1136
[461046f]1137 return node;
1138 }
1139
[e67991f]1140 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
[a16e246]1141 ++indent;
[94b1f718]1142 os << "Conditional expression on:" << endl << indent;
[a16e246]1143 safe_print( node->arg1 );
[94b1f718]1144 os << indent-1 << "First alternative:" << endl << indent;
[a16e246]1145 safe_print( node->arg2 );
[94b1f718]1146 os << indent-1 << "Second alternative:" << endl << indent;
[a16e246]1147 safe_print( node->arg3 );
1148 --indent;
1149 postprint( node );
1150
[461046f]1151 return node;
1152 }
1153
[e67991f]1154 virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
[a16e246]1155 ++indent;
[94b1f718]1156 os << "Comma Expression:" << endl << indent;
[a16e246]1157 safe_print( node->arg1 );
[94b1f718]1158 os << endl << indent;
[a16e246]1159 safe_print( node->arg2 );
1160 --indent;
1161 postprint( node );
1162
[461046f]1163 return node;
1164 }
1165
[e67991f]1166 virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
[a16e246]1167 safe_print( node->type );
1168 postprint( node );
1169
[461046f]1170 return node;
1171 }
1172
[4ec9513]1173 virtual const ast::Expr * visit( const ast::DimensionExpr * node ) override final {
1174 os << "Type-Sys Value: " << node->name;
1175 postprint( node );
1176
1177 return node;
1178 }
1179
[e67991f]1180 virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
[94b1f718]1181 os << "Asm Expression:" << endl;
[a16e246]1182 ++indent;
[665f432]1183 if ( !node->inout.empty() ) os << "[" << node->inout << "] ";
[a16e246]1184 if ( node->constraint ) node->constraint->accept( *this );
1185 if ( node->operand ) node->operand->accept( *this );
1186 --indent;
[d908563]1187
[461046f]1188 return node;
1189 }
1190
[e67991f]1191 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
[a16e246]1192 ++indent;
[94b1f718]1193 os << "Implicit Copy Constructor Expression:" << endl << indent;
[a16e246]1194 safe_print( node->callExpr );
1195 --indent;
1196 postprint( node );
1197
[461046f]1198 return node;
1199 }
1200
[e67991f]1201 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
[94b1f718]1202 os << "Constructor Expression:" << endl << indent+1;
[a16e246]1203 indent += 2;
1204 safe_print( node->callExpr );
1205 indent -= 2;
1206 postprint( node );
1207
[461046f]1208 return node;
1209 }
1210
[e67991f]1211 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
[a16e246]1212 ++indent;
[94b1f718]1213 os << "Compound Literal Expression: " << endl << indent;
[a16e246]1214 safe_print( node->result );
1215 os << indent;
1216 safe_print( node->init );
1217 --indent;
1218 postprint( node );
1219
[461046f]1220 return node;
1221 }
1222
[e67991f]1223 virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
[a16e246]1224 os << "Range Expression: ";
1225 safe_print( node->low );
1226 os << " ... ";
1227 safe_print( node->high );
1228 postprint( node );
1229
[461046f]1230 return node;
1231 }
1232
[e67991f]1233 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
[94b1f718]1234 os << "Untyped Tuple:" << endl;
[a16e246]1235 ++indent;
1236 printAll( node->exprs );
1237 --indent;
1238 postprint( node );
1239
[461046f]1240 return node;
1241 }
1242
[e67991f]1243 virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
[94b1f718]1244 os << "Tuple:" << endl;
[a16e246]1245 ++indent;
1246 printAll( node->exprs );
1247 --indent;
1248 postprint( node );
1249
[461046f]1250 return node;
1251 }
1252
[e67991f]1253 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
[94b1f718]1254 os << "Tuple Index Expression, with tuple:" << endl;
[a16e246]1255 ++indent;
1256 os << indent;
1257 safe_print( node->tuple );
[94b1f718]1258 os << indent << "with index: " << node->index << endl;
[a16e246]1259 --indent;
1260 postprint( node );
[d908563]1261
[461046f]1262 return node;
1263 }
1264
[e67991f]1265 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
[94b1f718]1266 os << "Tuple Assignment Expression, with stmt expr:" << endl;
[a16e246]1267 ++indent;
1268 os << indent;
1269 safe_print( node->stmtExpr );
1270 --indent;
1271 postprint( node );
1272
[461046f]1273 return node;
1274 }
1275
[e67991f]1276 virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
[a16e246]1277 ++indent;
[94b1f718]1278 os << "Statement Expression:" << endl << indent;
[a16e246]1279 safe_print( node->stmts );
1280 if ( ! node->returnDecls.empty() ) {
1281 os << indent << "... with returnDecls: ";
1282 printAll( node->returnDecls );
1283 }
1284 if ( ! node->dtors.empty() ) {
1285 os << indent << "... with dtors: ";
1286 printAll( node->dtors );
1287 }
1288 --indent;
1289 postprint( node );
1290
[461046f]1291 return node;
1292 }
1293
[e67991f]1294 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
[a16e246]1295 ++indent;
[94b1f718]1296 os << "Unique Expression with id: " << node->id << endl << indent;
[a16e246]1297 safe_print( node->expr );
1298 if ( node->object ) {
1299 os << indent-1 << "... with decl: ";
1300 short_print( node->object );
1301 }
1302 --indent;
1303 postprint( node );
1304
[461046f]1305 return node;
1306 }
1307
[e67991f]1308 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
[a16e246]1309 ++indent;
[94b1f718]1310 os << "Untyped Init Expression" << endl << indent;
[a16e246]1311 safe_print( node->expr );
1312 if ( ! node->initAlts.empty() ) {
1313 for ( const InitAlternative & alt : node->initAlts ) {
1314 os << indent << "InitAlternative: ";
1315 safe_print( alt.type );
1316 safe_print( alt.designation );
1317 }
1318 }
1319 --indent;
1320
[461046f]1321 return node;
1322 }
1323
[e67991f]1324 virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
[a16e246]1325 ++indent;
[94b1f718]1326 os << "Init Expression" << endl << indent;
[a16e246]1327 safe_print( node->expr );
1328 os << indent << "... with designation: ";
1329 safe_print( node->designation );
1330 --indent;
1331
[461046f]1332 return node;
1333 }
1334
[e67991f]1335 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
[a16e246]1336 ++indent;
[94b1f718]1337 os << "Deleted Expression" << endl << indent;
[a16e246]1338 safe_print( node->expr );
[94b1f718]1339 os << endl << indent << "... deleted by: ";
[a16e246]1340 safe_print( node->deleteStmt );
1341 --indent;
1342
[461046f]1343 return node;
1344 }
1345
[e67991f]1346 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
[a16e246]1347 ++indent;
[94b1f718]1348 os << "Default Argument Expression" << endl << indent;
[a16e246]1349 safe_print( node->expr );
1350 --indent;
1351
[461046f]1352 return node;
1353 }
1354
[e67991f]1355 virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
[a16e246]1356 ++indent;
[94b1f718]1357 os << "C11 _Generic Expression" << endl << indent;
[a16e246]1358 safe_print( node->control );
[94b1f718]1359 os << endl << indent << "... with associations:" << endl;
[a16e246]1360 for ( const auto & assoc : node->associations ) {
1361 os << indent;
1362 if ( assoc.type ) {
1363 os << "... type: ";
1364 assoc.type->accept( *this );
[94b1f718]1365 os << endl << indent << "... expression: ";
[a16e246]1366 safe_print( assoc.expr );
1367 } else {
1368 os << "... default: ";
1369 safe_print( assoc.expr );
1370 }
[94b1f718]1371 os << endl;
[a16e246]1372 }
1373 --indent;
1374
[461046f]1375 return node;
1376 }
1377
[e67991f]1378 virtual const ast::Type * visit( const ast::VoidType * node ) override final {
[b0ec971]1379 preprint( node );
1380 os << "void";
[461046f]1381 return node;
1382 }
1383
[e67991f]1384 virtual const ast::Type * visit( const ast::BasicType * node ) override final {
[b0ec971]1385 preprint( node );
1386 os << ast::BasicType::typeNames[ node->kind ];
[461046f]1387 return node;
1388 }
1389
[e67991f]1390 virtual const ast::Type * visit( const ast::PointerType * node ) override final {
[b0ec971]1391 preprint( node );
1392 if ( ! node->isArray() ) {
1393 os << "pointer to ";
1394 } else {
1395 os << "decayed ";
1396 if ( node->isStatic ) {
1397 os << "static ";
1398 }
1399
1400 if ( node->isVarLen ) {
1401 os << "variable length array of ";
1402 } else if ( node->dimension ) {
1403 os << "array of ";
1404 node->dimension->accept( *this );
1405 os << " ";
1406 }
1407 }
[20a5977]1408 safe_print( node->base );
[b0ec971]1409
[461046f]1410 return node;
1411 }
1412
[e67991f]1413 virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
[b0ec971]1414 preprint( node );
1415 if ( node->isStatic ) {
1416 os << "static ";
1417 }
1418
1419 if ( node->isVarLen ) {
1420 os << "variable length array of ";
1421 } else if ( node->dimension ) {
1422 os << "array of ";
1423 } else {
1424 os << "open array of ";
1425 }
1426
[20a5977]1427 safe_print( node->base );
[b0ec971]1428
1429 if ( node->dimension ) {
1430 os << " with dimension of ";
1431 node->dimension->accept( *this );
1432 }
1433
[461046f]1434 return node;
1435 }
1436
[e67991f]1437 virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
[b0ec971]1438 preprint( node );
1439 os << "reference to ";
[20a5977]1440 safe_print( node->base );
[b0ec971]1441
[461046f]1442 return node;
1443 }
1444
[e67991f]1445 virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
[b0ec971]1446 preprint( node );
1447 ++indent;
[94b1f718]1448 os << "Qualified Type:" << endl << indent;
[20a5977]1449 safe_print( node->parent );
[94b1f718]1450 os << endl << indent;
[20a5977]1451 safe_print( node->child );
[94b1f718]1452 os << endl;
[b0ec971]1453 --indent;
1454
[461046f]1455 return node;
1456 }
1457
[e67991f]1458 virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
[b0ec971]1459 preprint( node );
[d908563]1460
[94b1f718]1461 os << "function" << endl;
[b0ec971]1462 if ( ! node->params.empty() ) {
[94b1f718]1463 os << indent << "... with parameters" << endl;
[b0ec971]1464 ++indent;
1465 printAll( node->params );
1466 if ( node->isVarArgs ) {
[94b1f718]1467 os << indent << "and a variable number of other arguments" << endl;
[b0ec971]1468 }
1469 --indent;
1470 } else if ( node->isVarArgs ) {
[94b1f718]1471 os << indent+1 << "accepting unspecified arguments" << endl;
[b0ec971]1472 }
1473
1474 os << indent << "... returning";
1475 if ( node->returns.empty() ) {
[94b1f718]1476 os << " nothing" << endl;
[b0ec971]1477 } else {
[94b1f718]1478 os << endl;
[b0ec971]1479 ++indent;
1480 printAll( node->returns );
1481 --indent;
1482 }
1483
[461046f]1484 return node;
1485 }
1486
[e67991f]1487 virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
[b0ec971]1488 preprint( node );
1489 os << "instance of struct " << node->name;
1490 if ( node->base ) {
1491 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1492 }
1493 print( node->params );
1494
[461046f]1495 return node;
1496 }
1497
[e67991f]1498 virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
[b0ec971]1499 preprint( node );
1500 os << "instance of union " << node->name;
1501 if ( node->base ) {
1502 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1503 }
1504 print( node->params );
1505
[461046f]1506 return node;
1507 }
1508
[e67991f]1509 virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
[b0ec971]1510 preprint( node );
1511 os << "instance of enum " << node->name;
1512 if ( node->base ) {
1513 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1514 }
1515 print( node->params );
1516
[461046f]1517 return node;
1518 }
1519
[e67991f]1520 virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
[b0ec971]1521 preprint( node );
1522 os << "instance of trait " << node->name;
1523 print( node->params );
1524
[461046f]1525 return node;
1526 }
1527
[e67991f]1528 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
[b0ec971]1529 preprint( node );
[3e5dd913]1530 const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->typeString();
[cd6a6ff]1531 os << "instance of type " << _name
[07de76b]1532 << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)";
[b0ec971]1533 print( node->params );
1534
[461046f]1535 return node;
1536 }
1537
[e67991f]1538 virtual const ast::Type * visit( const ast::TupleType * node ) override final {
[b0ec971]1539 preprint( node );
[94b1f718]1540 os << "tuple of types" << endl;
[b0ec971]1541 ++indent;
1542 printAll( node->types );
1543 --indent;
1544
[461046f]1545 return node;
1546 }
1547
[e67991f]1548 virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
[b0ec971]1549 preprint( node );
1550 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
1551 os << "type-of expression ";
[20a5977]1552 safe_print( node->expr );
[b0ec971]1553
[461046f]1554 return node;
1555 }
1556
[3945abe]1557 virtual const ast::Type * visit( const ast::VTableType * node ) override final {
1558 preprint( node );
1559 os << "vtable for ";
1560 safe_print( node->base );
1561
1562 return node;
1563 }
1564
[e67991f]1565 virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
[b0ec971]1566 preprint( node );
1567 os << "builtin var args pack";
[461046f]1568 return node;
1569 }
1570
[e67991f]1571 virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
[b0ec971]1572 preprint( node );
1573 os << "zero_t";
[461046f]1574 return node;
1575 }
1576
[e67991f]1577 virtual const ast::Type * visit( const ast::OneType * node ) override final {
[b0ec971]1578 preprint( node );
1579 os << "one_t";
[461046f]1580 return node;
1581 }
1582
[e67991f]1583 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
[b0ec971]1584 preprint( node );
1585 os << "Global Scope Type";
[461046f]1586 return node;
1587 }
1588
[e67991f]1589 virtual const ast::Designation * visit( const ast::Designation * node ) override final {
[c957e7f]1590 if ( node->designators.empty() ) return node;
[94b1f718]1591 os << "... designated by: " << endl;
[c957e7f]1592 ++indent;
1593 for ( const ast::Expr * d : node->designators ) {
1594 os << indent;
1595 d->accept( *this );
[94b1f718]1596 os << endl;
[c957e7f]1597 }
1598 --indent;
[461046f]1599 return node;
1600 }
1601
[e67991f]1602 virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
[c957e7f]1603 os << "Simple Initializer: ";
[20a5977]1604 safe_print( node->value );
[461046f]1605 return node;
1606 }
1607
[e67991f]1608 virtual const ast::Init * visit( const ast::ListInit * node ) override final {
[94b1f718]1609 os << "Compound initializer: " << endl;
[c957e7f]1610 ++indent;
1611 for ( auto p : group_iterate( node->designations, node->initializers ) ) {
1612 const ast::Designation * d = std::get<0>(p);
1613 const ast::Init * init = std::get<1>(p);
1614 os << indent;
1615 init->accept( *this );
[94b1f718]1616 os << endl;
[c957e7f]1617 if ( ! d->designators.empty() ) {
1618 os << indent;
1619 d->accept( *this );
1620 }
1621 }
1622 --indent;
[461046f]1623 return node;
1624 }
1625
[e67991f]1626 virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
[94b1f718]1627 os << "Constructor initializer: " << endl;
[c957e7f]1628 if ( node->ctor ) {
1629 os << indent << "... initially constructed with ";
1630 ++indent;
1631 node->ctor->accept( *this );
1632 --indent;
1633 }
1634
1635 if ( node->dtor ) {
1636 os << indent << "... destructed with ";
1637 ++indent;
1638 node->dtor->accept( *this );
1639 --indent;
1640 }
1641
1642 if ( node->init ) {
1643 os << indent << "... with fallback C-style initializer: ";
1644 ++indent;
1645 node->init->accept( *this );
1646 --indent;
1647 }
[461046f]1648 return node;
1649 }
1650
[e67991f]1651 virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
[489bacf]1652 if ( node->empty() ) return node;
1653 os << "Attribute with name: " << node->name;
1654 if ( node->params.empty() ) return node;
[94b1f718]1655 os << " with parameters: " << endl;
[489bacf]1656 ++indent;
1657 printAll( node->params );
1658 --indent;
[461046f]1659 return node;
1660 }
1661
[e67991f]1662 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
[94b1f718]1663 os << indent << "Types:" << endl;
[76ed81f]1664 for ( const auto& i : *node ) {
[3e5dd913]1665 os << indent+1 << i.first.typeString() << " -> ";
[76ed81f]1666 indent += 2;
[20a5977]1667 safe_print( i.second );
[76ed81f]1668 indent -= 2;
[94b1f718]1669 os << endl;
[76ed81f]1670 }
[461046f]1671 return node;
1672 }
1673
1674};
1675
[257a8f5]1676} // namespace
1677
[5902625]1678void print( ostream & os, const ast::Node * node, Indenter indent ) {
1679 Printer printer { os, indent, false };
1680 node->accept(printer);
1681}
1682
[6f4b7f2]1683void printShort( ostream & os, const ast::Decl * node, Indenter indent ) {
[5902625]1684 Printer printer { os, indent, true };
[461046f]1685 node->accept(printer);
1686}
1687
[257a8f5]1688void print( ostream & os, Function::Specs specs ) {
1689 print( os, specs, Names::FuncSpecifiers );
1690}
1691
1692void print( ostream & os, Storage::Classes storage ) {
1693 print( os, storage, Names::StorageClasses );
[461046f]1694}
[257a8f5]1695
1696void print( ostream & os, CV::Qualifiers qualifiers ) {
1697 print( os, qualifiers, Names::Qualifiers );
1698}
1699
1700} // namespace ast
Note: See TracBrowser for help on using the repository browser.