Changes in src/AST/Expr.cpp [cf32116:312029a]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
rcf32116 r312029a 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 15 17:00:00 2019 11 // Last Modified By : Andrew Beach12 // Created On : Thr Jun 26 12:12:00 201913 // Update Count : 311 // Last Modified By : Peter A. Buhr 12 // Created On : Thr Jun 13 13:38:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 20 20 #include <vector> 21 21 22 #include "Copy.hpp" // for shallowCopy23 #include "Eval.hpp" // for call24 22 #include "GenericSubstitution.hpp" 25 #include "LinkageSpec.hpp"26 23 #include "Stmt.hpp" 27 24 #include "Type.hpp" … … 30 27 #include "Common/SemanticError.h" 31 28 #include "GenPoly/Lvalue.h" // for referencesPermissable 32 #include "InitTweak/InitTweak.h" // for get Function, getPointerBase29 #include "InitTweak/InitTweak.h" // for getPointerBase 33 30 #include "ResolvExpr/typeops.h" // for extractResultType 34 31 #include "Tuples/Tuples.h" // for makeTupleType 35 32 36 33 namespace ast { 37 38 namespace {39 std::set<std::string> const lvalueFunctionNames = {"*?", "?[?]"};40 }41 42 // --- Expr43 bool Expr::get_lvalue() const {44 return false;45 }46 34 47 35 // --- ApplicationExpr … … 58 46 } 59 47 60 bool ApplicationExpr::get_lvalue() const {61 if ( const DeclWithType * func = InitTweak::getFunction( this ) ) {62 return func->linkage == Linkage::Intrinsic && lvalueFunctionNames.count( func->name );63 }64 return false;65 }66 67 48 // --- UntypedExpr 68 49 … … 70 51 assert( arg ); 71 52 72 UntypedExpr * ret = call( loc, "*?", arg ); 53 UntypedExpr * ret = new UntypedExpr{ 54 loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } } 55 }; 73 56 if ( const Type * ty = arg->result ) { 74 57 const Type * base = InitTweak::getPointerBase( ty ); … … 88 71 } 89 72 90 bool UntypedExpr::get_lvalue() const {91 std::string fname = InitTweak::getFunctionName( this );92 return lvalueFunctionNames.count( fname );93 }94 95 73 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) { 96 74 assert( lhs && rhs ); 97 75 98 UntypedExpr * ret = call( loc, "?=?", lhs, rhs ); 76 UntypedExpr * ret = new UntypedExpr{ 77 loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } } 78 }; 99 79 if ( lhs->result && rhs->result ) { 100 80 // if both expressions are typed, assumes that this assignment is a C bitwise assignment, … … 128 108 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) { 129 109 if ( arg->result ) { 130 if ( arg-> get_lvalue() ) {110 if ( arg->result->is_lvalue() ) { 131 111 // lvalue, retains all levels of reference, and gains a pointer inside the references 132 112 Type * res = addrType( arg->result ); … … 159 139 : Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {} 160 140 161 bool CastExpr::get_lvalue() const {162 // This is actually wrong by C, but it works with our current set-up.163 return arg->get_lvalue();164 }165 166 141 // --- KeywordCastExpr 167 142 168 const std::string & KeywordCastExpr::targetString() const { 169 static const std::string targetStrs[] = { 170 "coroutine", "thread", "monitor" 171 }; 172 static_assert( 173 (sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS), 174 "Each KeywordCastExpr::Target should have a corresponding string representation" 175 ); 176 return targetStrs[(unsigned long)target]; 177 } 178 179 // --- UntypedMemberExpr 180 181 bool UntypedMemberExpr::get_lvalue() const { 182 return aggregate->get_lvalue(); 143 const char * KeywordCastExpr::targetString() const { 144 return AggregateDecl::aggrString( target ); 183 145 } 184 146 … … 191 153 assert( aggregate->result ); 192 154 193 // Deep copy on result type avoids mutation on transitively multiply referenced object. 194 // 195 // Example, adapted from parts of builtins and bootloader: 196 // 197 // forall(dtype T) 198 // struct __Destructor { 199 // T * object; 200 // void (*dtor)(T *); 201 // }; 202 // 203 // forall(dtype S) 204 // void foo(__Destructor(S) &d) { 205 // if (d.dtor) { // here 206 // } 207 // } 208 // 209 // Let e be the "d.dtor" guard espression, which is MemberExpr after resolve. Let d be the 210 // declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level 211 // declaration of __Destructor. Consider the types e.result and d.type. In the old AST, one 212 // is a clone of the other. Ordinary new-AST use would set them up as a multiply-referenced 213 // object. 214 // 215 // e.result: PointerType 216 // .base: FunctionType 217 // .params.front(): ObjectDecl, the anonymous parameter of type T* 218 // .type: PointerType 219 // .base: TypeInstType 220 // let x = that 221 // let y = similar, except start from d.type 222 // 223 // Consider two code lines down, genericSubstitution(...).apply(result). 224 // 225 // Applying this chosen-candidate's type substitution means modifying x, substituting 226 // S for T. This mutation should affect x and not y. 227 228 result = deepCopy(mem->get_type()); 229 155 // take ownership of member type 156 result = mem->get_type(); 230 157 // substitute aggregate generic parameters into member type 231 158 genericSubstitution( aggregate->result ).apply( result ); … … 234 161 } 235 162 236 MemberExpr::MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg,237 MemberExpr::NoOpConstruction overloadSelector )238 : Expr( loc ), member( mem ), aggregate( agg ) {239 assert( member );240 assert( aggregate );241 assert( aggregate->result );242 (void) overloadSelector;243 }244 245 bool MemberExpr::get_lvalue() const {246 // This is actually wrong by C, but it works with our current set-up.247 return true;248 }249 250 163 // --- VariableExpr 251 164 … … 257 170 assert( var ); 258 171 assert( var->get_type() ); 259 auto r = shallowCopy( var->get_type() ); 260 r->qualifiers |= CV::Lvalue; 261 result = r; 262 } 263 264 bool VariableExpr::get_lvalue() const { 265 // It isn't always an lvalue, but it is never an rvalue. 266 return true; 172 result = var->get_type(); 173 add_qualifiers( result, CV::Lvalue ); 267 174 } 268 175 … … 350 257 const CodeLocation & loc, const Expr * a1, const Expr * a2, LogicalFlag ia ) 351 258 : Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {} 352 353 // --- CommaExpr354 bool CommaExpr::get_lvalue() const {355 // This is wrong by C, but the current implementation uses it.356 // (ex: Specialize, Lvalue and Box)357 return arg2->get_lvalue();358 }359 259 360 260 // --- ConstructorExpr … … 379 279 } 380 280 381 bool CompoundLiteralExpr::get_lvalue() const {382 return true;383 }384 385 281 // --- TupleExpr 386 282 … … 398 294 result = type->types[ index ]; 399 295 add_qualifiers( result, CV::Lvalue ); 400 }401 402 bool TupleIndexExpr::get_lvalue() const {403 return tuple->get_lvalue();404 296 } 405 297
Note:
See TracChangeset
for help on using the changeset viewer.