Changes in src/AST/Expr.cpp [3e5dd913:490fb92e]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
r3e5dd913 r490fb92e 102 102 } 103 103 return ret; 104 }105 106 // --- VariableExpr107 108 VariableExpr::VariableExpr( const CodeLocation & loc )109 : Expr( loc ), var( nullptr ) {}110 111 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )112 : Expr( loc ), var( v ) {113 assert( var );114 assert( var->get_type() );115 result = shallowCopy( var->get_type() );116 }117 118 bool VariableExpr::get_lvalue() const {119 // It isn't always an lvalue, but it is never an rvalue.120 return true;121 }122 123 VariableExpr * VariableExpr::functionPointer(124 const CodeLocation & loc, const FunctionDecl * decl ) {125 // wrap usually-determined result type in a pointer126 VariableExpr * funcExpr = new VariableExpr{ loc, decl };127 funcExpr->result = new PointerType{ funcExpr->result };128 return funcExpr;129 104 } 130 105 … … 206 181 assert( aggregate->result ); 207 182 208 result = mem->get_type(); 183 // Deep copy on result type avoids mutation on transitively multiply referenced object. 184 // 185 // Example, adapted from parts of builtins and bootloader: 186 // 187 // forall(dtype T) 188 // struct __Destructor { 189 // T * object; 190 // void (*dtor)(T *); 191 // }; 192 // 193 // forall(dtype S) 194 // void foo(__Destructor(S) &d) { 195 // if (d.dtor) { // here 196 // } 197 // } 198 // 199 // Let e be the "d.dtor" guard espression, which is MemberExpr after resolve. Let d be the 200 // declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level 201 // declaration of __Destructor. Consider the types e.result and d.type. In the old AST, one 202 // is a clone of the other. Ordinary new-AST use would set them up as a multiply-referenced 203 // object. 204 // 205 // e.result: PointerType 206 // .base: FunctionType 207 // .params.front(): ObjectDecl, the anonymous parameter of type T* 208 // .type: PointerType 209 // .base: TypeInstType 210 // let x = that 211 // let y = similar, except start from d.type 212 // 213 // Consider two code lines down, genericSubstitution(...).apply(result). 214 // 215 // Applying this chosen-candidate's type substitution means modifying x, substituting 216 // S for T. This mutation should affect x and not y. 217 218 result = deepCopy(mem->get_type()); 209 219 210 220 // substitute aggregate generic parameters into member type … … 226 236 // This is actually wrong by C, but it works with our current set-up. 227 237 return true; 238 } 239 240 // --- VariableExpr 241 242 VariableExpr::VariableExpr( const CodeLocation & loc ) 243 : Expr( loc ), var( nullptr ) {} 244 245 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v ) 246 : Expr( loc ), var( v ) { 247 assert( var ); 248 assert( var->get_type() ); 249 result = shallowCopy( var->get_type() ); 250 } 251 252 bool VariableExpr::get_lvalue() const { 253 // It isn't always an lvalue, but it is never an rvalue. 254 return true; 255 } 256 257 VariableExpr * VariableExpr::functionPointer( 258 const CodeLocation & loc, const FunctionDecl * decl ) { 259 // wrap usually-determined result type in a pointer 260 VariableExpr * funcExpr = new VariableExpr{ loc, decl }; 261 funcExpr->result = new PointerType{ funcExpr->result }; 262 return funcExpr; 228 263 } 229 264
Note: See TracChangeset
for help on using the changeset viewer.