Changeset 8a6cf7e for src/GenPoly
- Timestamp:
- Jul 26, 2017, 4:26:08 PM (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:
- 2afec66
- Parents:
- d335627
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
rd335627 r8a6cf7e 66 66 struct ReferenceConversions final { 67 67 Expression * postmutate( CastExpr * castExpr ); 68 Expression * postmutate( AddressExpr * addrExpr ); 68 69 }; 69 70 … … 102 103 mutateAll( translationUnit, refCvt ); 103 104 mutateAll( translationUnit, fixer ); 104 mutateAll( translationUnit, elim );105 105 mutateAll( translationUnit, genLval ); 106 106 mutateAll( translationUnit, collapser ); 107 mutateAll( translationUnit, elim ); // last because other passes need reference types to work 107 108 } 108 109 109 110 namespace { 110 Type* isLvalueRet( FunctionType *function ) { 111 if ( function->get_returnVals().empty() ) return 0; 112 Type *ty = function->get_returnVals().front()->get_type(); 113 return dynamic_cast< ReferenceType * >( ty ) ; 114 } 115 116 bool isIntrinsicApp( ApplicationExpr *appExpr ) { 117 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) { 118 return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic; 119 } else { 120 return false; 121 } // if 122 } 123 124 bool isDeref( Expression * expr ) { 111 // true for intrinsic function calls that return a reference 112 bool isIntrinsicReference( Expression * expr ) { 125 113 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 126 return InitTweak::getFunctionName( untyped ) == "*?"; 114 std::string fname = InitTweak::getFunctionName( untyped ); 115 // known intrinsic-reference prelude functions 116 return fname == "*?" || fname == "?[?]"; 127 117 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 128 118 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 129 return func->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getFunctionName( appExpr ) == "*?"; 130 } 131 } 132 return false; 133 } 134 135 bool isIntrinsicReference( Expression * expr ) { 136 if ( isDeref( expr ) ) return true; 137 else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 138 return InitTweak::getFunctionName( untyped ) == "?[?]"; 139 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 140 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 141 return func->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getFunctionName( appExpr ) == "?[?]"; 119 // use type of return variable rather than expr result type, since it may have been changed to a pointer type 120 FunctionType * ftype = GenPoly::getFunctionType( func->get_type() ); 121 Type * ret = ftype->get_returnVals().empty() ? nullptr : ftype->get_returnVals().front()->get_type(); 122 return func->get_linkage() == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret ); 142 123 } 143 124 } … … 186 167 } 187 168 169 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { 170 // Inner expression may have been lvalue to reference conversion, which becomes an address expression. 171 // In this case, remove the outer address expression and return the argument. 172 // TODO: It's possible that this might catch too much and require a more sophisticated check. 173 if ( dynamic_cast<AddressExpr*>( addrExpr->get_arg() ) ) { 174 Expression * arg = addrExpr->get_arg(); 175 arg->set_env( addrExpr->get_env() ); 176 addrExpr->set_arg( nullptr ); 177 addrExpr->set_env( nullptr ); 178 delete addrExpr; 179 return arg; 180 } 181 return addrExpr; 182 } 183 188 184 Expression * ReferenceConversions::postmutate( CastExpr * castExpr ) { 189 185 // xxx - is it possible to convert directly between reference types with a different base? E.g., … … 244 240 (void)refType; 245 241 // conversion from reference to rvalue 246 PRINT( std::cerr << "convert reference to rvalue -- *" << std::endl; ) 247 PRINT( std::cerr << "was = " << castExpr << std::endl; ) 242 PRINT( 243 std::cerr << "convert reference to rvalue -- *" << std::endl; 244 std::cerr << "was = " << castExpr << std::endl; 245 ) 248 246 Expression * ret = castExpr->get_arg(); 247 TypeSubstitution * env = castExpr->get_env(); 248 castExpr->set_env( nullptr ); 249 249 if ( ! isIntrinsicReference( ret ) ) { 250 250 // dereference if not already dereferenced 251 251 ret = mkDeref( ret ); 252 252 } 253 ret->set_env( castExpr->get_env() ); 254 castExpr->set_arg( nullptr ); 255 castExpr->set_env( nullptr ); 256 delete castExpr; 253 if ( ResolvExpr::typesCompatibleIgnoreQualifiers( castExpr->get_result(), castExpr->get_arg()->get_result()->stripReferences(), SymTab::Indexer() ) ) { 254 // can remove cast if types are compatible 255 castExpr->set_arg( nullptr ); 256 delete castExpr; 257 } else { 258 // must keep cast if types are different 259 castExpr->set_arg( ret ); 260 ret = castExpr; 261 } 262 ret->set_env( env ); 257 263 PRINT( std::cerr << "now: " << ret << std::endl; ) 258 264 return ret; … … 263 269 Type * ReferenceTypeElimination::postmutate( ReferenceType * refType ) { 264 270 Type * base = refType->get_base(); 271 Type::Qualifiers qualifiers = refType->get_qualifiers(); 265 272 refType->set_base( nullptr ); 266 273 delete refType; 267 return new PointerType( Type::Qualifiers(), base );274 return new PointerType( qualifiers, base ); 268 275 } 269 276
Note: See TracChangeset
for help on using the changeset viewer.