Ignore:
Timestamp:
Mar 16, 2016, 3:36:29 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
f5ef08c
Parents:
5b40f30
Message:

generate bodies for autogenerated field ctors which appropriately calls default/copy ctor on each field

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r5b40f30 rdac0aa9  
    6464
    6565        template< typename OutputIterator >
    66         void makeScalarFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
     66        void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    6767                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    6868                // unnamed bit fields are not copied as they cannot be accessed
     
    8080                fExpr->get_args().push_back( dstselect );
    8181
    82                 if ( srcParam ) {
    83                         Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    84                         fExpr->get_args().push_back( srcselect );
     82                if ( src ) {
     83                        fExpr->get_args().push_back( src );
    8584                }
    8685
     
    183182        }
    184183
     184        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
     185                if ( isGeneric ) {
     186                        // rewrite member type in terms of the type variables on this operator
     187                        field = field->clone();
     188                        genericSubs.apply( field );
     189                }
     190
     191                ObjectDecl * returnVal = NULL;
     192                if ( ! func->get_functionType()->get_returnVals().empty() ) {
     193                        returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
     194                }
     195
     196                // assign to destination (and return value if generic)
     197                if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) {
     198                        UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     199                        derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     200                        Expression *dstselect = new MemberExpr( field, derefExpr );
     201
     202                        makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
     203                        if ( isGeneric && returnVal ) {
     204                                UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
     205                                derefRet->get_args().push_back( new VariableExpr( returnVal ) );
     206                                Expression *retselect = new MemberExpr( field, derefRet );
     207
     208                                makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
     209                        }
     210                } else {
     211                        makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     212                        if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     213                } // if
     214        }
     215
    185216        template<typename Iterator>
    186217        void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
    187218                for ( ; member != end; ++member ) {
    188                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     219                        if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
    189220                                // query the type qualifiers of this field and skip assigning it if it is marked const.
    190221                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
    191                                 Type * type = dwt->get_type();
     222                                Type * type = field->get_type();
    192223                                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    193224                                        type = at->get_base();
     
    205236                                        srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
    206237                                }
    207                                 ObjectDecl * returnVal = NULL;
    208                                 if ( ! func->get_functionType()->get_returnVals().empty() ) {
    209                                         returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
    210                                 }
    211238                                // srcParam may be NULL, in which case we have default ctor/dtor
    212239                                assert( dstParam );
    213240
    214 
    215                                 DeclarationWithType * memType = dwt;
    216                                 if ( isGeneric ) {
    217                                         // rewrite member type in terms of the type variables on this operator
    218                                         memType = memType->clone();
    219                                         genericSubs.apply( memType );
    220                                 }
    221 
    222 
    223                                 // assign to destination (and return value if generic)
    224                                 if ( ArrayType *array = dynamic_cast< ArrayType * >( memType->get_type() ) ) {
    225                                         UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    226                                         derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    227                                         Expression *dstselect = new MemberExpr( memType, derefExpr );
    228                                         Expression *srcselect = srcParam ? new MemberExpr( memType, new VariableExpr( srcParam ) ) : NULL;
    229 
    230                                         makeArrayFunction( srcselect, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    231                                         if ( isGeneric && returnVal ) {
    232                                                 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
    233                                                 derefRet->get_args().push_back( new VariableExpr( returnVal ) );
    234                                                 Expression *retselect = new MemberExpr( memType, derefRet );
    235 
    236                                                 makeArrayFunction( srcselect, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    237                                         }
    238                                 } else {
    239                                         makeScalarFunction( srcParam, dstParam, memType, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    240                                         if ( isGeneric && returnVal ) makeScalarFunction( srcParam, returnVal, memType, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    241                                 } // if
     241                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
     242                                makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric, forward );
    242243                        } // if
    243244                } // for
    244245        } // makeStructFunctionBody
     246
     247        /// generate the body of a constructor which takes parameters that match fields, e.g.
     248        /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
     249        template<typename Iterator>
     250        void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
     251                FunctionType * ftype = func->get_functionType();
     252                std::list<DeclarationWithType*> & params = ftype->get_parameters();
     253                assert( params.size() >= 2 );  // should not call this function for default ctor, etc.
     254
     255                // skip 'this' parameter
     256                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( params.front() );
     257                assert( dstParam );
     258                std::list<DeclarationWithType*>::iterator parameter = params.begin()+1;
     259                for ( ; member != end; ++member ) {
     260                        if ( DeclarationWithType * field = dynamic_cast<DeclarationWithType*>( *member ) ) {
     261                                if ( parameter != params.end() ) {
     262                                        // matching parameter, initialize field with copy ctor
     263                                        std::cerr << "matching parameter - copy ctor" << std::endl;
     264                                        Expression *srcselect = new VariableExpr(*parameter);
     265                                        makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric );
     266                                        ++parameter;
     267                                } else {
     268                                        std::cerr << "no matching parameter - default ctor" << std::endl;
     269                                        // no matching parameter, initialize field with default ctor
     270                                        makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isGeneric );
     271                                }
     272                        }
     273                }
     274        }
    245275
    246276        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
     
    289319                dtorDecl->fixUniqueId();
    290320
     321                // create constructors which take each member type as a parameter.
     322                // we might be able to eventually collapse this into a single function
     323                // which uses default parameters
     324                std::list<Declaration *> memCtors;
     325                FunctionType * memCtorType = ctorType->clone();
     326                for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
     327                        DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
     328                        assert( member );
     329                        memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
     330                        FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false );
     331                        ctor->fixUniqueId();
     332                        makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isGeneric );
     333                        memCtors.push_back( ctor );
     334                }
     335                delete memCtorType;
     336
    291337                // generate appropriate calls to member ctor, assignment
    292338                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isGeneric );
     
    302348                declsToAdd.push_back( copyCtorDecl );
    303349                declsToAdd.push_back( dtorDecl );
     350                declsToAdd.splice( declsToAdd.end(), memCtors );
    304351        }
    305352
Note: See TracChangeset for help on using the changeset viewer.