Ignore:
Timestamp:
Jul 18, 2016, 4:13:51 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
5f98ce5
Parents:
956a9c7
Message:

rework ctor/dtor generation to work properly with multidimensional arrays

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r956a9c7 r2be1023  
    537537                assert( callExpr );
    538538                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 ) || dynamic_cast< MemberExpr *>( 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                 }
     539
     540                // the first argument will always be &<expr>
     541                AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     542                assert( addrExpr );
     543
     544                // need to find the type of the first argument. In the case of an array,
     545                // need to remove one ArrayType layer from the type for each subscript expression.
     546                Expression * addressee = addrExpr->get_arg();
     547                int numLayers = 0;
     548                while ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( addressee ) ) {
     549                        assert( InitTweak::getFunctionName( untypedExpr ) == "?[?]" );
     550                        addressee = InitTweak::getCallArg( untypedExpr, 0 );
     551                        numLayers++;
     552                }
     553                assert( addressee->get_results().size() == 1 );
     554                Type * type = addressee->get_results().front();
     555                for ( int i = 0; i < numLayers; i++ ) {
     556                        type = InitTweak::getPointerBase( type );
     557                        assert( type && "Expected pointer or array type. May have generated too many ?[?] calls." );
     558                }
     559
    559560                // cast to T* with qualifiers removed.
    560561                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     
    562563                // remove lvalue as a qualifier, this can change to
    563564                //   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 );
     565                assert( type );
     566                type = type->clone();
     567                type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     568                type = new PointerType( Type::Qualifiers(), type );
    569569                constructee = new CastExpr( constructee, type );
    570570
Note: See TracChangeset for help on using the changeset viewer.