Changeset d63eeb0 for src/GenPoly


Ignore:
Timestamp:
Feb 9, 2016, 3:25:05 PM (10 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
7528ba1
Parents:
771b3c3 (diff), bd85400 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ctor

Conflicts:

src/CodeGen/CodeGenerator.cc
src/GenPoly/Box.cc
src/Makefile.in
src/Parser/ParseNode.h
src/Parser/parser.cc
src/Parser/parser.yy
src/SymTab/Validate.cc
src/SynTree/Initializer.h
src/SynTree/ObjectDecl.cc
src/SynTree/Visitor.h
src/main.cc

Location:
src/GenPoly
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r771b3c3 rd63eeb0  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Jan 07 13:40:05 2016
    13 // Update Count     : 219
     12// Last Modified On : Tue Feb 09 14:39:52 2016
     13// Update Count     : 295
    1414//
    1515
     
    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
     
    3941#include "SymTab/Mangler.h"
    4042
    41 #include "SemanticError.h"
    42 #include "UniqueName.h"
    43 #include "utility.h"
     43#include "Common/SemanticError.h"
     44#include "Common/UniqueName.h"
     45#include "Common/utility.h"
    4446
    4547#include <ext/functional> // temporary
     
    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                /// also fixes offsetof expressions.
     127                class MemberExprFixer : public PolyMutator {
    111128                  public:
    112129                        template< typename DeclClass >
     
    119136                        virtual Type *mutate( PointerType *pointerType );
    120137                        virtual Type *mutate( FunctionType *funcType );
     138                        virtual Expression *mutate( MemberExpr *memberExpr );
     139                        virtual Expression *mutate( OffsetofExpr *offsetofExpr );
     140                };
     141
     142                /// 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
     143                class Pass3 : public PolyMutator {
     144                  public:
     145                        template< typename DeclClass >
     146                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     147                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
     148                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl );
     149                        virtual TypedefDecl *mutate( TypedefDecl *objectDecl );
     150                        virtual TypeDecl *mutate( TypeDecl *objectDecl );
     151                        virtual Type *mutate( PointerType *pointerType );
     152                        virtual Type *mutate( FunctionType *funcType );
    121153                  private:
    122154                };
     
    133165        }
    134166
     167        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
     168        template< typename MutatorType >
     169        inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) {
     170                bool seenIntrinsic = false;
     171                SemanticError errors;
     172                for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     173                        try {
     174                                if ( *i ) {
     175                                        if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) {
     176                                                seenIntrinsic = true;
     177                                        } else if ( seenIntrinsic ) {
     178                                                seenIntrinsic = false; // break on this line when debugging for end of prelude
     179                                        }
     180
     181                                        *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );
     182                                        assert( *i );
     183                                } // if
     184                        } catch( SemanticError &e ) {
     185                                errors.append( e );
     186                        } // try
     187                } // for
     188                if ( ! errors.isEmpty() ) {
     189                        throw errors;
     190                } // if
     191        }
     192
    135193        void box( std::list< Declaration *>& translationUnit ) {
    136194                Pass1 pass1;
    137195                Pass2 pass2;
     196                MemberExprFixer memberFixer;
    138197                Pass3 pass3;
    139                 mutateAll( translationUnit, pass1 );
    140                 mutateAll( translationUnit, pass2 );
    141                 mutateAll( translationUnit, pass3 );
     198                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     199                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     200                instantiateGeneric( translationUnit );
     201                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
     202                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    142203        }
    143204
     
    185246                }
    186247
    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 ) {
     248                /// returns T if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be), NULL otherwise
     249                ReferenceToType *isAssignment( DeclarationWithType *decl ) {
    189250                        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
     251                                if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) {
     252                                        if ( funType->get_parameters().size() == 2 ) {
     253                                                if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
     254                                                        if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( pointer->get_base() ) ) {
     255                                                                if ( ReferenceToType *refType2 = dynamic_cast< ReferenceToType *>( funType->get_parameters().back()->get_type() ) ) {
     256                                                                        if ( refType->get_name() == refType2->get_name() ) {
     257                                                                                return refType;
    200258                                                                        } // if
    201259                                                                } // if
     
    205263                                } // if
    206264                        } // if
    207                         return false;
     265                        return 0;
    208266                }
    209267
     
    214272                                for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    215273                                        std::string typeName;
    216                                         if ( checkAssignment( *assert, typeName ) ) {
    217                                                 assignOps[ typeName ] = *assert;
     274                                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( isAssignment( *assert ) ) ) {
     275                                                assignOps[ typeInst->get_name() ] = *assert;
    218276                                        } // if
    219277                                } // for
     
    222280
    223281                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
     282                        // if this is a polymorphic assignment function, put it in the map for this scope
     283                        if ( ReferenceToType *refType = isAssignment( functionDecl ) ) {
     284                                if ( ! dynamic_cast< TypeInstType* >( refType ) ) {
     285                                        scopedAssignOps.insert( refType->get_name(), functionDecl );
     286                                }
     287                        }
     288
    224289                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    225290                                doBeginScope();
     
    231296                                // process polymorphic return value
    232297                                retval = 0;
    233                                 std::string typeName;
    234                                 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
     298                                if ( isPolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
    235299                                        retval = functionDecl->get_functionType()->get_returnVals().front();
    236300
     
    256320                                        findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );
    257321                                } // for
     322
    258323                                AdapterMap & adapters = Pass1::adapters.top();
    259324                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
     
    304369                        return condExpr;
    305370
     371                }
     372
     373                Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
     374                        std::list<Expression*> noDesignators;
     375                        std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
     376
     377                        // make a new temporary array
     378                        Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     379                        std::stringstream lenGen;
     380                        lenGen << baseMembers.size();
     381                        ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );
     382                        ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );
     383
     384                        // build initializer list for temporary
     385                        std::list< Initializer* > inits;
     386                        for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {
     387                                DeclarationWithType *memberDecl;
     388                                if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {
     389                                        memberDecl = origMember->clone();
     390                                } else {
     391                                        memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
     392                                }
     393                                inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );
     394                        }
     395                        arrayTemp->set_init( new ListInit( inits, noDesignators ) );
     396
     397                        // return variable pointing to temporary
     398                        return new VariableExpr( arrayTemp );
    306399                }
    307400
     
    325418
    326419                        // add size/align for generic types to parameter list
    327                         //assert( ! appExpr->get_function()->get_results().empty() );
    328420                        if ( appExpr->get_function()->get_results().empty() ) return;
    329421                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     
    334426                        std::set< std::string > seenTypes; //< names for generic types we've seen
    335427                        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 );
     428                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars );
     429                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     430                                        std::string sizeName = sizeofName( polyBase );
    339431                                        if ( seenTypes.count( sizeName ) ) continue;
    340432
    341                                         assert( ! (*fnArg)->get_results().empty() );
    342                                         Type *argType = (*fnArg)->get_results().front();
    343                                         arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     433                                        VariableExpr *fnArgBase = getBaseVar( *fnArg );
     434                                        assert( fnArgBase && ! fnArgBase->get_results().empty() );
     435                                        Type *argBaseType = fnArgBase->get_results().front();
     436                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
    344437                                        arg++;
    345                                         arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     438                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    346439                                        arg++;
     440                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     441                                                if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
     442                                                        arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) );
     443                                                        arg++;
     444                                                } else {
     445                                                        throw SemanticError( "Cannot pass non-struct type for generic struct" );
     446                                                }
     447                                        }
    347448
    348449                                        seenTypes.insert( sizeName );
     
    386487                }
    387488
    388                 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
    389                         ResolvExpr::EqvClass eqvClass;
     489                void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) {
     490                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     491                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     492                                assert(paramType && "Aggregate parameters should be type expressions");
     493                                paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) );
     494                        }
     495                }
     496
     497                Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) {
     498                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     499                                Type *concrete = env->lookup( typeInst->get_name() );
     500                                if ( concrete == 0 ) {
     501                                        throw SemanticError( "Unbound type variable " + typeInst->get_name() + " in ", appExpr );
     502                                } // if
     503                                return concrete;
     504                        } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     505                                if ( doClone ) {
     506                                        structType = structType->clone();
     507                                }
     508                                replaceParametersWithConcrete( appExpr, structType->get_parameters() );
     509                                return structType;
     510                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     511                                if ( doClone ) {
     512                                        unionType = unionType->clone();
     513                                }
     514                                replaceParametersWithConcrete( appExpr, unionType->get_parameters() );
     515                                return unionType;
     516                        }
     517                        return type;
     518                }
     519
     520                Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {
    390521                        assert( env );
    391                         Type *concrete = env->lookup( typeName );
    392                         if ( concrete == 0 ) {
    393                                 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
    394                         } // if
     522                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    395523                        return addRetParam( appExpr, function, concrete, arg );
    396524                }
     
    404532                        std::string adapterName = makeAdapterName( mangleName );
    405533
    406                         appExpr->get_args().push_front( appExpr->get_function() );
     534                        // cast adaptee to void (*)(), since it may have any type inside a polymorphic function
     535                        Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
     536                        appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
    407537                        appExpr->set_function( new NameExpr( adapterName ) );
    408538
     
    420550                                        arg = new AddressExpr( arg );
    421551                                } else {
    422                                         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
     552                                        // use type computed in unification to declare boxed variables
     553                                        Type * newType = param->clone();
     554                                        if ( env ) env->apply( newType );
     555                                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, newType, 0 );
    423556                                        newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right???
    424557                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     
    432565                }
    433566
     567                /// cast parameters to polymorphic functions so that types are replaced with
     568                /// void * if they are type parameters in the formal type.
     569                /// this gets rid of warnings from gcc.
    434570                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    435                         Type *newType = formal->clone();
    436                         std::list< FunctionType *> functions;
    437                         // instead of functions needing adapters, this really ought to look for
    438                         // any function mentioning a polymorphic type
    439                         findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    440                         if ( ! functions.empty() ) {
     571                        Type * newType = formal->clone();
     572                        if ( getFunctionType( newType ) ) {
     573                                newType = ScrubTyVars::scrub( newType, tyVars );
    441574                                actual = new CastExpr( actual, newType );
    442                         } else {
    443                                 delete newType;
    444575                        } // if
    445576                }
     
    492623                        assert( arg );
    493624                        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 {
    497625                                if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
    498626                                        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     
    501629                                        return deref;
    502630                                } // if
    503 //     }
    504631                        } // if
    505632                        return new VariableExpr( param );
     
    791918                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    792919
    793                         std::string typeName;
    794                         if ( isPolyRet( function, typeName ) ) {
    795                                 ret = addPolyRetParam( appExpr, function, typeName, arg );
     920                        if ( ReferenceToType *polyType = isPolyRet( function ) ) {
     921                                ret = addPolyRetParam( appExpr, function, polyType, arg );
    796922                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    797923                                // std::cerr << "needs adapter: ";
     
    8801006                                        delete castExpr;
    8811007                                } //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 ) );
     1008
     1009                                // find assignment operator for (polymorphic) return type
     1010                                DeclarationWithType *assignDecl = 0;
     1011                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1012                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     1013                                        if ( assignIter == assignOps.end() ) {
     1014                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     1015                                        } // if
     1016                                        assignDecl = assignIter->second;
     1017                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1018                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
     1019                                        if ( assignIter == scopedAssignOps.end() ) {
     1020                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
     1021                                        }
     1022                                        DeclarationWithType *functionDecl = assignIter->second;
     1023                                        // line below cloned from FixFunction.cc
     1024                                        assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     1025                                                                     new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     1026                                        assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1027                                }
     1028                                assert( assignDecl );
     1029
     1030                                // replace return statement with appropriate assignment to out parameter
     1031                                ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    8891032                                Expression *retParm = new NameExpr( retval->get_name() );
    8901033                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    9271070                        // push a copy of the current map
    9281071                        adapters.push(adapters.top());
     1072                        scopedAssignOps.beginScope();
    9291073                }
    9301074
    9311075                void Pass1::doEndScope() {
    9321076                        adapters.pop();
     1077                        scopedAssignOps.endScope();
    9331078                }
    9341079
     
    9981143
    9991144                        // move polymorphic return type to parameter list
    1000                         std::string typeName;
    1001                         if ( isPolyRet( funcType, typeName ) ) {
     1145                        if ( isPolyRet( funcType ) ) {
    10021146                                DeclarationWithType *ret = funcType->get_returnVals().front();
    10031147                                ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
     
    10101154                        std::list< DeclarationWithType *> inferredParams;
    10111155                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1156                        ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0,
     1157                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
    10121158//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10131159                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
     
    10361182
    10371183                        // add size/align for generic types to parameter list
    1038                         std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1184                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    10391185                        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 );
     1186                                Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
     1187                                if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
     1188                                        std::string sizeName = sizeofName( polyBase );
    10431189                                        if ( seenTypes.count( sizeName ) ) continue;
    10441190
    1045                                         ObjectDecl *sizeParm, *alignParm;
     1191                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    10461192                                        sizeParm = newObj.clone();
    10471193                                        sizeParm->set_name( sizeName );
     
    10501196
    10511197                                        alignParm = newObj.clone();
    1052                                         alignParm->set_name( alignofName( parmType ) );
     1198                                        alignParm->set_name( alignofName( polyBase ) );
    10531199                                        last = funcType->get_parameters().insert( last, alignParm );
    10541200                                        ++last;
     1201
     1202                                        if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     1203                                                offsetParm = newPtr.clone();
     1204                                                offsetParm->set_name( offsetofName( polyBase ) );
     1205                                                last = funcType->get_parameters().insert( last, offsetParm );
     1206                                                ++last;
     1207                                        }
    10551208
    10561209                                        seenTypes.insert( sizeName );
     
    10661219                        scopeTyVars = oldtyVars;
    10671220                        return funcType;
     1221                }
     1222
     1223////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
     1224
     1225                template< typename DeclClass >
     1226                DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) {
     1227                        TyVarMap oldtyVars = scopeTyVars;
     1228                        makeTyVarMap( type, scopeTyVars );
     1229
     1230                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
     1231
     1232                        scopeTyVars = oldtyVars;
     1233                        return ret;
     1234                }
     1235
     1236                ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {
     1237                        return handleDecl( objectDecl, objectDecl->get_type() );
     1238                }
     1239
     1240                DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {
     1241                        return handleDecl( functionDecl, functionDecl->get_functionType() );
     1242                }
     1243
     1244                TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {
     1245                        return handleDecl( typedefDecl, typedefDecl->get_base() );
     1246                }
     1247
     1248                TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {
     1249                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1250                        return Mutator::mutate( typeDecl );
     1251                }
     1252
     1253                Type * MemberExprFixer::mutate( PointerType *pointerType ) {
     1254                        TyVarMap oldtyVars = scopeTyVars;
     1255                        makeTyVarMap( pointerType, scopeTyVars );
     1256
     1257                        Type *ret = Mutator::mutate( pointerType );
     1258
     1259                        scopeTyVars = oldtyVars;
     1260                        return ret;
     1261                }
     1262
     1263                Type * MemberExprFixer::mutate( FunctionType *functionType ) {
     1264                        TyVarMap oldtyVars = scopeTyVars;
     1265                        makeTyVarMap( functionType, scopeTyVars );
     1266
     1267                        Type *ret = Mutator::mutate( functionType );
     1268
     1269                        scopeTyVars = oldtyVars;
     1270                        return ret;
     1271                }
     1272
     1273                Statement *MemberExprFixer::mutate( DeclStmt *declStmt ) {
     1274                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     1275                                if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
     1276                                        // change initialization of a polymorphic value object
     1277                                        // to allocate storage with alloca
     1278                                        Type *declType = objectDecl->get_type();
     1279                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
     1280                                        alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1281
     1282                                        delete objectDecl->get_init();
     1283
     1284                                        std::list<Expression*> designators;
     1285                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
     1286                                }
     1287                        }
     1288                        return Mutator::mutate( declStmt );
     1289                }
     1290
     1291                /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
     1292                long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
     1293                        long i = 0;
     1294                        for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
     1295                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1296
     1297                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1298                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1299                                        else continue;
     1300                                } else return i;
     1301                        }
     1302                        return -1;
     1303                }
     1304
     1305                /// Returns an index expression into the offset array for a type
     1306                Expression *makeOffsetIndex( Type *objectType, long i ) {
     1307                        std::stringstream offset_namer;
     1308                        offset_namer << i;
     1309                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1310                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1311                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1312                        fieldOffset->get_args().push_back( fieldIndex );
     1313                        return fieldOffset;
     1314                }
     1315
     1316                /// Returns an expression dereferenced n times
     1317                Expression *makeDerefdVar( Expression *derefdVar, long n ) {
     1318                        for ( int i = 1; i < n; ++i ) {
     1319                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     1320                                derefExpr->get_args().push_back( derefdVar );
     1321                                derefdVar = derefExpr;
     1322                        }
     1323                        return derefdVar;
     1324                }
     1325
     1326                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
     1327                        // mutate, exiting early if no longer MemberExpr
     1328                        Expression *expr = Mutator::mutate( memberExpr );
     1329                        memberExpr = dynamic_cast< MemberExpr* >( expr );
     1330                        if ( ! memberExpr ) return expr;
     1331
     1332                        // get declaration for base struct, exiting early if not found
     1333                        int varDepth;
     1334                        VariableExpr *varExpr = getBaseVar( memberExpr->get_aggregate(), &varDepth );
     1335                        if ( ! varExpr ) return memberExpr;
     1336                        ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     1337                        if ( ! objectDecl ) return memberExpr;
     1338
     1339                        // only mutate member expressions for polymorphic types
     1340                        int tyDepth;
     1341                        Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth );
     1342                        if ( ! objectType ) return memberExpr;
     1343
     1344                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
     1345                                // look up offset index
     1346                                long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
     1347                                if ( i == -1 ) return memberExpr;
     1348
     1349                                // replace member expression with pointer to base plus offset
     1350                                UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1351                                fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
     1352                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
     1353
     1354                                delete memberExpr;
     1355                                return fieldLoc;
     1356                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1357                                // union members are all at offset zero, so build appropriately-dereferenced variable
     1358                                Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
     1359                                delete memberExpr;
     1360                                return derefdVar;
     1361                        } else return memberExpr;
     1362                }
     1363
     1364                Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
     1365                        // mutate, exiting early if no longer OffsetofExpr
     1366                        Expression *expr = Mutator::mutate( offsetofExpr );
     1367                        offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
     1368                        if ( ! offsetofExpr ) return expr;
     1369
     1370                        // only mutate expressions for polymorphic structs/unions
     1371                        Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
     1372                        if ( ! ty ) return offsetofExpr;
     1373
     1374                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
     1375                                // replace offsetof expression by index into offset array
     1376                                long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );
     1377                                if ( i == -1 ) return offsetofExpr;
     1378
     1379                                Expression *offsetInd = makeOffsetIndex( ty, i );
     1380                                delete offsetofExpr;
     1381                                return offsetInd;
     1382                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
     1383                                // all union members are at offset zero
     1384                                delete offsetofExpr;
     1385                                return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );
     1386                        } else return offsetofExpr;
    10681387                }
    10691388
     
    11261445                        return ret;
    11271446                }
    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, false ) ); // not constructed
    1142                                 }
    1143                         }
    1144                         return Mutator::mutate( declStmt );
    1145                 }
    11461447        } // anonymous namespace
    11471448} // namespace GenPoly
  • src/GenPoly/CopyParams.cc

    r771b3c3 rd63eeb0  
    2323#include "SynTree/Statement.h"
    2424#include "SynTree/Visitor.h"
    25 #include "UniqueName.h"
     25#include "Common/UniqueName.h"
    2626
    2727namespace GenPoly {
  • src/GenPoly/FindFunction.cc

    r771b3c3 rd63eeb0  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FindFunction.cc -- 
     7// FindFunction.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 07:35:48 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Feb 05 12:22:20 2016
     13// Update Count     : 6
    1414//
    1515
     
    1919#include "SynTree/Visitor.h"
    2020
     21#include "ScrubTyVars.h"
     22
    2123namespace GenPoly {
    2224        class FindFunction : public Mutator {
    2325          public:
    2426                FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );
    25  
     27
    2628                virtual Type *mutate( FunctionType *functionType );
    2729                virtual Type *mutate( PointerType *pointerType );
     
    6668                        functions.push_back( functionType );
    6769                        if ( replaceMode ) {
    68                                 ret = new FunctionType( Type::Qualifiers(), true );
     70                                // replace type parameters in function type with void*
     71                                ret = ScrubTyVars::scrub( functionType->clone(), tyVars );
    6972                        } // if
    7073                } // if
  • src/GenPoly/GenPoly.cc

    r771b3c3 rd63eeb0  
    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

    r771b3c3 rd63eeb0  
    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/InstantiateGeneric.cc

    r771b3c3 rd63eeb0  
    3131#include "SynTree/TypeSubstitution.h"
    3232
    33 #include "UniqueName.h"
    34 #include "utility.h"
     33#include "Common/UniqueName.h"
     34#include "Common/utility.h"
    3535
    3636namespace GenPoly {
  • src/GenPoly/Lvalue.cc

    r771b3c3 rd63eeb0  
    2828#include "ResolvExpr/typeops.h"
    2929
    30 #include "UniqueName.h"
    31 #include "utility.h"
     30#include "Common/UniqueName.h"
     31#include "Common/utility.h"
    3232
    3333namespace GenPoly {
  • src/GenPoly/PolyMutator.cc

    r771b3c3 rd63eeb0  
    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

    r771b3c3 rd63eeb0  
    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

    r771b3c3 rd63eeb0  
    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

    r771b3c3 rd63eeb0  
    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/GenPoly/Specialize.cc

    r771b3c3 rd63eeb0  
    2828#include "SynTree/Mutator.h"
    2929#include "ResolvExpr/FindOpenVars.h"
    30 #include "UniqueName.h"
    31 #include "utility.h"
     30#include "Common/UniqueName.h"
     31#include "Common/utility.h"
    3232
    3333namespace GenPoly {
Note: See TracChangeset for help on using the changeset viewer.