Ignore:
Timestamp:
Sep 21, 2022, 11:02:15 AM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
95dab9e
Parents:
428adbc (diff), 0bd46fd (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.
Message:

Merge branch 'master' into pthread-emulation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    r428adbc r7f6a7c9  
    165165                ast::Type * newFirst  = shallowCopy( first  );
    166166                ast::Type * newSecond = shallowCopy( second );
     167                if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) {
     168                        if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) {
     169                                const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
     170                                if ( auto t = baseEnum->base.get() ) {
     171                                        newFirst = ast::shallowCopy( t );
     172                                }
     173                        }
     174                } else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) {
     175                        const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
     176                        if ( auto t = baseEnum->base.get() ) {
     177                                newSecond = ast::shallowCopy( t );
     178                        }
     179                }
     180
    167181                newFirst ->qualifiers = {};
    168182                newSecond->qualifiers = {};
     
    693707        }
    694708
     709        namespace {
     710                                /// Replaces ttype variables with their bound types.
     711                /// If this isn't done when satifying ttype assertions, then argument lists can have
     712                /// different size and structure when they should be compatible.
     713                struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor {
     714                        ast::TypeEnvironment & tenv;
     715
     716                        TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}
     717
     718                        const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
     719                                if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) {
     720                                        // expand ttype parameter into its actual type
     721                                        if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {
     722                                                return clz->bound;
     723                                        }
     724                                }
     725                                return typeInst;
     726                        }
     727                };
     728        }
     729
     730        std::vector< ast::ptr< ast::Type > > flattenList(
     731                const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
     732        ) {
     733                std::vector< ast::ptr< ast::Type > > dst;
     734                dst.reserve( src.size() );
     735                for ( const auto & d : src ) {
     736                        ast::Pass<TtypeExpander_new> expander{ env };
     737                        // TtypeExpander pass is impure (may mutate nodes in place)
     738                        // need to make nodes shared to prevent accidental mutation
     739                        ast::ptr<ast::Type> dc = d->accept(expander);
     740                        auto types = flatten( dc );
     741                        for ( ast::ptr< ast::Type > & t : types ) {
     742                                // outermost const, volatile, _Atomic qualifiers in parameters should not play
     743                                // a role in the unification of function types, since they do not determine
     744                                // whether a function is callable.
     745                                // NOTE: **must** consider at least mutex qualifier, since functions can be
     746                                // overloaded on outermost mutex and a mutex function has different
     747                                // requirements than a non-mutex function
     748                                remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
     749                                dst.emplace_back( t );
     750                        }
     751                }
     752                return dst;
     753        }
     754
    695755        class Unify_new final : public ast::WithShortCircuiting {
    696756                const ast::Type * type2;
     
    764824
    765825        private:
    766                 /// Replaces ttype variables with their bound types.
    767                 /// If this isn't done when satifying ttype assertions, then argument lists can have
    768                 /// different size and structure when they should be compatible.
    769                 struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor {
    770                         ast::TypeEnvironment & tenv;
    771 
    772                         TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}
    773 
    774                         const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
    775                                 if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) {
    776                                         // expand ttype parameter into its actual type
    777                                         if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {
    778                                                 return clz->bound;
    779                                         }
    780                                 }
    781                                 return typeInst;
    782                         }
    783                 };
    784 
    785                 /// returns flattened version of `src`
    786                 static std::vector< ast::ptr< ast::Type > > flattenList(
    787                         const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
    788                 ) {
    789                         std::vector< ast::ptr< ast::Type > > dst;
    790                         dst.reserve( src.size() );
    791                         for ( const auto & d : src ) {
    792                                 ast::Pass<TtypeExpander_new> expander{ env };
    793                                 // TtypeExpander pass is impure (may mutate nodes in place)
    794                                 // need to make nodes shared to prevent accidental mutation
    795                                 ast::ptr<ast::Type> dc = d->accept(expander);
    796                                 auto types = flatten( dc );
    797                                 for ( ast::ptr< ast::Type > & t : types ) {
    798                                         // outermost const, volatile, _Atomic qualifiers in parameters should not play
    799                                         // a role in the unification of function types, since they do not determine
    800                                         // whether a function is callable.
    801                                         // NOTE: **must** consider at least mutex qualifier, since functions can be
    802                                         // overloaded on outermost mutex and a mutex function has different
    803                                         // requirements than a non-mutex function
    804                                         remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
    805                                         dst.emplace_back( t );
    806                                 }
    807                         }
    808                         return dst;
    809                 }
    810 
    811                 /// Creates a tuple type based on a list of DeclWithType
    812                 template< typename Iter >
    813                 static const ast::Type * tupleFromTypes( Iter crnt, Iter end ) {
    814                         std::vector< ast::ptr< ast::Type > > types;
    815                         while ( crnt != end ) {
    816                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    817                                 // that this results in a flat tuple
    818                                 flatten( *crnt, types );
    819 
    820                                 ++crnt;
    821                         }
    822 
    823                         return new ast::TupleType{ std::move(types) };
    824                 }
    825826
    826827                template< typename Iter >
     
    10341035        private:
    10351036                /// Creates a tuple type based on a list of Type
    1036                 static const ast::Type * tupleFromTypes(
    1037                         const std::vector< ast::ptr< ast::Type > > & tys
    1038                 ) {
    1039                         std::vector< ast::ptr< ast::Type > > out;
    1040                         for ( const ast::Type * ty : tys ) {
    1041                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    1042                                 // that this results in a flat tuple
    1043                                 flatten( ty, out );
    1044                         }
    1045 
    1046                         return new ast::TupleType{ std::move(out) };
    1047                 }
     1037
    10481038
    10491039                static bool unifyList(
     
    12171207                        }
    12181208
    1219                 } else if (( common = commonType( t1, t2, widen, symtab, env, open ) )) {
     1209                } else if (( common = commonType( t1, t2, env, need, have, open, widen, symtab ))) {
    12201210                        // no exact unification, but common type
    12211211                        auto c = shallowCopy(common.get());
Note: See TracChangeset for help on using the changeset viewer.