Changeset 58fe85a for src/AST/Expr.cpp
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2b4daf2, 64aeca0
- Parents:
- 3c64c668 (diff), eef8dfb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
r3c64c668 r58fe85a 20 20 #include <vector> 21 21 22 #include "Copy.hpp" // for shallowCopy 23 #include "Eval.hpp" // for call 22 24 #include "GenericSubstitution.hpp" 25 #include "LinkageSpec.hpp" 23 26 #include "Stmt.hpp" 24 27 #include "Type.hpp" … … 27 30 #include "Common/SemanticError.h" 28 31 #include "GenPoly/Lvalue.h" // for referencesPermissable 29 #include "InitTweak/InitTweak.h" // for get PointerBase32 #include "InitTweak/InitTweak.h" // for getFunction, getPointerBase 30 33 #include "ResolvExpr/typeops.h" // for extractResultType 31 34 #include "Tuples/Tuples.h" // for makeTupleType 32 35 33 36 namespace ast { 37 38 namespace { 39 std::set<std::string> const lvalueFunctionNames = {"*?", "?[?]"}; 40 } 41 42 // --- Expr 43 bool Expr::get_lvalue() const { 44 return false; 45 } 34 46 35 47 // --- ApplicationExpr … … 46 58 } 47 59 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 48 67 // --- UntypedExpr 49 68 50 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, Expr * arg ) {69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, const Expr * arg ) { 51 70 assert( arg ); 52 71 53 UntypedExpr * ret = new UntypedExpr{ 54 loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } } 55 }; 72 UntypedExpr * ret = call( loc, "*?", arg ); 56 73 if ( const Type * ty = arg->result ) { 57 74 const Type * base = InitTweak::getPointerBase( ty ); … … 65 82 // base type 66 83 ret->result = base; 67 add_qualifiers( ret->result, CV::Lvalue );68 84 } 69 85 } … … 71 87 } 72 88 73 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) { 89 bool UntypedExpr::get_lvalue() const { 90 std::string fname = InitTweak::getFunctionName( this ); 91 return lvalueFunctionNames.count( fname ); 92 } 93 94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, const Expr * lhs, const Expr * rhs ) { 74 95 assert( lhs && rhs ); 75 96 76 UntypedExpr * ret = new UntypedExpr{ 77 loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } } 78 }; 97 UntypedExpr * ret = call( loc, "?=?", lhs, rhs ); 79 98 if ( lhs->result && rhs->result ) { 80 99 // if both expressions are typed, assumes that this assignment is a C bitwise assignment, … … 83 102 } 84 103 return ret; 104 } 105 106 // --- VariableExpr 107 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 pointer 126 VariableExpr * funcExpr = new VariableExpr{ loc, decl }; 127 funcExpr->result = new PointerType{ funcExpr->result }; 128 return funcExpr; 85 129 } 86 130 … … 108 152 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) { 109 153 if ( arg->result ) { 110 if ( arg-> result->is_lvalue() ) {154 if ( arg->get_lvalue() ) { 111 155 // lvalue, retains all levels of reference, and gains a pointer inside the references 112 156 Type * res = addrType( arg->result ); 113 res->set_lvalue( false ); // result of & is never an lvalue114 157 result = res; 115 158 } else { … … 118 161 dynamic_cast< const ReferenceType * >( arg->result.get() ) ) { 119 162 Type * res = addrType( refType->base ); 120 res->set_lvalue( false ); // result of & is never an lvalue121 163 result = res; 122 164 } else { … … 139 181 : Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {} 140 182 183 bool CastExpr::get_lvalue() const { 184 // This is actually wrong by C, but it works with our current set-up. 185 return arg->get_lvalue(); 186 } 187 141 188 // --- KeywordCastExpr 142 189 143 190 const char * KeywordCastExpr::targetString() const { 144 191 return AggregateDecl::aggrString( target ); 192 } 193 194 // --- UntypedMemberExpr 195 196 bool UntypedMemberExpr::get_lvalue() const { 197 return aggregate->get_lvalue(); 145 198 } 146 199 … … 153 206 assert( aggregate->result ); 154 207 155 // take ownership of member type156 208 result = mem->get_type(); 209 157 210 // substitute aggregate generic parameters into member type 158 211 genericSubstitution( aggregate->result ).apply( result ); 159 // ensure lvalue and appropriate restrictions from aggregate type 160 add_qualifiers( result, aggregate->result->qualifiers | CV::Lvalue ); 161 } 162 163 // --- VariableExpr 164 165 VariableExpr::VariableExpr( const CodeLocation & loc ) 166 : Expr( loc ), var( nullptr ) {} 167 168 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v ) 169 : Expr( loc ), var( v ) { 170 assert( var ); 171 assert( var->get_type() ); 172 result = var->get_type(); 173 add_qualifiers( result, CV::Lvalue ); 174 } 175 176 VariableExpr * VariableExpr::functionPointer( 177 const CodeLocation & loc, const FunctionDecl * decl ) { 178 // wrap usually-determined result type in a pointer 179 VariableExpr * funcExpr = new VariableExpr{ loc, decl }; 180 funcExpr->result = new PointerType{ funcExpr->result }; 181 return funcExpr; 212 // ensure appropriate restrictions from aggregate type 213 add_qualifiers( result, aggregate->result->qualifiers ); 214 } 215 216 MemberExpr::MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg, 217 MemberExpr::NoOpConstruction overloadSelector ) 218 : Expr( loc ), member( mem ), aggregate( agg ) { 219 assert( member ); 220 assert( aggregate ); 221 assert( aggregate->result ); 222 (void) overloadSelector; 223 } 224 225 bool MemberExpr::get_lvalue() const { 226 // This is actually wrong by C, but it works with our current set-up. 227 return true; 182 228 } 183 229 … … 258 304 : Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {} 259 305 306 // --- CommaExpr 307 bool CommaExpr::get_lvalue() const { 308 // This is wrong by C, but the current implementation uses it. 309 // (ex: Specialize, Lvalue and Box) 310 return arg2->get_lvalue(); 311 } 312 260 313 // --- ConstructorExpr 261 314 … … 276 329 assert( t && i ); 277 330 result = t; 278 add_qualifiers( result, CV::Lvalue ); 331 } 332 333 bool CompoundLiteralExpr::get_lvalue() const { 334 return true; 279 335 } 280 336 … … 293 349 // like MemberExpr, TupleIndexExpr is always an lvalue 294 350 result = type->types[ index ]; 295 add_qualifiers( result, CV::Lvalue ); 351 } 352 353 bool TupleIndexExpr::get_lvalue() const { 354 return tuple->get_lvalue(); 296 355 } 297 356
Note:
See TracChangeset
for help on using the changeset viewer.