Changeset 2c57025 for src/ResolvExpr


Ignore:
Timestamp:
Nov 25, 2016, 6:11:03 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
0f35657
Parents:
186fd86
Message:

add support for built-in sized trait which decouples size/alignment information from otype parameters, add test for sized trait

Location:
src/ResolvExpr
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AdjustExprType.cc

    r186fd86 r2c57025  
    9797                EqvClass eqvClass;
    9898                if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    99                         if ( eqvClass.kind == TypeDecl::Ftype ) {
     99                        if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    100100                                PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
    101101                                return pointerType;
  • src/ResolvExpr/AlternativeFinder.cc

    r186fd86 r2c57025  
    373373        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    374374                for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    375                         unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
     375                        unifiableVars[ (*tyvar)->get_name() ] = TypeDecl::Data{ *tyvar };
    376376                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
    377377                                needAssertions[ *assert ] = true;
  • src/ResolvExpr/CommonType.cc

    r186fd86 r2c57025  
    5757                Type *result = visitor.get_result();
    5858                if ( ! result ) {
     59                        // this appears to be handling for opaque type declarations
    5960                        if ( widenSecond ) {
    60                                 TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 );
    61                                 if ( inst ) {
    62                                         NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
    63                                         if ( nt ) {
    64                                                 TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
    65                                                 assert( type );
     61                                if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {
     62                                        if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {
     63                                                TypeDecl *type = safe_dynamic_cast< TypeDecl* >( nt );
    6664                                                if ( type->get_base() ) {
    6765                                                        Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
     
    145143        }
    146144
     145        /// true if a common type for t must be a complete type
     146        bool requiredComplete( Type * t ) {
     147                if ( TypeInstType * inst = dynamic_cast< TypeInstType * > ( t ) ) {
     148                        return inst->get_baseType()->isComplete();
     149                }
     150                return false;
     151        }
     152
    147153        void CommonType::visit( PointerType *pointerType ) {
    148154                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    149                         if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base(), indexer) ) {
     155                        // Note: relationship between formal and actual types is antisymmetric
     156                        //   void free(void *);
     157                        //   forall(otype T) void foo(T *);
     158                        //
     159                        // should be able to pass T* to free, but should not be able to pass a void* to foo.
     160                        // because of this, the requiredComplete check occurs only on the first, since it corresponds
     161                        // to the formal parameter type (though this may be incorrect in some cases, in which case
     162                        // perhaps the widen mode needs to incorporate another bit for whether this is a formal or actual context)
     163                        if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base(), indexer) && ! requiredComplete( pointerType->get_base() ) ) {
    150164                                result = otherPointer->clone();
    151165                                result->get_qualifiers() += pointerType->get_qualifiers();
     
    211225                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
    212226                        if ( nt ) {
    213                                 TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
    214                                 assert( type );
     227                                TypeDecl *type = safe_dynamic_cast< TypeDecl* >( nt );
    215228                                if ( type->get_base() ) {
    216229                                        Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
  • src/ResolvExpr/FindOpenVars.cc

    r186fd86 r2c57025  
    4848                if ( nextIsOpen ) {
    4949                        for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    50                                 openVars[ (*i)->get_name() ] = (*i)->get_kind();
     50                                openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    5151                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    5252                                        needAssertions[ *assert ] = false;
     
    5757                } else {
    5858                        for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    59                                 closedVars[ (*i)->get_name() ] = (*i)->get_kind();
     59                                closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    6060                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    6161                                        haveAssertions[ *assert ] = false;
  • src/ResolvExpr/PtrsCastable.cc

    r186fd86 r2c57025  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // PtrsCastable.cc -- 
     7// PtrsCastable.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2525          public:
    2626                PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    27  
     27
    2828                int get_result() const { return result; }
    2929
     
    6161                                } //if
    6262                        } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    63                                 if ( eqvClass.kind == TypeDecl::Ftype ) {
     63                                if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    6464                                        return -1;
    6565                                } // if
  • src/ResolvExpr/TypeEnvironment.cc

    r186fd86 r2c57025  
    9494                dest.type = maybeClone( src.type );
    9595                dest.allowWidening = src.allowWidening;
    96                 dest.kind = src.kind;
     96                dest.data = src.data;
    9797        }
    9898
     
    162162                        EqvClass newClass;
    163163                        newClass.vars.insert( (*i)->get_name() );
    164                         newClass.kind = (*i)->get_kind();
     164                        newClass.data = TypeDecl::Data{ (*i) };
    165165                        env.push_back( newClass );
    166166                } // for
     
    177177                                        sub.add( *theVar, theClass->type );
    178178                                } else if ( theVar != theClass->vars.begin() ) {
    179                                         TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->kind == TypeDecl::Ftype );
     179                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    180180///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
    181181                                        sub.add( *theVar, newTypeInst );
     
    243243                for ( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
    244244                        for ( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
    245                                 openVars[ *var ] = eqvClass->kind;
     245                                openVars[ *var ] = eqvClass->data;
    246246                        } // for
    247247                } // for
  • src/ResolvExpr/TypeEnvironment.h

    r186fd86 r2c57025  
    3232        };
    3333        typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
    34         typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
     34        typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
    3535
    3636        void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
     
    4141                Type *type;
    4242                bool allowWidening;
    43                 TypeDecl::Kind kind;
     43                TypeDecl::Data data;
    4444
    4545                void initialize( const EqvClass &src, EqvClass &dest );
  • src/ResolvExpr/Unify.cc

    r186fd86 r2c57025  
    109109                newFirst->get_qualifiers() = Type::Qualifiers();
    110110                newSecond->get_qualifiers() = Type::Qualifiers();
    111 ///   std::cout << "first is ";
    112 ///   first->print( std::cout );
    113 ///   std::cout << std::endl << "second is ";
    114 ///   second->print( std::cout );
    115 ///   std::cout << std::endl << "newFirst is ";
    116 ///   newFirst->print( std::cout );
    117 ///   std::cout << std::endl << "newSecond is ";
    118 ///   newSecond->print( std::cout );
    119 ///   std::cout << std::endl;
     111///   std::cerr << "first is ";
     112///   first->print( std::cerr );
     113///   std::cerr << std::endl << "second is ";
     114///   second->print( std::cerr );
     115///   std::cerr << std::endl << "newFirst is ";
     116///   newFirst->print( std::cerr );
     117///   std::cerr << std::endl << "newSecond is ";
     118///   newSecond->print( std::cerr );
     119///   std::cerr << std::endl;
    120120                bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    121121                delete newFirst;
     
    133133        }
    134134
    135         bool tyVarCompatible( TypeDecl::Kind kind, Type *type, const SymTab::Indexer &indexer ) {
    136                 switch ( kind ) {
     135        struct CompleteTypeChecker : public Visitor {
     136                virtual void visit( VoidType *basicType ) { status = false; }
     137                virtual void visit( BasicType *basicType ) {}
     138                virtual void visit( PointerType *pointerType ) {}
     139                virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }
     140                virtual void visit( FunctionType *functionType ) {}
     141                virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }
     142                virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }
     143                // xxx - enum inst does not currently contain a pointer to base, this should be fixed.
     144                virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }
     145                virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }
     146                virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }
     147                virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness
     148                virtual void visit( TypeofType *typeofType ) { assert( false ); }
     149                virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here
     150                virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?
     151                virtual void visit( ZeroType *zeroType ) {}
     152                virtual void visit( OneType *oneType ) {}
     153                bool status = true;
     154        };
     155        bool isComplete( Type * type ) {
     156                CompleteTypeChecker checker;
     157                assert( type );
     158                type->accept( checker );
     159                return checker.status;
     160        }
     161
     162        bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
     163                switch ( data.kind ) {
    137164                  case TypeDecl::Any:
    138165                  case TypeDecl::Dtype:
    139                         return ! isFtype( type, indexer );
    140 
     166                        // to bind to an object type variable, the type must not be a function type.
     167                        // if the type variable is specified to be a complete type then the incoming
     168                        // type must also be complete
     169                        return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
    141170                  case TypeDecl::Ftype:
    142171                        return isFtype( type, indexer );
     
    146175        }
    147176
    148         bool bindVar( TypeInstType *typeInst, Type *other, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     177        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 ) {
    149178                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    150179                assert( tyvar != openVars.end() );
     
    185214                        newClass.type->get_qualifiers() = Type::Qualifiers();
    186215                        newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    187                         newClass.kind = kind;
     216                        newClass.data = data;
    188217                        env.add( newClass );
    189218                } // if
     
    191220        }
    192221
    193         bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     222        bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    194223                bool result = true;
    195224                EqvClass class1, class2;
     
    220249
    221250                if ( type1 && type2 ) {
    222 //    std::cout << "has type1 && type2" << std::endl;
     251//    std::cerr << "has type1 && type2" << std::endl;
    223252                        WidenMode newWidenMode ( widen1, widen2 );
    224253                        Type *common = 0;
     
    258287                        newClass.vars.insert( var2->get_name() );
    259288                        newClass.allowWidening = widen1 && widen2;
    260                         newClass.kind = kind;
     289                        newClass.data = data;
    261290                        env.add( newClass );
    262291                } // if
     
    321350                } // if
    322351#ifdef DEBUG
    323                 std::cout << "============ unifyExact" << std::endl;
    324                 std::cout << "type1 is ";
    325                 type1->print( std::cout );
    326                 std::cout << std::endl << "type2 is ";
    327                 type2->print( std::cout );
    328                 std::cout << std::endl << "openVars are ";
    329                 printOpenVarSet( openVars, std::cout, 8 );
    330                 std::cout << std::endl << "input env is " << std::endl;
    331                 debugEnv.print( std::cout, 8 );
    332                 std::cout << std::endl << "result env is " << std::endl;
    333                 env.print( std::cout, 8 );
    334                 std::cout << "result is " << result << std::endl;
     352                std::cerr << "============ unifyExact" << std::endl;
     353                std::cerr << "type1 is ";
     354                type1->print( std::cerr );
     355                std::cerr << std::endl << "type2 is ";
     356                type2->print( std::cerr );
     357                std::cerr << std::endl << "openVars are ";
     358                printOpenVarSet( openVars, std::cerr, 8 );
     359                std::cerr << std::endl << "input env is " << std::endl;
     360                debugEnv.print( std::cerr, 8 );
     361                std::cerr << std::endl << "result env is " << std::endl;
     362                env.print( std::cerr, 8 );
     363                std::cerr << "result is " << result << std::endl;
    335364#endif
    336365                return result;
     
    347376                bool result;
    348377#ifdef DEBUG
    349                 std::cout << "unifyInexact type 1 is ";
    350                 type1->print( std::cout );
    351                 std::cout << "type 2 is ";
    352                 type2->print( std::cout );
    353                 std::cout << std::endl;
     378                std::cerr << "unifyInexact type 1 is ";
     379                type1->print( std::cerr );
     380                std::cerr << "type 2 is ";
     381                type2->print( std::cerr );
     382                std::cerr << std::endl;
    354383#endif
    355384                if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {
    356385#ifdef DEBUG
    357                         std::cout << "unifyInexact: no exact unification found" << std::endl;
     386                        std::cerr << "unifyInexact: no exact unification found" << std::endl;
    358387#endif
    359388                        if ( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
    360389                                common->get_qualifiers() = tq1 + tq2;
    361390#ifdef DEBUG
    362                                 std::cout << "unifyInexact: common type is ";
    363                                 common->print( std::cout );
    364                                 std::cout << std::endl;
     391                                std::cerr << "unifyInexact: common type is ";
     392                                common->print( std::cerr );
     393                                std::cerr << std::endl;
    365394#endif
    366395                                result = true;
    367396                        } else {
    368397#ifdef DEBUG
    369                                 std::cout << "unifyInexact: no common type found" << std::endl;
     398                                std::cerr << "unifyInexact: no common type found" << std::endl;
    370399#endif
    371400                                result = false;
     
    404433
    405434        void markAssertionSet( AssertionSet &assertions, DeclarationWithType *assert ) {
    406 ///   std::cout << "assertion set is" << std::endl;
    407 ///   printAssertionSet( assertions, std::cout, 8 );
    408 ///   std::cout << "looking for ";
    409 ///   assert->print( std::cout );
    410 ///   std::cout << std::endl;
     435///   std::cerr << "assertion set is" << std::endl;
     436///   printAssertionSet( assertions, std::cerr, 8 );
     437///   std::cerr << "looking for ";
     438///   assert->print( std::cerr );
     439///   std::cerr << std::endl;
    411440                AssertionSet::iterator i = assertions.find( assert );
    412441                if ( i != assertions.end() ) {
    413 ///     std::cout << "found it!" << std::endl;
     442///     std::cerr << "found it!" << std::endl;
    414443                        i->second = true;
    415444                } // if
Note: See TracChangeset for help on using the changeset viewer.