Changeset 4618319


Ignore:
Timestamp:
Jul 28, 2017, 11:29:47 AM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, resolv-new, with_gc
Children:
b0440b7
Parents:
1461809
Message:

Update GenStructMemberCalls? pass for references

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r1461809 r4618319  
    239239                        SemanticError errors;
    240240                  private:
    241                         void handleFirstParam( Expression * firstParam );
    242241                        template< typename... Params >
    243242                        void emit( CodeLocation, const Params &... params );
     
    10321031
    10331032                        if ( ! unhandled.empty() ) {
    1034                                 // need to explicitly re-add function parameters in order to resolve copy constructors
     1033                                // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors
    10351034                                enterScope();
    10361035                                maybeAccept( function->get_functionType(), *this );
     
    10551054                                        }
    10561055                                        InitExpander srcParam( arg2 );
    1057                                         SymTab::genImplicitCall( srcParam, new MemberExpr( field, new VariableExpr( thisParam ) ), function->get_name(), back_inserter( stmt ), field, isCtor );
     1056                                        // cast away reference type and construct field.
     1057                                        Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() );
     1058                                        Expression * memberDest = new MemberExpr( field, thisExpr );
     1059                                        SymTab::genImplicitCall( srcParam, memberDest, function->get_name(), back_inserter( stmt ), field, isCtor );
    10581060
    10591061                                        assert( stmt.size() <= 1 );
     
    10821084                }
    10831085
     1086                /// true if expr is effectively just the 'this' parameter
     1087                bool isThisExpression( Expression * expr, DeclarationWithType * thisParam ) {
     1088                        // TODO: there are more complicated ways to pass 'this' to a constructor, e.g. &*, *&, etc.
     1089                        if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
     1090                                return varExpr->get_var() == thisParam;
     1091                        } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( expr ) ) {
     1092                                return isThisExpression( castExpr->get_arg(), thisParam );
     1093                        }
     1094                        return false;
     1095                }
     1096
     1097                /// returns a MemberExpr if expr is effectively just member access on the 'this' parameter, else nullptr
     1098                MemberExpr * isThisMemberExpr( Expression * expr, DeclarationWithType * thisParam ) {
     1099                        if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( expr ) ) {
     1100                                if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     1101                                        return memberExpr;
     1102                                }
     1103                        } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     1104                                return isThisMemberExpr( castExpr->get_arg(), thisParam );
     1105                        }
     1106                        return nullptr;
     1107                }
     1108
    10841109                void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) {
    10851110                        if ( ! checkWarnings( function ) ) return;
     
    10901115                                Expression * firstParam = appExpr->get_args().front();
    10911116
    1092                                 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( firstParam ) ) {
     1117                                if ( isThisExpression( firstParam, thisParam ) ) {
    10931118                                        // if calling another constructor on thisParam, assume that function handles
    10941119                                        // all members - if it doesn't a warning will appear in that function.
    1095                                         if ( varExpr->get_var() == thisParam ) {
    1096                                                 unhandled.clear();
    1097                                         }
    1098                                 } else {
    1099                                         // if first parameter is a member expression then
    1100                                         // remove the member from unhandled set.
    1101                                         handleFirstParam( firstParam );
    1102                                 }
    1103                         }
    1104 
    1105                         Parent::visit( appExpr );
    1106                 }
    1107 
    1108                 void GenStructMemberCalls::handleFirstParam( Expression * firstParam ) {
    1109                         using namespace std;
    1110                         if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( firstParam ) ) {
    1111                                 if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( addrExpr->get_arg() ) ) {
    1112                                         if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
    1113                                                 if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
    1114                                                         if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
    1115                                                                 if ( varExpr->get_var() == thisParam ) {
    1116                                                                         unhandled.erase( memberExpr->get_member() );
    1117                                                                 }
    1118                                                         }
    1119                                                 }
     1120                                        unhandled.clear();
     1121                                } else if ( MemberExpr * memberExpr = isThisMemberExpr( firstParam, thisParam ) ) {
     1122                                        // if first parameter is a member expression on the this parameter,
     1123                                        // then remove the member from unhandled set.
     1124                                        if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     1125                                                unhandled.erase( memberExpr->get_member() );
    11201126                                        }
    11211127                                }
    11221128                        }
     1129                        Parent::visit( appExpr );
    11231130                }
    11241131
     
    11271134                        if ( ! isCtor ) return;
    11281135
    1129                         if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {
    1130                                 if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {
    1131                                         if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {
    1132                                                 if ( varExpr->get_var() == thisParam ) {
    1133                                                         if ( unhandled.count( memberExpr->get_member() ) ) {
    1134                                                                 // emit a warning because a member was used before it was constructed
    1135                                                                 usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
    1136                                                         }
    1137                                                 }
    1138                                         }
     1136                        if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     1137                                if ( unhandled.count( memberExpr->get_member() ) ) {
     1138                                        // emit a warning because a member was used before it was constructed
     1139                                        usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
    11391140                                }
    11401141                        }
Note: See TracChangeset for help on using the changeset viewer.