Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r7b3f66b r10a7775  
    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                // this code is fairly gross. If VariableExpr didn't have its own results list then this could be cleaned up a bit
     519                // by remembering the ObjectDecl in the ImplicitCtorDtorStmt and changing the ObjectDecl's type temporarily, but currently
     520                // VariableExprs have their own type list which is manipulated in AlternativeFinder (e.g. in inferRecursive).
     521
     522                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed)
     523                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     524                assert( callExpr );
     525                Expression * constructee = InitTweak::getCallArg( callExpr, 0 );
     526                Type * type = 0;
     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 = InitTweak::getPointerBase( arr->get_results().front() );
     534                        assert( type );
     535                } else {
     536                        // otherwise, constructing a plain object, which means the object's address is being taken.
     537                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     538                        // type of the VariableExpr to do so.
     539                        assert( constructee->get_results().size() == 1 );
     540                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     541                        assert( addrExpr );
     542                        VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
     543                        assert( varExpr && varExpr->get_results().size() == 1 );
     544                        type = varExpr->get_results().front();
     545                }
     546                // remember qualifiers so they can be replaced
     547                Type::Qualifiers qualifiers = type->get_qualifiers();
     548
     549                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     550                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     551                // remove lvalue as a qualifier, this can change to
     552                //   type->get_qualifiers() = Type::Qualifiers();
     553                type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     554
     555                // finally, resolve the ctor/dtor
     556                impCtorDtorStmt->get_callStmt()->accept( *this );
     557
     558                // reset type qualifiers, but first need to figure out where everything is again
     559                // because the expressions are often changed by the resolver.
     560                callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     561                assert( callExpr );
     562                constructee = InitTweak::getCallArg( callExpr, 0 );
     563                if ( ApplicationExpr * plusExpr = dynamic_cast< ApplicationExpr * >( constructee ) ) {
     564                        // constructee is <array>+<index>
     565                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     566                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     567                        assert( dynamic_cast< VariableExpr * >( arr ) );
     568                        assert( arr && arr->get_results().size() == 1 );
     569                        type = InitTweak::getPointerBase( arr->get_results().front() );
     570                        assert( type );
     571                        type->get_qualifiers() = qualifiers;
     572                } else {
     573                        // otherwise constructing a plain object
     574                        // replace qualifiers on AddressExpr and on inner VariableExpr
     575                        assert( constructee->get_results().size() == 1 );
     576                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     577                        assert( addrExpr );
     578                        type = InitTweak::getPointerBase( addrExpr->get_results().front() );
     579                        assert( type );
     580                        type->get_qualifiers() = qualifiers;
     581
     582                        VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
     583                        assert( varExpr && varExpr->get_results().size() == 1 );
     584                        type = varExpr->get_results().front();
     585                        type->get_qualifiers() = qualifiers;
     586                }
     587        }
    515588} // namespace ResolvExpr
    516589
Note: See TracChangeset for help on using the changeset viewer.