Changeset 2ad4b49


Ignore:
Timestamp:
Jun 4, 2018, 4:29:23 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
41770ed, d885a58, f77dbc0
Parents:
1ddbf3b (diff), ee3c93d (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.impl.h

    r1ddbf3b r2ad4b49  
    828828        VISIT_START( node );
    829829
    830         visitExpression( node->condition );
    831         node->body = visitStatement( node->body );
     830        {
     831                // while statements introduce a level of scope (for the initialization)
     832                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     833                maybeAccept_impl( node->initialization, *this );
     834                visitExpression ( node->condition );
     835                node->body = visitStatement( node->body );
     836        }
    832837
    833838        VISIT_END( node );
     
    838843        MUTATE_START( node );
    839844
    840         node->condition = mutateExpression( node->condition );
    841         node->body      = mutateStatement ( node->body      );
     845        {
     846                // while statements introduce a level of scope (for the initialization)
     847                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     848                maybeMutate_impl( node->initialization, *this );
     849                node->condition = mutateExpression( node->condition );
     850                node->body      = mutateStatement ( node->body      );
     851        }
     852
    842853
    843854        MUTATE_END( Statement, node );
  • src/ControlStruct/ForExprMutator.cc

    r1ddbf3b r2ad4b49  
    4545                return hoist( forStmt, forStmt->initialization );
    4646        }
     47        Statement *ForExprMutator::postmutate( WhileStmt *whileStmt ) {
     48                return hoist( whileStmt, whileStmt->initialization );
     49        }
    4750} // namespace ControlStruct
    4851
  • src/ControlStruct/ForExprMutator.h

    r1ddbf3b r2ad4b49  
    1818class IfStmt;
    1919class ForStmt;
     20class WhileStmt;
    2021class Statement;
    2122
     
    2526                Statement *postmutate( IfStmt * );
    2627                Statement *postmutate( ForStmt * );
     28                Statement *postmutate( WhileStmt * );
    2729        };
    2830} // namespace ControlStruct
  • src/Parser/ParseNode.h

    r1ddbf3b r2ad4b49  
    403403};
    404404
     405Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
    405406Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
    406407Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
  • src/Parser/StatementNode.cc

    r1ddbf3b r2ad4b49  
    8080}
    8181
    82 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
    83         Statement * thenb, * elseb = 0;
    84         std::list< Statement * > branches;
    85         buildMoveList< Statement, StatementNode >( then_stmt, branches );
    86         assert( branches.size() == 1 );
    87         thenb = branches.front();
    88 
    89         if ( else_stmt ) {
    90                 std::list< Statement * > branches;
    91                 buildMoveList< Statement, StatementNode >( else_stmt, branches );
    92                 assert( branches.size() == 1 );
    93                 elseb = branches.front();
    94         } // if
    95 
    96         std::list< Statement * > init;
     82Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ) {
    9783        if ( ctl->init != 0 ) {
    9884                buildMoveList( ctl->init, init );
     
    10288        if ( ctl->condition ) {
    10389                // compare the provided condition against 0
    104                 cond =  notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
     90                cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
    10591        } else {
    10692                for ( Statement * stmt : init ) {
     
    11399        }
    114100        delete ctl;
     101        return cond;
     102}
     103
     104Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
     105        Statement * thenb, * elseb = 0;
     106        std::list< Statement * > branches;
     107        buildMoveList< Statement, StatementNode >( then_stmt, branches );
     108        assert( branches.size() == 1 );
     109        thenb = branches.front();
     110
     111        if ( else_stmt ) {
     112                std::list< Statement * > branches;
     113                buildMoveList< Statement, StatementNode >( else_stmt, branches );
     114                assert( branches.size() == 1 );
     115                elseb = branches.front();
     116        } // if
     117
     118        std::list< Statement * > init;
     119        Expression * cond = build_if_control( ctl, init );
    115120        return new IfStmt( cond, thenb, elseb, init );
    116121}
     
    144149        buildMoveList< Statement, StatementNode >( stmt, branches );
    145150        assert( branches.size() == 1 );
    146         return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );
     151
     152        std::list< Statement * > init;
     153        return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), init, kind );
    147154}
    148155
  • src/ResolvExpr/Resolver.cc

    r1ddbf3b r2ad4b49  
    207207                        Alternative & choice = winners.front();
    208208                        if ( findDeletedExpr( choice.expr ) ) {
    209                                 SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
     209                                SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " );
    210210                        }
    211211                        alt = std::move( choice );
     
    242242
    243243                static CastExpr untyped( nullptr ); // cast to void
     244                untyped.location = expr->location;
    244245
    245246                // set up and resolve expression cast to void
     
    274275        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
    275276                assert( untyped && type );
     277                // transfer location to generated cast for error purposes
     278                CodeLocation location = untyped->location;
    276279                untyped = new CastExpr( untyped, type );
     280                untyped->location = location;
    277281                findSingleExpression( untyped, indexer );
    278282                removeExtraneousCast( untyped, indexer );
  • src/SymTab/Indexer.cc

    r1ddbf3b r2ad4b49  
    106106                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    107107
    108                 // helpful data structure
     108                // helpful data structure to organize properties for a type
    109109                struct ValueType {
    110                         struct DeclBall {
     110                        struct DeclBall { // properties for this particular decl
    111111                                IdData decl;
    112                                 bool isUserDefinedFunc; // properties for this particular decl
    113                                 bool isDefaultCtor;
    114                                 bool isDtor;
     112                                bool isUserDefinedFunc;
    115113                                bool isCopyFunc;
    116114                        };
    117115                        // properties for this type
    118                         bool existsUserDefinedFunc = false;    // any user-defined function found
    119                         bool existsUserDefinedCtor = false;    // any user-defined constructor found
    120                         bool existsUserDefinedDtor = false;    // any user-defined destructor found
    121116                        bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    122                         bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found
     117                        BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    123118                        std::list< DeclBall > decls;
    124119
     
    127122                        ValueType & operator+=( IdData data ) {
    128123                                DeclarationWithType * function = data.id;
    129                                 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    130                                 bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    131                                 bool isDtor = InitTweak::isDestructor( function );
    132                                 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    133                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    134                                 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    135                                 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
    136                                 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor);
     124                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     125                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
     126                                decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
    137127                                existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
    138                                 existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor);
     128                                if ( isUserDefinedFunc && ! data.deleteStmt ) {
     129                                        // any user-defined function can act as an implicit delete statement for generated constructors.
     130                                        // a delete stmt should not act as an implicit delete statement.
     131                                        deleteStmt = data.id;
     132                                }
    139133                                return *this;
    140134                        }
     
    160154
    161155                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
    162                 // the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines
    163                 // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
    164                 // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
    165                 // If the user defines any ctor then the generated default ctor should not be seen (intrinsic default
    166                 // ctor must be overridden exactly).
     156                // the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
     157                // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
     158                // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
     159                // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
     160                // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
     161                // then the generated copy constructor is unavailable, and likewise for the assignment operator.
    167162                for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
    168163                        ValueType & val = pair.second;
    169164                        for ( ValueType::DeclBall ball : val.decls ) {
    170                                 bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    171                                 bool isUserDefinedFunc = ball.isUserDefinedFunc;
    172                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->linkage == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    173                                 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    174                                 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
    175                                 if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) {
    176                                         // decl conforms to the rules described above, so it should be seen by the requester
    177                                         out.push_back( ball.decl );
     165                                bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
     166                                bool isCopyFunc = ball.isCopyFunc;
     167                                bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
     168                                // only implicitly delete non-user defined functions that are  not intrinsic, and are
     169                                // not copy functions (assignment or copy constructor), unless a user-defined copy function exists.
     170                                // deleteStmt will be non-null only if a user-defined function is found.
     171                                if (isNotUserDefinedFunc && (! isCopyFunc || existsUserDefinedCopyFunc)) {
     172                                        ball.decl.deleteStmt = val.deleteStmt;
    178173                                }
     174                                out.push_back( ball.decl );
    179175                        }
    180176                }
  • src/SynTree/Statement.cc

    r1ddbf3b r2ad4b49  
    243243}
    244244
    245 WhileStmt::WhileStmt( Expression *condition, Statement *body, bool isDoWhile ):
    246         Statement(), condition( condition), body( body), isDoWhile( isDoWhile) {
     245WhileStmt::WhileStmt( Expression *condition, Statement *body, std::list< Statement * > & initialization, bool isDoWhile ):
     246        Statement(), condition( condition), body( body), initialization( initialization ), isDoWhile( isDoWhile) {
    247247}
    248248
  • src/SynTree/Statement.h

    r1ddbf3b r2ad4b49  
    220220        Expression *condition;
    221221        Statement *body;
     222        std::list<Statement *> initialization;
    222223        bool isDoWhile;
    223224
    224225        WhileStmt( Expression *condition,
    225                Statement *body, bool isDoWhile = false );
     226               Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
    226227        WhileStmt( const WhileStmt &other );
    227228        virtual ~WhileStmt();
  • src/tests/raii/.expect/ctor-autogen-ERR1.txt

    r1ddbf3b r2ad4b49  
    1 raii/ctor-autogen.c:102:1 error: No reasonable alternatives for expression Applying untyped:
    2   Name: ?{}
    3 ...to:
    4   Cast of:
    5     Variable Expression: x: instance of struct Managed with body 1
    6   ... to:
    7     reference to instance of struct Managed with body 1
    8   constant expression (123 123: signed int)
     1raii/ctor-autogen.c:102:1 error: Unique best alternative includes deleted identifier in Cast of:
     2  Application of
     3    Deleted Expression
     4      Variable Expression: ?{}: static inline function
     5      ... with parameters
     6        _dst: reference to instance of struct Managed with body 1
     7        x: signed int
     8      ... returning nothing
    99
     10      ... deleted by: ?{}: function
     11      ... with parameters
     12        m: reference to instance of struct Managed with body 1
     13      ... returning nothing
     14      ... with body
     15        CompoundStmt
     16          Expression Statement:
     17            Application of
     18              Variable Expression: ?=?: function
     19              ... with parameters
     20                intrinsic reference to signed int
     21                intrinsic signed int
     22              ... returning
     23                _retval__operator_assign: signed int
     24                ... with attributes:
     25                  Attribute with name: unused
     26
     27
     28            ... to arguments
     29              Cast of:
     30                Member Expression, with field:
     31                  x: signed int
     32                ... from aggregate:
     33                  Cast of:
     34                    Variable Expression: m: reference to instance of struct Managed with body 1
     35                  ... to:
     36                    instance of struct Managed with body 1
     37              ... to:
     38                reference to signed int
     39              Cast of:
     40                constant expression (0 0: zero_t)
     41              ... to:
     42                signed int
     43
     44            ... with environment:
     45              Types:
     46              Non-types:
     47
     48
     49  ... to arguments
     50    Cast of:
     51      Variable Expression: x: instance of struct Managed with body 1
     52    ... to:
     53      reference to instance of struct Managed with body 1
     54    constant expression (123 123: signed int)
     55
     56... to: nothing
Note: See TracChangeset for help on using the changeset viewer.