Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r4e8949f re3e16bc  
    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;
    165166                Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static );
    166167                LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen;
     
    185186        /// using map and t, determines if is constructable, etc.
    186187        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 Container>
    203         bool shouldGenerate( const TypeMap & map, const Container & container ) {
    204                 for ( Type * t : container ) {
    205                         if ( ! lookup( map, t ) ) return false;
     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                        }
    206208                }
    207209                return true;
     
    209211
    210212        /// data structure for abstracting the generation of special functions
    211         template< typename OutputIterator, typename Container >
     213        template< typename OutputIterator >
    212214        struct FuncGenerator {
    213                 const Container & container;
    214                 Type *refType;
     215                StructDecl *aggregateDecl;
     216                StructInstType *refType;
    215217                unsigned int functionNesting;
    216218                const std::list< TypeDecl* > & typeParams;
    217219                OutputIterator 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 ) {}
     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 ) {}
    219221
    220222                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
    221223                void gen( const FuncData & data, bool concurrent_type ) {
    222                         if ( ! shouldGenerate( data.map, container ) ) return;
     224                        if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
    223225                        FunctionType * ftype = data.genType( refType );
    224226
    225                         if ( concurrent_type && CodeGen::isDestructor( data.fname ) ) {
    226                                 ftype->parameters.front()->get_type()->set_mutex( true );
    227                         }
    228 
    229                         cloneAll( typeParams, ftype->forall );
     227                        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() );
    230232                        *out++ = genFunc( data.fname, ftype, functionNesting );
    231233                        data.map.insert( Mangler::mangleType( refType ), true );
     
    233235        };
    234236
    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 );
     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 );
    238240        }
    239241
     
    391393        }
    392394
    393         Type * declToType( Declaration * decl ) {
    394                 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    395                         return dwt->get_type();
    396                 }
    397                 return nullptr;
    398         }
    399 
    400395        /// generates struct constructors, destructor, and assignment functions
    401396        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
     
    411406                // generate each of the functions based on the supplied FuncData objects
    412407                std::list< FunctionDecl * > 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 ) );
     408                auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
    415409                for ( const FuncData & d : data ) {
    416410                        generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() );
     
    611605        }
    612606
    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 *;
    621607        void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    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                 }
     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 );
    664629        }
    665630
Note: See TracChangeset for help on using the changeset viewer.