Changeset f1b1e4c for src/ResolvExpr


Ignore:
Timestamp:
Jun 1, 2016, 11:54:23 AM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, 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:
be945ac
Parents:
70f89d00
Message:

can construct global const objects, except with intrinsic constructors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r70f89d00 rf1b1e4c  
    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 );
     
    493494                        // no alternatives for the constructor initializer - fallback on C-style initializer
    494495                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
    495 
    496                         // reset type qualifiers
    497                         ctorInit->get_object()->get_type()->get_qualifiers() = ctorInit->get_qualifiers();
    498496                        fallbackInit( ctorInit );
    499497                        return;
    500498                }
    501                 // reset type qualifiers
    502                 ctorInit->get_object()->get_type()->get_qualifiers() = ctorInit->get_qualifiers();
    503499
    504500                // found a constructor - can get rid of C-style initializer
     
    518514                }
    519515        }
     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                        ArrayType * arrType = dynamic_cast< ArrayType * >( arr->get_results().front() );
     534                        assert( arrType );
     535                        type = arrType->get_base();
     536                } else {
     537                        // otherwise, constructing a plain object, which means the object's address is being taken.
     538                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     539                        // type of the VariableExpr to do so.
     540                        assert( constructee->get_results().size() == 1 );
     541                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     542                        assert( addrExpr );
     543                        VariableExpr * varExpr = dynamic_cast< VariableExpr * >( addrExpr->get_arg() );
     544                        assert( varExpr && varExpr->get_results().size() == 1 );
     545                        type = varExpr->get_results().front();
     546                }
     547                // remember qualifiers so they can be replaced
     548                Type::Qualifiers qualifiers = type->get_qualifiers();
     549
     550                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     551                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     552                // remove lvalue as a qualifier, this can change to
     553                //   type->get_qualifiers() = Type::Qualifiers();
     554                type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     555
     556                // finally, resolve the ctor/dtor
     557                impCtorDtorStmt->get_callStmt()->accept( *this );
     558
     559                // and reset type qualifiers after resolving
     560                type->get_qualifiers() = qualifiers;
     561        }
    520562} // namespace ResolvExpr
    521563
Note: See TracChangeset for help on using the changeset viewer.