Changes in / [421edab:803deb1]


Ignore:
Location:
src
Files:
1 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r421edab r803deb1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc -- 
     7// CodeGenerator.cc --
    88//
    99// Author           : Richard C. Bilson
     
    9898                handleStorageClass( objectDecl );
    9999                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    100        
     100
    101101                if ( objectDecl->get_init() ) {
    102102                        output << " = ";
     
    112112                if ( aggDecl->get_name() != "" )
    113113                        output << aggDecl->get_name();
    114        
     114
    115115                std::list< Declaration * > &memb = aggDecl->get_members();
    116116
     
    118118                        output << " {" << endl;
    119119
    120                         cur_indent += CodeGenerator::tabsize; 
     120                        cur_indent += CodeGenerator::tabsize;
    121121                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    122                                 output << indent; 
     122                                output << indent;
    123123                                (*i)->accept( *this );
    124124                                output << ";" << endl;
    125125                        }
    126126
    127                         cur_indent -= CodeGenerator::tabsize; 
     127                        cur_indent -= CodeGenerator::tabsize;
    128128
    129129                        output << indent << "}";
     
    140140                handleAggregate( aggregateDecl );
    141141        }
    142  
     142
    143143        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    144144                output << "enum ";
     
    146146                if ( aggDecl->get_name() != "" )
    147147                        output << aggDecl->get_name();
    148        
     148
    149149                std::list< Declaration* > &memb = aggDecl->get_members();
    150150
     
    152152                        output << " {" << endl;
    153153
    154                         cur_indent += CodeGenerator::tabsize; 
     154                        cur_indent += CodeGenerator::tabsize;
    155155                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    156156                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    157157                                assert( obj );
    158                                 output << indent << mangleName( obj ); 
     158                                output << indent << mangleName( obj );
    159159                                if ( obj->get_init() ) {
    160160                                        output << " = ";
     
    164164                        } // for
    165165
    166                         cur_indent -= CodeGenerator::tabsize; 
     166                        cur_indent -= CodeGenerator::tabsize;
    167167
    168168                        output << indent << "}";
    169169                } // if
    170170        }
    171  
     171
    172172        void CodeGenerator::visit( ContextDecl *aggregateDecl ) {}
    173  
     173
    174174        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    175175                output << "typedef ";
    176176                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    177177        }
    178  
     178
    179179        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    180180                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    216216        }
    217217
    218         void CodeGenerator::visit( Constant *constant ) { 
     218        void CodeGenerator::visit( Constant *constant ) {
    219219                output << constant->get_value() ;
    220220        }
     
    233233                                                assert( arg != applicationExpr->get_args().end() );
    234234                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    235                
     235
    236236                                                        *arg = addrExpr->get_arg();
    237237                                                } else {
     
    242242                                                break;
    243243                                        }
    244              
     244
    245245                                  default:
    246246                                        // do nothing
    247247                                        ;
    248248                                }
    249            
     249
    250250                                switch ( opInfo.type ) {
    251251                                  case OT_INDEX:
     
    256256                                        output << "]";
    257257                                        break;
    258              
     258
    259259                                  case OT_CALL:
    260260                                        // there are no intrinsic definitions of the function call operator
    261261                                        assert( false );
    262262                                        break;
    263              
     263
    264264                                  case OT_PREFIX:
    265265                                  case OT_PREFIXASSIGN:
     
    270270                                        output << ")";
    271271                                        break;
    272              
     272
    273273                                  case OT_POSTFIX:
    274274                                  case OT_POSTFIXASSIGN:
     
    287287                                        output << ")";
    288288                                        break;
    289              
     289
    290290                                  case OT_CONSTANT:
    291291                                  case OT_LABELADDRESS:
     
    306306                } // if
    307307        }
    308  
     308
    309309        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    310310                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    320320                                        output << "]";
    321321                                        break;
    322              
     322
    323323                                  case OT_CALL:
    324324                                        assert( false );
    325325                                        break;
    326              
     326
    327327                                  case OT_PREFIX:
    328328                                  case OT_PREFIXASSIGN:
     
    334334                                        output << ")";
    335335                                        break;
    336              
     336
    337337                                  case OT_POSTFIX:
    338338                                  case OT_POSTFIXASSIGN:
     
    341341                                        output << opInfo.symbol;
    342342                                        break;
    343  
     343
    344344                                  case OT_INFIX:
    345345                                  case OT_INFIXASSIGN:
     
    351351                                        output << ")";
    352352                                        break;
    353                                        
     353
    354354                                  case OT_CONSTANT:
    355355                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    369369                } // if
    370370        }
    371  
     371
    372372        void CodeGenerator::visit( NameExpr *nameExpr ) {
    373373                OperatorInfo opInfo;
     
    379379                } // if
    380380        }
    381  
     381
    382382        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    383383                output << "(&";
     
    408408                output << ")";
    409409        }
    410  
     410
    411411        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    412412                assert( false );
    413413        }
    414  
     414
    415415        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    416416                memberExpr->get_aggregate()->accept( *this );
    417417                output << "." << mangleName( memberExpr->get_member() );
    418418        }
    419  
     419
    420420        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    421421                OperatorInfo opInfo;
     
    426426                } // if
    427427        }
    428  
     428
    429429        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    430430                assert( constantExpr->get_constant() );
    431431                constantExpr->get_constant()->accept( *this );
    432432        }
    433  
     433
    434434        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    435435                output << "sizeof(";
     
    442442        }
    443443
    444         void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
     444        void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
    445445                // use GCC extension to avoid bumping std to C11
    446446                output << "__alignof__(";
    447                 if ( alignofExpr->get_isType() ) {
    448                         output << genType( alignofExpr->get_type(), "" );
    449                 } else {
    450                         alignofExpr->get_expr()->accept( *this );
     447                if ( sizeofExpr->get_isType() ) {
     448                        output << genType( sizeofExpr->get_type(), "" );
     449                } else {
     450                        sizeofExpr->get_expr()->accept( *this );
    451451                } // if
    452452                output << ")";
    453453        }
    454454
    455         void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
    456                 // use GCC builtin
    457                 output << "__builtin_offsetof(";
    458                 output << genType( offsetofExpr->get_type(), "" );
    459                 output << ", " << mangleName( offsetofExpr->get_member() );
    460                 output << ")";
    461         }
    462  
    463455        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    464456                output << "(";
     
    472464                output << ")";
    473465        }
    474  
     466
    475467        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    476468                output << "(";
     
    482474                output << ")";
    483475        }
    484  
     476
    485477        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    486478                output << "(";
     
    490482                output << ")";
    491483        }
    492  
     484
    493485        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    494  
     486
    495487        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    496488
     
    523515                        }
    524516                }
    525                 cur_indent -= CodeGenerator::tabsize; 
     517                cur_indent -= CodeGenerator::tabsize;
    526518
    527519                output << indent << "}";
     
    529521
    530522        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    531                 // I don't see why this check is necessary. 
    532                 // If this starts to cause problems then put it back in, 
     523                // I don't see why this check is necessary.
     524                // If this starts to cause problems then put it back in,
    533525                // with an explanation
    534526                assert( exprStmt );
     
    580572                switchStmt->get_condition()->accept( *this );
    581573                output << " ) ";
    582                
     574
    583575                output << "{" << std::endl;
    584576                cur_indent += CodeGenerator::tabsize;
     
    600592                } // if
    601593                output << ":\n";
    602                
     594
    603595                std::list<Statement *> sts = caseStmt->get_statements();
    604596
     
    617609                        if ( ! branchStmt->get_target().empty() )
    618610                                output << "goto " << branchStmt->get_target();
    619                         else { 
     611                        else {
    620612                                if ( branchStmt->get_computedTarget() != 0 ) {
    621613                                        output << "goto *";
     
    668660
    669661        void CodeGenerator::visit( ForStmt *forStmt ) {
    670                 // initialization is always hoisted, so don't 
    671                 // bother doing anything with that 
     662                // initialization is always hoisted, so don't
     663                // bother doing anything with that
    672664                output << "for (;";
    673665
     
    693685        void CodeGenerator::visit( DeclStmt *declStmt ) {
    694686                declStmt->get_decl()->accept( *this );
    695        
     687
    696688                if ( doSemicolon( declStmt->get_decl() ) ) {
    697689                        output << ";";
  • src/CodeGen/CodeGenerator.h

    r421edab r803deb1  
    6161                virtual void visit( SizeofExpr *sizeofExpr );
    6262                virtual void visit( AlignofExpr *alignofExpr );
    63                 virtual void visit( OffsetofExpr *offsetofExpr );
    6463                virtual void visit( LogicalExpr *logicalExpr );
    6564                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    r421edab r803deb1  
    2222
    2323#include "Box.h"
    24 #include "InstantiateGeneric.h"
    2524#include "PolyMutator.h"
    2625#include "FindFunction.h"
    27 #include "ScopedMap.h"
    2826#include "ScrubTyVars.h"
    2927
     
    7169                        virtual void doEndScope();
    7270                  private:
    73                         /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it
    74                         Expression *makeOffsetArray( StructInstType *type );
    75                         /// passes extra type parameters into a polymorphic function application
    7671                        void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    77                         /// wraps a function application with a new temporary for the out-parameter return value
    7872                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
    79                         /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment
    80                         void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params );
    81                         /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).
    82                         /// If `doClone` is set to false, will not clone interior types
    83                         Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true );
    84                         /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value
    85                         Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );
     73                        Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg );
    8674                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    8775                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
    8876                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    8977                        void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars );
    90                         /// Stores assignment operators from assertion list in local map of assignment operations
    9178                        void findAssignOps( const std::list< TypeDecl *> &forall );
    9279                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    9380                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
    94                         /// Replaces intrinsic operator functions with their arithmetic desugaring
    9581                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
    96                         /// Inserts a new temporary variable into the current scope with an auto-generated name
    9782                        ObjectDecl *makeTemporary( Type *type );
    9883
    9984                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    10085                        std::map< std::string, DeclarationWithType *> assignOps;
    101                         ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
    10286                        std::stack< AdapterMap > adapters;
    10387                        DeclarationWithType *retval;
     
    123107                };
    124108
    125                 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
    126                 class MemberExprFixer : public PolyMutator {
     109                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
     110                class Pass3 : public PolyMutator {
    127111                  public:
    128112                        template< typename DeclClass >
     
    135119                        virtual Type *mutate( PointerType *pointerType );
    136120                        virtual Type *mutate( FunctionType *funcType );
    137                         virtual Expression *mutate( MemberExpr *memberExpr );
    138                 };
    139                
    140                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    141                 class Pass3 : public PolyMutator {
    142                   public:
    143                         template< typename DeclClass >
    144                         DeclClass *handleDecl( DeclClass *decl, Type *type );
    145                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
    146                         virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
    147                         virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
    148                         virtual TypeDecl *mutate( TypeDecl *objectDecl );
    149                         virtual Type *mutate( PointerType *pointerType );
    150                         virtual Type *mutate( FunctionType *funcType );
    151121                  private:
    152122                };
     
    163133        }
    164134
    165         /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    166         template< typename MutatorType >
    167         inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
    168                 bool seenIntrinsic = false;
    169                 SemanticError errors;
    170                 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    171                         try {
    172                                 if ( *i ) {
    173                                         if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
    174                                                 seenIntrinsic = true;
    175                                         } else if ( seenIntrinsic ) {
    176                                                 seenIntrinsic = false; // break on this line when debugging for end of prelude
    177                                         }
    178                                        
    179                                         *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
    180                                         assert( *i );
    181                                 } // if
    182                         } catch( SemanticError &e ) {
    183                                 errors.append( e );
    184                         } // try
    185                 } // for
    186                 if ( ! errors.isEmpty() ) {
    187                         throw errors;
    188                 } // if
    189         }
    190 
    191135        void box( std::list< Declaration *>& translationUnit ) {
    192136                Pass1 pass1;
    193137                Pass2 pass2;
    194                 MemberExprFixer memberFixer;
    195138                Pass3 pass3;
    196                 mutateTranslationUnit/*All*/( translationUnit, pass1 );
    197                 mutateTranslationUnit/*All*/( translationUnit, pass2 );
    198                 instantiateGeneric( translationUnit );
    199                 mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    200                 mutateTranslationUnit/*All*/( translationUnit, pass3 );
     139                mutateAll( translationUnit, pass1 );
     140                mutateAll( translationUnit, pass2 );
     141                mutateAll( translationUnit, pass3 );
    201142        }
    202143
     
    244185                }
    245186
    246                 /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise
    247                 ReferenceToType *isAssignment( DeclarationWithType *decl ) {
     187                // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be)
     188                bool checkAssignment( DeclarationWithType *decl, std::string &name ) {
    248189                        if ( decl->get_name() == "?=?" ) {
    249                                 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
    250                                         if ( funType->get_parameters().size() == 2 ) {
    251                                                 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
    252                                                         if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {
    253                                                                 if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {
    254                                                                         if ( refType->get_name() == refType2->get_name() ) {
    255                                                                                 return refType;
     190                                if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) {
     191                                        if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) {
     192                                                if ( funType->get_parameters().size() == 2 ) {
     193                                                        if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     194                                                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
     195                                                                        if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
     196                                                                                if ( typeInst->get_name() == typeInst2->get_name() ) {
     197                                                                                        name = typeInst->get_name();
     198                                                                                        return true;
     199                                                                                } // if
    256200                                                                        } // if
    257201                                                                } // if
     
    261205                                } // if
    262206                        } // if
    263                         return 0;
     207                        return false;
    264208                }
    265209
     
    270214                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    271215                                        std::string typeName;
    272                                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
    273                                                 assignOps[ typeInst->get_name() ] = *assert;
     216                                        if ( checkAssignment( *assert, typeName ) ) {
     217                                                assignOps[ typeName ] = *assert;
    274218                                        } // if
    275219                                } // for
     
    278222
    279223                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    280                         // if this is a polymorphic assignment function, put it in the map for this scope
    281                         if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {
    282                                 if ( ! dynamic_cast< TypeInstType* >( refType ) ) {
    283                                         scopedAssignOps.insert( refType->get_name(), functionDecl );
    284                                 }
    285                         }
    286                        
    287224                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    288225                                doBeginScope();
     
    294231                                // process polymorphic return value
    295232                                retval = 0;
    296                                 if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     233                                std::string typeName;
     234                                if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    297235                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    298236
     
    318256                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    319257                                } // for
    320                                
    321258                                AdapterMap & adapters = Pass1::adapters.top();
    322259                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    369306                }
    370307
    371                 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
    372                         // make a new temporary array
    373                         Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    374                         ObjectDecl *arrayTemp = makeTemporary( new PointerType( Type::Qualifiers(), offsetType ) );
    375 
    376                         // build initializer list for temporary
    377                         std::list< Initializer* > inits;
    378                         StructDecl *tyBase = ty->get_baseStruct();
    379                         for ( std::list< Declaration* >::const_iterator member = tyBase->get_members().begin(); member != tyBase->get_members().end(); ++member ) {
    380                                 DeclarationWithType *memberDecl;
    381                                 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
    382                                         memberDecl = origMember->clone();
    383                                 } else {
    384                                         memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
    385                                 }
    386                                 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
    387                         }
    388                         arrayTemp->set_init( new ListInit( inits ) );
    389 
    390                         // return variable pointing to temporary
    391                         return new VariableExpr( arrayTemp );
    392                 }
    393                
    394308                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    395309                        // pass size/align for type variables
     
    411325
    412326                        // add size/align for generic types to parameter list
     327                        //assert( ! appExpr->get_function()->get_results().empty() );
    413328                        if ( appExpr->get_function()->get_results().empty() ) return;
    414329                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    430345                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
    431346                                        arg++;
    432                                         if ( dynamic_cast< StructInstType* >( parmType ) ) {
    433                                                 if ( StructInstType *argStructType = dynamic_cast< StructInstType* >( argType ) ) {
    434                                                         arg = appExpr->get_args().insert( arg, makeOffsetArray( argStructType ) );
    435                                                         arg++;
    436                                                 } else {
    437                                                         throw SemanticError( "Cannot pass non-struct type for generic struct" );
    438                                                 }
    439                                         }
    440347
    441348                                        seenTypes.insert( sizeName );
     
    479386                }
    480387
    481                 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
    482                         for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
    483                                 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    484                                 assert(paramType && "Aggregate parameters should be type expressions");
    485                                 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
    486                         }
    487                 }
    488                
    489                 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
    490                         if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    491                                 Type *concrete = env->lookup( typeInst->get_name() );
    492                                 if ( concrete == 0 ) {
    493                                         throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
    494                                 } // if
    495                                 return concrete;
    496                         } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
    497                                 if ( doClone ) {
    498                                         structType = structType->clone();
    499                                 }
    500                                 replaceParametersWithConcrete( appExpr, structType->get_parameters() );
    501                                 return structType;
    502                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
    503                                 if ( doClone ) {
    504                                         unionType = unionType->clone();
    505                                 }
    506                                 replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
    507                                 return unionType;
    508                         }
    509                         return type;
    510                 }
    511 
    512                 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
     388                Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
     389                        ResolvExpr::EqvClass eqvClass;
    513390                        assert( env );
    514                         Type *concrete = replaceWithConcrete( appExpr, polyType );
     391                        Type *concrete = env->lookup( typeName );
     392                        if ( concrete == 0 ) {
     393                                throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
     394                        } // if
    515395                        return addRetParam( appExpr, function, concrete, arg );
    516396                }
     
    612492                        assert( arg );
    613493                        if ( isPolyType( realParam->get_type(), tyVars ) ) {
     494//     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
     495//       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
     496//     } else {
    614497                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    615498                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    618501                                        return deref;
    619502                                } // if
     503//     }
    620504                        } // if
    621505                        return new VariableExpr( param );
     
    907791                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    908792
    909                         if ( ReferenceToType *polyType = isPolyRet( function ) ) {
    910                                 ret = addPolyRetParam( appExpr, function, polyType, arg );
     793                        std::string typeName;
     794                        if ( isPolyRet( function, typeName ) ) {
     795                                ret = addPolyRetParam( appExpr, function, typeName, arg );
    911796                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    912797                                // std::cerr << "needs adapter: ";
     
    995880                                        delete castExpr;
    996881                                } //while
    997 
    998                                 // find assignment operator for (polymorphic) return type
    999                                 DeclarationWithType *assignDecl = 0;
    1000                                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    1001                                         std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    1002                                         if ( assignIter == assignOps.end() ) {
    1003                                                 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    1004                                         } // if
    1005                                         assignDecl = assignIter->second;
    1006                                 } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
    1007                                         ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    1008                                         if ( assignIter == scopedAssignOps.end() ) {
    1009                                                 throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    1010                                         }
    1011                                         DeclarationWithType *functionDecl = assignIter->second;
    1012                                         // line below cloned from FixFunction.cc
    1013                                         assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1014                                                                      new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1015                                         assignDecl->set_mangleName( functionDecl->get_mangleName() );
    1016                                 }
    1017                                 assert( assignDecl );
    1018 
    1019                                 // replace return statement with appropriate assignment to out parameter
    1020                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
     882                                TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
     883                                assert( typeInst );
     884                                std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     885                                if ( assignIter == assignOps.end() ) {
     886                                        throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     887                                } // if
     888                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    1021889                                Expression *retParm = new NameExpr( retval->get_name() );
    1022890                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    1059927                        // push a copy of the current map
    1060928                        adapters.push(adapters.top());
    1061                         scopedAssignOps.beginScope();
    1062929                }
    1063930
    1064931                void Pass1::doEndScope() {
    1065932                        adapters.pop();
    1066                         scopedAssignOps.endScope();
    1067933                }
    1068934
     
    1132998
    1133999                        // move polymorphic return type to parameter list
    1134                         if ( isPolyRet( funcType ) ) {
     1000                        std::string typeName;
     1001                        if ( isPolyRet( funcType, typeName ) ) {
    11351002                                DeclarationWithType *ret = funcType->get_returnVals().front();
    11361003                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    11431010                        std::list< DeclarationWithType *> inferredParams;
    11441011                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1145                         ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
    1146                                            new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    11471012//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    11481013                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    11711036
    11721037                        // add size/align for generic types to parameter list
    1173                         std::set< std::string > seenTypes; // sizeofName for generic types we've seen
     1038                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
    11741039                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    11751040                                Type *parmType = (*fnParm)->get_type();
     
    11781043                                        if ( seenTypes.count( sizeName ) ) continue;
    11791044
    1180                                         ObjectDecl *sizeParm, *alignParm, *offsetParm;
     1045                                        ObjectDecl *sizeParm, *alignParm;
    11811046                                        sizeParm = newObj.clone();
    11821047                                        sizeParm->set_name( sizeName );
     
    11881053                                        last = funcType->get_parameters().insert( last, alignParm );
    11891054                                        ++last;
    1190 
    1191                                         if ( dynamic_cast< StructInstType* >( parmType ) ) {
    1192                                                 offsetParm = newPtr.clone();
    1193                                                 offsetParm->set_name( offsetofName( parmType ) );
    1194                                                 last = funcType->get_parameters().insert( last, offsetParm );
    1195                                                 ++last;
    1196                                         }
    11971055
    11981056                                        seenTypes.insert( sizeName );
     
    12081066                        scopeTyVars = oldtyVars;
    12091067                        return funcType;
    1210                 }
    1211 
    1212 ////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    1213 
    1214                 template< typename DeclClass >
    1215                 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
    1216                         TyVarMap oldtyVars = scopeTyVars;
    1217                         makeTyVarMap( type, scopeTyVars );
    1218 
    1219                         DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    1220 
    1221                         scopeTyVars = oldtyVars;
    1222                         return ret;
    1223                 }
    1224 
    1225                 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
    1226                         return handleDecl( objectDecl, objectDecl->get_type() );
    1227                 }
    1228 
    1229                 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
    1230                         return handleDecl( functionDecl, functionDecl->get_functionType() );
    1231                 }
    1232 
    1233                 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
    1234                         return handleDecl( typedefDecl, typedefDecl->get_base() );
    1235                 }
    1236 
    1237                 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
    1238                         scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1239                         return Mutator::mutate( typeDecl );
    1240                 }
    1241 
    1242                 Type * MemberExprFixer::mutate( PointerType *pointerType ) {
    1243                         TyVarMap oldtyVars = scopeTyVars;
    1244                         makeTyVarMap( pointerType, scopeTyVars );
    1245 
    1246                         Type *ret = Mutator::mutate( pointerType );
    1247 
    1248                         scopeTyVars = oldtyVars;
    1249                         return ret;
    1250                 }
    1251 
    1252                 Type * MemberExprFixer::mutate( FunctionType *functionType ) {
    1253                         TyVarMap oldtyVars = scopeTyVars;
    1254                         makeTyVarMap( functionType, scopeTyVars );
    1255 
    1256                         Type *ret = Mutator::mutate( functionType );
    1257 
    1258                         scopeTyVars = oldtyVars;
    1259                         return ret;
    1260                 }
    1261 
    1262                 Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
    1263                         if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
    1264                                 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
    1265                                         // change initialization of a polymorphic value object
    1266                                         // to allocate storage with alloca
    1267                                         Type *declType = objectDecl->get_type();
    1268                                         UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1269                                         alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
    1270 
    1271                                         delete objectDecl->get_init();
    1272 
    1273                                         std::list<Expression*> designators;
    1274                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
    1275                                 }
    1276                         }
    1277                         return Mutator::mutate( declStmt );
    1278                 }
    1279 
    1280                 Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    1281                         // mutate, exiting early if no longer MemberExpr
    1282                         Expression *expr = Mutator::mutate( memberExpr );
    1283                         memberExpr = dynamic_cast< MemberExpr* >( expr );
    1284                         if ( ! memberExpr ) return expr;
    1285 
    1286                         // get declaration for base struct, exiting early if not found
    1287                         VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate() );
    1288                         if ( ! varExpr ) return memberExpr;
    1289                         ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1290                         if ( ! objectDecl ) return memberExpr;
    1291 
    1292                         // only mutate member expressions for polymorphic types
    1293                         Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars );
    1294                         if ( ! objectType ) return memberExpr;
    1295 
    1296                         // get base aggregate for type so members can be looked up
    1297                         AggregateDecl *memberBase = 0;
    1298                         if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    1299                                 memberBase = structType->get_baseStruct();
    1300                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
    1301                                 memberBase = unionType->get_baseUnion();
    1302                         } else return memberExpr;
    1303 
    1304                         // look up numeric index of member in base aggregate
    1305                         DeclarationWithType *memberDecl = memberExpr->get_member();
    1306                         std::list< Declaration* > &baseDecls = memberBase->get_members();
    1307                         std::list< Declaration* >::const_iterator decl = baseDecls.begin();
    1308                         unsigned long i = 0;
    1309                         for( ; decl != baseDecls.end(); ++decl, ++i ) {
    1310                                 if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
    1311 
    1312                                 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1313                                         if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
    1314                                         else continue;
    1315                                 } else break;
    1316                         }
    1317                         if ( decl == baseDecls.end() ) return memberExpr;
    1318 
    1319                         // replace member expression with dereference of pointer offset
    1320                         std::stringstream offset_namer;
    1321                         offset_namer << i;
    1322                         ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
    1323                         UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    1324                         fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    1325                         fieldOffset->get_args().push_back( fieldIndex );
    1326                         UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1327                         fieldLoc->get_args().push_back( memberExpr->get_aggregate() );
    1328                         fieldLoc->get_args().push_back( fieldOffset );
    1329                         UntypedExpr *ret = new UntypedExpr( new NameExpr( "*?" ) );
    1330                         ret->get_args().push_back( fieldLoc );
    1331 
    1332                         memberExpr->set_aggregate( 0 );
    1333                         delete memberExpr;
    1334                         return ret;
    13351068                }
    13361069
     
    13931126                        return ret;
    13941127                }
     1128
     1129                Statement *Pass3::mutate( DeclStmt *declStmt ) {
     1130                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1131                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1132                                        // change initialization of a polymorphic value object
     1133                                        // to allocate storage with alloca
     1134                                        Type *declType = objectDecl->get_type();
     1135                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
     1136                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1137
     1138                                        delete objectDecl->get_init();
     1139
     1140                                        std::list<Expression*> designators;
     1141                                        objectDecl->set_init( new SingleInit( alloc, designators ) );
     1142                                }
     1143                        }
     1144                        return Mutator::mutate( declStmt );
     1145                }
    13951146        } // anonymous namespace
    13961147} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    r421edab r803deb1  
    3636        }
    3737
    38         ReferenceToType *isPolyRet( FunctionType *function ) {
     38        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
     39                bool doTransform = false;
    3940                if ( ! function->get_returnVals().empty() ) {
    40                         TyVarMap forallTypes;
    41                         makeTyVarMap( function, forallTypes );
    42                         return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes );
     41                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
     42       
     43                                // figure out if the return type is specified by a type parameter
     44                                for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
     45                                        if ( (*tyVar)->get_name() == typeInst->get_name() ) {
     46                                                doTransform = true;
     47                                                name = typeInst->get_name();
     48                                                break;
     49                                        } // if
     50                                } // for
     51                                if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
     52                                        doTransform = true;
     53                                } // if
     54                        } // if
    4355                } // if
    44                 return 0;
     56                return doTransform;
     57        }
     58
     59        bool isPolyRet( FunctionType *function, std::string &name ) {
     60                TyVarMap dummyTyVars;
     61                return isPolyRet( function, name, dummyTyVars );
     62        }
     63
     64        bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) {
     65                std::string dummyString;
     66                return isPolyRet( function, dummyString, otherTyVars );
    4567        }
    4668
     
    127149        }
    128150
    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
    138                 }
    139 
    140                 return isPolyType( type, env );
    141         }
    142        
    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
    152                 }
    153 
    154                 return isPolyType( type, tyVars, env );
    155         }
    156 
    157151        FunctionType * getFunctionType( Type *ty ) {
    158152                PointerType *ptrType;
     
    164158        }
    165159
    166         VariableExpr *getBaseVar( Expression *expr ) {
    167                 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
    168                         // found the variable directly
    169                         return varExpr;
    170                 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
    171                         // look for compiler-inserted dereference operator
    172                         NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
    173                         if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
    174                         return getBaseVar( *untypedExpr->begin_args() );
    175                 } else return 0;
    176         }
    177 
    178         void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
    179                 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
    180                         assert( *tyVar );
    181                         tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
    182                 }
    183                 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
    184                         makeTyVarMap( pointer->get_base(), tyVarMap );
    185                 }
    186         }
    187        
    188160        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
    189161                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
     
    200172                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
    201173        }
    202 
    203         std::string offsetofName( Type* ty ) {
    204                 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );
    205         }
    206 
    207174} // namespace GenPoly
    208175
  • src/GenPoly/GenPoly.h

    r421edab r803deb1  
    2222
    2323#include "SynTree/Declaration.h"
    24 #include "SynTree/Type.h"
    2524#include "SynTree/TypeSubstitution.h"
    2625
     
    3332
    3433        /// true iff function has polymorphic return type
    35         ReferenceToType *isPolyRet( FunctionType *function );
     34        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars );
     35        bool isPolyRet( FunctionType *function, std::string &name );
     36        bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars );
    3637
    3738        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
     
    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        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
     51        FunctionType * getFunctionType( Type *ty );
    5252
    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 );
    56 
    57         /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    58         FunctionType *getFunctionType( Type *ty );
    59 
    60         /// Returns the base variable (possibly repeatedly dereferenced) for an expression, NULL if none found
    61         VariableExpr *getBaseVar( Expression *expr );
    62 
    63         /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
    64         void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    65        
    6653        /// Prints type variable map
    6754        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     
    7259        /// Gets the name of the alignof parameter for the type
    7360        std::string alignofName( Type *ty );
    74 
    75         /// Gets the name of the offsetof parameter for the type
    76         std::string offsetofName( Type *ty );
    7761} // namespace GenPoly
    7862
  • src/GenPoly/PolyMutator.cc

    r421edab r803deb1  
    152152        }
    153153
     154
     155        /* static class method */
     156        void PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     157                for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     158                        assert( *tyVar );
     159                        tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
     160                }
     161                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
     162                        makeTyVarMap( pointer->get_base(), tyVarMap );
     163                }
     164        }
    154165} // namespace GenPoly
    155166
  • src/GenPoly/PolyMutator.h

    r421edab r803deb1  
    5151                virtual void doBeginScope() {}
    5252                virtual void doEndScope() {}
     53               
     54                static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
    5355          protected:
    5456                void mutateStatementList( std::list< Statement* > &statements );
  • src/GenPoly/ScrubTyVars.cc

    r421edab r803deb1  
    2727        Type * ScrubTyVars::mutate( TypeInstType *typeInst ) {
    2828                TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
    29                 if ( tyVar != tyVars.end() ) {
     29                if ( doAll || tyVar != tyVars.end() ) {
    3030                        switch ( tyVar->second ) {
    3131                          case TypeDecl::Any:
     
    4242                } // if
    4343                return typeInst;
    44         }
    45 
    46         Type * ScrubTyVars::mutateAggregateType( Type *ty ) {
    47                 if ( isPolyType( ty, tyVars ) ) {
    48                         PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( ty->get_qualifiers() ) );
    49                         delete ty;
    50                         return ret;
    51                 }
    52                 return ty;
    53         }
    54        
    55         Type * ScrubTyVars::mutate( StructInstType *structInst ) {
    56                 return mutateAggregateType( structInst );
    57         }
    58 
    59         Type * ScrubTyVars::mutate( UnionInstType *unionInst ) {
    60                 return mutateAggregateType( unionInst );
    6144        }
    6245
     
    8366        Type * ScrubTyVars::mutate( PointerType *pointer ) {
    8467                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) {
    85                         if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
     68                        if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    8669                                Type *ret = mutate( typeInst );
    8770                                ret->get_qualifiers() += pointer->get_qualifiers();
  • src/GenPoly/ScrubTyVars.h

    r421edab r803deb1  
    2727        class ScrubTyVars : public Mutator {
    2828          public:
    29                 ScrubTyVars( const TyVarMap &tyVars ): tyVars( tyVars ) {}
     29                ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
    3030
    31                 /// For all polymorphic types with type variables in `tyVars`, replaces generic types, dtypes, and ftypes with the appropriate void type,
    32                 /// and sizeof/alignof expressions with the proper variable
     31                /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
    3332                template< typename SynTreeClass >
    3433                static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
    35 
     34                /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable
     35                template< typename SynTreeClass >
     36                static SynTreeClass *scrub( SynTreeClass *target );
     37 
    3638                virtual Type* mutate( TypeInstType *typeInst );
    37                 virtual Type* mutate( StructInstType *structInst );
    38                 virtual Type* mutate( UnionInstType *unionInst );
    39                 virtual Expression* mutate( SizeofExpr *szeof );
    40                 virtual Expression* mutate( AlignofExpr *algnof );
     39                Expression* mutate( SizeofExpr *szeof );
     40                Expression* mutate( AlignofExpr *algnof );
    4141                virtual Type* mutate( PointerType *pointer );
    42 
    4342          private:
    44                 /// Mutates (possibly generic) aggregate types appropriately
    45                 Type* mutateAggregateType( Type *ty );
    46                
     43                bool doAll;
    4744                const TyVarMap &tyVars;
    4845        };
     
    5148        template< typename SynTreeClass >
    5249        SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) {
    53                 ScrubTyVars scrubber( tyVars );
     50                ScrubTyVars scrubber( false, tyVars );
    5451                return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) );
    5552        }
    5653
     54        /* static class method */
     55        template< typename SynTreeClass >
     56        SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target ) {
     57                TyVarMap tyVars;
     58                ScrubTyVars scrubber( true, tyVars );
     59                return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
     60        }
    5761} // namespace GenPoly
    5862
  • src/InitTweak/InitModel.h

    r421edab r803deb1  
    7373                        void visit( SizeofExpr * ) { throw 0; }
    7474                        void visit( AlignofExpr * ) { throw 0; }
    75                         void visit( OffsetofExpr * ) { throw 0; }
    7675                        void visit( AttrExpr * ) { throw 0; }
    7776                        void visit( LogicalExpr * ) { throw 0; }
  • src/ResolvExpr/AlternativeFinder.cc

    r421edab r803deb1  
    811811        }
    812812
    813         void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
    814                 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
    815         }
    816 
    817813        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    818814                // assume no polymorphism
  • src/ResolvExpr/AlternativeFinder.h

    r421edab r803deb1  
    5656                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
    58                 virtual void visit( AlignofExpr *alignofExpr );
    59                 virtual void visit( OffsetofExpr *offsetofExpr );
     58                virtual void visit( AlignofExpr *sizeofExpr );
    6059                virtual void visit( AttrExpr *attrExpr );
    6160                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Indexer.cc

    r421edab r803deb1  
    225225                        maybeAccept( alignofExpr->get_expr(), *this );
    226226                }
    227         }
    228 
    229         void Indexer::visit( OffsetofExpr *offsetofExpr ) {
    230                 acceptAllNewScope( offsetofExpr->get_results(), *this );
    231                 maybeAccept( offsetofExpr->get_type(), *this );
    232                 maybeAccept( offsetofExpr->get_member(), *this );
    233227        }
    234228
  • src/SymTab/Indexer.h

    r421edab r803deb1  
    5555                virtual void visit( SizeofExpr *sizeofExpr );
    5656                virtual void visit( AlignofExpr *alignofExpr );
    57                 virtual void visit( OffsetofExpr *offsetofExpr );
    5857                virtual void visit( AttrExpr *attrExpr );
    5958                virtual void visit( LogicalExpr *logicalExpr );
  • src/SynTree/Expression.cc

    r421edab r803deb1  
    103103SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
    104104                Expression( _aname ), expr(expr_), type(0), isType(false) {
    105         add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     105        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
    106106}
    107107
    108108SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) :
    109109                Expression( _aname ), expr(0), type(type_), isType(true) {
    110         add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     110        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
    111111}
    112112
     
    134134AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
    135135                Expression( _aname ), expr(expr_), type(0), isType(false) {
    136         add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     136        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
    137137}
    138138
    139139AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
    140140                Expression( _aname ), expr(0), type(type_), isType(true) {
    141         add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     141        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
    142142}
    143143
     
    158158        else
    159159                expr->print(os, indent + 2);
    160 
    161         os << std::endl;
    162         Expression::print( os, indent );
    163 }
    164 
    165 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
    166                 Expression( _aname ), type(type_), member(member_) {
    167         add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    168 }
    169 
    170 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
    171         Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {}
    172 
    173 OffsetofExpr::~OffsetofExpr() {
    174         delete type;
    175         delete member;
    176 }
    177 
    178 void OffsetofExpr::print( std::ostream &os, int indent) const {
    179         os << std::string( indent, ' ' ) << "Offsetof Expression on member ";
    180 
    181         if ( member ) {
    182                 os << member->get_name();
    183         } else {
    184                 os << "<NULL>";
    185         }
    186 
    187         os << " of ";
    188 
    189         if ( type ) {
    190                 type->print(os, indent + 2);
    191         } else {
    192                 os << "<NULL>";
    193         }
    194160
    195161        os << std::endl;
  • src/SynTree/Expression.h

    r421edab r803deb1  
    319319};
    320320
    321 /// OffsetofExpr represents an offsetof expression
    322 class OffsetofExpr : public Expression {
    323   public:
    324         OffsetofExpr( Type *type, DeclarationWithType *member, Expression *_aname = 0 );
    325         OffsetofExpr( const OffsetofExpr &other );
    326         virtual ~OffsetofExpr();
    327 
    328         Type *get_type() const { return type; }
    329         void set_type( Type *newValue ) { type = newValue; }
    330         DeclarationWithType *get_member() const { return member; }
    331         void set_member( DeclarationWithType *newValue ) { member = newValue; }
    332 
    333         virtual OffsetofExpr *clone() const { return new OffsetofExpr( *this ); }
    334         virtual void accept( Visitor &v ) { v.visit( this ); }
    335         virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    336         virtual void print( std::ostream &os, int indent = 0 ) const;
    337   private:
    338         Type *type;
    339         DeclarationWithType *member;
    340 };
    341 
    342321/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    343322class AttrExpr : public Expression {
  • src/SynTree/Initializer.h

    r421edab r803deb1  
    5555class SingleInit : public Initializer {
    5656  public:
    57         SingleInit( Expression *value, std::list< Expression *> &designators = *(new std::list<Expression *>()) );
     57        SingleInit( Expression *value, std::list< Expression *> &designators );
    5858        SingleInit( const SingleInit &other );
    5959        virtual ~SingleInit();
  • src/SynTree/Mutator.cc

    r421edab r803deb1  
    261261}
    262262
    263 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
    264         mutateAll( offsetofExpr->get_results(), *this );
    265         offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
    266         offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) );
    267         return offsetofExpr;
    268 }
    269 
    270263Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    271264        mutateAll( attrExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    r421edab r803deb1  
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
    6666        virtual Expression* mutate( AlignofExpr *alignofExpr );
    67         virtual Expression* mutate( OffsetofExpr *offsetofExpr );
    6867        virtual Expression* mutate( AttrExpr *attrExpr );
    6968        virtual Expression* mutate( LogicalExpr *logicalExpr );
  • src/SynTree/SynTree.h

    r421edab r803deb1  
    7070class SizeofExpr;
    7171class AlignofExpr;
    72 class OffsetofExpr;
    7372class AttrExpr;
    7473class LogicalExpr;
  • src/SynTree/Visitor.cc

    r421edab r803deb1  
    219219}
    220220
    221 void Visitor::visit( OffsetofExpr *offsetofExpr ) {
    222         acceptAll( offsetofExpr->get_results(), *this );
    223         maybeAccept( offsetofExpr->get_type(), *this );
    224         maybeAccept( offsetofExpr->get_member(), *this );
    225 }
    226 
    227221void Visitor::visit( AttrExpr *attrExpr ) {
    228222        acceptAll( attrExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    r421edab r803deb1  
    6565        virtual void visit( SizeofExpr *sizeofExpr );
    6666        virtual void visit( AlignofExpr *alignofExpr );
    67         virtual void visit( OffsetofExpr *offsetofExpr );
    6867        virtual void visit( AttrExpr *attrExpr );
    6968        virtual void visit( LogicalExpr *logicalExpr );
  • src/Tuples/FlattenTuple.cc

    r421edab r803deb1  
    4747        void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4848        void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    49         void FlattenTuple::CollectArgs::visit( OffsetofExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5049        void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5150        void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    r421edab r803deb1  
    4343                        virtual void visit( SizeofExpr * );
    4444                        virtual void visit( AlignofExpr * );
    45                         virtual void visit( OffsetofExpr * );
    4645                        virtual void visit( AttrExpr * );
    4746                        virtual void visit( LogicalExpr * );
  • src/main.cc

    r421edab r803deb1  
    2424#include "SynTree/Declaration.h"
    2525#include "SynTree/Visitor.h"
     26#include "GenPoly/InstantiateGeneric.h"
    2627#include "GenPoly/Lvalue.h"
    2728#include "GenPoly/Specialize.h"
     
    264265                }
    265266
     267                OPTPRINT( "instantiateGeneric" )
     268                GenPoly::instantiateGeneric( translationUnit );
    266269                OPTPRINT( "copyParams" );
    267270                GenPoly::copyParams( translationUnit );
     
    272275                OPTPRINT( "box" )
    273276                GenPoly::box( translationUnit );
    274                
     277
    275278                // print tree right before code generation
    276279                if ( codegenp ) {
Note: See TracChangeset for help on using the changeset viewer.