Changeset c13e8dc8 for src/InitTweak


Ignore:
Timestamp:
Dec 5, 2017, 2:35:03 PM (8 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

Location:
src/InitTweak
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r9c35431 rc13e8dc8  
    2020#include <algorithm>               // for replace_if
    2121
     22#include "Common/PassVisitor.h"
    2223#include "Common/SemanticError.h"  // for SemanticError
    2324#include "Common/UniqueName.h"     // for UniqueName
     
    2930#include "SynTree/Expression.h"    // for ConstantExpr, Expression (ptr only)
    3031#include "SynTree/Initializer.h"   // for ConstructorInit, Initializer
    31 #include "SynTree/Label.h"         // for Label, noLabels
     32#include "SynTree/Label.h"         // for Label
    3233#include "SynTree/Statement.h"     // for CompoundStmt, Statement (ptr only)
    3334#include "SynTree/Type.h"          // for Type, Type::StorageClasses, Functi...
     
    3536
    3637namespace InitTweak {
    37         class GlobalFixer : public Visitor {
     38        class GlobalFixer : public WithShortCircuiting {
    3839          public:
    3940                GlobalFixer( const std::string & name, bool inLibrary );
    4041
    41                 virtual void visit( ObjectDecl *objDecl );
    42                 virtual void visit( FunctionDecl *functionDecl );
    43                 virtual void visit( StructDecl *aggregateDecl );
    44                 virtual void visit( UnionDecl *aggregateDecl );
    45                 virtual void visit( EnumDecl *aggregateDecl );
    46                 virtual void visit( TraitDecl *aggregateDecl );
    47                 virtual void visit( TypeDecl *typeDecl );
     42                void previsit( ObjectDecl *objDecl );
     43                void previsit( FunctionDecl *functionDecl );
     44                void previsit( StructDecl *aggregateDecl );
     45                void previsit( UnionDecl *aggregateDecl );
     46                void previsit( EnumDecl *aggregateDecl );
     47                void previsit( TraitDecl *aggregateDecl );
     48                void previsit( TypeDecl *typeDecl );
    4849
    4950                UniqueName tempNamer;
     
    5354
    5455        void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
    55                 GlobalFixer fixer( name, inLibrary );
    56                 acceptAll( translationUnit, fixer );
     56                PassVisitor<GlobalFixer> visitor( name, inLibrary );
     57                acceptAll( translationUnit, visitor );
     58                GlobalFixer & fixer = visitor.pass;
    5759                // don't need to include function if it's empty
    5860                if ( fixer.initFunction->get_statements()->get_kids().empty() ) {
     
    9294                        dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
    9395                }
    94                 initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
     96                initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
    9597                initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) );
    96                 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
     98                destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
    9799                destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) );
    98100        }
    99101
    100         void GlobalFixer::visit( ObjectDecl *objDecl ) {
     102        void GlobalFixer::previsit( ObjectDecl *objDecl ) {
    101103                std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids();
    102104                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
     
    134136
    135137        // only modify global variables
    136         void GlobalFixer::visit( __attribute__((unused)) FunctionDecl *functionDecl ) {}
    137         void GlobalFixer::visit( __attribute__((unused)) StructDecl *aggregateDecl ) {}
    138         void GlobalFixer::visit( __attribute__((unused)) UnionDecl *aggregateDecl ) {}
    139         void GlobalFixer::visit( __attribute__((unused)) EnumDecl *aggregateDecl ) {}
    140         void GlobalFixer::visit( __attribute__((unused)) TraitDecl *aggregateDecl ) {}
    141         void GlobalFixer::visit( __attribute__((unused)) TypeDecl *typeDecl ) {}
     138        void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
     139        void GlobalFixer::previsit( StructDecl * ) { visit_children = false; }
     140        void GlobalFixer::previsit( UnionDecl * ) { visit_children = false; }
     141        void GlobalFixer::previsit( EnumDecl * ) { visit_children = false; }
     142        void GlobalFixer::previsit( TraitDecl * ) { visit_children = false; }
     143        void GlobalFixer::previsit( TypeDecl * ) { visit_children = false; }
    142144
    143145} // namespace InitTweak
  • src/InitTweak/FixInit.cc

    r9c35431 rc13e8dc8  
    4949#include "SynTree/Expression.h"        // for UniqueExpr, VariableExpr, Unty...
    5050#include "SynTree/Initializer.h"       // for ConstructorInit, SingleInit
    51 #include "SynTree/Label.h"             // for Label, noLabels, operator<
     51#include "SynTree/Label.h"             // for Label, operator<
    5252#include "SynTree/Mutator.h"           // for mutateAll, Mutator, maybeMutate
    5353#include "SynTree/Statement.h"         // for ExprStmt, CompoundStmt, Branch...
     
    547547                        // add all temporary declarations and their constructors
    548548                        for ( ObjectDecl * obj : tempDecls ) {
    549                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     549                                stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    550550                        } // for
    551551                        for ( ObjectDecl * obj : returnDecls ) {
    552                                 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     552                                stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    553553                        } // for
    554554
    555555                        // add destructors after current statement
    556556                        for ( Expression * dtor : dtors ) {
    557                                 stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
     557                                stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    558558                        } // for
    559559
     
    601601                        if ( ! result->isVoid() ) {
    602602                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    603                                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
     603                                        stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    604604                                } // for
    605605                                // add destructors after current statement
    606606                                for ( Expression * dtor : stmtExpr->get_dtors() ) {
    607                                         stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
     607                                        stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    608608                                } // for
    609609                                // must have a non-empty body, otherwise it wouldn't have a result
    610610                                assert( ! stmts.empty() );
    611611                                assert( ! stmtExpr->get_returnDecls().empty() );
    612                                 stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
     612                                stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );
    613613                                stmtExpr->get_returnDecls().clear();
    614614                                stmtExpr->get_dtors().clear();
     
    739739
    740740                                                // generate body of if
    741                                                 CompoundStmt * initStmts = new CompoundStmt( noLabels );
     741                                                CompoundStmt * initStmts = new CompoundStmt();
    742742                                                std::list< Statement * > & body = initStmts->get_kids();
    743743                                                body.push_back( ctor );
    744                                                 body.push_back( new ExprStmt( noLabels, setTrue ) );
     744                                                body.push_back( new ExprStmt( setTrue ) );
    745745
    746746                                                // put it all together
    747                                                 IfStmt * ifStmt = new IfStmt( noLabels, new VariableExpr( isUninitializedVar ), initStmts, 0 );
    748                                                 stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
     747                                                IfStmt * ifStmt = new IfStmt( new VariableExpr( isUninitializedVar ), initStmts, 0 );
     748                                                stmtsToAddAfter.push_back( new DeclStmt( isUninitializedVar ) );
    749749                                                stmtsToAddAfter.push_back( ifStmt );
    750750
     
    761761
    762762                                                        // void __objName_dtor_atexitN(...) {...}
    763                                                         FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ) );
     763                                                        FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
    764764                                                        dtorCaller->fixUniqueId();
    765765                                                        dtorCaller->get_statements()->push_back( dtorStmt );
     
    769769                                                        callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
    770770
    771                                                         body.push_back( new ExprStmt( noLabels, callAtexit ) );
     771                                                        body.push_back( new ExprStmt( callAtexit ) );
    772772
    773773                                                        // hoist variable and dtor caller decls to list of decls that will be added into global scope
  • 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.