Changeset 8488c71


Ignore:
Timestamp:
Jan 22, 2016, 3:30:43 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
aaron-thesis, arm-eh, 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, string, with_gc
Children:
73a28e2
Parents:
6d160d7
Message:

Fixed dereferencing in member expressions

Location:
src/GenPoly
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r6d160d7 r8488c71  
    12901290
    12911291                        // get declaration for base struct, exiting early if not found
    1292                         VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() );
     1292                        int varDepth;
     1293                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
    12931294                        if ( ! varExpr ) return memberExpr;
    12941295                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     
    12961297
    12971298                        // only mutate member expressions for polymorphic types
    1298                         Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars );
     1299                        int tyDepth;
     1300                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
    12991301                        if ( ! objectType ) return memberExpr;
    13001302
     
    13231325
    13241326                        // replace member expression with pointer to base plus offset
    1325                         // this is in a polymorphic context, so maybe keeping it as a void* is fine?
     1327                        // get offset for field
    13261328                        std::stringstream offset_namer;
    13271329                        offset_namer << i;
     
    13301332                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    13311333                        fieldOffset->get_args().push_back( fieldIndex );
     1334                        // build appropriately-dereferenced variable
     1335                        Expression *derefdVar = varExpr->clone();
     1336                        for ( int i = 1; i < varDepth; ++i ) {
     1337                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     1338                                derefExpr->get_args().push_back( derefdVar );
     1339                                derefdVar = derefExpr;
     1340                        }
     1341                        // add offset to deref'd variable
    13321342                        UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1333                         fieldLoc->get_args().push_back( memberExpr->get_aggregate() );
     1343                        fieldLoc->get_args().push_back( derefdVar );
    13341344                        fieldLoc->get_args().push_back( fieldOffset );
    13351345
    1336                         memberExpr->set_aggregate( 0 );
    13371346                        delete memberExpr;
    13381347                        return fieldLoc;
  • src/GenPoly/GenPoly.cc

    r6d160d7 r8488c71  
    127127        }
    128128
    129         Type *hasPolyBase( Type *type, const TypeSubstitution *env ) {
    130                 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    131                         return hasPolyBase( ptr->get_base(), env );
    132                 } else if ( env ) {
    133                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    134                                 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    135                                         return hasPolyBase( newType, env );
    136                                 } // if
    137                         } // if
     129        Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
     130                int dummy;
     131                if ( ! levels ) { levels = &dummy; }
     132                *levels = 0;
     133
     134                while ( true ) {
     135                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     136                                type = ptr->get_base();
     137                                ++(*levels);
     138                        } else if ( env ) {
     139                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     140                                        if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     141                                                type = newType;
     142                                        } else break;
     143                                } else break;
     144                        } else break;
    138145                }
    139146
     
    141148        }
    142149       
    143         Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    144                 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
    145                         return hasPolyBase( ptr->get_base(), tyVars, env );
    146                 } else if ( env ) {
    147                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    148                                 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    149                                         return hasPolyBase( newType, tyVars, env );
    150                                 } // if
    151                         } // if
     150        Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
     151                int dummy;
     152                if ( ! levels ) { levels = &dummy; }
     153                *levels = 0;
     154
     155                while ( true ) {
     156                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     157                                type = ptr->get_base();
     158                                ++(*levels);
     159                        } else if ( env ) {
     160                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     161                                        if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     162                                                type = newType;
     163                                        } else break;
     164                                } else break;
     165                        } else break;
    152166                }
    153167
     
    164178        }
    165179
    166         VariableExpr *getBaseVar( Expression *expr ) {
    167                 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
    168                         // found the variable directly
    169                         return varExpr;
    170                 } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
    171                         return getBaseVar( addressExpr->get_arg() );
    172                 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
    173                         // look for compiler-inserted dereference operator
    174                         NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
    175                         if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
    176                         return getBaseVar( *untypedExpr->begin_args() );
    177                 } else return 0;
     180        VariableExpr * getBaseVar( Expression *expr, int *levels ) {
     181                int dummy;
     182                if ( ! levels ) { levels = &dummy; }
     183                *levels = 0;
     184
     185                while ( true ) {
     186                        if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
     187                                return varExpr;
     188                        } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
     189                                expr = addressExpr->get_arg();
     190                        } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
     191                                // look for compiler-inserted dereference operator
     192                                NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
     193                                if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
     194                                expr = *untypedExpr->begin_args();
     195                        } else break;
     196
     197                        ++(*levels);
     198                }
     199
     200                return 0;
    178201        }
    179202
  • src/GenPoly/GenPoly.h

    r6d160d7 r8488c71  
    2020#include <string>
    2121#include <iostream>
     22#include <utility>
    2223
    2324#include "SynTree/Declaration.h"
     
    4748        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    4849
    49         /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type, NULL otherwise;
    50         /// will look up substitution in env if provided
    51         Type *hasPolyBase( Type *type, const TypeSubstitution *env = 0 );
     50        /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise;
     51        /// N will be stored in levels, if provided, will look up substitution in env if provided
     52        Type *hasPolyBase( Type *type, int *levels = 0, const TypeSubstitution *env = 0 );
    5253
    53         /// returns polymorphic base type if the base type (after dereferencing any number of pointers) is a polymorphic type in tyVars, NULL otherwise;
    54         /// will look up substitution in env if provided
    55         Type *hasPolyBase( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     54        /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type in tyVars, returns the base type, NULL otherwise;
     55        /// N will be stored in levels, if provided, will look up substitution in env if provided
     56        Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 );
    5657
    5758        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    5859        FunctionType *getFunctionType( Type *ty );
    5960
    60         /// Returns the base variable (possibly repeatedly dereferenced) for an expression, NULL if none found
    61         VariableExpr *getBaseVar( Expression *expr );
     61        /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise;
     62        /// N will be stored in levels, if provided
     63        VariableExpr *getBaseVar( Expression *expr, int *levels = 0 );
    6264
    6365        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
Note: See TracChangeset for help on using the changeset viewer.