Changeset 071a31a


Ignore:
Timestamp:
Mar 3, 2016, 2:45:51 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
620cb95
Parents:
c14cff1
Message:

removed array ctor/dtors from prelude, generalized struct routine generation, fix fall back on initializer if ctor not found, begin special casing array ctor/dtor

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/RemoveInit.cc

    rc14cff1 r071a31a  
    192192                if ( tryConstruct( objDecl ) ) {
    193193                        if ( inFunction ) {
    194                                 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
    195                                 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
    196 
    197                                 // need to remember init expression, in case no ctors exist
    198                                 // if ctor does exist, want to use ctor expression instead of init
    199                                 // push this decision to the resolver
    200                                 objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
    201                                 destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
     194                                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     195                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
     196                                } else {
     197                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     198                                        Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     199                                        Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
     200
     201                                        // need to remember init expression, in case no ctors exist
     202                                        // if ctor does exist, want to use ctor expression instead of init
     203                                        // push this decision to the resolver
     204                                        objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
     205                                        destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
     206                                }
    202207                        } else {
    203208                                // xxx - find a way to construct/destruct globals
    204209                                // hack: implicit "static" initialization routine for each struct type? or something similar?
    205210                                // --ties into module system
     211                                // this can be done by mangling main and replacing it with our own main which calls each
     212                                // module initialization routine in some decided order (order given in link command?)
     213                                // and finally calls mangled main
    206214                        }
    207215                }
  • src/ResolvExpr/Resolver.cc

    rc14cff1 r071a31a  
    479479                TypeEnvironment env;
    480480                AlternativeFinder finder( *this, env );
    481                 finder.find( ctorInit->get_ctor() );
    482 
    483                 if ( finder.get_alternatives().size() == 0 ) {
     481                try {
     482                        finder.find( ctorInit->get_ctor() );
     483                } catch ( SemanticError ) {
     484                        // no alternatives for the constructor initializer - fallback on C-style initializer
     485                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
    484486                        fallbackInit( ctorInit );
    485                 } else if ( finder.get_alternatives().size() == 1 ) {
     487                        return;
     488                }
     489
     490                assert( ! finder.get_alternatives().empty() );
     491
     492                if ( finder.get_alternatives().size() == 1 ) {
    486493                        Alternative &choice = finder.get_alternatives().front();
    487494                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( choice.expr ) ) {
  • src/SymTab/Validate.cc

    rc14cff1 r071a31a  
    698698        }
    699699
    700         Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
     700        void makeStructFunctionBody( StructDecl *aggregateDecl, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
     701                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
     702                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     703                                // query the type qualifiers of this field and skip assigning it if it is marked const.
     704                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
     705                                Type * type = dwt->get_type();
     706                                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     707                                        type = at->get_base();
     708                                }
     709
     710                                if ( type->get_qualifiers().isConst ) {
     711                                        // don't assign const members
     712                                        continue;
     713                                }
     714
     715                                // temporary hack: for now only works for 2 parameters
     716                                assert( func->get_functionType()->get_parameters().size() == 2 );
     717
     718                                ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
     719                                ObjectDecl * srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
     720                                ObjectDecl * returnVal;
     721                                if ( ! func->get_functionType()->get_returnVals().empty() ) {
     722                                        returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
     723                                }
     724
     725                                if ( isGeneric ) {
     726                                        // rewrite member type in terms of the type variables on this operator
     727                                        DeclarationWithType *fixedMember = dwt->clone();
     728                                        genericSubs.apply( fixedMember );
     729
     730                                        // assign to both destination and return value
     731                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
     732                                                makeArrayFunction( srcParam, dstParam, fixedMember, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     733                                                if ( returnVal ) makeArrayFunction( srcParam, returnVal, fixedMember, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     734                                        } else {
     735                                                makeScalarFunction( srcParam, dstParam, fixedMember, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     736                                                if ( returnVal ) makeScalarFunction( srcParam, returnVal, fixedMember, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     737                                        } // if
     738                                } else {
     739                                        // assign to destination
     740                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
     741                                                makeArrayFunction( srcParam, dstParam, dwt, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     742                                        } else {
     743                                                makeScalarFunction( srcParam, dstParam, dwt, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     744                                        } // if
     745                                } // if
     746                        } // if
     747                } // for
     748        } // makeStructFunctionBody
     749
     750        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    701751                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    702752
     
    715765                }
    716766
     767                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
     768                assignType->get_parameters().push_back( dstParam );
     769
     770                // void ?{}(T *); void ^?{}(T *);
     771                FunctionType *ctorType = assignType->clone();
     772                FunctionType *dtorType = assignType->clone();
     773
     774                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     775                assignType->get_parameters().push_back( srcParam );
     776
     777                // void ?{}(T *, T);
     778                FunctionType *copyCtorType = assignType->clone();
     779
     780                // T ?=?(T *, T);
    717781                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    718782                assignType->get_returnVals().push_back( returnVal );
    719 
    720                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    721                 assignType->get_parameters().push_back( dstParam );
    722 
    723                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    724                 assignType->get_parameters().push_back( srcParam );
    725783
    726784                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    727785                // because each unit generates copies of the default routines for each aggregate.
    728786                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
     787                FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
     788                FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, new CompoundStmt( noLabels ), true, false );
     789                FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
    729790                assignDecl->fixUniqueId();
    730 
    731                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    732                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    733                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    734                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    735                                 Type * type = dwt->get_type();
    736                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    737                                         type = at->get_base();
    738                                 }
    739 
    740                                 if ( type->get_qualifiers().isConst ) {
    741                                         // don't assign const members
    742                                         continue;
    743                                 }
    744 
    745                                 if ( isGeneric ) {
    746                                         // rewrite member type in terms of the type variables on this operator
    747                                         DeclarationWithType *fixedMember = dwt->clone();
    748                                         genericSubs.apply( fixedMember );
    749 
    750                                         // assign to both destination and return value
    751                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    752                                                 makeArrayFunction( srcParam, dstParam, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    753                                                 makeArrayFunction( srcParam, returnVal, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    754                                         } else {
    755                                                 makeScalarFunction( srcParam, dstParam, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    756                                                 makeScalarFunction( srcParam, returnVal, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    757                                         } // if
    758                                 } else {
    759                                         // assign to destination
    760                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    761                                                 makeArrayFunction( srcParam, dstParam, dwt, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    762                                         } else {
    763                                                 makeScalarFunction( srcParam, dstParam, dwt, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    764                                         } // if
    765                                 } // if
    766                         } // if
    767                 } // for
    768                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    769 
    770                 return assignDecl;
    771         }
    772 
    773         void makeStructCtorDtor( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    774                 FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
    775 
    776                 // Make function polymorphic in same parameters as generic struct, if applicable
    777                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    778                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    779                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    780                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    781                         isGeneric = true;
    782                         TypeDecl *typeParam = (*param)->clone();
    783                         ctorType->get_forall().push_back( typeParam );
    784                         structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    785                 }
    786 
    787                 ObjectDecl *thisParam = new ObjectDecl( "_this", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    788                 ctorType->get_parameters().push_back( thisParam );
    789 
    790                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    791                 // because each unit generates copies of the default routines for each aggregate.
    792                 FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, 0, true, false );
    793                 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
    794                 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
    795791                ctorDecl->fixUniqueId();
    796792                copyCtorDecl->fixUniqueId();
    797793                dtorDecl->fixUniqueId();
    798794
    799                 // add definitions
    800                 // TODO: add in calls to default constructors and destructors for fields
    801                 ctorDecl->set_statements( new CompoundStmt( noLabels ) );
    802                 copyCtorDecl->set_statements( new CompoundStmt( noLabels ) );
    803                 dtorDecl->set_statements( new CompoundStmt( noLabels ) );
     795                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     796
     797                makeStructFunctionBody( aggregateDecl, assignDecl, genericSubs, isGeneric );
     798                makeStructFunctionBody( aggregateDecl, copyCtorDecl, genericSubs, isGeneric );
     799
     800                declsToAdd.push_back( assignDecl );
    804801                declsToAdd.push_back( ctorDecl );
    805802                declsToAdd.push_back( copyCtorDecl );
    806803                declsToAdd.push_back( dtorDecl );
    807 
    808                 ObjectDecl * srcParam = new ObjectDecl( "_other", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    809                 copyCtorDecl->get_functionType()->get_parameters().push_back( srcParam );
    810                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    811                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    812                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    813                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    814                                 Type * type = dwt->get_type();
    815                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    816                                         type = at->get_base();
    817                                 }
    818 
    819                                 if ( type->get_qualifiers().isConst ) {
    820                                         // don't assign const members
    821                                         continue;
    822                                 }
    823 
    824                                 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    825                                         makeArrayFunction( srcParam, thisParam, dwt, array, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    826                                         // if ( isGeneric ) makeArrayFunction( srcParam, returnVal, dwt, array, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    827                                 } else {
    828                                         makeScalarFunction( srcParam, thisParam, dwt, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    829                                         // if ( isGeneric ) makeScalarCtor( srcParam, returnVal, dwt, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    830                                 } // if
    831                         } // if
    832                 } // for
    833                 // if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    834804        }
    835805
     
    904874                        StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    905875                        structInst.set_baseStruct( structDecl );
    906 
    907                         declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
    908                         makeStructCtorDtor( structDecl, &structInst, functionNesting, declsToAdd );
     876                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );
    909877                        structsDone.insert( structDecl->get_name() );
    910878                } // if
  • src/libcfa/prelude.cf

    rc14cff1 r071a31a  
    810810forall( dtype DT ) void ?{}( const volatile  DT * volatile *);
    811811
    812 forall( dtype DT ) void ?{}(          DT (*)[] ); // xxx - probably incomplete
    813 forall( dtype DT ) void ?{}( const    DT (*)[] );
    814 forall( dtype DT ) void ?{}( volatile DT (*)[] );
    815 forall( dtype DT ) void ?{}( const volatile DT (*)[] );
    816 
    817812void    ?{}(                void *          *);
    818813void    ?{}(                void * volatile *);
     
    837832forall( dtype DT ) void ^?{}( const volatile  DT * volatile *);
    838833
    839 forall( dtype DT ) void ^?{}(        DT (*) [] ); // xxx - probably incomplete
    840 forall( dtype DT ) void ^?{}( const    DT (*)[] );
    841 forall( dtype DT ) void ^?{}( volatile DT (*)[] );
    842 forall( dtype DT ) void ^?{}( const volatile DT (*)[] );
    843 
    844 
    845834void    ^?{}(               void *          *);
    846835void    ^?{}(               void * volatile *);
Note: See TracChangeset for help on using the changeset viewer.