Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r4d2434a r4e06c1e  
    2424#include "SynTree/Initializer.h"
    2525#include "SymTab/Indexer.h"
    26 #include "SymTab/Autogen.h"
    2726#include "Common/utility.h"
    2827#include "InitTweak/InitTweak.h"
     
    4241
    4342                virtual void visit( ArrayType * at );
    44                 virtual void visit( PointerType * at );
    4543
    4644                virtual void visit( ExprStmt *exprStmt );
     
    5452                virtual void visit( BranchStmt *branchStmt );
    5553                virtual void visit( ReturnStmt *returnStmt );
     54                virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5655
    5756                virtual void visit( SingleInit *singleInit );
     
    6059          private:
    6160        typedef std::list< Initializer * >::iterator InitIterator;
    62 
    63                 template< typename PtrType >
    64                 void handlePtrType( PtrType * type );
    6561
    6662          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
     
    196192        }
    197193
    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() );
     194        void Resolver::visit( ArrayType * at ) {
     195                if ( at->get_dimension() ) {
     196                        BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     197                        CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
    202198                        Expression *newExpr = findSingleExpression( castExpr, *this );
    203                         delete type->get_dimension();
    204                         type->set_dimension( newExpr );
    205                 }
    206         }
    207 
    208         void Resolver::visit( ArrayType * at ) {
    209                 handlePtrType( at );
     199                        delete at->get_dimension();
     200                        at->set_dimension( newExpr );
     201                }
    210202                Visitor::visit( at );
    211         }
    212 
    213         void Resolver::visit( PointerType * pt ) {
    214                 handlePtrType( pt );
    215                 Visitor::visit( pt );
    216203        }
    217204
     
    435422
    436423        void Resolver::visit( ListInit * listInit ) {
    437                 InitIterator iter = listInit->begin();
    438                 InitIterator end = listInit->end();
     424                InitIterator iter = listInit->begin_initializers();
     425                InitIterator end = listInit->end_initializers();
    439426
    440427                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     
    538525                        ctorInit->set_ctor( NULL );
    539526                }
    540                 if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
     527                if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
    541528                        delete ctorInit->get_dtor();
    542529                        ctorInit->set_dtor( NULL );
    543530                }
     531        }
     532
     533        void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
     534                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
     535                // Do this through a cast expression to greatly simplify the code.
     536                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     537                assert( callExpr );
     538                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
     539                Type * type = 0;
     540
     541                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     542                // includes an untyped '+' expression.
     543                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     544                        // constructee is <array>+<index>
     545                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     546                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     547                        assert( dynamic_cast< VariableExpr * >( arr ) );
     548                        assert( arr && arr->get_results().size() == 1 );
     549                        type = arr->get_results().front()->clone();
     550                } else {
     551                        // otherwise, constructing a plain object, which means the object's address is being taken.
     552                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     553                        // type of the VariableExpr to do so.
     554                        assert( constructee->get_results().size() == 1 );
     555                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     556                        assert( addrExpr && addrExpr->get_results().size() == 1);
     557                        type = addrExpr->get_results().front()->clone();
     558                }
     559                // cast to T* with qualifiers removed.
     560                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     561                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     562                // remove lvalue as a qualifier, this can change to
     563                //   type->get_qualifiers() = Type::Qualifiers();
     564                Type * base = InitTweak::getPointerBase( type );
     565                assert( base );
     566                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     567                // if pointer has lvalue qualifier, cast won't appear in output
     568                type->set_isLvalue( false );
     569                constructee = new CastExpr( constructee, type );
     570
     571                // finally, resolve the ctor/dtor
     572                impCtorDtorStmt->get_callStmt()->accept( *this );
    544573        }
    545574} // namespace ResolvExpr
Note: See TracChangeset for help on using the changeset viewer.