Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r679864e1 rf9cebb5  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.cc -- 
     7// Resolver.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Sep 15 16:24:07 2015
    13 // Update Count     : 181
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 12 17:45:42 2016
     13// Update Count     : 204
    1414//
    1515
     
    2424#include "SynTree/Initializer.h"
    2525#include "SymTab/Indexer.h"
    26 #include "utility.h"
     26#include "SymTab/Autogen.h"
     27#include "Common/utility.h"
     28#include "InitTweak/InitTweak.h"
    2729
    2830#include <iostream>
     
    3335          public:
    3436                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    35  
     37
    3638                virtual void visit( FunctionDecl *functionDecl );
    3739                virtual void visit( ObjectDecl *functionDecl );
    3840                virtual void visit( TypeDecl *typeDecl );
     41                virtual void visit( EnumDecl * enumDecl );
    3942
    4043                virtual void visit( ArrayType * at );
     44                virtual void visit( PointerType * at );
    4145
    4246                virtual void visit( ExprStmt *exprStmt );
     
    4751                virtual void visit( ForStmt *forStmt );
    4852                virtual void visit( SwitchStmt *switchStmt );
    49                 virtual void visit( ChooseStmt *switchStmt );
    5053                virtual void visit( CaseStmt *caseStmt );
    5154                virtual void visit( BranchStmt *branchStmt );
     
    5457                virtual void visit( SingleInit *singleInit );
    5558                virtual void visit( ListInit *listInit );
     59                virtual void visit( ConstructorInit *ctorInit );
    5660          private:
    5761        typedef std::list< Initializer * >::iterator InitIterator;
    5862
     63                template< typename PtrType >
     64                void handlePtrType( PtrType * type );
     65
    5966          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    6067          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    61 
     68          void fallbackInit( ConstructorInit * ctorInit );
    6269                std::list< Type * > functionReturn;
    6370                Type *initContext;
    6471                Type *switchType;
     72                bool inEnumDecl = false;
    6573        };
    6674
     
    8290        }
    8391
     92
    8493        namespace {
    8594                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     
    8796                        env.makeSubstitution( *expr->get_env() );
    8897                }
    89 
    90                 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    91                         global_renamer.reset();
    92                         TypeEnvironment env;
    93                         Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    94                         finishExpr( newExpr, env );
    95                         return newExpr;
    96                 }
    97  
     98        } // namespace
     99
     100        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     101                global_renamer.reset();
     102                TypeEnvironment env;
     103                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     104                finishExpr( newExpr, env );
     105                return newExpr;
     106        }
     107
     108        namespace {
    98109                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99110                        TypeEnvironment env;
     
    126137                        } // if
    127138                }
    128  
     139
    129140                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130141                        TypeEnvironment env;
     
    159170                        return newExpr;
    160171                }
    161  
    162         }
    163  
     172
     173        }
     174
    164175        void Resolver::visit( ObjectDecl *objectDecl ) {
    165176                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
    166177                objectDecl->set_type( new_type );
     178                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
     179                // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes
     180                // initContext because of a function type can contain object declarations in the return and parameter types. So
     181                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
     182                // the RHS.
     183                Type *temp = initContext;
    167184                initContext = new_type;
     185                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     186                        // enumerator initializers should not use the enum type to initialize, since
     187                        // the enum type is still incomplete at this point. Use signed int instead.
     188                        initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     189                }
    168190                SymTab::Indexer::visit( objectDecl );
     191                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     192                        // delete newly created signed int type
     193                        delete initContext;
     194                }
     195                initContext = temp;
     196        }
     197
     198        template< typename PtrType >
     199        void Resolver::handlePtrType( PtrType * type ) {
     200                if ( type->get_dimension() ) {
     201                        CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
     202                        Expression *newExpr = findSingleExpression( castExpr, *this );
     203                        delete type->get_dimension();
     204                        type->set_dimension( newExpr );
     205                }
    169206        }
    170207
    171208        void Resolver::visit( ArrayType * at ) {
    172                 if ( at->get_dimension() ) {
    173                         BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    174                         CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
    175                         Expression *newExpr = findSingleExpression( castExpr, *this );
    176                         delete at->get_dimension();
    177                         at->set_dimension( newExpr );
    178                 }
     209                handlePtrType( at );
    179210                Visitor::visit( at );
     211        }
     212
     213        void Resolver::visit( PointerType * pt ) {
     214                handlePtrType( pt );
     215                Visitor::visit( pt );
    180216        }
    181217
     
    205241        }
    206242
     243        void Resolver::visit( EnumDecl * enumDecl ) {
     244                // in case we decide to allow nested enums
     245                bool oldInEnumDecl = inEnumDecl;
     246                inEnumDecl = true;
     247                SymTab::Indexer::visit( enumDecl );
     248                inEnumDecl = oldInEnumDecl;
     249        }
     250
    207251        void Resolver::visit( ExprStmt *exprStmt ) {
    208252                if ( exprStmt->get_expr() ) {
     
    251295                        forStmt->set_condition( newExpr );
    252296                } // if
    253                
     297
    254298                if ( forStmt->get_increment() ) {
    255299                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    265309                delete switchStmt->get_condition();
    266310                switchStmt->set_condition( newExpr );
    267  
     311
    268312                visitor.Visitor::visit( switchStmt );
    269313        }
    270314
    271315        void Resolver::visit( SwitchStmt *switchStmt ) {
    272                 handleSwitchStmt( switchStmt, *this );
    273         }
    274 
    275         void Resolver::visit( ChooseStmt *switchStmt ) {
    276316                handleSwitchStmt( switchStmt, *this );
    277317        }
     
    307347        bool isCharType( T t ) {
    308348                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    309                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     349                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    310350                                bt->get_kind() == BasicType::UnsignedChar;
    311351                }
     
    319359                                string n = ne->get_name();
    320360                                if (n == "0") {
    321                                         initContext = new BasicType(Type::Qualifiers(), 
     361                                        initContext = new BasicType(Type::Qualifiers(),
    322362                                                                                                BasicType::SignedInt);
    323363                                } else {
    324                                         DeclarationWithType * decl = lookupId(n);
     364                                        DeclarationWithType * decl = lookupId( n );
    325365                                        initContext = decl->get_type();
    326366                                }
    327                         } else if (ConstantExpr * e = 
     367                        } else if (ConstantExpr * e =
    328368                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    329369                                Constant *c = e->get_constant();
     
    344384                                        if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) {
    345385                                                if ( isCharType( pt->get_base() ) ) {
    346                                                         // strip cast if we're initializing a char[] with a char *, e.g.
    347                                                         // char x[] = "hello";
     386                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    348387                                                        CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
    349388                                                        singleInit->set_value( ce->get_arg() );
    350389                                                        ce->set_arg( NULL );
    351                                                         delete ce;                                                                     
     390                                                        delete ce;
    352391                                                }
    353392                                        }
     
    396435
    397436        void Resolver::visit( ListInit * listInit ) {
    398                 InitIterator iter = listInit->begin_initializers();
    399                 InitIterator end = listInit->end_initializers();
     437                InitIterator iter = listInit->begin();
     438                InitIterator end = listInit->end();
    400439
    401440                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     
    407446                } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
    408447                        resolveAggrInit( st->get_baseStruct(), iter, end );
    409                 } else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {
     448                } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) {
    410449                        resolveAggrInit( st->get_baseUnion(), iter, end );
    411                 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    412                         // try again...
    413                         initContext = tt->get_baseType()->get_base();
    414                         visit(listInit);
    415450                } else {
    416                         assert( dynamic_cast< BasicType * >( initContext ) );
    417451                        // basic types are handled here
    418452                        Visitor::visit( listInit );
     
    470504#endif
    471505        }
     506
     507        // ConstructorInit - fall back on C-style initializer
     508        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     509                // could not find valid constructor, or found an intrinsic constructor
     510                // fall back on C-style initializer
     511                delete ctorInit->get_ctor();
     512                ctorInit->set_ctor( NULL );
     513                delete ctorInit->get_dtor();
     514                ctorInit->set_dtor( NULL );
     515                maybeAccept( ctorInit->get_init(), *this );
     516        }
     517
     518        void Resolver::visit( ConstructorInit *ctorInit ) {
     519                try {
     520                        maybeAccept( ctorInit->get_ctor(), *this );
     521                        maybeAccept( ctorInit->get_dtor(), *this );
     522                } catch ( SemanticError ) {
     523                        // no alternatives for the constructor initializer - fallback on C-style initializer
     524                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
     525                        fallbackInit( ctorInit );
     526                        return;
     527                }
     528
     529                // found a constructor - can get rid of C-style initializer
     530                delete ctorInit->get_init();
     531                ctorInit->set_init( NULL );
     532
     533                // intrinsic single parameter constructors and destructors do nothing. Since this was
     534                // implicitly generated, there's no way for it to have side effects, so get rid of it
     535                // to clean up generated code.
     536                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     537                        delete ctorInit->get_ctor();
     538                        ctorInit->set_ctor( NULL );
     539                }
     540
     541                // xxx - todo
     542                // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
     543                //      // can reduce the constructor down to a SingleInit using the
     544                //      // second argument from the ctor call
     545                // }
     546
     547                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
     548                        delete ctorInit->get_dtor();
     549                        ctorInit->set_dtor( NULL );
     550                }
     551        }
    472552} // namespace ResolvExpr
    473553
Note: See TracChangeset for help on using the changeset viewer.