Ignore:
Timestamp:
Dec 5, 2017, 2:35:03 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
f9feab8
Parents:
9c35431 (diff), 65197c2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/InitTweak.cc

    r9c35431 rc13e8dc8  
    55#include <memory>                  // for __shared_ptr
    66
     7#include "Common/PassVisitor.h"
    78#include "Common/SemanticError.h"  // for SemanticError
    89#include "Common/UniqueName.h"     // for UniqueName
     
    1920#include "SynTree/Expression.h"    // for Expression, UntypedExpr, Applicati...
    2021#include "SynTree/Initializer.h"   // for Initializer, ListInit, Designation
    21 #include "SynTree/Label.h"         // for Label, noLabels
     22#include "SynTree/Label.h"         // for Label
    2223#include "SynTree/Statement.h"     // for CompoundStmt, ExprStmt, BranchStmt
    2324#include "SynTree/Type.h"          // for FunctionType, ArrayType, PointerType
     
    2930namespace InitTweak {
    3031        namespace {
    31                 class HasDesignations : public Visitor {
    32                 public:
     32                struct HasDesignations : public WithShortCircuiting {
    3333                        bool hasDesignations = false;
    34                         virtual void visit( Designation * des ) {
    35                                 if ( ! des->get_designators().empty() ) hasDesignations = true;
    36                                 else Visitor::visit( des );
     34
     35                        void previsit( BaseSyntaxNode * ) {
     36                                // short circuit if we already know there are designations
     37                                if ( hasDesignations ) visit_children = false;
     38                        }
     39
     40                        void previsit( Designation * des ) {
     41                                // short circuit if we already know there are designations
     42                                if ( hasDesignations ) visit_children = false;
     43                                else if ( ! des->get_designators().empty() ) {
     44                                        hasDesignations = true;
     45                                        visit_children = false;
     46                                }
    3747                        }
    3848                };
    3949
    40                 class InitDepthChecker : public Visitor {
    41                 public:
     50                struct InitDepthChecker : public WithGuards {
    4251                        bool depthOkay = true;
    4352                        Type * type;
     
    5160                                maxDepth++;
    5261                        }
    53                         virtual void visit( ListInit * listInit ) {
     62                        void previsit( ListInit * ) {
    5463                                curDepth++;
     64                                GuardAction( [this]() { curDepth--; } );
    5565                                if ( curDepth > maxDepth ) depthOkay = false;
    56                                 Visitor::visit( listInit );
    57                                 curDepth--;
    5866                        }
    5967                };
    6068
    61                 class InitFlattener : public Visitor {
    62                         public:
    63                         virtual void visit( SingleInit * singleInit );
    64                         virtual void visit( ListInit * listInit );
     69                struct InitFlattener : public WithShortCircuiting {
     70                        void previsit( SingleInit * singleInit ) {
     71                                visit_children = false;
     72                                argList.push_back( singleInit->value->clone() );
     73                        }
    6574                        std::list< Expression * > argList;
    6675                };
    6776
    68                 void InitFlattener::visit( SingleInit * singleInit ) {
    69                         argList.push_back( singleInit->get_value()->clone() );
    70                 }
    71 
    72                 void InitFlattener::visit( ListInit * listInit ) {
    73                         // flatten nested list inits
    74                         std::list<Initializer*>::iterator it = listInit->begin();
    75                         for ( ; it != listInit->end(); ++it ) {
    76                                 (*it)->accept( *this );
    77                         }
    78                 }
    7977        }
    8078
    8179        std::list< Expression * > makeInitList( Initializer * init ) {
    82                 InitFlattener flattener;
     80                PassVisitor<InitFlattener> flattener;
    8381                maybeAccept( init, flattener );
    84                 return flattener.argList;
     82                return flattener.pass.argList;
    8583        }
    8684
    8785        bool isDesignated( Initializer * init ) {
    88                 HasDesignations finder;
     86                PassVisitor<HasDesignations> finder;
    8987                maybeAccept( init, finder );
    90                 return finder.hasDesignations;
     88                return finder.pass.hasDesignations;
    9189        }
    9290
    9391        bool checkInitDepth( ObjectDecl * objDecl ) {
    94                 InitDepthChecker checker( objDecl->get_type() );
    95                 maybeAccept( objDecl->get_init(), checker );
    96                 return checker.depthOkay;
     92                PassVisitor<InitDepthChecker> checker( objDecl->type );
     93                maybeAccept( objDecl->init, checker );
     94                return checker.pass.depthOkay;
    9795        }
    9896
     
    195193                        callExpr->get_args().splice( callExpr->get_args().end(), args );
    196194
    197                         *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
     195                        *out++ = new IfStmt( cond, new ExprStmt( callExpr ), nullptr );
    198196
    199197                        UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
    200198                        increment->get_args().push_back( index->clone() );
    201                         *out++ = new ExprStmt( noLabels, increment );
     199                        *out++ = new ExprStmt( increment );
    202200                }
    203201
     
    244242                                        std::list< Statement * > stmts;
    245243                                        build( callExpr, idx, idxEnd, init, back_inserter( stmts ) );
    246                                         stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) );
    247                                         CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts );
     244                                        stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) );
     245                                        CaseStmt * caseStmt = new CaseStmt( condition, stmts );
    248246                                        branches.push_back( caseStmt );
    249247                                }
    250                                 *out++ = new SwitchStmt( noLabels, index->clone(), branches );
    251                                 *out++ = new NullStmt( std::list<Label>{ switchLabel } );
     248                                *out++ = new SwitchStmt( index->clone(), branches );
     249                                *out++ = new NullStmt( { switchLabel } );
    252250                        }
    253251                }
     
    262260        Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    263261                if ( ! init ) return nullptr;
    264                 CompoundStmt * block = new CompoundStmt( noLabels );
     262                CompoundStmt * block = new CompoundStmt();
    265263                build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
    266264                if ( block->get_kids().empty() ) {
     
    309307        }
    310308
    311         class CallFinder : public Visitor {
    312         public:
    313                 typedef Visitor Parent;
     309        struct CallFinder {
    314310                CallFinder( const std::list< std::string > & names ) : names( names ) {}
    315311
    316                 virtual void visit( ApplicationExpr * appExpr ) {
     312                void postvisit( ApplicationExpr * appExpr ) {
    317313                        handleCallExpr( appExpr );
    318314                }
    319315
    320                 virtual void visit( UntypedExpr * untypedExpr ) {
     316                void postvisit( UntypedExpr * untypedExpr ) {
    321317                        handleCallExpr( untypedExpr );
    322318                }
     
    328324                template< typename CallExpr >
    329325                void handleCallExpr( CallExpr * expr ) {
    330                         Parent::visit( expr );
    331326                        std::string fname = getFunctionName( expr );
    332327                        if ( std::find( names.begin(), names.end(), fname ) != names.end() ) {
     
    337332
    338333        void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) {
    339                 static CallFinder finder( std::list< std::string >{ "?{}", "^?{}" } );
    340                 finder.matches = &matches;
     334                static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } );
     335                finder.pass.matches = &matches;
    341336                maybeAccept( stmt, finder );
    342337        }
     
    544539        }
    545540
    546         class ConstExprChecker : public Visitor {
    547         public:
    548                 ConstExprChecker() : isConstExpr( true ) {}
    549 
    550                 using Visitor::visit;
    551 
    552                 virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
    553                 virtual void visit( UntypedExpr * ) { isConstExpr = false; }
    554                 virtual void visit( NameExpr * ) { isConstExpr = false; }
    555                 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
    556                 virtual void visit( AddressExpr *addressExpr ) {
     541        struct ConstExprChecker : public WithShortCircuiting {
     542                // most expressions are not const expr
     543                void previsit( Expression * ) { isConstExpr = false; visit_children = false; }
     544
     545                void previsit( AddressExpr *addressExpr ) {
     546                        visit_children = false;
     547
    557548                        // address of a variable or member expression is constexpr
    558549                        Expression * arg = addressExpr->get_arg();
    559550                        if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
    560551                }
    561                 virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
    562                 virtual void visit( MemberExpr * ) { isConstExpr = false; }
    563                 virtual void visit( VariableExpr * ) { isConstExpr = false; }
    564                 // these might be okay?
    565                 // virtual void visit( SizeofExpr *sizeofExpr );
    566                 // virtual void visit( AlignofExpr *alignofExpr );
    567                 // virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    568                 // virtual void visit( OffsetofExpr *offsetofExpr );
    569                 // virtual void visit( OffsetPackExpr *offsetPackExpr );
    570                 // virtual void visit( AttrExpr *attrExpr );
    571                 // virtual void visit( CommaExpr *commaExpr );
    572                 // virtual void visit( LogicalExpr *logicalExpr );
    573                 // virtual void visit( ConditionalExpr *conditionalExpr );
    574                 virtual void visit( TypeExpr * ) { isConstExpr = false; }
    575                 virtual void visit( AsmExpr * ) { isConstExpr = false; }
    576                 virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
    577                 virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
    578                 virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
    579                 virtual void visit( TupleExpr * ) { isConstExpr = false; }
    580                 virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
    581 
    582                 bool isConstExpr;
     552
     553                // these expressions may be const expr, depending on their children
     554                void previsit( SizeofExpr * ) {}
     555                void previsit( AlignofExpr * ) {}
     556                void previsit( UntypedOffsetofExpr * ) {}
     557                void previsit( OffsetofExpr * ) {}
     558                void previsit( OffsetPackExpr * ) {}
     559                void previsit( AttrExpr * ) {}
     560                void previsit( CommaExpr * ) {}
     561                void previsit( LogicalExpr * ) {}
     562                void previsit( ConditionalExpr * ) {}
     563                void previsit( CastExpr * ) {}
     564                void previsit( ConstantExpr * ) {}
     565
     566                bool isConstExpr = true;
    583567        };
    584568
    585569        bool isConstExpr( Expression * expr ) {
    586570                if ( expr ) {
    587                         ConstExprChecker checker;
     571                        PassVisitor<ConstExprChecker> checker;
    588572                        expr->accept( checker );
    589                         return checker.isConstExpr;
     573                        return checker.pass.isConstExpr;
    590574                }
    591575                return true;
     
    594578        bool isConstExpr( Initializer * init ) {
    595579                if ( init ) {
    596                         ConstExprChecker checker;
     580                        PassVisitor<ConstExprChecker> checker;
    597581                        init->accept( checker );
    598                         return checker.isConstExpr;
     582                        return checker.pass.isConstExpr;
    599583                } // if
    600584                // for all intents and purposes, no initializer means const expr
Note: See TracChangeset for help on using the changeset viewer.