source: src/AST/Print.cpp@ f23de79d

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since f23de79d was f23de79d, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 15.6 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 --
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
24using namespace std;
25
26namespace ast {
27
28template <typename C, typename... T>
29constexpr auto make_array(T&&... values) ->
30 array<C,sizeof...(T)>
31{
32 return array<C,sizeof...(T)>{
33 forward<T>(values)...
34 };
35}
36
37class Printer : public Visitor {
38public:
39 ostream & os;
40 Indenter indent;
41 bool short_mode;
42
43 Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
44
45private:
46 template< typename C >
47 void printAll( const C & c ) {
48 for ( const auto & i : c ) {
49 if ( i ) {
50 os << indent;
51 i->accept( *this );
52 // need an endl after each element because it's not
53 // easy to know when each individual item should end
54 os << endl;
55 } // if
56 } // for
57 }
58
59
60 static const char* Names[];
61
62 struct Names {
63 static constexpr auto FuncSpecifiers = make_array<const char*>(
64 "inline", "_Noreturn", "fortran"
65 );
66
67 static constexpr auto StorageClasses = make_array<const char*>(
68 "extern", "static", "auto", "register", "_Thread_local"
69 );
70
71 static constexpr auto Qualifiers = make_array<const char*>(
72 "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic"
73 );
74 };
75
76 template<typename storage_t, size_t N>
77 void print(const storage_t & storage, const array<const char *, N> & Names ) {
78 if ( storage.any() ) {
79 for ( size_t i = 0; i < Names.size(); i += 1 ) {
80 if ( storage[i] ) {
81 os << Names[i] << ' ';
82 }
83 }
84 }
85 }
86
87 void print( const ast::Function::Specs & specs ) {
88 print(specs, Names::FuncSpecifiers);
89 }
90
91 void print( const ast::Storage::Classes & storage ) {
92 print(storage, Names::StorageClasses);
93 }
94
95 void print( const ast::CV::Qualifiers & qualifiers ) {
96 print(qualifiers, Names::Qualifiers);
97 }
98
99 void print( const ast::AggregateDecl * node ) {
100 os << node->typeString() << " " << node->name << ":";
101 if ( node->linkage != Linkage::Cforall ) {
102 os << " " << Linkage::name( node->linkage );
103 } // if
104 os << " with body : " << (node->body ? "yes " : "no ");
105
106 if ( ! node->params.empty() ) {
107 os << endl << indent << "... with parameters" << endl;
108 ++indent;
109 printAll( node->params );
110 --indent;
111 } // if
112 if ( ! node->members.empty() ) {
113 os << endl << indent << "... with members" << endl;
114 ++indent;
115 printAll( node->members );
116 --indent;
117 } // if
118 if ( ! node->attributes.empty() ) {
119 os << endl << indent << "... with attributes" << endl;
120 ++indent;
121 printAll( node->attributes );
122 --indent;
123 } // if
124 os << endl;
125 }
126
127 void print( const ast::NamedTypeDecl * node ) {
128 if ( !node->name.empty() ) os << node->name << ": ";
129
130 if ( node->linkage != Linkage::Cforall ) {
131 os << Linkage::name( node->linkage ) << " ";
132 } // if
133 print( node->storage );
134 os << node->typeString();
135 if ( node->base ) {
136 os << " for ";
137 ++indent;
138 node->base->accept( *this );
139 --indent;
140 } // if
141 if ( ! node->params.empty() ) {
142 os << endl << indent << "... with parameters" << endl;
143 ++indent;
144 printAll( node->params );
145 --indent;
146 } // if
147 if ( ! node->assertions.empty() ) {
148 os << endl << indent << "... with assertions" << endl;
149 ++indent;
150 printAll( node->assertions );
151 --indent;
152 } // if
153 }
154
155public:
156 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
157 if ( !node->name.empty() ) os << node->name << ": ";
158
159 if ( node->linkage != Linkage::Cforall ) {
160 os << Linkage::name( node->linkage ) << " ";
161 } // if
162
163 print( node->storage );
164
165 if ( node->type ) {
166 node->type->accept( *this );
167 } else {
168 os << " untyped entity ";
169 } // if
170
171 if ( node->init ) {
172 os << " with initializer (" << (
173 node->init->maybeConstructed
174 ? "maybe constructed"
175 : "not constructed"
176 ) << ")" << endl << indent+1;
177
178 ++indent;
179 node->init->accept( *this );
180 --indent;
181 os << endl;
182 } // if
183
184 if ( ! node->attributes.empty() ) {
185 os << endl << indent << "... with attributes:" << endl;
186 ++indent;
187 printAll( node->attributes );
188 --indent;
189 }
190
191 if ( node->bitfieldWidth ) {
192 os << indent << " with bitfield width ";
193 node->bitfieldWidth->accept( *this );
194 } // if
195 return node;
196 }
197
198 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
199 if ( !node->name.empty() ) {
200 os << node->name << ": ";
201 } // if
202 if ( node->linkage != Linkage::Cforall ) {
203 os << Linkage::name( node->linkage ) << " ";
204 } // if
205
206 printAll( node->attributes );
207
208 print( node->storage );
209 print( node->funcSpec );
210
211 if ( node->type ) {
212 node->type->accept( *this );
213 } else {
214 os << "untyped entity ";
215 } // if
216
217 if ( node->stmts ) {
218 os << indent << "... with body" << endl << indent+1;
219 ++indent;
220 node->stmts->accept( *this );
221 --indent;
222 } // if
223 return node;
224 }
225
226 virtual const ast::Decl * visit( const ast::StructDecl * node ) {
227 print(node);
228 return node;
229 }
230
231 virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
232 print(node);
233 return node;
234 }
235
236 virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
237 print(node);
238 return node;
239 }
240
241 virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
242 print(node);
243 return node;
244 }
245
246 virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
247 print( node );
248 if ( node->init ) {
249 os << endl << indent << "with type initializer: ";
250 ++indent;
251 node->init->accept( *this );
252 --indent;
253 }
254 return node;
255 }
256
257 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
258 print( node );
259 return node;
260 }
261
262 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
263 node->stmt->accept( *this );
264 return node;
265 }
266
267 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
268 os << "Static Assert with condition: ";
269 ++indent;
270 node->cond->accept( *this );
271 --indent;
272 os << endl << indent << "and message: ";
273 ++indent;
274 node->msg->accept( *this );
275 --indent;
276 os << endl;
277 return node;
278 }
279
280 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
281 os << "CompoundStmt" << endl;
282 ++indent;
283 printAll( node->kids );
284 --indent;
285 return node;
286 }
287
288 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
289 ++indent;
290 os << "Expression Statement:" << endl << indent;
291 node->expr->accept( *this );
292 --indent;
293 return node;
294 }
295
296 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
297 os << "Assembler Statement:" << endl;
298 ++indent;
299 os << indent << "instruction: " << endl << indent;
300 node->instruction->accept( *this );
301 if ( ! node->output.empty() ) {
302 os << endl << indent+1 << "output: " << endl;
303 printAll( node->output );
304 } // if
305 if ( ! node->input.empty() ) {
306 os << indent+1 << "input: " << endl;
307 printAll( node->input );
308 } // if
309 if ( ! node->clobber.empty() ) {
310 os << indent+1 << "clobber: " << endl;
311 printAll( node->clobber );
312 } // if
313 --indent;
314 return node;
315 }
316
317 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
318 os << "GCC Directive:" << node->directive << endl;
319 return node;
320 }
321
322 virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
323 os << "If on condition: " << endl;
324 os << indent+1;
325 ++indent;
326 node->cond->accept( *this );
327 --indent;
328
329 if ( !node->inits.empty() ) {
330 os << indent << "... with initialization: \n";
331 ++indent;
332 for ( const Stmt * stmt : node->inits ) {
333 os << indent;
334 stmt->accept( *this );
335 }
336 --indent;
337 os << endl;
338 }
339
340 os << indent << "... then: " << endl;
341
342 ++indent;
343 os << indent;
344 node->thenPart->accept( *this );
345 --indent;
346
347 if ( node->elsePart != 0 ) {
348 os << indent << "... else: " << endl;
349 ++indent;
350 os << indent;
351 node->elsePart->accept( *this );
352 --indent;
353 } // if
354 return node;
355 }
356
357 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
358 return node;
359 }
360
361 virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
362 return node;
363 }
364
365 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
366 return node;
367 }
368
369 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
370 return node;
371 }
372
373 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
374 return node;
375 }
376
377 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
378 return node;
379 }
380
381 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
382 return node;
383 }
384
385 virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
386 return node;
387 }
388
389 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
390 return node;
391 }
392
393 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
394 return node;
395 }
396
397 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
398 return node;
399 }
400
401 virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
402 return node;
403 }
404
405 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
406 return node;
407 }
408
409 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
410 return node;
411 }
412
413 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
414 return node;
415 }
416
417 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
418 return node;
419 }
420
421 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
422 return node;
423 }
424
425 virtual const ast::Expr * visit( const ast::NameExpr * node ) {
426 return node;
427 }
428
429 virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
430 return node;
431 }
432
433 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
434 return node;
435 }
436
437 virtual const ast::Expr * visit( const ast::CastExpr * node ) {
438 return node;
439 }
440
441 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
442 return node;
443 }
444
445 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
446 return node;
447 }
448
449 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
450 return node;
451 }
452
453 virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
454 return node;
455 }
456
457 virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
458 return node;
459 }
460
461 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
462 return node;
463 }
464
465 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
466 return node;
467 }
468
469 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
470 return node;
471 }
472
473 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
474 return node;
475 }
476
477 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
478 return node;
479 }
480
481 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
482 return node;
483 }
484
485 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
486 return node;
487 }
488
489 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
490 return node;
491 }
492
493 virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
494 return node;
495 }
496
497 virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
498 return node;
499 }
500
501 virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
502 return node;
503 }
504
505 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
506 return node;
507 }
508
509 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
510 return node;
511 }
512
513 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
514 return node;
515 }
516
517 virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
518 return node;
519 }
520
521 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
522 return node;
523 }
524
525 virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
526 return node;
527 }
528
529 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
530 return node;
531 }
532
533 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
534 return node;
535 }
536
537 virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
538 return node;
539 }
540
541 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
542 return node;
543 }
544
545 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
546 return node;
547 }
548
549 virtual const ast::Expr * visit( const ast::InitExpr * node ) {
550 return node;
551 }
552
553 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
554 return node;
555 }
556
557 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
558 return node;
559 }
560
561 virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
562 return node;
563 }
564
565 virtual const ast::Type * visit( const ast::VoidType * node ) {
566 return node;
567 }
568
569 virtual const ast::Type * visit( const ast::BasicType * node ) {
570 return node;
571 }
572
573 virtual const ast::Type * visit( const ast::PointerType * node ) {
574 return node;
575 }
576
577 virtual const ast::Type * visit( const ast::ArrayType * node ) {
578 return node;
579 }
580
581 virtual const ast::Type * visit( const ast::ReferenceType * node ) {
582 return node;
583 }
584
585 virtual const ast::Type * visit( const ast::QualifiedType * node ) {
586 return node;
587 }
588
589 virtual const ast::Type * visit( const ast::FunctionType * node ) {
590 return node;
591 }
592
593 virtual const ast::Type * visit( const ast::StructInstType * node ) {
594 return node;
595 }
596
597 virtual const ast::Type * visit( const ast::UnionInstType * node ) {
598 return node;
599 }
600
601 virtual const ast::Type * visit( const ast::EnumInstType * node ) {
602 return node;
603 }
604
605 virtual const ast::Type * visit( const ast::TraitInstType * node ) {
606 return node;
607 }
608
609 virtual const ast::Type * visit( const ast::TypeInstType * node ) {
610 return node;
611 }
612
613 virtual const ast::Type * visit( const ast::TupleType * node ) {
614 return node;
615 }
616
617 virtual const ast::Type * visit( const ast::TypeofType * node ) {
618 return node;
619 }
620
621 virtual const ast::Type * visit( const ast::VarArgsType * node ) {
622 return node;
623 }
624
625 virtual const ast::Type * visit( const ast::ZeroType * node ) {
626 return node;
627 }
628
629 virtual const ast::Type * visit( const ast::OneType * node ) {
630 return node;
631 }
632
633 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
634 return node;
635 }
636
637 virtual const ast::Designation * visit( const ast::Designation * node ) {
638 return node;
639 }
640
641 virtual const ast::Init * visit( const ast::SingleInit * node ) {
642 return node;
643 }
644
645 virtual const ast::Init * visit( const ast::ListInit * node ) {
646 return node;
647 }
648
649 virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
650 return node;
651 }
652
653 virtual const ast::Attribute * visit( const ast::Attribute * node ) {
654 return node;
655 }
656
657 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
658 os << indent << "Types:" << std::endl;
659 for ( const auto& i : *node ) {
660 os << indent+1 << i.first << " -> ";
661 indent += 2;
662 i.second->accept( *this );
663 indent -= 2;
664 os << std::endl;
665 }
666 os << indent << "Non-types:" << std::endl;
667 for ( auto i = node->beginVar(); i != node->endVar(); ++i ) {
668 os << indent+1 << i->first << " -> ";
669 indent += 2;
670 i->second->accept( *this );
671 indent -= 2;
672 os << std::endl;
673 }
674 return node;
675 }
676
677};
678
679void print( ostream & os, const ast::Node * node, Indenter indent ) {
680 Printer printer { os, indent, false };
681 node->accept(printer);
682}
683
684void printShort( ostream & os, const ast::Node * node, Indenter indent ) {
685 Printer printer { os, indent, true };
686 node->accept(printer);
687}
688
689// Annoyingly these needed to be defined out of line to avoid undefined references.
690// The size here needs to be explicit but at least the compiler will produce an error
691// if the wrong size is specified
692constexpr array<const char*, 3> Printer::Names::FuncSpecifiers;
693constexpr array<const char*, 5> Printer::Names::StorageClasses;
694constexpr array<const char*, 6> Printer::Names::Qualifiers;
695}
Note: See TracBrowser for help on using the repository browser.