Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Unify.cc

    rea6332d rf0ecf9b  
    1717#include <iterator>               // for back_insert_iterator, back_inserter
    1818#include <map>                    // for _Rb_tree_const_iterator, _Rb_tree_i...
    19 #include <memory>                 // for unique_ptr, auto_ptr
     19#include <memory>                 // for unique_ptr
    2020#include <set>                    // for set
    2121#include <string>                 // for string, operator==, operator!=, bas...
    2222#include <utility>                // for pair
    2323
     24#include "Common/PassVisitor.h"   // for PassVisitor
    2425#include "FindOpenVars.h"         // for findOpenVars
    2526#include "Parser/LinkageSpec.h"   // for C
     
    5354                virtual void visit(PointerType *pointerType);
    5455                virtual void visit(ArrayType *arrayType);
     56                virtual void visit(ReferenceType *refType);
    5557                virtual void visit(FunctionType *functionType);
    5658                virtual void visit(StructInstType *aggregateUseType);
     
    136138        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    137139                switch ( data.kind ) {
    138                   case TypeDecl::Any:
    139140                  case TypeDecl::Dtype:
    140141                        // to bind to an object type variable, the type must not be a function type.
     
    153154
    154155        bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     156                // remove references from other, so that type variables can only bind to value types
     157                other = other->stripReferences();
    155158                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    156159                assert( tyvar != openVars.end() );
     
    166169                                Type *common = 0;
    167170                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    168                                 std::auto_ptr< Type > newType( curClass.type->clone() );
     171                                std::unique_ptr< Type > newType( curClass.type->clone() );
    169172                                newType->get_qualifiers() = typeInst->get_qualifiers();
    170173                                if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
     
    387390                                } // if
    388391                        } else {
     392                                common = type1->clone();
     393                                common->get_qualifiers() = tq1 | tq2;
    389394                                result = true;
    390395                        } // if
     
    439444        }
    440445
     446        void Unify::visit(ReferenceType *refType) {
     447                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
     448                        result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     449                        markAssertions( haveAssertions, needAssertions, refType );
     450                        markAssertions( haveAssertions, needAssertions, otherRef );
     451                } // if
     452        }
     453
    441454        void Unify::visit(ArrayType *arrayType) {
    442455                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
     
    444457                // and must both have a dimension expression or not have a dimension
    445458                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    446 
    447                         // not positive this is correct in all cases, but it's needed for typedefs
    448                         if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {
    449                                 return;
    450                         }
    451459
    452460                        if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() &&
     
    524532        /// If this isn't done then argument lists can have wildly different
    525533        /// size and structure, when they should be compatible.
    526         struct TtypeExpander : public Mutator {
    527                 TypeEnvironment & env;
    528                 TtypeExpander( TypeEnvironment & env ) : env( env ) {}
    529                 Type * mutate( TypeInstType * typeInst ) {
     534        struct TtypeExpander : public WithShortCircuiting {
     535                TypeEnvironment & tenv;
     536                TtypeExpander( TypeEnvironment & tenv ) : tenv( tenv ) {}
     537                void premutate( TypeInstType * ) { visit_children = false; }
     538                Type * postmutate( TypeInstType * typeInst ) {
    530539                        EqvClass eqvClass;
    531                         if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     540                        if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
    532541                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
    533542                                        // expand ttype parameter into its actual type
     
    547556                dst.clear();
    548557                for ( DeclarationWithType * dcl : src ) {
    549                         TtypeExpander expander( env );
     558                        PassVisitor<TtypeExpander> expander( env );
    550559                        dcl->acceptMutator( expander );
    551560                        std::list< Type * > types;
     
    737746                        std::list<Type *> types1, types2;
    738747
    739                         TtypeExpander expander( env );
     748                        PassVisitor<TtypeExpander> expander( env );
    740749                        flat1->acceptMutator( expander );
    741750                        flat2->acceptMutator( expander );
Note: See TracChangeset for help on using the changeset viewer.