Changes in / [f3fc8cbe:73a28e2]


Ignore:
Location:
src
Files:
1 added
26 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rf3fc8cbe r73a28e2  
    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 *sizeofExpr ) {
     444        void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
    445445                // use GCC extension to avoid bumping std to C11
    446446                output << "__alignof__(";
    447                 if ( sizeofExpr->get_isType() ) {
    448                         output << genType( sizeofExpr->get_type(), "" );
    449                 } else {
    450                         sizeofExpr->get_expr()->accept( *this );
     447                if ( alignofExpr->get_isType() ) {
     448                        output << genType( alignofExpr->get_type(), "" );
     449                } else {
     450                        alignofExpr->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 
    455463        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    456464                output << "(";
     
    464472                output << ")";
    465473        }
    466 
     474 
    467475        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    468476                output << "(";
     
    474482                output << ")";
    475483        }
    476 
     484 
    477485        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    478486                output << "(";
     
    482490                output << ")";
    483491        }
    484 
     492 
    485493        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    486 
     494 
    487495        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    488496
     
    515523                        }
    516524                }
    517                 cur_indent -= CodeGenerator::tabsize;
     525                cur_indent -= CodeGenerator::tabsize; 
    518526
    519527                output << indent << "}";
     
    521529
    522530        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    523                 // I don't see why this check is necessary.
    524                 // If this starts to cause problems then put it back in,
     531                // I don't see why this check is necessary. 
     532                // If this starts to cause problems then put it back in, 
    525533                // with an explanation
    526534                assert( exprStmt );
     
    572580                switchStmt->get_condition()->accept( *this );
    573581                output << " ) ";
    574 
     582               
    575583                output << "{" << std::endl;
    576584                cur_indent += CodeGenerator::tabsize;
     
    592600                } // if
    593601                output << ":\n";
    594 
     602               
    595603                std::list<Statement *> sts = caseStmt->get_statements();
    596604
     
    609617                        if ( ! branchStmt->get_target().empty() )
    610618                                output << "goto " << branchStmt->get_target();
    611                         else {
     619                        else { 
    612620                                if ( branchStmt->get_computedTarget() != 0 ) {
    613621                                        output << "goto *";
     
    660668
    661669        void CodeGenerator::visit( ForStmt *forStmt ) {
    662                 // initialization is always hoisted, so don't
    663                 // bother doing anything with that
     670                // initialization is always hoisted, so don't 
     671                // bother doing anything with that 
    664672                output << "for (;";
    665673
     
    685693        void CodeGenerator::visit( DeclStmt *declStmt ) {
    686694                declStmt->get_decl()->accept( *this );
    687 
     695       
    688696                if ( doSemicolon( declStmt->get_decl() ) ) {
    689697                        output << ";";
  • src/CodeGen/CodeGenerator.h

    rf3fc8cbe r73a28e2  
    6161                virtual void visit( SizeofExpr *sizeofExpr );
    6262                virtual void visit( AlignofExpr *alignofExpr );
     63                virtual void visit( OffsetofExpr *offsetofExpr );
    6364                virtual void visit( LogicalExpr *logicalExpr );
    6465                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    rf3fc8cbe r73a28e2  
    2222
    2323#include "Box.h"
     24#include "InstantiateGeneric.h"
    2425#include "PolyMutator.h"
    2526#include "FindFunction.h"
     27#include "ScopedMap.h"
    2628#include "ScrubTyVars.h"
    2729
     
    6971                        virtual void doEndScope();
    7072                  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
    7176                        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
    7278                        Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg );
    73                         Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, 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 );
    7486                        Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7587                        void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
    7688                        void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );
    7789                        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
    7891                        void findAssignOps( const std::list< TypeDecl *> &forall );
    7992                        void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
    8093                        FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
     94                        /// Replaces intrinsic operator functions with their arithmetic desugaring
    8195                        Expression *handleIntrinsics( ApplicationExpr *appExpr );
     96                        /// Inserts a new temporary variable into the current scope with an auto-generated name
    8297                        ObjectDecl *makeTemporary( Type *type );
    8398
    8499                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    85100                        std::map< std::string, DeclarationWithType *> assignOps;
     101                        ScopedMap< std::string, DeclarationWithType *> scopedAssignOps;
    86102                        std::stack< AdapterMap > adapters;
    87103                        DeclarationWithType *retval;
     
    107123                };
    108124
    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 {
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
     126                class MemberExprFixer : public PolyMutator {
    111127                  public:
    112128                        template< typename DeclClass >
     
    119135                        virtual Type *mutate( PointerType *pointerType );
    120136                        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 );
    121151                  private:
    122152                };
     
    133163        }
    134164
     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
    135191        void box( std::list< Declaration *>& translationUnit ) {
    136192                Pass1 pass1;
    137193                Pass2 pass2;
     194                MemberExprFixer memberFixer;
    138195                Pass3 pass3;
    139                 mutateAll( translationUnit, pass1 );
    140                 mutateAll( translationUnit, pass2 );
    141                 mutateAll( translationUnit, pass3 );
     196                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     197                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     198                instantiateGeneric( translationUnit );
     199                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     200                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    142201        }
    143202
     
    185244                }
    186245
    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 ) {
     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 ) {
    189248                        if ( decl->get_name() == "?=?" ) {
    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
     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;
    200256                                                                        } // if
    201257                                                                } // if
     
    205261                                } // if
    206262                        } // if
    207                         return false;
     263                        return 0;
    208264                }
    209265
     
    214270                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    215271                                        std::string typeName;
    216                                         if ( checkAssignment( *assert, typeName ) ) {
    217                                                 assignOps[ typeName ] = *assert;
     272                                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
     273                                                assignOps[ typeInst->get_name() ] = *assert;
    218274                                        } // if
    219275                                } // for
     
    222278
    223279                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                       
    224287                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    225288                                doBeginScope();
     
    231294                                // process polymorphic return value
    232295                                retval = 0;
    233                                 std::string typeName;
    234                                 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     296                                if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    235297                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    236298
     
    256318                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    257319                                } // for
     320                               
    258321                                AdapterMap & adapters = Pass1::adapters.top();
    259322                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    306369                }
    307370
     371                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     372                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
     373                       
     374                        // make a new temporary array
     375                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     376                        std::stringstream lenGen;
     377                        lenGen << baseMembers.size();
     378                        ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
     379                        ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
     380
     381                        // build initializer list for temporary
     382                        std::list< Initializer* > inits;
     383                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     384                                DeclarationWithType *memberDecl;
     385                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     386                                        memberDecl = origMember->clone();
     387                                } else {
     388                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     389                                }
     390                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
     391                        }
     392                        arrayTemp->set_init( new ListInit( inits ) );
     393
     394                        // return variable pointing to temporary
     395                        return new VariableExpr( arrayTemp );
     396                }
     397               
    308398                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    309399                        // pass size/align for type variables
     
    325415
    326416                        // add size/align for generic types to parameter list
    327                         //assert( ! appExpr->get_function()->get_results().empty() );
    328417                        if ( appExpr->get_function()->get_results().empty() ) return;
    329418                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    334423                        std::set< std::string > seenTypes; //< names for generic types we've seen
    335424                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
    336                                 Type *parmType = (*fnParm)->get_type();
    337                                 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
    338                                         std::string sizeName = sizeofName( parmType );
     425                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars );
     426                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     427                                        std::string sizeName = sizeofName( polyBase );
    339428                                        if ( seenTypes.count( sizeName ) ) continue;
    340429
    341                                         assert( ! (*fnArg)->get_results().empty() );
    342                                         Type *argType = (*fnArg)->get_results().front();
    343                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     430                                        VariableExpr *fnArgBase = getBaseVar( *fnArg );
     431                                        assert( fnArgBase && ! fnArgBase->get_results().empty() );
     432                                        Type *argBaseType = fnArgBase->get_results().front();
     433                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
    344434                                        arg++;
    345                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     435                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    346436                                        arg++;
     437                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     438                                                if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
     439                                                        arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     440                                                        arg++;
     441                                                } else {
     442                                                        throw SemanticError( "Cannot pass non-struct type for generic struct" );
     443                                                }
     444                                        }
    347445
    348446                                        seenTypes.insert( sizeName );
     
    386484                }
    387485
    388                 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
    389                         ResolvExpr::EqvClass eqvClass;
     486                void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
     487                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     488                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     489                                assert(paramType && "Aggregate parameters should be type expressions");
     490                                paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
     491                        }
     492                }
     493               
     494                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
     495                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     496                                Type *concrete = env->lookup( typeInst->get_name() );
     497                                if ( concrete == 0 ) {
     498                                        throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
     499                                } // if
     500                                return concrete;
     501                        } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     502                                if ( doClone ) {
     503                                        structType = structType->clone();
     504                                }
     505                                replaceParametersWithConcrete( appExpr, structType->get_parameters() );
     506                                return structType;
     507                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     508                                if ( doClone ) {
     509                                        unionType = unionType->clone();
     510                                }
     511                                replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
     512                                return unionType;
     513                        }
     514                        return type;
     515                }
     516
     517                Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
    390518                        assert( env );
    391                         Type *concrete = env->lookup( typeName );
    392                         if ( concrete == 0 ) {
    393                                 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
    394                         } // if
     519                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    395520                        return addRetParam( appExpr, function, concrete, arg );
    396521                }
     
    492617                        assert( arg );
    493618                        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 {
    497619                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    498620                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    501623                                        return deref;
    502624                                } // if
    503 //     }
    504625                        } // if
    505626                        return new VariableExpr( param );
     
    791912                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    792913
    793                         std::string typeName;
    794                         if ( isPolyRet( function, typeName ) ) {
    795                                 ret = addPolyRetParam( appExpr, function, typeName, arg );
     914                        if ( ReferenceToType *polyType = isPolyRet( function ) ) {
     915                                ret = addPolyRetParam( appExpr, function, polyType, arg );
    796916                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    797917                                // std::cerr << "needs adapter: ";
     
    8801000                                        delete castExpr;
    8811001                                } //while
    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 ) );
     1002
     1003                                // find assignment operator for (polymorphic) return type
     1004                                DeclarationWithType *assignDecl = 0;
     1005                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1006                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     1007                                        if ( assignIter == assignOps.end() ) {
     1008                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     1009                                        } // if
     1010                                        assignDecl = assignIter->second;
     1011                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1012                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
     1013                                        if ( assignIter == scopedAssignOps.end() ) {
     1014                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
     1015                                        }
     1016                                        DeclarationWithType *functionDecl = assignIter->second;
     1017                                        // line below cloned from FixFunction.cc
     1018                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1019                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1020                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1021                                }
     1022                                assert( assignDecl );
     1023
     1024                                // replace return statement with appropriate assignment to out parameter
     1025                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    8891026                                Expression *retParm = new NameExpr( retval->get_name() );
    8901027                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    9271064                        // push a copy of the current map
    9281065                        adapters.push(adapters.top());
     1066                        scopedAssignOps.beginScope();
    9291067                }
    9301068
    9311069                void Pass1::doEndScope() {
    9321070                        adapters.pop();
     1071                        scopedAssignOps.endScope();
    9331072                }
    9341073
     
    9981137
    9991138                        // move polymorphic return type to parameter list
    1000                         std::string typeName;
    1001                         if ( isPolyRet( funcType, typeName ) ) {
     1139                        if ( isPolyRet( funcType ) ) {
    10021140                                DeclarationWithType *ret = funcType->get_returnVals().front();
    10031141                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    10101148                        std::list< DeclarationWithType *> inferredParams;
    10111149                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1150                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
     1151                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    10121152//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10131153                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    10361176
    10371177                        // add size/align for generic types to parameter list
    1038                         std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1178                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    10391179                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1040                                 Type *parmType = (*fnParm)->get_type();
    1041                                 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
    1042                                         std::string sizeName = sizeofName( parmType );
     1180                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
     1181                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     1182                                        std::string sizeName = sizeofName( polyBase );
    10431183                                        if ( seenTypes.count( sizeName ) ) continue;
    10441184
    1045                                         ObjectDecl *sizeParm, *alignParm;
     1185                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    10461186                                        sizeParm = newObj.clone();
    10471187                                        sizeParm->set_name( sizeName );
     
    10501190
    10511191                                        alignParm = newObj.clone();
    1052                                         alignParm->set_name( alignofName( parmType ) );
     1192                                        alignParm->set_name( alignofName( polyBase ) );
    10531193                                        last = funcType->get_parameters().insert( last, alignParm );
    10541194                                        ++last;
     1195
     1196                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     1197                                                offsetParm = newPtr.clone();
     1198                                                offsetParm->set_name( offsetofName( polyBase ) );
     1199                                                last = funcType->get_parameters().insert( last, offsetParm );
     1200                                                ++last;
     1201                                        }
    10551202
    10561203                                        seenTypes.insert( sizeName );
     
    10661213                        scopeTyVars = oldtyVars;
    10671214                        return funcType;
     1215                }
     1216
     1217////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
     1218
     1219                template< typename DeclClass >
     1220                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1221                        TyVarMap oldtyVars = scopeTyVars;
     1222                        makeTyVarMap( type, scopeTyVars );
     1223
     1224                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1225
     1226                        scopeTyVars = oldtyVars;
     1227                        return ret;
     1228                }
     1229
     1230                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
     1231                        return handleDecl( objectDecl, objectDecl->get_type() );
     1232                }
     1233
     1234                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
     1235                        return handleDecl( functionDecl, functionDecl->get_functionType() );
     1236                }
     1237
     1238                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
     1239                        return handleDecl( typedefDecl, typedefDecl->get_base() );
     1240                }
     1241
     1242                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
     1243                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1244                        return Mutator::mutate( typeDecl );
     1245                }
     1246
     1247                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1248                        TyVarMap oldtyVars = scopeTyVars;
     1249                        makeTyVarMap( pointerType, scopeTyVars );
     1250
     1251                        Type *ret = Mutator::mutate( pointerType );
     1252
     1253                        scopeTyVars = oldtyVars;
     1254                        return ret;
     1255                }
     1256
     1257                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1258                        TyVarMap oldtyVars = scopeTyVars;
     1259                        makeTyVarMap( functionType, scopeTyVars );
     1260
     1261                        Type *ret = Mutator::mutate( functionType );
     1262
     1263                        scopeTyVars = oldtyVars;
     1264                        return ret;
     1265                }
     1266
     1267                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
     1268                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1269                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1270                                        // change initialization of a polymorphic value object
     1271                                        // to allocate storage with alloca
     1272                                        Type *declType = objectDecl->get_type();
     1273                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
     1274                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1275
     1276                                        delete objectDecl->get_init();
     1277
     1278                                        std::list<Expression*> designators;
     1279                                        objectDecl->set_init( new SingleInit( alloc, designators ) );
     1280                                }
     1281                        }
     1282                        return Mutator::mutate( declStmt );
     1283                }
     1284
     1285                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1286                        // mutate, exiting early if no longer MemberExpr
     1287                        Expression *expr = Mutator::mutate( memberExpr );
     1288                        memberExpr = dynamic_cast< MemberExpr* >( expr );
     1289                        if ( ! memberExpr ) return expr;
     1290
     1291                        // get declaration for base struct, exiting early if not found
     1292                        int varDepth;
     1293                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
     1294                        if ( ! varExpr ) return memberExpr;
     1295                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1296                        if ( ! objectDecl ) return memberExpr;
     1297
     1298                        // only mutate member expressions for polymorphic types
     1299                        int tyDepth;
     1300                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
     1301                        if ( ! objectType ) return memberExpr;
     1302
     1303                        // get base aggregate for type so members can be looked up
     1304                        AggregateDecl *memberBase = 0;
     1305                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     1306                                memberBase = structType->get_baseStruct();
     1307                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1308                                memberBase = unionType->get_baseUnion();
     1309                        } else return memberExpr;
     1310
     1311                        // look up numeric index of member in base aggregate
     1312                        DeclarationWithType *memberDecl = memberExpr->get_member();
     1313                        std::list< Declaration* > &baseDecls = memberBase->get_members();
     1314                        std::list< Declaration* >::const_iterator decl = baseDecls.begin();
     1315                        unsigned long i = 0;
     1316                        for( ; decl != baseDecls.end(); ++decl, ++i ) {
     1317                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1318
     1319                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1320                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
     1321                                        else continue;
     1322                                } else break;
     1323                        }
     1324                        if ( decl == baseDecls.end() ) return memberExpr;
     1325
     1326                        // replace member expression with pointer to base plus offset
     1327                        // get offset for field
     1328                        std::stringstream offset_namer;
     1329                        offset_namer << i;
     1330                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1331                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1332                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1333                        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
     1342                        UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1343                        fieldLoc->get_args().push_back( derefdVar );
     1344                        fieldLoc->get_args().push_back( fieldOffset );
     1345
     1346                        delete memberExpr;
     1347                        return fieldLoc;
    10681348                }
    10691349
     
    11261406                        return ret;
    11271407                }
    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                 }
    11461408        } // anonymous namespace
    11471409} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    rf3fc8cbe r73a28e2  
    3636        }
    3737
    38         bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
    39                 bool doTransform = false;
     38        ReferenceToType *isPolyRet( FunctionType *function ) {
    4039                if ( ! function->get_returnVals().empty() ) {
    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
    55                 } // if
    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 );
     40                        TyVarMap forallTypes;
     41                        makeTyVarMap( function, forallTypes );
     42                        return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes );
     43                } // if
     44                return 0;
    6745        }
    6846
     
    149127        }
    150128
     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;
     145                }
     146
     147                return isPolyType( type, env );
     148        }
     149       
     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;
     166                }
     167
     168                return isPolyType( type, tyVars, env );
     169        }
     170
    151171        FunctionType * getFunctionType( Type *ty ) {
    152172                PointerType *ptrType;
     
    158178        }
    159179
     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;
     201        }
     202
     203        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
     204                for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     205                        assert( *tyVar );
     206                        tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
     207                }
     208                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
     209                        makeTyVarMap( pointer->get_base(), tyVarMap );
     210                }
     211        }
     212       
    160213        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
    161214                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
     
    172225                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
    173226        }
     227
     228        std::string offsetofName( Type* ty ) {
     229                return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );
     230        }
     231
    174232} // namespace GenPoly
    175233
  • src/GenPoly/GenPoly.h

    rf3fc8cbe r73a28e2  
    2020#include <string>
    2121#include <iostream>
     22#include <utility>
    2223
    2324#include "SynTree/Declaration.h"
     25#include "SynTree/Type.h"
    2426#include "SynTree/TypeSubstitution.h"
    2527
     
    3234
    3335        /// true iff function has polymorphic return type
    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 );
     36        ReferenceToType *isPolyRet( FunctionType *function );
    3737
    3838        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
     
    4848        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    4949
     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 );
     53
     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 );
     57
    5058        /// 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 );
     59        FunctionType *getFunctionType( Type *ty );
    5260
     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 );
     64
     65        /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap`
     66        void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
     67       
    5368        /// Prints type variable map
    5469        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
     
    5974        /// Gets the name of the alignof parameter for the type
    6075        std::string alignofName( Type *ty );
     76
     77        /// Gets the name of the offsetof parameter for the type
     78        std::string offsetofName( Type *ty );
    6179} // namespace GenPoly
    6280
  • src/GenPoly/PolyMutator.cc

    rf3fc8cbe r73a28e2  
    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         }
    165154} // namespace GenPoly
    166155
  • src/GenPoly/PolyMutator.h

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

    rf3fc8cbe r73a28e2  
    2727        Type * ScrubTyVars::mutate( TypeInstType *typeInst ) {
    2828                TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
    29                 if ( doAll || tyVar != tyVars.end() ) {
     29                if ( 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 );
    4461        }
    4562
     
    6582
    6683        Type * ScrubTyVars::mutate( PointerType *pointer ) {
    67                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) {
    68                         if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    69                                 Type *ret = mutate( typeInst );
    70                                 ret->get_qualifiers() += pointer->get_qualifiers();
    71                                 pointer->set_base( 0 );
    72                                 delete pointer;
    73                                 return ret;
    74                         } // if
    75                 } // if
     84                if ( Type *polyType = isPolyType( pointer->get_base(), tyVars ) ) {
     85                        Type *ret = polyType->acceptMutator( *this );
     86                        ret->get_qualifiers() += pointer->get_qualifiers();
     87                        pointer->set_base( 0 );
     88                        delete pointer;
     89                        return ret;
     90                }
    7691                return Mutator::mutate( pointer );
    7792        }
  • src/GenPoly/ScrubTyVars.h

    rf3fc8cbe r73a28e2  
    2727        class ScrubTyVars : public Mutator {
    2828          public:
    29                 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
     29                ScrubTyVars( const TyVarMap &tyVars ): tyVars( tyVars ) {}
    3030
    31                 /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
     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
    3233                template< typename SynTreeClass >
    3334                static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
    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  
     35
    3836                virtual Type* mutate( TypeInstType *typeInst );
    39                 Expression* mutate( SizeofExpr *szeof );
    40                 Expression* mutate( AlignofExpr *algnof );
     37                virtual Type* mutate( StructInstType *structInst );
     38                virtual Type* mutate( UnionInstType *unionInst );
     39                virtual Expression* mutate( SizeofExpr *szeof );
     40                virtual Expression* mutate( AlignofExpr *algnof );
    4141                virtual Type* mutate( PointerType *pointer );
     42
    4243          private:
    43                 bool doAll;
     44                /// Mutates (possibly generic) aggregate types appropriately
     45                Type* mutateAggregateType( Type *ty );
     46               
    4447                const TyVarMap &tyVars;
    4548        };
     
    4851        template< typename SynTreeClass >
    4952        SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) {
    50                 ScrubTyVars scrubber( false, tyVars );
     53                ScrubTyVars scrubber( tyVars );
    5154                return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) );
    5255        }
    5356
    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         }
    6157} // namespace GenPoly
    6258
  • src/InitTweak/InitModel.h

    rf3fc8cbe r73a28e2  
    7373                        void visit( SizeofExpr * ) { throw 0; }
    7474                        void visit( AlignofExpr * ) { throw 0; }
     75                        void visit( OffsetofExpr * ) { throw 0; }
    7576                        void visit( AttrExpr * ) { throw 0; }
    7677                        void visit( LogicalExpr * ) { throw 0; }
  • src/ResolvExpr/AlternativeFinder.cc

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

    rf3fc8cbe r73a28e2  
    5656                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
    58                 virtual void visit( AlignofExpr *sizeofExpr );
     58                virtual void visit( AlignofExpr *alignofExpr );
     59                virtual void visit( OffsetofExpr *offsetofExpr );
    5960                virtual void visit( AttrExpr *attrExpr );
    6061                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Indexer.cc

    rf3fc8cbe r73a28e2  
    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 );
    227233        }
    228234
  • src/SymTab/Indexer.h

    rf3fc8cbe r73a28e2  
    5555                virtual void visit( SizeofExpr *sizeofExpr );
    5656                virtual void visit( AlignofExpr *alignofExpr );
     57                virtual void visit( OffsetofExpr *offsetofExpr );
    5758                virtual void visit( AttrExpr *attrExpr );
    5859                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Validate.cc

    rf3fc8cbe r73a28e2  
    585585        }
    586586
     587        template< typename OutputIterator >
     588        void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
     589                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
     590                copy->get_args().push_back( new VariableExpr( dstParam ) );
     591                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
     592                copy->get_args().push_back( new SizeofExpr( unionType ) );
     593
     594                *out++ = new ExprStmt( noLabels, copy );
     595        }
     596
    587597        //E ?=?(E volatile*, int),
    588598        //  ?=?(E _Atomic volatile*, int);
     
    653663
    654664                // Make function polymorphic in same parameters as generic struct, if applicable
     665                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    655666                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    656667                std::list< Expression* > structParams;  // List of matching parameters to put on types
    657668                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     669                        isGeneric = true;
    658670                        TypeDecl *typeParam = (*param)->clone();
    659671                        assignType->get_forall().push_back( typeParam );
     
    661673                }
    662674
    663                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     675                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    664676                assignType->get_returnVals().push_back( returnVal );
    665677
     
    691703                                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    692704                                        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     705                                        if ( isGeneric ) makeArrayAssignment( srcParam, returnVal, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    693706                                } else {
    694707                                        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     708                                        if ( isGeneric ) makeScalarAssignment( srcParam, returnVal, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    695709                                } // if
    696710                        } // if
    697711                } // for
    698                 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     712                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    699713
    700714                return assignDecl;
     
    705719
    706720                // Make function polymorphic in same parameters as generic union, if applicable
     721                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    707722                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    708723                std::list< Expression* > unionParams;  // List of matching parameters to put on types
    709724                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     725                        isGeneric = true;
    710726                        TypeDecl *typeParam = (*param)->clone();
    711727                        assignType->get_forall().push_back( typeParam );
     
    713729                }
    714730
    715                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     731                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    716732                assignType->get_returnVals().push_back( returnVal );
    717733
     
    727743                assignDecl->fixUniqueId();
    728744
    729                 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    730                 copy->get_args().push_back( new VariableExpr( dstParam ) );
    731                 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    732                 copy->get_args().push_back( new SizeofExpr( cloneWithParams( refType, unionParams ) ) );
    733 
    734                 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
    735                 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     745                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     746                if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     747               
     748                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    736749
    737750                return assignDecl;
  • src/SynTree/Expression.cc

    rf3fc8cbe r73a28e2  
    103103SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
    104104                Expression( _aname ), expr(expr_), type(0), isType(false) {
    105         add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
     105        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    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::UnsignedInt ) );
     110        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    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::UnsignedInt ) );
     136        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    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::UnsignedInt ) );
     141        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    142142}
    143143
     
    158158        else
    159159                expr->print(os, indent + 2);
     160
     161        os << std::endl;
     162        Expression::print( os, indent );
     163}
     164
     165OffsetofExpr::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
     170OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
     171        Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {}
     172
     173OffsetofExpr::~OffsetofExpr() {
     174        delete type;
     175        delete member;
     176}
     177
     178void 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        }
    160194
    161195        os << std::endl;
  • src/SynTree/Expression.h

    rf3fc8cbe r73a28e2  
    319319};
    320320
     321/// OffsetofExpr represents an offsetof expression
     322class 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
    321342/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    322343class AttrExpr : public Expression {
  • src/SynTree/Initializer.h

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

    rf3fc8cbe r73a28e2  
    261261}
    262262
     263Expression *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
    263270Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    264271        mutateAll( attrExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    rf3fc8cbe r73a28e2  
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
    6666        virtual Expression* mutate( AlignofExpr *alignofExpr );
     67        virtual Expression* mutate( OffsetofExpr *offsetofExpr );
    6768        virtual Expression* mutate( AttrExpr *attrExpr );
    6869        virtual Expression* mutate( LogicalExpr *logicalExpr );
  • src/SynTree/SynTree.h

    rf3fc8cbe r73a28e2  
    7070class SizeofExpr;
    7171class AlignofExpr;
     72class OffsetofExpr;
    7273class AttrExpr;
    7374class LogicalExpr;
  • src/SynTree/Visitor.cc

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

    rf3fc8cbe r73a28e2  
    6565        virtual void visit( SizeofExpr *sizeofExpr );
    6666        virtual void visit( AlignofExpr *alignofExpr );
     67        virtual void visit( OffsetofExpr *offsetofExpr );
    6768        virtual void visit( AttrExpr *attrExpr );
    6869        virtual void visit( LogicalExpr *logicalExpr );
  • src/Tuples/FlattenTuple.cc

    rf3fc8cbe r73a28e2  
    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 );  }
    4950        void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5051        void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    rf3fc8cbe r73a28e2  
    4343                        virtual void visit( SizeofExpr * );
    4444                        virtual void visit( AlignofExpr * );
     45                        virtual void visit( OffsetofExpr * );
    4546                        virtual void visit( AttrExpr * );
    4647                        virtual void visit( LogicalExpr * );
  • src/main.cc

    rf3fc8cbe r73a28e2  
    2424#include "SynTree/Declaration.h"
    2525#include "SynTree/Visitor.h"
    26 #include "GenPoly/InstantiateGeneric.h"
    2726#include "GenPoly/Lvalue.h"
    2827#include "GenPoly/Specialize.h"
     
    265264                }
    266265
    267                 OPTPRINT( "instantiateGeneric" )
    268                 GenPoly::instantiateGeneric( translationUnit );
    269266                OPTPRINT( "copyParams" );
    270267                GenPoly::copyParams( translationUnit );
     
    275272                OPTPRINT( "box" )
    276273                GenPoly::box( translationUnit );
    277 
     274               
    278275                // print tree right before code generation
    279276                if ( codegenp ) {
Note: See TracChangeset for help on using the changeset viewer.