source: src/AST/Print.cpp @ f23de79

arm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since f23de79 was f23de79, checked in by Thierry Delisle <tdelisle@…>, 4 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.