Changeset 071a31a for src/SymTab


Ignore:
Timestamp:
Mar 3, 2016, 2:45:51 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:
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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.