Ignore:
Timestamp:
Sep 13, 2017, 2:44:01 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
ba54f7d, c935c3a
Parents:
e3e16bc (diff), 7dc09294 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    re3e16bc r982832e  
    163163                // Routines at global scope marked "static" to prevent multiple definitions in separate translation units
    164164                // because each unit generates copies of the default routines for each aggregate.
    165 //              DeclarationNode::StorageClass sc = functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static;
    166165                Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static );
    167166                LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen;
     
    186185        /// using map and t, determines if is constructable, etc.
    187186        bool lookup( const TypeMap & map, Type * t ) {
     187                assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() );
    188188                if ( dynamic_cast< PointerType * >( t ) ) {
    189189                        // will need more complicated checking if we want this to work with pointer types, since currently
     
    200200
    201201        /// using map and aggr, examines each member to determine if constructor, etc. should be generated
    202         template<typename AggrDecl>
    203         bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) {
    204                 for ( Declaration * dcl : aggr->get_members() ) {
    205                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) {
    206                                 if ( ! lookup( map, dwt->get_type() ) ) return false;
    207                         }
     202        template<typename Container>
     203        bool shouldGenerate( const TypeMap & map, const Container & container ) {
     204                for ( Type * t : container ) {
     205                        if ( ! lookup( map, t ) ) return false;
    208206                }
    209207                return true;
     
    211209
    212210        /// data structure for abstracting the generation of special functions
    213         template< typename OutputIterator >
     211        template< typename OutputIterator, typename Container >
    214212        struct FuncGenerator {
    215                 StructDecl *aggregateDecl;
    216                 StructInstType *refType;
     213                const Container & container;
     214                Type *refType;
    217215                unsigned int functionNesting;
    218216                const std::list< TypeDecl* > & typeParams;
    219217                OutputIterator out;
    220                 FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
     218                FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
    221219
    222220                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
    223221                void gen( const FuncData & data, bool concurrent_type ) {
    224                         if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
     222                        if ( ! shouldGenerate( data.map, container ) ) return;
    225223                        FunctionType * ftype = data.genType( refType );
    226224
    227225                        if(concurrent_type && CodeGen::isDestructor( data.fname )) {
    228                                 ftype->get_parameters().front()->get_type()->set_mutex( true );
    229                         }
    230 
    231                         cloneAll( typeParams, ftype->get_forall() );
     226                                ftype->parameters.front()->get_type()->set_mutex( true );
     227                        }
     228
     229                        cloneAll( typeParams, ftype->forall );
    232230                        *out++ = genFunc( data.fname, ftype, functionNesting );
    233231                        data.map.insert( Mangler::mangleType( refType ), true );
     
    235233        };
    236234
    237         template< typename OutputIterator >
    238         FuncGenerator<OutputIterator> makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
    239                 return FuncGenerator<OutputIterator>( aggregateDecl, refType, functionNesting, typeParams, out );
     235        template< typename OutputIterator, typename Container >
     236        FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
     237                return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out );
    240238        }
    241239
     
    393391        }
    394392
     393        Type * declToType( Declaration * decl ) {
     394                if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     395                        return dwt->get_type();
     396                }
     397                return nullptr;
     398        }
     399
    395400        /// generates struct constructors, destructor, and assignment functions
    396401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
     
    406411                // generate each of the functions based on the supplied FuncData objects
    407412                std::list< FunctionDecl * > newFuncs;
    408                 auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
     413                // structure that iterates aggregate decl members, returning their types
     414                auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) );
    409415                for ( const FuncData & d : data ) {
    410416                        generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() );
     
    605611        }
    606612
     613        Type * declToTypeDeclBase( Declaration * decl ) {
     614                if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) {
     615                        return td->base;
     616                }
     617                return nullptr;
     618        }
     619
     620        // generate ctor/dtors/assign for typedecls, e.g., otype T = int *;
    607621        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    608                 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    609                 typeInst->set_baseType( typeDecl );
    610                 ObjectDecl *src = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, typeInst->clone(), nullptr );
    611                 ObjectDecl *dst = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), typeInst->clone() ), nullptr );
    612 
    613                 std::list< Statement * > stmts;
    614                 if ( typeDecl->get_base() ) {
    615                         // xxx - generate ctor/dtors for typedecls, e.g.
    616                         // otype T = int *;
    617                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    618                         assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    619                         assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    620                         stmts.push_back( new ReturnStmt( std::list< Label >(), assign ) );
    621                 } // if
    622                 FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    623                 type->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, typeInst, 0 ) );
    624                 type->get_parameters().push_back( dst );
    625                 type->get_parameters().push_back( src );
    626                 FunctionDecl *func = genFunc( "?=?", type, functionNesting );
    627                 func->get_statements()->get_kids() = stmts;
    628                 declsToAddAfter.push_back( func );
     622                if ( ! typeDecl->base ) return;
     623
     624                // generate each of the functions based on the supplied FuncData objects
     625                std::list< FunctionDecl * > newFuncs;
     626                std::list< Declaration * > tds { typeDecl };
     627                std::list< TypeDecl * > typeParams;
     628                TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl );
     629                auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) );
     630                for ( const FuncData & d : data ) {
     631                        generator.gen( d, false );
     632                }
     633
     634                if ( functionNesting == 0 ) {
     635                        // forward declare if top-level struct, so that
     636                        // type is complete as soon as its body ends
     637                        // Note: this is necessary if we want structs which contain
     638                        // generic (otype) structs as members.
     639                        for ( FunctionDecl * dcl : newFuncs ) {
     640                                addForwardDecl( dcl, declsToAddAfter );
     641                        }
     642                }
     643
     644                for ( FunctionDecl * dcl : newFuncs ) {
     645                        FunctionType * ftype = dcl->type;
     646                        assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() );
     647                        DeclarationWithType * dst = ftype->parameters.front();
     648                        DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr;
     649                        // generate appropriate calls to member ctor, assignment
     650                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
     651                        UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) );
     652                        expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) );
     653                        if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) );
     654                        dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) );
     655                        if ( CodeGen::isAssignment( dcl->get_name() ) ) {
     656                                // assignment needs to return a value
     657                                FunctionType * assignType = dcl->type;
     658                                assert( assignType->parameters.size() == 2 );
     659                                ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.back() );
     660                                dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     661                        }
     662                        declsToAddAfter.push_back( dcl );
     663                }
    629664        }
    630665
Note: See TracChangeset for help on using the changeset viewer.