source: src/AST/Print.cpp @ 08e0d65

Last change on this file since 08e0d65 was b6f2e7ab, checked in by Andrew Beach <ajbeach@…>, 2 months ago

Removed SizeofExpr::expr and AlignofExpr::expr, expressions that would be stored there are wrapped in TypeofType? and stored in the type field. Some special cases to hide the typeof in code generation were added. In addition, initializer length is calculated in more cases so that the full type of more arrays is known sooner. Other than that, most of the code changes were just stripping out the conditional code and checks no longer needed. Some tests had to be updated, because the typeof is not hidden in dumps and the resolver replaces known typeof expressions with the type. The extension case caused some concern but it appears that just hides warnings in the expression which no longer exists.

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