Changeset 9a34b5a
- Timestamp:
- Jul 18, 2017, 5:02:20 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:
- 17f22e78
- Parents:
- d1685588
- git-author:
- Rob Schluntz <rschlunt@…> (07/18/17 16:59:34)
- git-committer:
- Rob Schluntz <rschlunt@…> (07/18/17 17:02:20)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
rd1685588 r9a34b5a 27 27 #include "SynTree/Mutator.h" 28 28 #include "SymTab/Indexer.h" 29 #include "SymTab/Autogen.h" 29 30 #include "ResolvExpr/Resolver.h" 30 31 #include "ResolvExpr/typeops.h" … … 41 42 namespace GenPoly { 42 43 namespace { 44 // TODO: fold this into the general createDeref function?? 45 Expression * mkDeref( Expression * arg ) { 46 if ( SymTab::dereferenceOperator ) { 47 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator ); 48 deref->set_result( new PointerType( Type::Qualifiers(), deref->get_result() ) ); 49 Type * base = InitTweak::getPointerBase( arg->get_result() ); 50 assertf( base, "expected pointer type in dereference (type was %s)", toString( arg->get_result() ).c_str() ); 51 ApplicationExpr * ret = new ApplicationExpr( deref, { arg } ); 52 delete ret->get_result(); 53 ret->set_result( new ReferenceType( Type::Qualifiers(), base->clone() ) ); 54 return ret; 55 } else { 56 return UntypedExpr::createDeref( arg ); 57 } 58 } 59 43 60 struct ReferenceConversions final { 44 61 Expression * postmutate( CastExpr * castExpr ); … … 115 132 116 133 void fixArg( Expression *& arg, Type * formal ) { 117 // if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( arg ) ) { 118 if ( dynamic_cast<ReferenceType*>( formal ) ) { // xxx - but might be deref, in which case result isn't REALLY a reference, at least not in the sense that we need to add another deref... 119 // doesn't work, for some reason left arg is skipped in assign 120 ReferenceType * refType = safe_dynamic_cast< ReferenceType * >( arg->get_result() ) ; 121 std::cerr << "appexpr arg is non-deref/index intrinsic call" << std::endl; 122 std::cerr << arg << std::endl; 123 PointerType * ptrType = new PointerType( Type::Qualifiers(), refType->get_base()->clone() ); 124 delete refType; 125 arg->set_result( ptrType ); 126 arg = UntypedExpr::createDeref( arg ); 127 } 128 129 // } 134 if ( dynamic_cast<ReferenceType*>( formal ) ) { 135 // if the parameter is a reference, add a dereference to the reference-typed argument. 136 Type * baseType = InitTweak::getPointerBase( arg->get_result() ); 137 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->get_result() ) ); 138 PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() ); 139 delete arg->get_result(); 140 arg->set_result( ptrType ); 141 arg = mkDeref( new CastExpr( arg, arg->get_result()->clone() ) ); 142 } 130 143 } 131 144 132 145 Expression * FixIntrinsicArgs::postmutate( ApplicationExpr * appExpr ) { 146 // intrinsic functions don't really take reference-typed parameters, so they require an implicit dereference on their arguments. 133 147 if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) { 134 if ( function->get_linkage() == LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references148 if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 135 149 FunctionType * ftype = GenPoly::getFunctionType( function->get_type() ); 136 150 assertf( ftype, "Function declaration does not have function type." ); … … 140 154 std::cerr << "pair<0>: " << arg << std::endl; 141 155 std::cerr << "pair<1>: " << formal->get_type() << std::endl; 142 if ( isIntrinsicReference( arg ) ) { 156 if ( isIntrinsicReference( arg ) ) { // intrinsic functions that turn pointers into references 157 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 143 158 std::cerr << "skipping intrinsic reference" << std::endl; 144 159 continue; … … 153 168 154 169 Expression * ReferenceConversions::postmutate( CastExpr * castExpr ) { 170 // xxx - is it possible to convert directly between reference types with a different base? E.g., 171 // int x; 172 // (double&)x; 173 // At the moment, I am working off of the assumption that this is illegal, thus the cast becomes redundant 174 // after this pass, so trash the cast altogether. If that changes, care must be taken to insert the correct 175 // pointer casts in the right places. 176 155 177 // conversion to reference type 156 178 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_result() ) ) { … … 162 184 if ( isIntrinsicReference( castExpr->get_arg() ) ) { 163 185 Expression * callExpr = castExpr->get_arg(); 164 Expression ** arg = nullptr;165 Expression *& arg0 = InitTweak::getCallArg( callExpr, 0 );166 if ( dynamic_cast<PointerType *>( arg0->get_result() ) ) {167 arg = &arg0;168 } else {169 arg = &InitTweak::getCallArg( callExpr, 1 );170 }171 172 castExpr->set_arg( *arg );173 *arg = castExpr;174 186 std::cerr << "but arg is deref -- &" << std::endl; 175 187 std::cerr << callExpr << std::endl; 176 // castExpr->set_arg( new AddressExpr( castExpr->get_arg() ) );177 178 188 // move environment out to new top-level 179 189 callExpr->set_env( castExpr->get_env() ); 190 castExpr->set_arg( nullptr ); 180 191 castExpr->set_env( nullptr ); 192 delete castExpr; 181 193 return callExpr; 182 194 } 195 assertf( false, "non-intrinsic reference with cast of reference to reference not yet supported: ", toString( castExpr ) ); 183 196 std::cerr << castExpr << std::endl; 184 197 return castExpr; … … 189 202 std::cerr << "convert lvalue to reference -- &" << std::endl; 190 203 std::cerr << castExpr->get_arg() << std::endl; 191 castExpr->set_arg( new AddressExpr( castExpr->get_arg() ) ); 192 // return new AddressExpr( castExpr->get_arg() ); 193 return castExpr; 204 Expression * ret = new AddressExpr( castExpr->get_arg() ); 205 ret->set_env( castExpr->get_env() ); 206 castExpr->set_env( nullptr ); 207 castExpr->set_arg( nullptr ); 208 delete castExpr; 209 return ret; 194 210 } else { 195 211 // rvalue to reference conversion -- introduce temporary … … 197 213 assertf( false, "Only conversions to reference from lvalue are currently supported: %s", toString( castExpr ).c_str() ); 198 214 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) { 215 // conversion from reference to rvalue 199 216 // should be easy, just need to move deref code up here? 200 217 std::cerr << "convert reference to rvalue -- *" << std::endl; … … 203 220 return castExpr; 204 221 } 205 std::cerr << castExpr << std::endl; 206 207 PointerType * ptrType = new PointerType( refType->get_qualifiers(), refType->get_base()->clone() ); 208 delete castExpr->get_result(); 209 castExpr->set_result( ptrType ); 210 Expression * deref = UntypedExpr::createDeref( castExpr ); 222 std::cerr << "was = " << castExpr << std::endl; 223 224 Expression * deref = mkDeref( castExpr->get_arg() ); 211 225 deref->set_env( castExpr->get_env() ); 226 castExpr->set_arg( nullptr ); 212 227 castExpr->set_env( nullptr ); 228 delete castExpr; 229 std::cerr << "now: " << deref << std::endl; 213 230 return deref; 214 // assertf( false, "Conversions from reference types are not currently supported." );215 231 } 216 232 return castExpr;
Note: See TracChangeset
for help on using the changeset viewer.