Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r32d281d r1cbca6e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Nov 20 16:33:52 2015
    13 // Update Count     : 201
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Aug 11 16:59:35 2015
     13// Update Count     : 196
    1414//
    1515
     
    126126        };
    127127
    128         class AutogenerateRoutines : public Visitor {
     128        class AddStructAssignment : public Visitor {
    129129          public:
    130130                /// Generates assignment operators for aggregate types as required
    131                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     131                static void addStructAssignment( std::list< Declaration * > &translationUnit );
    132132
    133133                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     
    152152                virtual void visit( CatchStmt *catchStmt );
    153153
    154                 AutogenerateRoutines() : functionNesting( 0 ) {}
     154                AddStructAssignment() : functionNesting( 0 ) {}
    155155          private:
    156156                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     
    196196                acceptAll( translationUnit, pass1 );
    197197                acceptAll( translationUnit, pass2 );
    198                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     198                // need to collect all of the assignment operators prior to
     199                // this point and only generate assignment operators if one doesn't exist
     200                AddStructAssignment::addStructAssignment( translationUnit );
    199201                acceptAll( translationUnit, pass3 );
    200202        }
     
    500502        static const std::list< std::string > noLabels;
    501503
    502         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    503                 AutogenerateRoutines visitor;
     504        void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
     505                AddStructAssignment visitor;
    504506                acceptAndAdd( translationUnit, visitor, false );
    505507        }
     
    625627        }
    626628
    627         /// Clones a reference type, replacing any parameters it may have with a clone of the provided list
    628         template< typename GenericInstType >
    629         GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
    630                 GenericInstType *clone = refType->clone();
    631                 clone->get_parameters().clear();
    632                 cloneAll( params, clone->get_parameters() );
    633                 return clone;
    634         }
    635629
    636630        Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    637631                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    638 
    639                 // Make function polymorphic in same parameters as generic struct, if applicable
    640                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    641                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    642                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    643                         TypeDecl *typeParam = (*param)->clone();
    644                         assignType->get_forall().push_back( typeParam );
    645                         structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    646                 }
    647  
    648                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     632 
     633                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    649634                assignType->get_returnVals().push_back( returnVal );
    650635 
    651                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
     636                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    652637                assignType->get_parameters().push_back( dstParam );
    653638 
    654                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     639                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    655640                assignType->get_parameters().push_back( srcParam );
    656641
     
    688673        Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    689674                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    690 
    691                 // Make function polymorphic in same parameters as generic union, if applicable
    692                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    693                 std::list< Expression* > unionParams;  // List of matching parameters to put on types
    694                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    695                         TypeDecl *typeParam = (*param)->clone();
    696                         assignType->get_forall().push_back( typeParam );
    697                         unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    698                 }
    699  
    700                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     675 
     676                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    701677                assignType->get_returnVals().push_back( returnVal );
    702678 
    703                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
     679                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    704680                assignType->get_parameters().push_back( dstParam );
    705681 
    706                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     682                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    707683                assignType->get_parameters().push_back( srcParam );
    708684 
     
    715691                copy->get_args().push_back( new VariableExpr( dstParam ) );
    716692                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    717                 copy->get_args().push_back( new SizeofExpr( cloneWithParams( refType, unionParams ) ) );
     693                copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
    718694
    719695                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
     
    723699        }
    724700
    725         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
     701        void AddStructAssignment::visit( EnumDecl *enumDecl ) {
    726702                if ( ! enumDecl->get_members().empty() ) {
    727703                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    732708        }
    733709
    734         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
     710        void AddStructAssignment::visit( StructDecl *structDecl ) {
    735711                if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    736                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    737                         structInst.set_baseStruct( structDecl );
    738                         declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
     712                        StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     713                        structInst->set_baseStruct( structDecl );
     714                        declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
    739715                        structsDone.insert( structDecl->get_name() );
    740716                } // if
    741717        }
    742718
    743         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     719        void AddStructAssignment::visit( UnionDecl *unionDecl ) {
    744720                if ( ! unionDecl->get_members().empty() ) {
    745                         UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    746                         unionInst.set_baseUnion( unionDecl );
    747                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
    748                 } // if
    749         }
    750 
    751         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     721                        UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     722                        unionInst->set_baseUnion( unionDecl );
     723                        declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
     724                } // if
     725        }
     726
     727        void AddStructAssignment::visit( TypeDecl *typeDecl ) {
    752728                CompoundStmt *stmts = 0;
    753729                TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     
    777753        }
    778754
    779         void AutogenerateRoutines::visit( FunctionType *) {
     755        void AddStructAssignment::visit( FunctionType *) {
    780756                // ensure that we don't add assignment ops for types defined as part of the function
    781757        }
    782758
    783         void AutogenerateRoutines::visit( PointerType *) {
     759        void AddStructAssignment::visit( PointerType *) {
    784760                // ensure that we don't add assignment ops for types defined as part of the pointer
    785761        }
    786762
    787         void AutogenerateRoutines::visit( ContextDecl *) {
     763        void AddStructAssignment::visit( ContextDecl *) {
    788764                // ensure that we don't add assignment ops for types defined as part of the context
    789765        }
    790766
    791767        template< typename StmtClass >
    792         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
     768        inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
    793769                std::set< std::string > oldStructs = structsDone;
    794770                addVisit( stmt, *this );
     
    796772        }
    797773
    798         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     774        void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
    799775                maybeAccept( functionDecl->get_functionType(), *this );
    800776                acceptAll( functionDecl->get_oldDecls(), *this );
     
    804780        }
    805781
    806         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
     782        void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
    807783                visitStatement( compoundStmt );
    808784        }
    809785
    810         void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
     786        void AddStructAssignment::visit( IfStmt *ifStmt ) {
    811787                visitStatement( ifStmt );
    812788        }
    813789
    814         void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
     790        void AddStructAssignment::visit( WhileStmt *whileStmt ) {
    815791                visitStatement( whileStmt );
    816792        }
    817793
    818         void AutogenerateRoutines::visit( ForStmt *forStmt ) {
     794        void AddStructAssignment::visit( ForStmt *forStmt ) {
    819795                visitStatement( forStmt );
    820796        }
    821797
    822         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
     798        void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
    823799                visitStatement( switchStmt );
    824800        }
    825801
    826         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
     802        void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
    827803                visitStatement( switchStmt );
    828804        }
    829805
    830         void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
     806        void AddStructAssignment::visit( CaseStmt *caseStmt ) {
    831807                visitStatement( caseStmt );
    832808        }
    833809
    834         void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
     810        void AddStructAssignment::visit( CatchStmt *cathStmt ) {
    835811                visitStatement( cathStmt );
    836812        }
Note: See TracChangeset for help on using the changeset viewer.