Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r10a7775 r7b3f66b  
    5252                virtual void visit( BranchStmt *branchStmt );
    5353                virtual void visit( ReturnStmt *returnStmt );
    54                 virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5554
    5655                virtual void visit( SingleInit *singleInit );
     
    493492                } catch ( SemanticError ) {
    494493                        // no alternatives for the constructor initializer - fallback on C-style initializer
    495                         // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
     494                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
    496495                        fallbackInit( ctorInit );
    497496                        return;
     
    514513                }
    515514        }
    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         }
    588515} // namespace ResolvExpr
    589516
Note: See TracChangeset for help on using the changeset viewer.