Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r7b3f66b ra436947  
    3838                virtual void visit( ObjectDecl *functionDecl );
    3939                virtual void visit( TypeDecl *typeDecl );
     40                virtual void visit( EnumDecl * enumDecl );
    4041
    4142                virtual void visit( ArrayType * at );
     
    5253                virtual void visit( BranchStmt *branchStmt );
    5354                virtual void visit( ReturnStmt *returnStmt );
     55                virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5456
    5557                virtual void visit( SingleInit *singleInit );
     
    6567                Type *initContext;
    6668                Type *switchType;
     69                bool inEnumDecl = false;
    6770        };
    6871
     
    177180                Type *temp = initContext;
    178181                initContext = new_type;
     182                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     183                        // enumerator initializers should not use the enum type to initialize, since
     184                        // the enum type is still incomplete at this point. Use signed int instead.
     185                        initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     186                }
    179187                SymTab::Indexer::visit( objectDecl );
     188                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     189                        // delete newly created signed int type
     190                        delete initContext;
     191                }
    180192                initContext = temp;
    181193        }
     
    215227                SymTab::Indexer::visit( functionDecl );
    216228                functionReturn = oldFunctionReturn;
     229        }
     230
     231        void Resolver::visit( EnumDecl * enumDecl ) {
     232                // in case we decide to allow nested enums
     233                bool oldInEnumDecl = inEnumDecl;
     234                inEnumDecl = true;
     235                SymTab::Indexer::visit( enumDecl );
     236                inEnumDecl = oldInEnumDecl;
    217237        }
    218238
     
    492512                } catch ( SemanticError ) {
    493513                        // 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?
     514                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
    495515                        fallbackInit( ctorInit );
    496516                        return;
     
    513533                }
    514534        }
     535
     536        void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
     537                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
     538                // Do this through a cast expression to greatly simplify the code.
     539                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     540                assert( callExpr );
     541                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
     542                Type * type = 0;
     543
     544                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     545                // includes an untyped '+' expression.
     546                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     547                        // constructee is <array>+<index>
     548                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     549                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     550                        assert( dynamic_cast< VariableExpr * >( arr ) );
     551                        assert( arr && arr->get_results().size() == 1 );
     552                        type = arr->get_results().front()->clone();
     553                } else {
     554                        // otherwise, constructing a plain object, which means the object's address is being taken.
     555                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     556                        // type of the VariableExpr to do so.
     557                        assert( constructee->get_results().size() == 1 );
     558                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     559                        assert( addrExpr && addrExpr->get_results().size() == 1);
     560                        type = addrExpr->get_results().front()->clone();
     561                }
     562                // cast to T* with qualifiers removed.
     563                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     564                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     565                // remove lvalue as a qualifier, this can change to
     566                //   type->get_qualifiers() = Type::Qualifiers();
     567                Type * base = InitTweak::getPointerBase( type );
     568                assert( base );
     569                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     570                // if pointer has lvalue qualifier, cast won't appear in output
     571                type->set_isLvalue( false );
     572                constructee = new CastExpr( constructee, type );
     573
     574                // finally, resolve the ctor/dtor
     575                impCtorDtorStmt->get_callStmt()->accept( *this );
     576        }
    515577} // namespace ResolvExpr
    516578
Note: See TracChangeset for help on using the changeset viewer.