Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rf066321 r37a3b8f9  
    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 : Thu Nov 19 10:44:55 2015
    13 // Update Count     : 199
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Aug 11 16:59:35 2015
     13// Update Count     : 196
    1414//
    1515
     
    5454#include "MakeLibCfa.h"
    5555#include "TypeEquality.h"
    56 #include "ResolvExpr/typeops.h"
    5756
    5857#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    126125        };
    127126
    128         class AutogenerateRoutines : public Visitor {
     127        class AddStructAssignment : public Visitor {
    129128          public:
    130129                /// Generates assignment operators for aggregate types as required
    131                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     130                static void addStructAssignment( std::list< Declaration * > &translationUnit );
    132131
    133132                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     
    152151                virtual void visit( CatchStmt *catchStmt );
    153152
    154                 AutogenerateRoutines() : functionNesting( 0 ) {}
     153                AddStructAssignment() : functionNesting( 0 ) {}
    155154          private:
    156155                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     
    196195                acceptAll( translationUnit, pass1 );
    197196                acceptAll( translationUnit, pass2 );
    198                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     197                // need to collect all of the assignment operators prior to
     198                // this point and only generate assignment operators if one doesn't exist
     199                AddStructAssignment::addStructAssignment( translationUnit );
    199200                acceptAll( translationUnit, pass3 );
    200201        }
     
    500501        static const std::list< std::string > noLabels;
    501502
    502         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    503                 AutogenerateRoutines visitor;
     503        void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
     504                AddStructAssignment visitor;
    504505                acceptAndAdd( translationUnit, visitor, false );
    505506        }
     
    628629        Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    629630                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     631
     632                // Make function polymorphic in same parameters as generic struct, if applicable
     633                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
     634                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     635                        assignType->get_forall().push_back( (*param)->clone() );
     636                }
    630637 
    631638                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     
    697704        }
    698705
    699         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
     706        void AddStructAssignment::visit( EnumDecl *enumDecl ) {
    700707                if ( ! enumDecl->get_members().empty() ) {
    701708                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     
    706713        }
    707714
    708         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
     715        void AddStructAssignment::visit( StructDecl *structDecl ) {
    709716                if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    710717                        StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     
    715722        }
    716723
    717         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
     724        void AddStructAssignment::visit( UnionDecl *unionDecl ) {
    718725                if ( ! unionDecl->get_members().empty() ) {
    719726                        UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     
    723730        }
    724731
    725         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
     732        void AddStructAssignment::visit( TypeDecl *typeDecl ) {
    726733                CompoundStmt *stmts = 0;
    727734                TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     
    751758        }
    752759
    753         void AutogenerateRoutines::visit( FunctionType *) {
     760        void AddStructAssignment::visit( FunctionType *) {
    754761                // ensure that we don't add assignment ops for types defined as part of the function
    755762        }
    756763
    757         void AutogenerateRoutines::visit( PointerType *) {
     764        void AddStructAssignment::visit( PointerType *) {
    758765                // ensure that we don't add assignment ops for types defined as part of the pointer
    759766        }
    760767
    761         void AutogenerateRoutines::visit( ContextDecl *) {
     768        void AddStructAssignment::visit( ContextDecl *) {
    762769                // ensure that we don't add assignment ops for types defined as part of the context
    763770        }
    764771
    765772        template< typename StmtClass >
    766         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
     773        inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
    767774                std::set< std::string > oldStructs = structsDone;
    768775                addVisit( stmt, *this );
     
    770777        }
    771778
    772         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     779        void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
    773780                maybeAccept( functionDecl->get_functionType(), *this );
    774781                acceptAll( functionDecl->get_oldDecls(), *this );
     
    778785        }
    779786
    780         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
     787        void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
    781788                visitStatement( compoundStmt );
    782789        }
    783790
    784         void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
     791        void AddStructAssignment::visit( IfStmt *ifStmt ) {
    785792                visitStatement( ifStmt );
    786793        }
    787794
    788         void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
     795        void AddStructAssignment::visit( WhileStmt *whileStmt ) {
    789796                visitStatement( whileStmt );
    790797        }
    791798
    792         void AutogenerateRoutines::visit( ForStmt *forStmt ) {
     799        void AddStructAssignment::visit( ForStmt *forStmt ) {
    793800                visitStatement( forStmt );
    794801        }
    795802
    796         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
     803        void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
    797804                visitStatement( switchStmt );
    798805        }
    799806
    800         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
     807        void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
    801808                visitStatement( switchStmt );
    802809        }
    803810
    804         void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
     811        void AddStructAssignment::visit( CaseStmt *caseStmt ) {
    805812                visitStatement( caseStmt );
    806813        }
    807814
    808         void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
     815        void AddStructAssignment::visit( CatchStmt *cathStmt ) {
    809816                visitStatement( cathStmt );
    810817        }
     
    850857                        Type * t1 = tyDecl->get_base();
    851858                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    852                         if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
     859                        if ( ! typeEquals( t1, t2, true ) ) {
    853860                                throw SemanticError( "cannot redefine typedef: " + tyDecl->get_name() );
    854861                        }
Note: See TracChangeset for help on using the changeset viewer.