Changeset 4a9ccc3


Ignore:
Timestamp:
Jan 24, 2017, 3:56:33 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:
ad6343e
Parents:
0bfaf80
Message:

propagate sized status through trait instances

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/Common/utility.h

    r0bfaf80 r4a9ccc3  
    252252
    253253template< typename T >
    254 struct reverseIterate_t {
     254struct reverse_iterate_t {
    255255        T& ref;
    256256
    257         reverseIterate_t( T & ref ) : ref(ref) {}
     257        reverse_iterate_t( T & ref ) : ref(ref) {}
    258258
    259259        typedef typename T::reverse_iterator iterator;
     
    263263
    264264template< typename T >
    265 reverseIterate_t< T > reverseIterate( T & ref ) {
    266         return reverseIterate_t< T >( ref );
    267 }
    268 
     265reverse_iterate_t< T > reverseIterate( T & ref ) {
     266        return reverse_iterate_t< T >( ref );
     267}
     268
     269// -----------------------------------------------------------------------------
     270// Helper struct and function to support
     271// for ( val : group_iterate( container1, container2, ... ) ) {}
     272// syntax to have a for each that iterates multiple containers of the same length
     273// TODO: update to use variadic arguments
     274
     275template< typename T1, typename T2 >
     276struct group_iterate_t {
     277        group_iterate_t( const T1 & v1, const T2 & v2 ) : args(v1, v2) {
     278                assertf(v1.size() == v2.size(), "group iteration requires containers of the same size.");
     279        };
     280
     281        struct iterator {
     282                typedef std::tuple<typename T1::value_type, typename T2::value_type> value_type;
     283                typedef typename T1::iterator T1Iter;
     284                typedef typename T2::iterator T2Iter;
     285                typedef std::tuple<T1Iter, T2Iter> IterTuple;
     286                IterTuple it;
     287                iterator( T1Iter i1, T2Iter i2 ) : it( i1, i2 ) {}
     288                iterator operator++() {
     289                        return iterator( ++std::get<0>(it), ++std::get<1>(it) );
     290                }
     291                bool operator!=( const iterator &other ) const { return it != other.it; }
     292                value_type operator*() const { return std::make_tuple( *std::get<0>(it), *std::get<1>(it) ); }
     293        };
     294        iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); }
     295        iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); }
     296
     297private:
     298        std::tuple<T1, T2> args;
     299};
     300
     301template< typename... Args >
     302group_iterate_t<Args...> group_iterate( const Args &... args ) {
     303        return group_iterate_t<Args...>(args...);
     304}
    269305#endif // _UTILITY_H
    270306
  • src/Parser/TypeData.cc

    r0bfaf80 r4a9ccc3  
    5757                aggregate.actuals = nullptr;
    5858                aggregate.fields = nullptr;
     59                aggregate.body = false;
    5960                break;
    6061          case AggregateInst:
  • src/ResolvExpr/Unify.cc

    r0bfaf80 r4a9ccc3  
    123123        }
    124124
    125         struct CompleteTypeChecker : public Visitor {
    126                 virtual void visit( VoidType *basicType ) { status = false; }
    127                 virtual void visit( BasicType *basicType ) {}
    128                 virtual void visit( PointerType *pointerType ) {}
    129                 virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }
    130                 virtual void visit( FunctionType *functionType ) {}
    131                 virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }
    132                 virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }
    133                 // xxx - enum inst does not currently contain a pointer to base, this should be fixed.
    134                 virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }
    135                 virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }
    136                 virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }
    137                 virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness
    138                 virtual void visit( TypeofType *typeofType ) { assert( false ); }
    139                 virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here
    140                 virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?
    141                 virtual void visit( ZeroType *zeroType ) {}
    142                 virtual void visit( OneType *oneType ) {}
    143                 bool status = true;
    144         };
    145         bool isComplete( Type * type ) {
    146                 CompleteTypeChecker checker;
    147                 assert( type );
    148                 type->accept( checker );
    149                 return checker.status;
    150         }
    151 
    152125        bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
    153126                switch ( data.kind ) {
     
    158131                        // type must also be complete
    159132                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    160                         return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
     133                        return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() );
    161134                  case TypeDecl::Ftype:
    162135                        return isFtype( type, indexer );
  • src/SymTab/Validate.cc

    r0bfaf80 r4a9ccc3  
    114114                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    115115          private:
    116                 using Indexer::visit;
     116                using Parent::visit;
    117117                void visit( StructInstType *structInst ) final;
    118118                void visit( UnionInstType *unionInst ) final;
     
    131131
    132132        /// Replaces array and function types in forall lists by appropriate pointer type
    133         class Pass3 : public Indexer {
     133        class Pass3 final : public Indexer {
    134134                typedef Indexer Parent;
    135135          public:
     136                using Parent::visit;
    136137                Pass3( const Indexer *indexer );
    137138          private:
    138                 virtual void visit( ObjectDecl *object );
    139                 virtual void visit( FunctionDecl *func );
     139                virtual void visit( ObjectDecl *object ) override;
     140                virtual void visit( FunctionDecl *func ) override;
    140141
    141142                const Indexer *indexer;
     
    375376        }
    376377
    377         void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
    378                 Parent::visit( contextInst );
    379                 if ( contextInst->get_name() == "sized" ) {
     378        void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     379                Parent::visit( traitInst );
     380                if ( traitInst->get_name() == "sized" ) {
    380381                        // "sized" is a special trait with no members - just flick the sized status on for the type variable
    381                         if ( contextInst->get_parameters().size() != 1 ) {
    382                                 throw SemanticError( "incorrect number of context parameters: ", contextInst );
     382                        if ( traitInst->get_parameters().size() != 1 ) {
     383                                throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    383384                        }
    384                         TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
     385                        TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
    385386                        TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
    386387                        TypeDecl * decl = inst->get_baseType();
     
    389390                        return;
    390391                }
    391                 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
    392                 if ( ! ctx ) {
    393                         throw SemanticError( "use of undeclared context " + contextInst->get_name() );
    394                 } // if
    395                 for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    396                         for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    397                                 if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
    398                                         cloneAll( otherCtx->get_members(), contextInst->get_members() );
    399                                 } else {
    400                                         contextInst->get_members().push_back( (*assert )->clone() );
    401                                 } // if
     392                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     393                if ( ! traitDecl ) {
     394                        throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     395                } // if
     396                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
     397                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
     398                } // if
     399
     400                for ( TypeDecl * td : traitDecl->get_parameters() ) {
     401                        for ( DeclarationWithType * assert : td->get_assertions() ) {
     402                                traitInst->get_members().push_back( assert->clone() );
    402403                        } // for
    403404                } // for
    404405
    405                 if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
    406                         throw SemanticError( "incorrect number of context parameters: ", contextInst );
    407                 } // if
    408 
    409                 // need to clone members of the context for ownership purposes
     406                // need to clone members of the trait for ownership purposes
    410407                std::list< Declaration * > members;
    411                 std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
    412 
    413                 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
     408                std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
     409
     410                applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
     411
     412                // need to carry over the 'sized' status of each decl in the instance
     413                for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
     414                        TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
     415                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
     416                                TypeDecl * formalDecl = std::get<0>(p);
     417                                TypeDecl * instDecl = inst->get_baseType();
     418                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
     419                        }
     420                }
    414421        }
    415422
     
    457464        }
    458465
    459         /// Fix up assertions
    460         void forallFixer( Type *func ) {
    461                 for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     466        /// Fix up assertions - flattens assertion lists, removing all trait instances
     467        void forallFixer( Type * func ) {
     468                for ( TypeDecl * type : func->get_forall() ) {
    462469                        std::list< DeclarationWithType * > toBeDone, nextRound;
    463                         toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
     470                        toBeDone.splice( toBeDone.end(), type->get_assertions() );
    464471                        while ( ! toBeDone.empty() ) {
    465                                 for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    466                                         if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
    467                                                 for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    468                                                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
    469                                                         assert( dwt );
     472                                for ( DeclarationWithType * assertion : toBeDone ) {
     473                                        if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     474                                                // expand trait instance into all of its members
     475                                                for ( Declaration * member : traitInst->get_members() ) {
     476                                                        DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
    470477                                                        nextRound.push_back( dwt->clone() );
    471478                                                }
    472                                                 delete ctx;
     479                                                delete traitInst;
    473480                                        } else {
     481                                                // pass assertion through
    474482                                                FixFunction fixer;
    475                                                 *assertion = (*assertion )->acceptMutator( fixer );
     483                                                assertion = assertion->acceptMutator( fixer );
    476484                                                if ( fixer.get_isVoid() ) {
    477485                                                        throw SemanticError( "invalid type void in assertion of function ", func );
    478486                                                }
    479                                                 (*type )->get_assertions().push_back( *assertion );
     487                                                type->get_assertions().push_back( assertion );
    480488                                        } // if
    481489                                } // for
  • src/SynTree/AggregateDecl.cc

    r0bfaf80 r4a9ccc3  
    6969std::string EnumDecl::typeString() const { return "enum"; }
    7070
    71 std::string TraitDecl::typeString() const { return "context"; }
     71std::string TraitDecl::typeString() const { return "trait"; }
    7272
    7373// Local Variables: //
  • src/SynTree/ReferenceToType.cc

    r0bfaf80 r4a9ccc3  
    6464}
    6565
     66bool StructInstType::isComplete() const { return baseStruct->has_body(); }
     67
    6668void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    6769        assert( baseStruct );
     
    9092}
    9193
     94bool UnionInstType::isComplete() const { return baseUnion->has_body(); }
     95
    9296void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    9397        assert( baseUnion );
     
    111115std::string EnumInstType::typeString() const { return "enum"; }
    112116
    113 std::string TraitInstType::typeString() const { return "context"; }
     117std::string TraitInstType::typeString() const { return "trait"; }
    114118
    115119TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
     
    120124        deleteAll( members );
    121125}
     126
     127bool TraitInstType::isComplete() const { assert( false ); }
    122128
    123129TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name ) {
     
    143149std::string TypeInstType::typeString() const { return "type"; }
    144150
     151bool TypeInstType::isComplete() const { return baseType->isComplete(); }
     152
    145153void TypeInstType::print( std::ostream &os, int indent ) const {
    146154        using std::endl;
  • src/SynTree/Type.h

    r0bfaf80 r4a9ccc3  
    7474        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
    7575
     76        virtual bool isComplete() const { return true; }
     77
    7678        virtual Type *clone() const = 0;
    7779        virtual void accept( Visitor &v ) = 0;
     
    9092
    9193        virtual unsigned size() const { return 0; };
     94        virtual bool isComplete() const { return false; }
    9295
    9396        virtual VoidType *clone() const { return new VoidType( *this ); }
     
    185188        void set_isStatic( bool newValue ) { isStatic = newValue; }
    186189
     190        virtual bool isComplete() const { return ! isVarLen; }
     191
    187192        virtual ArrayType *clone() const { return new ArrayType( *this ); }
    188193        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    258263        std::list<TypeDecl*> * get_baseParameters();
    259264
     265        virtual bool isComplete() const;
     266
    260267        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    261268        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    287294        std::list<TypeDecl*> * get_baseParameters();
    288295
     296        virtual bool isComplete() const;
     297
    289298        /// looks up the members of this union named "name" and places them into "foundDecls"
    290299        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    310319        EnumInstType( const EnumInstType &other ) : Parent( other ) {}
    311320
     321        // xxx - enum inst does not currently contain a pointer to base, this should be fixed.
     322        // virtual bool isComplete() const { return baseEnum()->hasBody(); }
     323
    312324        virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
    313325        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    325337
    326338        std::list< Declaration* >& get_members() { return members; }
     339
     340        virtual bool isComplete() const;
    327341
    328342        virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
     
    349363        bool get_isFtype() const { return isFtype; }
    350364        void set_isFtype( bool newValue ) { isFtype = newValue; }
     365
     366        virtual bool isComplete() const;
    351367
    352368        virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
     
    382398        }
    383399
     400        // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
     401
    384402        virtual TupleType *clone() const { return new TupleType( *this ); }
    385403        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    398416        Expression *get_expr() const { return expr; }
    399417        void set_expr( Expression *newValue ) { expr = newValue; }
     418
     419        virtual bool isComplete() const { assert( false ); return false; }
    400420
    401421        virtual TypeofType *clone() const { return new TypeofType( *this ); }
     
    423443        void set_isType( bool newValue ) { isType = newValue; }
    424444
     445        virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
     446
    425447        virtual AttrType *clone() const { return new AttrType( *this ); }
    426448        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    439461        VarArgsType();
    440462        VarArgsType( Type::Qualifiers tq );
     463
     464        virtual bool isComplete() const{ return true; } // xxx - is this right?
    441465
    442466        virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
  • src/tests/vector/array.c

    r0bfaf80 r4a9ccc3  
    1616#include "array.h"
    1717
    18 /// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
    19 /// [ array_iterator begin, array_iterator end ]
    20 /// get_iterators( array_type array )
    21 /// {
    22 ///   begin = 0;
    23 ///   end = last( array );
    24 /// }
     18forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
     19[ elt_type * begin, elt_type * end ] get_iterators( array_type * array ) {
     20        return [ begin( array ), end( array ) ];
     21}
    2522
    2623// The first element is always at index 0.
  • src/tests/vector/array.h

    r0bfaf80 r4a9ccc3  
    3232// implement iterator_for
    3333
    34 typedef int array_iterator;
    35 
    36 /// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
    37 /// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
     34forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
     35[ elt_type * begin, elt_type * end ] get_iterators( array_type * );
    3836
    3937
Note: See TracChangeset for help on using the changeset viewer.