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
Line 
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//
7// Print.cpp -- Print an AST (or sub-tree) to a stream.
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"
23#include "CompilationState.h"
24
25#include "Common/utility.h" // for group_iterate
26
27using namespace std;
28
29namespace ast {
30
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 }
61}
62
63class Printer final : public Visitor {
64public:
65 ostream & os;
66 Indenter indent;
67 bool short_mode;
68
69 Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
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
80 os << endl;
81 } // if
82 } // for
83 }
84
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()
97 void short_print( const ast::Decl * n ) {
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
104 static const char* Names[];
105
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
117 void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) {
118 if (inferred.data.resnSlots && !inferred.data.resnSlots->empty()) {
119 os << indent << "with " << inferred.data.resnSlots->size()
120 << " pending inference slots" << endl;
121 }
122 if (inferred.data.inferParams && !inferred.data.inferParams->empty()) {
123 os << indent << "with inferred parameters " << level << ":" << endl;
124 ++indent;
125 for ( const auto & i : *inferred.data.inferParams ) {
126 os << indent;
127 short_print( i.second.declptr );
128 os << endl;
129 print( i.second.expr->inferred, level+1 );
130 }
131 --indent;
132 }
133 }
134
135 void print( const ast::FunctionType::ForallList & forall ) {
136 if ( forall.empty() ) return;
137 os << "forall" << endl;
138 ++indent;
139 printAll( forall );
140 os << indent;
141 --indent;
142 }
143
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
153 void print( const std::vector<ptr<Attribute>> & attrs ) {
154 if ( attrs.empty() ) return;
155 os << "with attributes" << endl;
156 ++indent;
157 printAll( attrs );
158 --indent;
159 }
160
161 void print( const std::vector<ptr<Expr>> & params ) {
162 if ( params.empty() ) return;
163 os << endl << indent << "... with parameters" << endl;
164 ++indent;
165 printAll( params );
166 --indent;
167 }
168
169 void print( const ast::AggregateDecl * node ) {
170 os << node->typeString() << " " << node->name;
171
172 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
173 os << " " << Linkage::name( node->linkage );
174 }
175
176 os << " " << (node->body ? "with" : "without") << " body";
177
178 if ( ! node->params.empty() ) {
179 os << endl << indent << "... with parameters" << endl;
180 ++indent;
181 printAll( node->params );
182 --indent;
183 }
184
185 if ( ! short_mode && ! node->members.empty() ) {
186 os << endl << indent << "... with members" << endl;
187 ++indent;
188 printAll( node->members );
189 --indent;
190 }
191
192 if ( ! short_mode && ! node->attributes.empty() ) {
193 os << endl << indent << "... with attributes" << endl;
194 ++indent;
195 printAll( node->attributes );
196 --indent;
197 }
198
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 );
204 --indent;
205 }
206
207 os << endl;
208 }
209
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
237 void preprint( const ast::NamedTypeDecl * node ) {
238 if ( ! node->name.empty() ) {
239 os << node->name << ": ";
240 }
241
242 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
243 os << Linkage::name( node->linkage ) << " ";
244 }
245
246 ast::print( os, node->storage );
247 os << node->typeString();
248
249 if ( node->base ) {
250 os << " for ";
251 ++indent;
252 node->base->accept( *this );
253 --indent;
254 }
255
256 if ( ! node->assertions.empty() ) {
257 os << endl << indent << "... with assertions" << endl;
258 ++indent;
259 printAll( node->assertions );
260 --indent;
261 }
262 }
263
264 void postprint( const ast::Expr * node ) {
265 print( node->inferred );
266
267 if ( node->result ) {
268 os << endl << indent << "... with resolved type:" << endl;
269 ++indent;
270 os << indent;
271 node->result->accept( *this );
272 --indent;
273 }
274
275 if ( node->env ) {
276 os << endl << indent << "... with environment:" << endl;
277 ++indent;
278 node->env->accept( *this );
279 --indent;
280 }
281
282 if ( node->extension ) {
283 os << endl << indent << "... with extension";
284 }
285 }
286
287 void preprint( const ast::Type * node ) {
288 ast::print( os, node->qualifiers );
289 }
290
291 void preprint( const ast::FunctionType * node ) {
292 print( node->forall );
293 print( node->assertions );
294 ast::print( os, node->qualifiers );
295 }
296
297 void preprint( const ast::BaseInstType * node ) {
298 print( node->attributes );
299 ast::print( os, node->qualifiers );
300 }
301
302public:
303 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
304 if ( ! node->name.empty() ) os << node->name << ": ";
305
306 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
307 os << Linkage::name( node->linkage ) << " ";
308 }
309
310 ast::print( os, node->storage );
311
312 if ( node->type ) {
313 node->type->accept( *this );
314 } else {
315 os << "untyped entity";
316 }
317
318 if ( ! short_mode && node->init ) {
319 ++indent;
320 os << " with initializer (" << (
321 node->init->maybeConstructed
322 ? "maybe constructed"
323 : "not constructed"
324 ) << ")" << endl << indent;
325 node->init->accept( *this );
326 --indent;
327 os << endl;
328 }
329
330 if ( ! short_mode && ! node->attributes.empty() ) {
331 os << endl << indent << "... with attributes:" << endl;
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 );
340 }
341
342 return node;
343 }
344
345 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
346 if ( !node->name.empty() ) os << node->name << ": ";
347
348 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
349 os << Linkage::name( node->linkage ) << " ";
350 }
351
352 if ( ! short_mode ) printAll( node->attributes );
353
354 ast::print( os, node->storage );
355 ast::print( os, node->funcSpec );
356
357 if ( node->type && node->isTypeFixed ) {
358 node->type->accept( *this );
359 } else {
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 }
398 }
399
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
408 if ( ! short_mode && node->stmts ) {
409 ++indent;
410 os << " with body" << endl << indent;
411 node->stmts->accept( *this );
412 --indent;
413 }
414
415 return node;
416 }
417
418 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
419 print(node);
420 return node;
421 }
422
423 virtual const ast::DeclWithType * visit( const ast::InlineMemberDecl * node ) override final {
424 os << "inline ";
425 if ( ! node->name.empty() ) os << node->name;
426
427 return node;
428 }
429
430 virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
431 print(node);
432 return node;
433 }
434
435 virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
436 print(node);
437 return node;
438 }
439
440 virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
441 print(node);
442 return node;
443 }
444
445 virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
446 preprint( node );
447 if ( ! short_mode && node->init ) {
448 os << endl << indent << "with type initializer: ";
449 ++indent;
450 node->init->accept( *this );
451 --indent;
452 }
453
454 return node;
455 }
456
457 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
458 preprint( node );
459 return node;
460 }
461
462 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
463 safe_print( node->stmt );
464 return node;
465 }
466
467 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final {
468 safe_print( node->stmt );
469 return node;
470 }
471
472 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
473 os << "Static Assert with condition: ";
474 ++indent;
475 safe_print( node->cond );
476 os << endl << indent-1 << "and message: ";
477 safe_print( node->msg );
478 --indent;
479 os << endl;
480
481 return node;
482 }
483
484 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
485 os << "Compound Statement:" << endl;
486 ++indent;
487 printAll( node->kids );
488 --indent;
489 return node;
490 }
491
492 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
493 ++indent;
494 os << "Expression Statement:" << endl << indent;
495 safe_print( node->expr );
496 --indent;
497 return node;
498 }
499
500 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
501 os << "Assembler Statement:" << endl;
502 ++indent;
503 os << indent-1 << "instruction:" << endl << indent;
504 safe_print( node->instruction );
505 if ( ! node->output.empty() ) {
506 os << endl << indent << "output:" << endl;
507 printAll( node->output );
508 } // if
509 if ( ! node->input.empty() ) {
510 os << indent << "input:" << endl;
511 printAll( node->input );
512 } // if
513 if ( ! node->clobber.empty() ) {
514 os << indent << "clobber:" << endl;
515 printAll( node->clobber );
516 } // if
517 --indent;
518 return node;
519 }
520
521 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
522 os << "GCC Directive: " << node->directive << endl;
523 return node;
524 }
525
526 virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
527 os << "If on condition:" << endl;
528 ++indent;
529 os << indent;
530 safe_print( node->cond );
531 --indent;
532
533 if ( ! node->inits.empty() ) {
534 os << indent << "... with initialization:" << endl;
535 ++indent;
536 for ( const ast::Stmt * stmt : node->inits ) {
537 os << indent;
538 safe_print( stmt );
539 }
540 --indent;
541 os << endl;
542 }
543
544 os << indent << "... then:" << endl;
545
546 ++indent;
547 os << indent;
548 safe_print( node->then );
549 --indent;
550
551 if ( node->else_ != 0 ) {
552 os << indent << "... else:" << endl;
553 ++indent;
554 os << indent;
555 node->else_->accept( *this );
556 --indent;
557 } // if
558 return node;
559 }
560
561 virtual const ast::Stmt * visit( const ast::WhileDoStmt * node ) override final {
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
575 return node;
576 }
577
578 virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
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
617 return node;
618 }
619
620 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
621 os << "Switch on condition: ";
622 safe_print( node->cond );
623 os << endl;
624
625 ++indent;
626 for ( const ast::CaseClause * stmt : node->cases ) {
627 stmt->accept( *this );
628 }
629 --indent;
630
631 return node;
632 }
633
634 virtual const ast::CaseClause * visit( const ast::CaseClause * node ) override final {
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
650 return node;
651 }
652
653 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
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
671 return node;
672 }
673
674 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
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
686 return node;
687 }
688
689 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
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
706 return node;
707 }
708
709 virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
710 ++indent;
711 os << "Try Statement" << endl << indent-1
712 << "... with block:" << endl << indent;
713 safe_print( node->body );
714
715 os << indent-1 << "... and handlers:" << endl;
716 for ( const ast::CatchClause * stmt : node->handlers ) {
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
727 return node;
728 }
729
730 virtual const ast::CatchClause * visit( const ast::CatchClause * node ) override final {
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;
751
752 return node;
753 }
754
755 virtual const ast::FinallyClause * visit( const ast::FinallyClause * node ) override final {
756 os << "Finally Statement" << endl;
757 os << indent << "... with block:" << endl;
758 ++indent;
759 os << indent;
760 safe_print( node->body );
761 --indent;
762
763 return node;
764 }
765
766 virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
767 os << "Suspend Statement";
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;
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
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
802 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
803 os << "Waitfor Statement" << endl;
804 indent += 2;
805 for( const auto & clause : node->clauses ) {
806 clause->accept( *this );
807 }
808
809 if ( node->timeout_time ) {
810 os << indent-1 << "timeout of:" << endl;
811 node->timeout_time->accept( *this );
812
813 if ( node->timeout_stmt ) {
814 os << indent-1 << "... with statment:" << endl;
815 node->timeout_stmt->accept( *this );
816 }
817
818 if ( node->timeout_cond ) {
819 os << indent-1 << "... with condition:" << endl;
820 node->timeout_cond->accept( *this );
821 }
822 }
823
824 if ( node->else_stmt ) {
825 os << indent-1 << "else:" << endl;
826 node->else_stmt->accept( *this );
827
828 if ( node->else_cond ) {
829 os << indent-1 << "... with condition:" << endl;
830 node->else_cond->accept( *this );
831 }
832 }
833
834 return node;
835 }
836
837 virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
838 os << indent-1 << "target function: ";
839 safe_print( node->target );
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 );
845 }
846 }
847
848 if ( node->stmt ) {
849 os << indent-1 << "... with statment:" << endl;
850 node->stmt->accept( *this );
851 }
852
853 if ( node->when_cond ) {
854 os << indent-1 << "... with condition:" << endl;
855 node->when_cond->accept( *this );
856 }
857
858 return node;
859 }
860
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
871 virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
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
880 return node;
881 }
882
883 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
884 os << "Null Statement" << endl;
885 print( node->labels );
886
887 return node;
888 }
889
890 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
891 os << "Declaration of ";
892 safe_print( node->decl );
893
894 return node;
895 }
896
897 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
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
905 return node;
906 }
907
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
923 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
924 ++indent;
925 os << "Application of" << endl << indent;
926 safe_print( node->func );
927 os << endl;
928 if ( ! node->args.empty() ) {
929 os << indent << "... to arguments" << endl;
930 printAll( node->args );
931 }
932 --indent;
933 postprint( node );
934
935 return node;
936 }
937
938 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
939 ++indent;
940 os << "Applying untyped:" << endl;
941 os << indent;
942 safe_print( node->func );
943 os << endl << indent-1 << "...to:" << endl;
944 printAll( node->args );
945 --indent;
946 postprint( node );
947
948 return node;
949 }
950
951 virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
952 os << "Name: " << node->name;
953 postprint( node );
954
955 return node;
956 }
957
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
969 virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
970 os << "Address of:" << endl;
971 ++indent;
972 os << indent;
973 safe_print( node->arg );
974
975 --indent;
976
977 return node;
978 }
979
980 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
981 os << "Address of label:" << node->arg;
982
983 return node;
984 }
985
986 virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
987 ++indent;
988 os << (node->isGenerated ? "Generated" : "Explicit") << " Cast of:" << endl << indent;
989 safe_print( node->arg );
990 os << endl << indent-1 << "... to:";
991 if ( ! node->result ) {
992 os << " ";
993 undefined();
994 } else if ( node->result->isVoid() ) {
995 os << " nothing";
996 } else {
997 os << endl << indent;
998 node->result->accept( *this );
999 } // if
1000 --indent;
1001 postprint( node );
1002
1003 return node;
1004 }
1005
1006 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
1007 ++indent;
1008 os << "Keyword Cast of:" << endl << indent;
1009 safe_print( node->arg );
1010 --indent;
1011 os << endl << indent << "... to: " << node->targetString();
1012 postprint( node );
1013
1014 return node;
1015 }
1016
1017 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
1018 ++indent;
1019 os << "Virtual Cast of:" << endl << indent;
1020 safe_print( node->arg );
1021 os << endl << indent-1 << "... to:";
1022 if ( ! node->result ) {
1023 os << " unknown";
1024 } else {
1025 os << endl << indent;
1026 node->result->accept( *this );
1027 }
1028 --indent;
1029 postprint( node );
1030
1031 return node;
1032 }
1033
1034 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
1035 ++indent;
1036 os << "Untyped Member Expression, with field: " << endl << indent;
1037 safe_print( node->member );
1038 os << indent-1 << "... from aggregate:" << endl << indent;
1039 safe_print( node->aggregate );
1040 --indent;
1041 postprint( node );
1042
1043 return node;
1044 }
1045
1046 virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
1047 ++indent;
1048 os << "Member Expression, with field:" << endl << indent;
1049 safe_print( node->member );
1050 os << endl << indent-1 << "... from aggregate:" << endl << indent;
1051 safe_print( node->aggregate );
1052 --indent;
1053 postprint( node );
1054
1055 return node;
1056 }
1057
1058 virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
1059 os << "Variable Expression: ";
1060 short_print( node->var );
1061 postprint( node );
1062
1063 return node;
1064 }
1065
1066 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
1067 os << "Constant Expression (" << node->rep;
1068 if ( node->result ) {
1069 os << ": ";
1070 node->result->accept( *this );
1071 }
1072 os << ")";
1073 postprint( node );
1074
1075 return node;
1076 }
1077
1078 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
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
1086 return node;
1087 }
1088
1089 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
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 );
1096
1097 return node;
1098 }
1099
1100 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
1101 os << "Untyped Offsetof Expression on member " << node->member << " of ";
1102 ++indent;
1103 safe_print( node->type );
1104 --indent;
1105 postprint( node );
1106
1107 return node;
1108 }
1109
1110 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
1111 os << "Offsetof Expression on member " << node->member->name << " of ";
1112 ++indent;
1113 safe_print( node->type );
1114 --indent;
1115 postprint( node );
1116
1117 return node;
1118 }
1119
1120 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
1121 os << "Offset Pack Expression on: ";
1122 ++indent;
1123 safe_print( node->type );
1124 --indent;
1125 postprint( node );
1126
1127 return node;
1128 }
1129
1130 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
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
1137 return node;
1138 }
1139
1140 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
1141 ++indent;
1142 os << "Conditional expression on:" << endl << indent;
1143 safe_print( node->arg1 );
1144 os << indent-1 << "First alternative:" << endl << indent;
1145 safe_print( node->arg2 );
1146 os << indent-1 << "Second alternative:" << endl << indent;
1147 safe_print( node->arg3 );
1148 --indent;
1149 postprint( node );
1150
1151 return node;
1152 }
1153
1154 virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
1155 ++indent;
1156 os << "Comma Expression:" << endl << indent;
1157 safe_print( node->arg1 );
1158 os << endl << indent;
1159 safe_print( node->arg2 );
1160 --indent;
1161 postprint( node );
1162
1163 return node;
1164 }
1165
1166 virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
1167 safe_print( node->type );
1168 postprint( node );
1169
1170 return node;
1171 }
1172
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
1180 virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
1181 os << "Asm Expression:" << endl;
1182 ++indent;
1183 if ( !node->inout.empty() ) os << "[" << node->inout << "] ";
1184 if ( node->constraint ) node->constraint->accept( *this );
1185 if ( node->operand ) node->operand->accept( *this );
1186 --indent;
1187
1188 return node;
1189 }
1190
1191 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
1192 ++indent;
1193 os << "Implicit Copy Constructor Expression:" << endl << indent;
1194 safe_print( node->callExpr );
1195 --indent;
1196 postprint( node );
1197
1198 return node;
1199 }
1200
1201 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
1202 os << "Constructor Expression:" << endl << indent+1;
1203 indent += 2;
1204 safe_print( node->callExpr );
1205 indent -= 2;
1206 postprint( node );
1207
1208 return node;
1209 }
1210
1211 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
1212 ++indent;
1213 os << "Compound Literal Expression: " << endl << indent;
1214 safe_print( node->result );
1215 os << indent;
1216 safe_print( node->init );
1217 --indent;
1218 postprint( node );
1219
1220 return node;
1221 }
1222
1223 virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
1224 os << "Range Expression: ";
1225 safe_print( node->low );
1226 os << " ... ";
1227 safe_print( node->high );
1228 postprint( node );
1229
1230 return node;
1231 }
1232
1233 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
1234 os << "Untyped Tuple:" << endl;
1235 ++indent;
1236 printAll( node->exprs );
1237 --indent;
1238 postprint( node );
1239
1240 return node;
1241 }
1242
1243 virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
1244 os << "Tuple:" << endl;
1245 ++indent;
1246 printAll( node->exprs );
1247 --indent;
1248 postprint( node );
1249
1250 return node;
1251 }
1252
1253 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
1254 os << "Tuple Index Expression, with tuple:" << endl;
1255 ++indent;
1256 os << indent;
1257 safe_print( node->tuple );
1258 os << indent << "with index: " << node->index << endl;
1259 --indent;
1260 postprint( node );
1261
1262 return node;
1263 }
1264
1265 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
1266 os << "Tuple Assignment Expression, with stmt expr:" << endl;
1267 ++indent;
1268 os << indent;
1269 safe_print( node->stmtExpr );
1270 --indent;
1271 postprint( node );
1272
1273 return node;
1274 }
1275
1276 virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
1277 ++indent;
1278 os << "Statement Expression:" << endl << indent;
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
1291 return node;
1292 }
1293
1294 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
1295 ++indent;
1296 os << "Unique Expression with id: " << node->id << endl << indent;
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
1305 return node;
1306 }
1307
1308 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
1309 ++indent;
1310 os << "Untyped Init Expression" << endl << indent;
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
1321 return node;
1322 }
1323
1324 virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
1325 ++indent;
1326 os << "Init Expression" << endl << indent;
1327 safe_print( node->expr );
1328 os << indent << "... with designation: ";
1329 safe_print( node->designation );
1330 --indent;
1331
1332 return node;
1333 }
1334
1335 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
1336 ++indent;
1337 os << "Deleted Expression" << endl << indent;
1338 safe_print( node->expr );
1339 os << endl << indent << "... deleted by: ";
1340 safe_print( node->deleteStmt );
1341 --indent;
1342
1343 return node;
1344 }
1345
1346 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
1347 ++indent;
1348 os << "Default Argument Expression" << endl << indent;
1349 safe_print( node->expr );
1350 --indent;
1351
1352 return node;
1353 }
1354
1355 virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
1356 ++indent;
1357 os << "C11 _Generic Expression" << endl << indent;
1358 safe_print( node->control );
1359 os << endl << indent << "... with associations:" << endl;
1360 for ( const auto & assoc : node->associations ) {
1361 os << indent;
1362 if ( assoc.type ) {
1363 os << "... type: ";
1364 assoc.type->accept( *this );
1365 os << endl << indent << "... expression: ";
1366 safe_print( assoc.expr );
1367 } else {
1368 os << "... default: ";
1369 safe_print( assoc.expr );
1370 }
1371 os << endl;
1372 }
1373 --indent;
1374
1375 return node;
1376 }
1377
1378 virtual const ast::Type * visit( const ast::VoidType * node ) override final {
1379 preprint( node );
1380 os << "void";
1381 return node;
1382 }
1383
1384 virtual const ast::Type * visit( const ast::BasicType * node ) override final {
1385 preprint( node );
1386 os << ast::BasicType::typeNames[ node->kind ];
1387 return node;
1388 }
1389
1390 virtual const ast::Type * visit( const ast::PointerType * node ) override final {
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 }
1408 safe_print( node->base );
1409
1410 return node;
1411 }
1412
1413 virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
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
1427 safe_print( node->base );
1428
1429 if ( node->dimension ) {
1430 os << " with dimension of ";
1431 node->dimension->accept( *this );
1432 }
1433
1434 return node;
1435 }
1436
1437 virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
1438 preprint( node );
1439 os << "reference to ";
1440 safe_print( node->base );
1441
1442 return node;
1443 }
1444
1445 virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
1446 preprint( node );
1447 ++indent;
1448 os << "Qualified Type:" << endl << indent;
1449 safe_print( node->parent );
1450 os << endl << indent;
1451 safe_print( node->child );
1452 os << endl;
1453 --indent;
1454
1455 return node;
1456 }
1457
1458 virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
1459 preprint( node );
1460
1461 os << "function" << endl;
1462 if ( ! node->params.empty() ) {
1463 os << indent << "... with parameters" << endl;
1464 ++indent;
1465 printAll( node->params );
1466 if ( node->isVarArgs ) {
1467 os << indent << "and a variable number of other arguments" << endl;
1468 }
1469 --indent;
1470 } else if ( node->isVarArgs ) {
1471 os << indent+1 << "accepting unspecified arguments" << endl;
1472 }
1473
1474 os << indent << "... returning";
1475 if ( node->returns.empty() ) {
1476 os << " nothing" << endl;
1477 } else {
1478 os << endl;
1479 ++indent;
1480 printAll( node->returns );
1481 --indent;
1482 }
1483
1484 return node;
1485 }
1486
1487 virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
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
1495 return node;
1496 }
1497
1498 virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
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
1506 return node;
1507 }
1508
1509 virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
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
1517 return node;
1518 }
1519
1520 virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
1521 preprint( node );
1522 os << "instance of trait " << node->name;
1523 print( node->params );
1524
1525 return node;
1526 }
1527
1528 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
1529 preprint( node );
1530 const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->typeString();
1531 os << "instance of type " << _name
1532 << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)";
1533 print( node->params );
1534
1535 return node;
1536 }
1537
1538 virtual const ast::Type * visit( const ast::TupleType * node ) override final {
1539 preprint( node );
1540 os << "tuple of types" << endl;
1541 ++indent;
1542 printAll( node->types );
1543 --indent;
1544
1545 return node;
1546 }
1547
1548 virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
1549 preprint( node );
1550 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
1551 os << "type-of expression ";
1552 safe_print( node->expr );
1553
1554 return node;
1555 }
1556
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
1565 virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
1566 preprint( node );
1567 os << "builtin var args pack";
1568 return node;
1569 }
1570
1571 virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
1572 preprint( node );
1573 os << "zero_t";
1574 return node;
1575 }
1576
1577 virtual const ast::Type * visit( const ast::OneType * node ) override final {
1578 preprint( node );
1579 os << "one_t";
1580 return node;
1581 }
1582
1583 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
1584 preprint( node );
1585 os << "Global Scope Type";
1586 return node;
1587 }
1588
1589 virtual const ast::Designation * visit( const ast::Designation * node ) override final {
1590 if ( node->designators.empty() ) return node;
1591 os << "... designated by: " << endl;
1592 ++indent;
1593 for ( const ast::Expr * d : node->designators ) {
1594 os << indent;
1595 d->accept( *this );
1596 os << endl;
1597 }
1598 --indent;
1599 return node;
1600 }
1601
1602 virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
1603 os << "Simple Initializer: ";
1604 safe_print( node->value );
1605 return node;
1606 }
1607
1608 virtual const ast::Init * visit( const ast::ListInit * node ) override final {
1609 os << "Compound initializer: " << endl;
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 );
1616 os << endl;
1617 if ( ! d->designators.empty() ) {
1618 os << indent;
1619 d->accept( *this );
1620 }
1621 }
1622 --indent;
1623 return node;
1624 }
1625
1626 virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
1627 os << "Constructor initializer: " << endl;
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 }
1648 return node;
1649 }
1650
1651 virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
1652 if ( node->empty() ) return node;
1653 os << "Attribute with name: " << node->name;
1654 if ( node->params.empty() ) return node;
1655 os << " with parameters: " << endl;
1656 ++indent;
1657 printAll( node->params );
1658 --indent;
1659 return node;
1660 }
1661
1662 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
1663 os << indent << "Types:" << endl;
1664 for ( const auto& i : *node ) {
1665 os << indent+1 << i.first.typeString() << " -> ";
1666 indent += 2;
1667 safe_print( i.second );
1668 indent -= 2;
1669 os << endl;
1670 }
1671 return node;
1672 }
1673
1674};
1675
1676} // namespace
1677
1678void print( ostream & os, const ast::Node * node, Indenter indent ) {
1679 Printer printer { os, indent, false };
1680 node->accept(printer);
1681}
1682
1683void printShort( ostream & os, const ast::Decl * node, Indenter indent ) {
1684 Printer printer { os, indent, true };
1685 node->accept(printer);
1686}
1687
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 );
1694}
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.