Changeset 4618319
- Timestamp:
- Jul 28, 2017, 11:29:47 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- b0440b7
- Parents:
- 1461809
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r1461809 r4618319 239 239 SemanticError errors; 240 240 private: 241 void handleFirstParam( Expression * firstParam );242 241 template< typename... Params > 243 242 void emit( CodeLocation, const Params &... params ); … … 1032 1031 1033 1032 if ( ! unhandled.empty() ) { 1034 // need to explicitly re-add function parameters in order to resolve copy constructors1033 // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors 1035 1034 enterScope(); 1036 1035 maybeAccept( function->get_functionType(), *this ); … … 1055 1054 } 1056 1055 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 ); 1058 1060 1059 1061 assert( stmt.size() <= 1 ); … … 1082 1084 } 1083 1085 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 1084 1109 void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) { 1085 1110 if ( ! checkWarnings( function ) ) return; … … 1090 1115 Expression * firstParam = appExpr->get_args().front(); 1091 1116 1092 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( firstParam ) ) {1117 if ( isThisExpression( firstParam, thisParam ) ) { 1093 1118 // if calling another constructor on thisParam, assume that function handles 1094 1119 // 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() ); 1120 1126 } 1121 1127 } 1122 1128 } 1129 Parent::visit( appExpr ); 1123 1130 } 1124 1131 … … 1127 1134 if ( ! isCtor ) return; 1128 1135 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 } ); 1139 1140 } 1140 1141 }
Note: See TracChangeset
for help on using the changeset viewer.