Changeset f9ad69d
- Timestamp:
- Aug 14, 2024, 1:12:18 PM (4 months ago)
- Branches:
- master
- Children:
- 2f31773
- Parents:
- 1a2ba84
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/GenPoly.cpp
r1a2ba84 rf9ad69d 27 27 #include "AST/Type.hpp" 28 28 #include "AST/TypeSubstitution.hpp" 29 #include "Common/Eval.hpp" // for eval 29 30 #include "GenPoly/ErasableScopedMap.hpp" // for ErasableScopedMap<>::const_... 30 31 #include "ResolvExpr/Typeops.hpp" // for flatten … … 243 244 } // namespace 244 245 246 // This function, and its helpers following, have logic duplicated from 247 // unification. The difference in context is that unification applies where 248 // the types "must" match, while this variation applies to arbitrary type 249 // pairs, when an optimization could apply if they happen to match. This 250 // variation does not bind type variables. The helper functions support 251 // the case for matching ArrayType. 252 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ); 253 254 static bool exprsPolyCompatibleByStaticValue( 255 const ast::Expr * e1, const ast::Expr * e2 ) { 256 Evaluation r1 = eval(e1); 257 Evaluation r2 = eval(e2); 258 259 if ( !r1.hasKnownValue ) return false; 260 if ( !r2.hasKnownValue ) return false; 261 262 if ( r1.knownValue != r2.knownValue ) return false; 263 264 return true; 265 } 266 267 static bool exprsPolyCompatible( ast::Expr const * lhs, 268 ast::Expr const * rhs ) { 269 type_index const lid = typeid(*lhs); 270 type_index const rid = typeid(*rhs); 271 if ( lid != rid ) return false; 272 273 if ( exprsPolyCompatibleByStaticValue( lhs, rhs ) ) return true; 274 275 if ( type_index(typeid(ast::CastExpr)) == lid ) { 276 ast::CastExpr const * l = as<ast::CastExpr>(lhs); 277 ast::CastExpr const * r = as<ast::CastExpr>(rhs); 278 279 // inspect casts' target types 280 if ( !typesPolyCompatible( 281 l->result, r->result ) ) return false; 282 283 // inspect casts' inner expressions 284 return exprsPolyCompatible( l->arg, r->arg ); 285 286 } else if ( type_index(typeid(ast::VariableExpr)) == lid ) { 287 ast::VariableExpr const * l = as<ast::VariableExpr>(lhs); 288 ast::VariableExpr const * r = as<ast::VariableExpr>(rhs); 289 290 assert(l->var); 291 assert(r->var); 292 293 // conservative: variable exprs match if their declarations are 294 // represented by the same C++ AST object 295 return (l->var == r->var); 296 297 } else if ( type_index(typeid(ast::SizeofExpr)) == lid ) { 298 ast::SizeofExpr const * l = as<ast::SizeofExpr>(lhs); 299 ast::SizeofExpr const * r = as<ast::SizeofExpr>(rhs); 300 301 assert((l->type != nullptr) ^ (l->expr != nullptr)); 302 assert((r->type != nullptr) ^ (r->expr != nullptr)); 303 if ( !(l->type && r->type) ) return false; 304 305 // mutual recursion with type poly compatibility 306 return typesPolyCompatible( l->type, r->type ); 307 308 } else { 309 // All other forms compare on static value only, done earlier 310 return false; 311 } 312 } 313 245 314 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) { 246 315 type_index const lid = typeid(*lhs); … … 256 325 257 326 // So remaining types can be examined case by case. 258 // Recurse through type structure (conditions borrowed from Unify.cpp).327 // Recurse through type structure (conditions duplicated from Unify.cpp). 259 328 260 329 if ( type_index(typeid(ast::BasicType)) == lid ) { … … 280 349 ast::ArrayType const * r = as<ast::ArrayType>(rhs); 281 350 282 if ( l->isVarLen ) {283 if ( !r->isVarLen ) return false;284 } else {285 if ( r->isVarLen ) return false; 286 287 a uto lc = l->dimension.as<ast::ConstantExpr>();288 auto rc = r->dimension.as<ast::ConstantExpr>();289 if ( lc && rc && lc->intValue() != rc->intValue() ) {351 if ( l->isVarLen != r->isVarLen ) return false; 352 if ( (l->dimension != nullptr) != (r->dimension != nullptr) ) 353 return false; 354 355 if ( l->dimension ) { 356 assert( r->dimension ); 357 // mutual recursion with expression poly compatibility 358 if ( !exprsPolyCompatible(l->dimension, r->dimension) ) 290 359 return false; 291 }292 360 } 293 361
Note: See TracChangeset
for help on using the changeset viewer.