Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rde62360d r94b4364  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 24 15:47:16 2015
    13 // Update Count     : 50
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jun 16 14:50:11 2015
     13// Update Count     : 154
    1414//
    1515
     
    3838                virtual void visit( TypeDecl *typeDecl );
    3939
     40                virtual void visit( ArrayType * at );
     41
    4042                virtual void visit( ExprStmt *exprStmt );
    4143                virtual void visit( IfStmt *ifStmt );
     
    4547                virtual void visit( ChooseStmt *switchStmt );
    4648                virtual void visit( CaseStmt *caseStmt );
    47                 virtual void visit( BranchStmt *branchStmt );
    4849                virtual void visit( ReturnStmt *returnStmt );
    4950
     
    5152                virtual void visit( ListInit *listInit );
    5253          private:
     54        typedef std::list< Initializer * >::iterator InitIterator;
     55
     56          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
     57          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
     58
    5359                std::list< Type * > functionReturn;
    5460                Type *initContext;
     
    158164                initContext = new_type;
    159165                SymTab::Indexer::visit( objectDecl );
    160 
    161                 if ( ArrayType * at = dynamic_cast< ArrayType * >( new_type ) ){
    162                         if ( at->get_dimension() ) {
    163                                 BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    164                                 CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
    165                                 Expression *newExpr = findSingleExpression( castExpr, *this );
    166                                 delete at->get_dimension();
    167                                 at->set_dimension( newExpr );
    168                         }
    169                 }
    170         }
    171  
     166        }
     167
     168        void Resolver::visit( ArrayType * at ) {
     169                if ( at->get_dimension() ) {
     170                        BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     171                        CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
     172                        Expression *newExpr = findSingleExpression( castExpr, *this );
     173                        delete at->get_dimension();
     174                        at->set_dimension( newExpr );
     175                }
     176                Visitor::visit( at );
     177        }
     178
    172179        void Resolver::visit( TypeDecl *typeDecl ) {
    173180                if ( typeDecl->get_base() ) {
     
    177184                SymTab::Indexer::visit( typeDecl );
    178185        }
    179  
     186
    180187        void Resolver::visit( FunctionDecl *functionDecl ) {
    181188#if 0
     
    263270        }
    264271
    265         void Resolver::visit( BranchStmt *branchStmt ) {
    266                 // must resolve the argument for a computed goto
    267                 if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
    268                         if ( NameExpr * arg = dynamic_cast< NameExpr * >( branchStmt->get_computedTarget() ) ) {
    269                                 VoidType v = Type::Qualifiers();                // cast to void * for the alternative finder
    270                                 PointerType pt( Type::Qualifiers(), v.clone() );
    271                                 CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    272                                 Expression * newExpr = findSingleExpression( castExpr, *this ); // find best expression
    273                                 branchStmt->set_target( newExpr );
    274                         } // if
    275                 } // if
    276         }
    277 
    278272        void Resolver::visit( ReturnStmt *returnStmt ) {
    279273                if ( returnStmt->get_expr() ) {
     
    284278                        returnStmt->set_expr( newExpr );
    285279                } // if
     280        }
     281
     282        template< typename T >
     283        bool isCharType( T t ) {
     284                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
     285                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     286                                bt->get_kind() == BasicType::UnsignedChar;
     287                }
     288                return false;
    286289        }
    287290
     
    310313                        delete castExpr;
    311314                        singleInit->set_value( newExpr );
     315
     316                        // check if initializing type is char[]
     317                        if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     318                                if ( isCharType( at->get_base() ) ) {
     319                                        // check if the resolved type is char *
     320                                        if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) {
     321                                                if ( isCharType( pt->get_base() ) ) {
     322                                                        // strip cast if we're initializing a char[] with a char *, e.g.
     323                                                        // char x[] = "hello";
     324                                                        CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
     325                                                        singleInit->set_value( ce->get_arg() );
     326                                                        ce->set_arg( NULL );
     327                                                        delete ce;                                                                     
     328                                                }
     329                                        }
     330                                }
     331                        }
    312332                } // if
    313333//      singleInit->get_value()->accept( *this );
    314334        }
    315335
    316         void Resolver::visit( ListInit *listInit ) {
    317                 Visitor::visit(listInit);
     336        void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd ) {
     337                DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
     338                assert( dt );
     339                initContext = dt->get_type();
     340                try {
     341                        if ( init == initEnd ) return; // stop when there are no more initializers
     342                        (*init)->accept( *this );
     343                        ++init; // made it past an initializer
     344                } catch( SemanticError & ) {
     345                        // need to delve deeper, if you can
     346                        if ( StructInstType * sit = dynamic_cast< StructInstType * >( dt->get_type() ) ) {
     347                                resolveAggrInit( sit->get_baseStruct(), init, initEnd );
     348                        } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( dt->get_type() ) ) {
     349                                resolveAggrInit( uit->get_baseUnion(), init, initEnd );
     350                        } else {
     351                                // might need to rethink what is being thrown
     352                                throw;
     353                        } // if
     354                }
     355        }
     356
     357        void Resolver::resolveAggrInit( AggregateDecl * aggr, InitIterator & init, InitIterator & initEnd ) {
     358                if ( StructDecl * st = dynamic_cast< StructDecl * >( aggr ) ) {
     359                        // want to resolve each initializer to the members of the struct,
     360                        // but if there are more initializers than members we should stop
     361                        list< Declaration * >::iterator it = st->get_members().begin();
     362                        for ( ; it != st->get_members().end(); ++it) {
     363                                resolveSingleAggrInit( *it, init, initEnd );
     364                        }
     365                } else if ( UnionDecl * un = dynamic_cast< UnionDecl * >( aggr ) ) {
     366                        // only resolve to the first member of a union
     367                        resolveSingleAggrInit( *un->get_members().begin(), init, initEnd );
     368                } // if
     369        }
     370
     371        void Resolver::visit( ListInit * listInit ) {
     372                InitIterator iter = listInit->begin_initializers();
     373                InitIterator end = listInit->end_initializers();
     374
     375                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     376                        // resolve each member to the base type of the array
     377                        for ( ; iter != end; ++iter ) {
     378                                initContext = at->get_base();
     379                                (*iter)->accept( *this );
     380                        } // for
     381                } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
     382                        resolveAggrInit( st->get_baseStruct(), iter, end );
     383                } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) {
     384                        resolveAggrInit( st->get_baseUnion(), iter, end );
     385                } else {
     386                        // basic types are handled here
     387                        Visitor::visit( listInit );
     388                }
     389
    318390#if 0
    319391                if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
Note: See TracChangeset for help on using the changeset viewer.