Changeset d4b6638 for src/ResolvExpr


Ignore:
Timestamp:
Jun 5, 2019, 11:24:29 AM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2a8f0c1, 300fbee
Parents:
4741dfe (diff), 0e42794 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r4741dfe rd4b6638  
    1818#include <utility>                       // for pair
    1919
     20#include "AST/Decl.hpp"
     21#include "AST/Type.hpp"
    2022#include "Common/PassVisitor.h"
    2123#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    3537
    3638namespace ResolvExpr {
    37         struct CommonType : public WithShortCircuiting {
    38                 CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     39        struct CommonType_old : public WithShortCircuiting {
     40                CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    3941                Type *get_result() const { return result; }
    4042
     
    9496
    9597        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
    96                 PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
     98                PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    9799
    98100                int depth1 = type1->referenceDepth();
     
    176178        }
    177179
    178         const ast::Type * commonType(
    179                         const ast::Type * type1, const ast::Type * type2, WidenMode widen,
    180                         const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
    181                         const ast::OpenVarSet & open ) {
    182                 #warning unimplemented
    183                 (void)type1; (void)type2; (void)widen; (void)symtab; (void)env; (void)open;
    184                 assert(false);
    185                 return nullptr;
    186         }
    187 
    188180        // GENERATED START, DO NOT EDIT
    189181        // GENERATED BY BasicTypes-gen.cc
     
    493485        );
    494486
    495         CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     487        CommonType_old::CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    496488                : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
    497489        }
    498490
    499         void CommonType::postvisit( VoidType * ) {}
    500 
    501         void CommonType::postvisit( BasicType *basicType ) {
     491        void CommonType_old::postvisit( VoidType * ) {}
     492
     493        void CommonType_old::postvisit( BasicType *basicType ) {
    502494                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    503495                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
     
    515507
    516508        template< typename Pointer >
    517         void CommonType::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
     509        void CommonType_old::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
    518510                if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
    519511                        OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
     
    528520        }
    529521
    530         void CommonType::postvisit( PointerType *pointerType ) {
     522        void CommonType_old::postvisit( PointerType *pointerType ) {
    531523                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    532524                        // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
     
    563555        }
    564556
    565         void CommonType::postvisit( ArrayType * ) {}
    566 
    567         void CommonType::postvisit( ReferenceType *refType ) {
     557        void CommonType_old::postvisit( ArrayType * ) {}
     558
     559        void CommonType_old::postvisit( ReferenceType *refType ) {
    568560                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
    569561                        // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
     
    600592        }
    601593
    602         void CommonType::postvisit( FunctionType * ) {}
    603         void CommonType::postvisit( StructInstType * ) {}
    604         void CommonType::postvisit( UnionInstType * ) {}
    605 
    606         void CommonType::postvisit( EnumInstType *enumInstType ) {
     594        void CommonType_old::postvisit( FunctionType * ) {}
     595        void CommonType_old::postvisit( StructInstType * ) {}
     596        void CommonType_old::postvisit( UnionInstType * ) {}
     597
     598        void CommonType_old::postvisit( EnumInstType *enumInstType ) {
    607599                if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
    608600                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
     
    611603        }
    612604
    613         void CommonType::postvisit( TraitInstType * ) {
    614         }
    615 
    616         void CommonType::postvisit( TypeInstType *inst ) {
     605        void CommonType_old::postvisit( TraitInstType * ) {
     606        }
     607
     608        void CommonType_old::postvisit( TypeInstType *inst ) {
    617609                if ( widenFirst ) {
    618610                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     
    636628        }
    637629
    638         void CommonType::postvisit( TupleType * ) {}
    639         void CommonType::postvisit( VarArgsType * ) {}
    640 
    641         void CommonType::postvisit( ZeroType *zeroType ) {
     630        void CommonType_old::postvisit( TupleType * ) {}
     631        void CommonType_old::postvisit( VarArgsType * ) {}
     632
     633        void CommonType_old::postvisit( ZeroType *zeroType ) {
    642634                if ( widenFirst ) {
    643635                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
     
    653645        }
    654646
    655         void CommonType::postvisit( OneType *oneType ) {
     647        void CommonType_old::postvisit( OneType *oneType ) {
    656648                if ( widenFirst ) {
    657649                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
     
    666658                }
    667659        }
     660
     661        class CommonType_new final : public ast::WithShortCircuiting {
     662                const ast::Type * type2;
     663                WidenMode widen;
     664                const ast::SymbolTable & symtab;
     665                ast::TypeEnvironment & tenv;
     666                const ast::OpenVarSet & open;
     667        public:
     668                ast::ptr< ast::Type > result;
     669
     670                CommonType_new(
     671                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
     672                        ast::TypeEnvironment & env, const ast::OpenVarSet & o )
     673                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
     674
     675                void previsit( const ast::Node * ) { visit_children = false; }
     676
     677                void postvisit( const ast::VoidType * ) {}
     678
     679                void postvisit( const ast::BasicType * basic ) {
     680                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
     681                                #warning remove casts when `commonTypes` moved to new AST
     682                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
     683                                if (
     684                                        ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
     685                                                || widen.first )
     686                                        && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
     687                                                || widen.second )
     688                                ) {
     689                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
     690                                }
     691                        } else if (
     692                                dynamic_cast< const ast::EnumInstType * >( type2 )
     693                                || dynamic_cast< const ast::ZeroType * >( type2 )
     694                                || dynamic_cast< const ast::OneType * >( type2 )
     695                        ) {
     696                                #warning remove casts when `commonTypes` moved to new AST
     697                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
     698                                if (
     699                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     700                                                || widen.first )
     701                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
     702                                                || widen.second )
     703                                ) {
     704                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     705                                }
     706                        }
     707                }
     708
     709        private:
     710                template< typename Pointer >
     711                void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
     712                        const ast::Type * base = oPtr->base;
     713                        if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
     714                                auto entry = open.find( var->name );
     715                                if ( entry != open.end() ) {
     716                                        ast::AssertionSet need, have;
     717                                        if ( ! tenv.bindVar(
     718                                                var, voidPtr->base, entry->second, need, have, open, widen, symtab )
     719                                        ) return;
     720                                }
     721                        }
     722                        result = voidPtr;
     723                        add_qualifiers( result, oPtr->qualifiers );
     724                }
     725
     726        public:
     727                void postvisit( const ast::PointerType * pointer ) {
     728                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
     729                                if (
     730                                        widen.first
     731                                        && pointer2->base.as< ast::VoidType >()
     732                                        && ! ast::isFtype( pointer->base )
     733                                ) {
     734                                        getCommonWithVoidPointer( pointer2, pointer );
     735                                } else if (
     736                                        widen.second
     737                                        && pointer->base.as< ast::VoidType >()
     738                                        && ! ast::isFtype( pointer2->base )
     739                                ) {
     740                                        getCommonWithVoidPointer( pointer, pointer2 );
     741                                } else if (
     742                                        ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
     743                                        && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
     744                                ) {
     745                                        ast::CV::Qualifiers q1 = pointer->base->qualifiers;
     746                                        ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
     747
     748                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     749                                        // pointer{,2}->base are unchanged
     750                                        ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
     751                                        reset_qualifiers( t1 );
     752                                        reset_qualifiers( t2 );
     753                                       
     754                                        ast::AssertionSet have, need;
     755                                        ast::OpenVarSet newOpen{ open };
     756                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     757                                                result = pointer;
     758                                                if ( q1.val != q2.val ) {
     759                                                        // reset result->base->qualifiers to be union of two base qualifiers
     760                                                        strict_dynamic_cast< ast::PointerType * >(
     761                                                                result.get_and_mutate()
     762                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
     763                                                }
     764                                        }
     765                                }
     766                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     767                                result = pointer;
     768                                add_qualifiers( result, type2->qualifiers );
     769                        }
     770                }
     771
     772                void postvisit( const ast::ArrayType * ) {}
     773
     774                void postvisit( const ast::ReferenceType * ref ) {
     775                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
     776                                if (
     777                                        widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
     778                                ) {
     779                                        getCommonWithVoidPointer( ref2, ref );
     780                                } else if (
     781                                        widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
     782                                ) {
     783                                        getCommonWithVoidPointer( ref, ref2 );
     784                                } else if (
     785                                        ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
     786                                        && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
     787                                ) {
     788                                        ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
     789
     790                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     791                                        // ref{,2}->base are unchanged
     792                                        ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
     793                                        reset_qualifiers( t1 );
     794                                        reset_qualifiers( t2 );
     795
     796                                        ast::AssertionSet have, need;
     797                                        ast::OpenVarSet newOpen{ open };
     798                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     799                                                result = ref;
     800                                                if ( q1.val != q2.val ) {
     801                                                        // reset result->base->qualifiers to be union of two base qualifiers
     802                                                        strict_dynamic_cast< ast::ReferenceType * >(
     803                                                                result.get_and_mutate()
     804                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
     805                                                }
     806                                        }
     807                                }
     808                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     809                                result = ref;
     810                                add_qualifiers( result, type2->qualifiers );
     811                        }
     812                }
     813
     814                void postvisit( const ast::FunctionType * ) {}
     815
     816                void postvisit( const ast::StructInstType * ) {}
     817
     818                void postvisit( const ast::UnionInstType * ) {}
     819
     820                void postvisit( const ast::EnumInstType * enumInst ) {
     821                        if (
     822                                dynamic_cast< const ast::BasicType * >( type2 )
     823                                || dynamic_cast< const ast::ZeroType * >( type2 )
     824                                || dynamic_cast< const ast::OneType * >( type2 )
     825                        ) {
     826                                // reuse BasicType/EnumInstType common type by swapping
     827                                result = commonType( type2, enumInst, widen, symtab, tenv, open );
     828                        }
     829                }
     830
     831                void postvisit( const ast::TraitInstType * ) {}
     832
     833                void postvisit( const ast::TypeInstType * inst ) {
     834                        if ( ! widen.first ) return;
     835                        if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
     836                                if ( const ast::Type * base =
     837                                                strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
     838                                ) {
     839                                        ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
     840
     841                                        // force t{1,2} to be cloned if their qualifiers must be mutated
     842                                        ast::ptr< ast::Type > t1{ base }, t2{ type2 };
     843                                        reset_qualifiers( t1, q1 );
     844                                        reset_qualifiers( t2 );
     845
     846                                        ast::AssertionSet have, need;
     847                                        ast::OpenVarSet newOpen{ open };
     848                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     849                                                result = type2;
     850                                                reset_qualifiers( result, q1 | q2 );
     851                                        }
     852                                }
     853                        }
     854                }
     855
     856                void postvisit( const ast::TupleType * ) {}
     857
     858                void postvisit( const ast::VarArgsType * ) {}
     859
     860                void postvisit( const ast::ZeroType * zero ) {
     861                        if ( ! widen.first ) return;
     862                        if (
     863                                dynamic_cast< const ast::BasicType * >( type2 )
     864                                || dynamic_cast< const ast::PointerType * >( type2 )
     865                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     866                        ) {
     867                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
     868                                        result = type2;
     869                                        add_qualifiers( result, zero->qualifiers );
     870                                }
     871                        } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
     872                                result = new ast::BasicType{
     873                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
     874                        }
     875                }
     876
     877                void postvisit( const ast::OneType * one ) {
     878                        if ( ! widen.first ) return;
     879                        if (
     880                                dynamic_cast< const ast::BasicType * >( type2 )
     881                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     882                        ) {
     883                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
     884                                        result = type2;
     885                                        add_qualifiers( result, one->qualifiers );
     886                                }
     887                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     888                                result = new ast::BasicType{
     889                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
     890                        }
     891                }
     892
     893        };
     894
     895        namespace {
     896                ast::ptr< ast::Type > handleReference(
     897                        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
     898                        const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     899                        const ast::OpenVarSet & open
     900                ) {
     901                        ast::ptr<ast::Type> common;
     902                        ast::AssertionSet have, need;
     903                        ast::OpenVarSet newOpen{ open };
     904
     905                        // need unify to bind type variables
     906                        if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) {
     907                                ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
     908                                PRINT(
     909                                        std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
     910                                )
     911                                if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
     912                                        PRINT(
     913                                                std::cerr << "widen okay" << std::endl;
     914                                        )
     915                                        add_qualifiers( common, q1 | q2 );
     916                                        return common;
     917                                }
     918                        }
     919
     920                        PRINT(
     921                                std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
     922                        )
     923                        return { nullptr };
     924                }
     925        }
     926
     927        ast::ptr< ast::Type > commonType(
     928                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
     929                        WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     930                        const ast::OpenVarSet & open
     931        ) {
     932                unsigned depth1 = type1->referenceDepth();
     933                unsigned depth2 = type2->referenceDepth();
     934
     935                if ( depth1 != depth2 ) {  // implies depth1 > 0 || depth2 > 0
     936                        PRINT(
     937                                std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
     938                        )
     939                        ast::ptr< ast::Type > result;
     940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
     941                        const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >();
     942                       
     943                        if ( depth1 > depth2 ) {
     944                                assert( ref1 );
     945                                result = handleReference( ref1->base, type2, widen, symtab, env, open );
     946                        } else {  // implies depth1 < depth2
     947                                assert( ref2 );
     948                                result = handleReference( type1, ref2->base, widen, symtab, env, open );
     949                        }
     950
     951                        if ( result && ref1 ) {
     952                                // formal is reference, so result should be reference
     953                                PRINT(
     954                                        std::cerr << "formal is reference; result should be reference" << std::endl;
     955                                )
     956                                result = new ast::ReferenceType{ result, ref1->qualifiers };
     957                        }
     958
     959                        PRINT(
     960                                std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
     961                                "[" << result << "]" << std::endl;
     962                        )
     963                        return result;
     964                }
     965                // otherwise both are reference types of the same depth and this is handled by the visitor
     966                ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };
     967                type1->accept( visitor );
     968                ast::ptr< ast::Type > result = visitor.pass.result;
     969
     970                // handling for opaque type declarations (?)
     971                if ( ! result && widen.second ) {
     972                        if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) {
     973                                if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
     974                                        auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt );
     975                                        if ( type->base ) {
     976                                                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
     977                                                ast::AssertionSet have, need;
     978                                                ast::OpenVarSet newOpen{ open };
     979
     980                                                // force t{1,2} to be cloned if its qualifiers must be stripped, so that
     981                                                // type1 and type->base are left unchanged; calling convention forces
     982                                                // {type1,type->base}->strong_ref >= 1
     983                                                ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
     984                                                reset_qualifiers( t1 );
     985                                                reset_qualifiers( t2, q1 );
     986                                               
     987                                                if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
     988                                                        result = t1;
     989                                                        reset_qualifiers( result, q1 | q2 );
     990                                                }
     991                                        }
     992                                }
     993                        }
     994                }
     995
     996                return result;
     997        }
     998
    668999} // namespace ResolvExpr
    6691000
  • src/ResolvExpr/FindOpenVars.cc

    r4741dfe rd4b6638  
    1919#include <map>                    // for map<>::mapped_type
    2020
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
    2123#include "Common/PassVisitor.h"
    2224#include "SynTree/Declaration.h"  // for TypeDecl, DeclarationWithType (ptr ...
     
    2426
    2527namespace ResolvExpr {
    26         struct FindOpenVars : public WithGuards {
    27                 FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
     28        struct FindOpenVars_old : public WithGuards {
     29                FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    2830
    2931                void previsit( PointerType * pointerType );
     
    4042
    4143        void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
    42                 PassVisitor<FindOpenVars> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
     44                PassVisitor<FindOpenVars_old> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
    4345                type->accept( finder );
    4446        }
    4547
    46         FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
     48        FindOpenVars_old::FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
    4749                : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen ) {
    4850        }
    4951
    50         void FindOpenVars::common_action( Type *type ) {
     52        void FindOpenVars_old::common_action( Type *type ) {
    5153                if ( nextIsOpen ) {
    5254                        for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     
    7678        }
    7779
    78         void FindOpenVars::previsit(PointerType *pointerType) {
     80        void FindOpenVars_old::previsit(PointerType *pointerType) {
    7981                common_action( pointerType );
    8082        }
    8183
    82         void FindOpenVars::previsit(ArrayType *arrayType) {
     84        void FindOpenVars_old::previsit(ArrayType *arrayType) {
    8385                common_action( arrayType );
    8486        }
    8587
    86         void FindOpenVars::previsit(FunctionType *functionType) {
     88        void FindOpenVars_old::previsit(FunctionType *functionType) {
    8789                common_action( functionType );
    8890                nextIsOpen = ! nextIsOpen;
     
    9092        }
    9193
    92         void FindOpenVars::previsit(TupleType *tupleType) {
     94        void FindOpenVars_old::previsit(TupleType *tupleType) {
    9395                common_action( tupleType );
     96        }
     97
     98        namespace {
     99                struct FindOpenVars_new final : public ast::WithGuards {
     100                        ast::OpenVarSet & open;
     101                        ast::OpenVarSet & closed;
     102                        ast::AssertionSet & need;
     103                        ast::AssertionSet & have;
     104                        bool nextIsOpen;
     105
     106                        FindOpenVars_new(
     107                                ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n,
     108                                ast::AssertionSet & h, FirstMode firstIsOpen )
     109                        : open( o ), closed( c ), need( n ), have( h ), nextIsOpen( firstIsOpen ) {}
     110
     111                        void previsit( const ast::FunctionType * type ) {
     112                                // mark open/closed variables
     113                                if ( nextIsOpen ) {
     114                                        for ( const ast::TypeDecl * decl : type->forall ) {
     115                                                open[ decl->name ] = ast::TypeDecl::Data{ decl };
     116                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
     117                                                        need[ assert ].isUsed = false;
     118                                                }
     119                                        }
     120                                } else {
     121                                        for ( const ast::TypeDecl * decl : type->forall ) {
     122                                                closed[ decl->name ] = ast::TypeDecl::Data{ decl };
     123                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
     124                                                        have[ assert ].isUsed = false;
     125                                                }
     126                                        }
     127                                }
     128
     129                                // flip open variables for contained function types
     130                                nextIsOpen = ! nextIsOpen;
     131                                GuardAction( [this](){ nextIsOpen = ! nextIsOpen; } );
     132                        }
     133
     134                };
    94135        }
    95136
     
    97138                        const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed,
    98139                        ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ) {
    99                 #warning unimplemented
    100                 (void)type; (void)open; (void)closed; (void)need; (void)have; (void)firstIsOpen;
    101                 assert(false);
     140                ast::Pass< FindOpenVars_new > finder{ open, closed, need, have, firstIsOpen };
     141                type->accept( finder );
    102142        }
    103143} // namespace ResolvExpr
  • src/ResolvExpr/Resolver.cc

    r4741dfe rd4b6638  
    938938
    939939        class Resolver_new final
    940         : public ast::WithIndexer, public ast::WithGuards, public ast::WithVisitorRef<Resolver_new>,
    941           public ast::WithShortCircuiting, public ast::WithStmtsToAdd<> {
     940        : public ast::WithSymbolTable, public ast::WithGuards,
     941          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     942          public ast::WithStmtsToAdd<> {
    942943                 
    943944        public:
    944945                Resolver_new() = default;
    945                 Resolver_new( const ast::SymbolTable & syms ) { /*symtab = syms;*/ }
     946                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    946947
    947948                void previsit( ast::FunctionDecl * functionDecl );
  • src/ResolvExpr/Unify.cc

    r4741dfe rd4b6638  
    136136
    137137                return unifyExact(
    138                         newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );
     138                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    139139        }
    140140
     
    173173                env.apply( newFirst );
    174174                env.apply( newSecond );
    175                 clear_qualifiers( newFirst );
    176                 clear_qualifiers( newSecond );
     175                reset_qualifiers( newFirst );
     176                reset_qualifiers( newSecond );
    177177
    178178                return unifyExact(
    179                         newFirst, newSecond, newEnv, need, have, open, WidenMode{ false, false }, symtab );
     179                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    180180        }
    181181
     
    700700        }
    701701
    702         class Unify_new : public ast::WithShortCircuiting {
     702        class Unify_new final : public ast::WithShortCircuiting {
    703703                const ast::Type * type2;
    704704                ast::TypeEnvironment & tenv;
     
    720720                void previsit( const ast::Node * ) { visit_children = false; }
    721721               
    722                 void previsit( const ast::VoidType * ) {
    723                         visit_children = false;
     722                void postvisit( const ast::VoidType * ) {
    724723                        result = dynamic_cast< const ast::VoidType * >( type2 );
    725724                }
    726725
    727                 void previsit( const ast::BasicType * basic ) {
    728                         visit_children = false;
     726                void postvisit( const ast::BasicType * basic ) {
    729727                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
    730728                                result = basic->kind == basic2->kind;
     
    732730                }
    733731
    734                 void previsit( const ast::PointerType * pointer ) {
    735                         visit_children = false;
     732                void postvisit( const ast::PointerType * pointer ) {
    736733                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    737734                                result = unifyExact(
    738735                                        pointer->base, pointer2->base, tenv, need, have, open,
    739                                         WidenMode{ false, false }, symtab );
    740                         }
    741                 }
    742 
    743                 void previsit( const ast::ArrayType * array ) {
    744                         visit_children = false;
     736                                        noWiden(), symtab );
     737                        }
     738                }
     739
     740                void postvisit( const ast::ArrayType * array ) {
    745741                        auto array2 = dynamic_cast< const ast::ArrayType * >( type2 );
    746742                        if ( ! array2 ) return;
     
    761757
    762758                        result = unifyExact(
    763                                 array->base, array2->base, tenv, need, have, open, WidenMode{ false, false },
     759                                array->base, array2->base, tenv, need, have, open, noWiden(),
    764760                                symtab );
    765761                }
    766762
    767                 void previsit( const ast::ReferenceType * ref ) {
    768                         visit_children = false;
     763                void postvisit( const ast::ReferenceType * ref ) {
    769764                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    770765                                result = unifyExact(
    771                                         ref->base, ref2->base, tenv, need, have, open, WidenMode{ false, false },
     766                                        ref->base, ref2->base, tenv, need, have, open, noWiden(),
    772767                                        symtab );
    773768                        }
     
    783778                        TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}
    784779
    785                         const ast::Type * postmutate( const ast::TypeInstType * typeInst ) {
     780                        const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
    786781                                if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) {
    787782                                        // expand ttype parameter into its actual type
     
    811806                                        // overloaded on outermost mutex and a mutex function has different
    812807                                        // requirements than a non-mutex function
    813                                         t.get_and_mutate()->qualifiers
    814                                                 -= ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic;
     808                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
    815809                                        dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } );
    816810                                }
     
    851845                                        return unifyExact(
    852846                                                t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    853                                                 WidenMode{ false, false }, symtab );
     847                                                noWiden(), symtab );
    854848                                } else if ( ! isTuple1 && isTuple2 ) {
    855849                                        // combine remainder of list1, then unify
    856850                                        return unifyExact(
    857851                                                tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    858                                                 WidenMode{ false, false }, symtab );
     852                                                noWiden(), symtab );
    859853                                }
    860854
    861855                                if ( ! unifyExact(
    862                                         t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )
     856                                        t1, t2, env, need, have, open, noWiden(), symtab )
    863857                                ) return false;
    864858
     
    874868                                return unifyExact(
    875869                                        t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    876                                         WidenMode{ false, false }, symtab );
     870                                        noWiden(), symtab );
    877871                        } else if ( crnt2 != end2 ) {
    878872                                // try unifying empty tuple with ttype
     
    881875                                return unifyExact(
    882876                                        tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    883                                         WidenMode{ false, false }, symtab );
     877                                        noWiden(), symtab );
    884878                        }
    885879
     
    919913
    920914        public:
    921                 void previsit( const ast::FunctionType * func ) {
    922                         visit_children = false;
     915                void postvisit( const ast::FunctionType * func ) {
    923916                        auto func2 = dynamic_cast< const ast::FunctionType * >( type2 );
    924917                        if ( ! func2 ) return;
     
    952945                template< typename RefType >
    953946                const RefType * handleRefType( const RefType * inst, const ast::Type * other ) {
    954                         visit_children = false;
    955947                        // check that the other type is compatible and named the same
    956948                        auto otherInst = dynamic_cast< const RefType * >( other );
     
    10111003
    10121004                                if ( ! unifyExact(
    1013                                                 pty, pty2, tenv, need, have, open, WidenMode{ false, false }, symtab ) ) {
     1005                                                pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
    10141006                                        result = false;
    10151007                                        return;
     
    10231015
    10241016        public:
    1025                 void previsit( const ast::StructInstType * aggrType ) {
     1017                void postvisit( const ast::StructInstType * aggrType ) {
    10261018                        handleGenericRefType( aggrType, type2 );
    10271019                }
    10281020
    1029                 void previsit( const ast::UnionInstType * aggrType ) {
     1021                void postvisit( const ast::UnionInstType * aggrType ) {
    10301022                        handleGenericRefType( aggrType, type2 );
    10311023                }
    10321024
    1033                 void previsit( const ast::EnumInstType * aggrType ) {
     1025                void postvisit( const ast::EnumInstType * aggrType ) {
    10341026                        handleRefType( aggrType, type2 );
    10351027                }
    10361028
    1037                 void previsit( const ast::TraitInstType * aggrType ) {
     1029                void postvisit( const ast::TraitInstType * aggrType ) {
    10381030                        handleRefType( aggrType, type2 );
    10391031                }
    10401032
    1041                 void previsit( const ast::TypeInstType * typeInst ) {
     1033                void postvisit( const ast::TypeInstType * typeInst ) {
    10421034                        assert( open.find( typeInst->name ) == open.end() );
    10431035                        handleRefType( typeInst, type2 );
     
    10781070                                        return unifyExact(
    10791071                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1080                                                 WidenMode{ false, false }, symtab );
     1072                                                noWiden(), symtab );
    10811073                                } else if ( ! isTuple1 && isTuple2 ) {
    10821074                                        // combine entirety of list1, then unify
    10831075                                        return unifyExact(
    10841076                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1085                                                 WidenMode{ false, false }, symtab );
     1077                                                noWiden(), symtab );
    10861078                                }
    10871079
    10881080                                if ( ! unifyExact(
    1089                                         t1, t2, env, need, have, open, WidenMode{ false, false }, symtab )
     1081                                        t1, t2, env, need, have, open, noWiden(), symtab )
    10901082                                ) return false;
    10911083
     
    11011093                                return unifyExact(
    11021094                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    1103                                                 WidenMode{ false, false }, symtab );
     1095                                                noWiden(), symtab );
    11041096                        } else if ( crnt2 != list2.end() ) {
    11051097                                // try unifying empty tuple with ttype
     
    11101102                                return unifyExact(
    11111103                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    1112                                                 WidenMode{ false, false }, symtab );
     1104                                                noWiden(), symtab );
    11131105                        }
    11141106
     
    11171109
    11181110        public:
    1119                 void previsit( const ast::TupleType * tuple ) {
    1120                         visit_children = false;
     1111                void postvisit( const ast::TupleType * tuple ) {
    11211112                        auto tuple2 = dynamic_cast< const ast::TupleType * >( type2 );
    11221113                        if ( ! tuple2 ) return;
     
    11321123                }
    11331124
    1134                 void previsit( const ast::VarArgsType * ) {
    1135                         visit_children = false;
     1125                void postvisit( const ast::VarArgsType * ) {
    11361126                        result = dynamic_cast< const ast::VarArgsType * >( type2 );
    11371127                }
    11381128
    1139                 void previsit( const ast::ZeroType * ) {
    1140                         visit_children = false;
     1129                void postvisit( const ast::ZeroType * ) {
    11411130                        result = dynamic_cast< const ast::ZeroType * >( type2 );
    11421131                }
    11431132
    1144                 void previsit( const ast::OneType * ) {
    1145                         visit_children = false;
     1133                void postvisit( const ast::OneType * ) {
    11461134                        result = dynamic_cast< const ast::OneType * >( type2 );
    11471135                }       
     
    11511139                template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
    11521140        };
     1141
     1142        bool unify(
     1143                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1144                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1145                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1146        ) {
     1147                ast::OpenVarSet closed;
     1148                findOpenVars( type1, open, closed, need, have, FirstClosed );
     1149                findOpenVars( type2, open, closed, need, have, FirstOpen );
     1150                return unifyInexact(
     1151                        type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
     1152        }
    11531153
    11541154        bool unifyExact(
     
    11841184
    11851185        bool unifyInexact(
    1186                         ast::ptr<ast::Type> & type1, ast::ptr<ast::Type> & type2, ast::TypeEnvironment & env,
    1187                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    1188                         WidenMode widen, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1186                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1187                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1188                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     1189                        ast::ptr<ast::Type> & common
    11891190        ) {
    11901191                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
     
    11931194                // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
    11941195                ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
    1195                 clear_qualifiers( t1 );
    1196                 clear_qualifiers( t2 );
     1196                reset_qualifiers( t1 );
     1197                reset_qualifiers( t2 );
    11971198               
    11981199                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
     
    12011202                        // if exact unification on unqualified types, try to merge qualifiers
    12021203                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
    1203                                 common.set_and_mutate( type1 )->qualifiers = q1 | q2;
     1204                                common = type1;
     1205                                reset_qualifiers( common, q1 | q2 );
    12041206                                return true;
    12051207                        } else {
     
    12111213
    12121214                        // no exact unification, but common type
    1213                         common.get_and_mutate()->qualifiers = q1 | q2;
     1215                        reset_qualifiers( common, q1 | q2 );
    12141216                        return true;
    12151217                } else {
  • src/ResolvExpr/Unify.h

    r4741dfe rd4b6638  
    6969        }
    7070
     71        bool unify(
     72                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     73                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     74                ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
     75
    7176        bool unifyExact(
    7277                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
    73                 ast::AssertionSet & need, ast::AssertionSet & have, ast::OpenVarSet & open,
    74                 const ast::SymbolTable & symtab );
     78                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     79                WidenMode widen, const ast::SymbolTable & symtab );
    7580
    7681        bool unifyInexact(
    77                 ast::ptr<ast::Type> & type1, ast::ptr<ast::Type> & type2, ast::TypeEnvironment & env,
    78                 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    79                 WidenMode widen, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
     82                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     83                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     84                const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     85                ast::ptr<ast::Type> & common );
    8086
    8187} // namespace ResolvExpr
  • src/ResolvExpr/WidenMode.h

    r4741dfe rd4b6638  
    4040                bool first : 1, second : 1;
    4141        };
     42
     43        static inline WidenMode noWiden() { return { false, false }; }
    4244} // namespace ResolvExpr
    4345
  • src/ResolvExpr/typeops.h

    r4741dfe rd4b6638  
    8989
    9090        // in Unify.cc
    91         bool isFtype( Type *type );
    9291        bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    9392        bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     
    118117        // in CommonType.cc
    119118        Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    120         const ast::Type * commonType(
    121                 const ast::Type * type1, const ast::Type * type2, WidenMode widen,
     119        ast::ptr< ast::Type > commonType(
     120                const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
    122121                const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
    123122
     
    177176                return out;
    178177        }
     178
     179        // in TypeEnvironment.cc
     180        bool isFtype( Type *type );
    179181} // namespace ResolvExpr
     182
     183namespace ast {
     184        // in TypeEnvironment.cpp
     185        bool isFtype( const ast::Type * type );
     186} // namespace ast
    180187
    181188// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.