Changeset a9a259c


Ignore:
Timestamp:
Feb 25, 2016, 4:34:09 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:
c14cff1
Parents:
ae42f2a
Message:

autogenerate union ctor/dtors, autogenerate struct copy ctor, temporarily allow explicit calls to autogenerated ctors, add copy ctor to type constraints

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rae42f2a ra9a259c  
    263263
    264264                                  case OT_CTOR:
     265                                  // it's just an optimization to disallow this, so for now let it through
     266                                  // since it makes autogenerating constructors a lot easier
     267                                varExpr->accept( *this );
     268                                        output << "(";
     269                                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
     270                                        output << ")";
     271
    265272                                  // intrinsic constructors should never be called directly - they should be transformed back into Initializer nodes
    266                                   assert(false);
     273                                  // assert(false);
    267274                                  break;
    268275
  • src/Parser/TypeData.cc

    rae42f2a ra9a259c  
    437437                if ( (*i)->get_kind() == TypeDecl::Any ) {
    438438                        // add assertion parameters to `type' tyvars
    439                         // add:  T * ?=?(T *, T)
     439                        // add assignment operator:  T * ?=?(T *, T)
    440440                        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    441441                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     
    444444                        (*i)->get_assertions().push_front( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignType, 0, false, false ) );
    445445
    446                         // add:  void ?{}(T *)
     446                        // add default ctor:  void ?{}(T *)
    447447                        FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
    448448                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
    449449                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
    450450
    451                         // add:  void ^?{}(T *)
     451                        // add copy ctor:  void ?{}(T *, T)
     452                        FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
     453                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     454                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     455                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
     456
     457                        // add dtor:  void ^?{}(T *)
    452458                        FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
    453459                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
  • src/ResolvExpr/Resolver.cc

    rae42f2a ra9a259c  
    487487                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( choice.expr ) ) {
    488488                                if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
    489                                         if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    490                                                 // if the constructor that was found is intrinsic, reset to C-style
     489                                        if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
     490                                                // if the constructor that was found is intrinsic or autogenerated, reset to C-style
    491491                                                // initializer so that code generation is easy to handle
    492492                                                fallbackInit( ctorInit );
  • src/SymTab/Validate.cc

    rae42f2a ra9a259c  
    535535
    536536        template< typename OutputIterator >
    537         void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
     537        void makeScalarFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    538538                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    539539                // unnamed bit fields are not copied as they cannot be accessed
    540540                if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    541541
    542                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     542                // want to be able to generate assignment, ctor, and dtor generically,
     543                // so fname is either ?=?, ?{}, or ^?{}
     544                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    543545
    544546                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    547549                // do something special for unnamed members
    548550                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    549                 assignExpr->get_args().push_back( dstselect );
     551                fExpr->get_args().push_back( dstselect );
    550552
    551553                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    552                 assignExpr->get_args().push_back( srcselect );
    553 
    554                 *out++ = new ExprStmt( noLabels, assignExpr );
     554                fExpr->get_args().push_back( srcselect );
     555
     556                *out++ = new ExprStmt( noLabels, fExpr );
    555557        }
    556558
    557559        template< typename OutputIterator >
    558         void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
     560        void makeArrayFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, std::string fname, OutputIterator out ) {
    559561                static UniqueName indexName( "_index" );
    560562
     
    579581                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    580582
    581                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     583                // want to be able to generate assignment, ctor, and dtor generically,
     584                // so fname is either ?=?, ?{}, or ^?{}
     585                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    582586
    583587                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    588592                dstIndex->get_args().push_back( dstselect );
    589593                dstIndex->get_args().push_back( new VariableExpr( index ) );
    590                 assignExpr->get_args().push_back( dstIndex );
     594                fExpr->get_args().push_back( dstIndex );
    591595
    592596                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     
    594598                srcIndex->get_args().push_back( srcselect );
    595599                srcIndex->get_args().push_back( new VariableExpr( index ) );
    596                 assignExpr->get_args().push_back( srcIndex );
    597 
    598                 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
     600                fExpr->get_args().push_back( srcIndex );
     601
     602                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) );
    599603        }
    600604
     
    746750                                        // assign to both destination and return value
    747751                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    748                                                 makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    749                                                 makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     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() ) );
    750754                                        } else {
    751                                                 makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    752                                                 makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
     755                                                makeScalarFunction( srcParam, dstParam, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     756                                                makeScalarFunction( srcParam, returnVal, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    753757                                        } // if
    754758                                } else {
    755759                                        // assign to destination
    756760                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    757                                                 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     761                                                makeArrayFunction( srcParam, dstParam, dwt, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    758762                                        } else {
    759                                                 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     763                                                makeScalarFunction( srcParam, dstParam, dwt, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    760764                                        } // if
    761765                                } // if
     
    766770                return assignDecl;
    767771        }
    768 
    769772
    770773        void makeStructCtorDtor( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
     
    788791                // because each unit generates copies of the default routines for each aggregate.
    789792                FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, 0, true, false );
    790                 FunctionDecl *dtorDecl = 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 );
    791795                ctorDecl->fixUniqueId();
     796                copyCtorDecl->fixUniqueId();
    792797                dtorDecl->fixUniqueId();
    793798
     
    795800                // TODO: add in calls to default constructors and destructors for fields
    796801                ctorDecl->set_statements( new CompoundStmt( noLabels ) );
     802                copyCtorDecl->set_statements( new CompoundStmt( noLabels ) );
    797803                dtorDecl->set_statements( new CompoundStmt( noLabels ) );
    798804                declsToAdd.push_back( ctorDecl );
     805                declsToAdd.push_back( copyCtorDecl );
    799806                declsToAdd.push_back( dtorDecl );
    800807
    801 
    802                 // for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    803                 //      if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    804                 //              // query the type qualifiers of this field and skip assigning it if it is marked const.
    805                 //              // If it is an array type, we need to strip off the array layers to find its qualifiers.
    806                 //              Type * type = dwt->get_type();
    807                 //              while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    808                 //                      type = at->get_base();
    809                 //              }
    810 
    811                 //              if ( type->get_qualifiers().isConst ) {
    812                 //                      // don't assign const members
    813                 //                      continue;
    814                 //              }
    815 
    816                 //              if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    817                 //                      makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    818                 //                      if ( isGeneric ) makeArrayAssignment( srcParam, returnVal, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    819                 //              } else {
    820                 //                      makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    821                 //                      if ( isGeneric ) makeScalarAssignment( srcParam, returnVal, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    822                 //              } // if
    823                 //      } // if
    824                 // } // for
     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
    825833                // if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    826 
    827                 // return assignDecl;
    828         }
    829 
    830         Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
     834        }
     835
     836        void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    831837                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    832838
     
    842848                }
    843849
     850                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
     851                assignType->get_parameters().push_back( dstParam );
     852
     853                // default ctor/dtor need only first parameter
     854                FunctionType * ctorType = assignType->clone();
     855                FunctionType * dtorType = assignType->clone();
     856
     857                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     858                assignType->get_parameters().push_back( srcParam );
     859
     860                // copy ctor needs both parameters
     861                FunctionType * copyCtorType = assignType->clone();
     862
     863                // assignment needs both and return value
    844864                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    845865                assignType->get_returnVals().push_back( returnVal );
    846 
    847                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    848                 assignType->get_parameters().push_back( dstParam );
    849 
    850                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    851                 assignType->get_parameters().push_back( srcParam );
    852866
    853867                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    854868                // because each unit generates copies of the default routines for each aggregate.
    855869                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
     870                FunctionDecl *ctorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
     871                FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );
     872                FunctionDecl *dtorDecl = new FunctionDecl( "^?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
     873
    856874                assignDecl->fixUniqueId();
     875                ctorDecl->fixUniqueId();
     876                copyCtorDecl->fixUniqueId();
     877                dtorDecl->fixUniqueId();
    857878
    858879                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     
    861882                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    862883
    863                 return assignDecl;
     884                // body of assignment and copy ctor is the same
     885                copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
     886
     887                declsToAdd.push_back( assignDecl );
     888                declsToAdd.push_back( ctorDecl );
     889                declsToAdd.push_back( copyCtorDecl );
     890                declsToAdd.push_back( dtorDecl );
    864891        }
    865892
     
    888915                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    889916                        unionInst.set_baseUnion( unionDecl );
    890                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
     917                        makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd );
    891918                } // if
    892919        }
Note: See TracChangeset for help on using the changeset viewer.