Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r7b3f66b r64071c2  
    5252                virtual void visit( BranchStmt *branchStmt );
    5353                virtual void visit( ReturnStmt *returnStmt );
     54                virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5455
    5556                virtual void visit( SingleInit *singleInit );
     
    492493                } catch ( SemanticError ) {
    493494                        // no alternatives for the constructor initializer - fallback on C-style initializer
    494                         // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     495                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
    495496                        fallbackInit( ctorInit );
    496497                        return;
     
    513514                }
    514515        }
     516
     517        void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
     518                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
     519                // Do this through a cast expression to greatly simplify the code.
     520                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     521                assert( callExpr );
     522                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
     523                Type * type = 0;
     524
     525                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     526                // includes an untyped '+' expression.
     527                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     528                        // constructee is <array>+<index>
     529                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     530                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     531                        assert( dynamic_cast< VariableExpr * >( arr ) );
     532                        assert( arr && arr->get_results().size() == 1 );
     533                        type = arr->get_results().front()->clone();
     534                } else {
     535                        // otherwise, constructing a plain object, which means the object's address is being taken.
     536                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     537                        // type of the VariableExpr to do so.
     538                        assert( constructee->get_results().size() == 1 );
     539                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     540                        assert( addrExpr && addrExpr->get_results().size() == 1);
     541                        type = addrExpr->get_results().front()->clone();
     542                }
     543                // cast to T* with qualifiers removed.
     544                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     545                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     546                // remove lvalue as a qualifier, this can change to
     547                //   type->get_qualifiers() = Type::Qualifiers();
     548                Type * base = InitTweak::getPointerBase( type );
     549                assert( base );
     550                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     551                // if pointer has lvalue qualifier, cast won't appear in output
     552                type->set_isLvalue( false );
     553                constructee = new CastExpr( constructee, type );
     554
     555                // finally, resolve the ctor/dtor
     556                impCtorDtorStmt->get_callStmt()->accept( *this );
     557        }
    515558} // namespace ResolvExpr
    516559
Note: See TracChangeset for help on using the changeset viewer.