Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cpp

    rf9ad69d r5f225f5  
    2727#include "AST/Type.hpp"
    2828#include "AST/TypeSubstitution.hpp"
    29 #include "Common/Eval.hpp"                // for eval
    3029#include "GenPoly/ErasableScopedMap.hpp"  // for ErasableScopedMap<>::const_...
    3130#include "ResolvExpr/Typeops.hpp"         // for flatten
     
    244243} // namespace
    245244
    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 
    314245bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) {
    315246        type_index const lid = typeid(*lhs);
     
    325256
    326257        // So remaining types can be examined case by case.
    327         // Recurse through type structure (conditions duplicated from Unify.cpp).
     258        // Recurse through type structure (conditions borrowed from Unify.cpp).
    328259
    329260        if ( type_index(typeid(ast::BasicType)) == lid ) {
     
    349280                ast::ArrayType const * r = as<ast::ArrayType>(rhs);
    350281
    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) )
     282                if ( l->isVarLen ) {
     283                        if ( !r->isVarLen ) return false;
     284                } else {
     285                        if ( r->isVarLen ) return false;
     286
     287                        auto lc = l->dimension.as<ast::ConstantExpr>();
     288                        auto rc = r->dimension.as<ast::ConstantExpr>();
     289                        if ( lc && rc && lc->intValue() != rc->intValue() ) {
    359290                                return false;
     291                        }
    360292                }
    361293
Note: See TracChangeset for help on using the changeset viewer.