Changeset 4389966 for src/GenPoly


Ignore:
Timestamp:
Dec 15, 2015, 4:14:01 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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, string, with_gc
Children:
5f6c42c
Parents:
cf16f94 (diff), 78dd0da (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:

fix comment

Location:
src/GenPoly
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rcf16f94 r4389966  
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    5051                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5152
     53                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    5254                class Pass1 : public PolyMutator {
    5355                  public:
     
    8890                };
    8991
     92                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9093                class Pass2 : public PolyMutator {
    9194                  public:
    92                         Pass2();
    9395                        template< typename DeclClass >
    9496                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    105107                };
    106108
     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
    107110                class Pass3 : public PolyMutator {
    108111                  public:
     
    178181                }
    179182
    180                 Pass1::Pass1()
    181                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    182184                        adapters.push(AdapterMap());
    183185                }
     
    312314                                        if ( concrete ) {
    313315                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
     316                                                arg++;
     317                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
    314318                                                arg++;
    315319                                        } else {
     
    647651                }
    648652
    649                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     653                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    650654                        NameExpr *opExpr;
    651655                        if ( isIncr ) {
     
    660664                                addAssign->get_args().push_back( appExpr->get_args().front() );
    661665                        } // if
    662                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     666                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    663667                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    664668                        if ( appExpr->get_env() ) {
     
    687691                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    688692                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    689                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     693                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    690694                                                        ret->get_args().push_back( appExpr->get_args().front() );
    691695                                                        ret->get_args().push_back( multiply );
     
    693697                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    694698                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    695                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     699                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
    696700                                                        ret->get_args().push_back( multiply );
    697701                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    739743                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    740744                                                        } // if
    741                                                         CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     745                                                        CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "?++" ) );
    742746                                                        return new CommaExpr( firstComma, tempExpr );
    743747                                                } // if
     
    746750                                                assert( appExpr->get_args().size() == 1 );
    747751                                                if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    748                                                         return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     752                                                        return makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "++?" );
    749753                                                } // if
    750754                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
     
    756760                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    757761                                                        divide->get_args().push_back( appExpr );
    758                                                         divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     762                                                        divide->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    759763                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    760764                                                        if ( appExpr->get_env() ) {
     
    766770                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    767771                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    768                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     772                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    769773                                                        appExpr->get_args().back() = multiply;
    770774                                                } else if ( typeInst2 ) {
    771775                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    772776                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    773                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     777                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
    774778                                                        appExpr->get_args().front() = multiply;
    775779                                                } // if
     
    781785                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    782786                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    783                                                         multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     787                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
    784788                                                        appExpr->get_args().back() = multiply;
    785789                                                } // if
     
    963967////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    964968
    965                 Pass2::Pass2() {}
    966 
    967969                void Pass2::addAdapters( FunctionType *functionType ) {
    968970                        std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    10371039                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10381040                        std::list< DeclarationWithType *> inferredParams;
    1039                         ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1040 ///   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
     1041                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1042//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10411043                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1042                                 ObjectDecl *thisParm;
    1043                                 // add all size parameters to parameter list
     1044                                ObjectDecl *sizeParm, *alignParm;
     1045                                // add all size and alignment parameters to parameter list
    10441046                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1045                                         thisParm = newObj->clone();
    1046                                         thisParm->set_name( (*tyParm)->get_name() );
    1047                                         last = funcType->get_parameters().insert( last, thisParm );
     1047                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1048                                       
     1049                                        sizeParm = newObj.clone();
     1050                                        sizeParm->set_name( sizeofName( &parmType ) );
     1051                                        last = funcType->get_parameters().insert( last, sizeParm );
     1052                                        ++last;
     1053
     1054                                        alignParm = newObj.clone();
     1055                                        alignParm->set_name( alignofName( &parmType ) );
     1056                                        last = funcType->get_parameters().insert( last, alignParm );
    10481057                                        ++last;
    10491058                                }
    10501059                                // move all assertions into parameter list
    10511060                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1052 ///      *assert = (*assert)->acceptMutator( *this );
     1061//      *assert = (*assert)->acceptMutator( *this );
    10531062                                        inferredParams.push_back( *assert );
    10541063                                }
    10551064                                (*tyParm)->get_assertions().clear();
    10561065                        }
    1057                         delete newObj;
    10581066                        funcType->get_parameters().splice( last, inferredParams );
    10591067                        addAdapters( funcType );
     
    10921100
    10931101                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1094 ///   Initializer *init = 0;
    1095 ///   std::list< Expression *> designators;
    1096 ///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1097 ///   if ( typeDecl->get_base() ) {
    1098 ///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1099 ///   }
    1100 ///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
     1102//   Initializer *init = 0;
     1103//   std::list< Expression *> designators;
     1104//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1105//   if ( typeDecl->get_base() ) {
     1106//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
     1107//   }
     1108//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    11011109
    11021110                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    11311139                                        assert( typeInst );
    11321140                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1133                                         alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1141                                        alloc->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
    11341142
    11351143                                        delete objectDecl->get_init();
  • src/GenPoly/FindFunction.h

    rcf16f94 r4389966  
    2323        typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
    2424
     25        /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions`
    2526        void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
     27        /// like `findFunction`, but also replaces the function type with void ()(void)
    2628        void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
    2729} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    rcf16f94 r4389966  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  1 15:18:54 2015
    13 // Update Count     : 12
     12// Last Modified On : Tue Dec 15 16:11:18 2015
     13// Update Count     : 13
    1414//
    1515
     
    2121
    2222namespace GenPoly {
    23         // A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
     23        /// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
    2424        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    2525                if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
  • src/GenPoly/InstantiateGeneric.cc

    rcf16f94 r4389966  
    4444                ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    4545
    46                 /// Extracts types from a list of Expression* (which should be TypeExpr*)
    47                 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
    48                         for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
    49                                 TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    50                                 assert(param && "Aggregate parameters should be type expressions");
    51                                 params.push_back( param->get_type()->clone() );
     46                /// Extracts types from a list of TypeExpr*
     47                ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     48                        for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
     49                                params.push_back( (*param)->get_type()->clone() );
    5250                        }
    5351                }
     
    6664
    6765                bool operator== (const ConcreteType& that) const {
     66                        if ( base != that.base ) return false;
     67
    6868                        SymTab::Indexer dummy;
    69 
    70                         if ( base != that.base ) return false;
    7169                        if ( params.size() != that.params.size() ) return false;
    7270                        for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     
    7977                std::list< Type* > params;  ///< Instantiation parameters
    8078        };
    81 
     79       
    8280        /// Maps a concrete type to the instantiated struct type, accounting for scope
    8381        class InstantiationMap {
    84                 /// Pair of concrete type and declaration that instantiates it
    85                 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
     82                /// Instantiation of a generic type, with key information to find it
     83                struct Instantiation {
     84                        ConcreteType key;     ///< Instantiation parameters for this type
     85                        AggregateDecl *decl;  ///< Declaration of the instantiated generic type
     86
     87                        Instantiation() : key(), decl(0) {}
     88                        Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
     89                };
    8690                /// Map of generic types to instantiations of them
    8791                typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     
    107111                /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    108112                /// Returns NULL on none such.
    109                 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
     113                AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    110114                        ConcreteType key(generic, params);
    111115                        // scan scopes from innermost out
     
    116120                                // look through instantiations for matches to concrete type
    117121                                for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    118                                         if ( inst->first == key ) return inst->second;
     122                                        if ( inst->key == key ) return inst->decl;
    119123                                }
    120124                        }
     
    123127                }
    124128        public:
    125                 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
    126                 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
     129                StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     130                UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    127131
    128132        private:
    129133                /// Adds a declaration for a concrete type to the current scope
    130                 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
     134                void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
    131135                        ConcreteType key(generic, params);
    132                         scopes.back()[generic].push_back( std::make_pair( key, decl ) );
     136                        scopes.back()[generic].push_back( Instantiation( key, decl ) );
    133137                }
    134138        public:
    135                 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
    136                 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
     139                void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     140                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    137141        };
    138142
    139143        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    140144        class Instantiate : public DeclMutator {
     145                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    141146                InstantiationMap instantiations;
     147                /// Namer for concrete types
    142148                UniqueName typeNamer;
    143149
     
    147153                virtual Type* mutate( StructInstType *inst );
    148154                virtual Type* mutate( UnionInstType *inst );
     155
     156//              virtual Expression* mutate( MemberExpr *memberExpr );
    149157               
    150158                virtual void doBeginScope();
     
    157165        }
    158166
    159         /// Substitutes types of members of in according to baseParams => params, appending the result to out
    160         void substituteMembers( const std::list< Declaration* >& in,
    161                                                         const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
     167        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     168        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     169                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     170
     171                // substitute concrete types for given parameters, and incomplete types for placeholders
     172                std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     173                std::list< Expression* >::const_iterator param = params.begin();
     174                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     175//                      switch ( (*baseParam)->get_kind() ) {
     176//                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     177                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     178                                assert(paramType && "Aggregate parameters should be type expressions");
     179                                out.push_back( paramType->clone() );
     180                                // check that the substituted type isn't a type variable itself
     181                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     182                                        allConcrete = false;
     183                                }
     184//                              break;
     185//                      }
     186//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     187//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     188//                              break;
     189//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     190//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     191//                              break;
     192//                      }
     193                }
     194
     195                // if any parameters left over, not done
     196                if ( baseParam != baseParams.end() ) return false;
     197//              // if not enough parameters given, substitute remaining incomplete types for placeholders
     198//              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     199//                      switch ( (*baseParam)->get_kind() ) {
     200//                      case TypeDecl::Any:    // no more substitutions here, fail early
     201//                              return false;
     202//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     203//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     204//                              break;
     205//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     206//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     207//                              break;
     208//                      }
     209//              }
     210
     211                return allConcrete;
     212        }
     213
     214        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     215        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    162216                                                    std::list< Declaration* >& out ) {
    163217                // substitute types into new members
    164                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
     218                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    165219                for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    166220                        Declaration *newMember = (*member)->clone();
     
    178232                // exit early if no need for further mutation
    179233                if ( inst->get_parameters().empty() ) return inst;
     234                assert( inst->get_baseParameters() && "Base struct has parameters" );
     235
     236                // check if type can be concretely instantiated; put substitutions into typeSubs
     237                std::list< TypeExpr* > typeSubs;
     238                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     239                        deleteAll( typeSubs );
     240                        return inst;
     241                }
    180242               
    181243                // make concrete instantiation of generic type
    182                 StructDecl *concDecl = instantiations.lookup( inst );
     244                StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
    183245                if ( ! concDecl ) {
    184                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    185246                        // set concDecl to new type, insert type declaration into statements to add
    186247                        concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    187                         substituteMembers( inst->get_baseStruct()->get_members(),
    188                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    189                                                                 concDecl->get_members() );
     248                        substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    190249                        DeclMutator::addDeclaration( concDecl );
    191                         instantiations.insert( inst, concDecl );
     250                        instantiations.insert( inst, typeSubs, concDecl );
    192251                }
    193252                StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    194253                newInst->set_baseStruct( concDecl );
     254
     255                deleteAll( typeSubs );
    195256                delete inst;
    196257                return newInst;
     
    205266                // exit early if no need for further mutation
    206267                if ( inst->get_parameters().empty() ) return inst;
    207 
     268                assert( inst->get_baseParameters() && "Base union has parameters" );
     269
     270                // check if type can be concretely instantiated; put substitutions into typeSubs
     271                std::list< TypeExpr* > typeSubs;
     272                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     273                        deleteAll( typeSubs );
     274                        return inst;
     275                }
     276               
    208277                // make concrete instantiation of generic type
    209                 UnionDecl *concDecl = instantiations.lookup( inst );
     278                UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
    210279                if ( ! concDecl ) {
    211280                        // set concDecl to new type, insert type declaration into statements to add
    212                         assert( inst->get_baseParameters() && "Base union has parameters" );
    213281                        concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    214                         substituteMembers( inst->get_baseUnion()->get_members(),
    215                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    216                                                                 concDecl->get_members() );
     282                        substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    217283                        DeclMutator::addDeclaration( concDecl );
    218                         instantiations.insert( inst, concDecl );
     284                        instantiations.insert( inst, typeSubs, concDecl );
    219285                }
    220286                UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    221287                newInst->set_baseUnion( concDecl );
     288
     289                deleteAll( typeSubs );
    222290                delete inst;
    223291                return newInst;
    224292        }
     293
     294//      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     295//      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     296//              // get variable for member aggregate
     297//              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     298//              if ( ! varExpr ) return NULL;
     299//
     300//              // get object for variable
     301//              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     302//              if ( ! objectDecl ) return NULL;
     303//
     304//              // get base declaration from object type
     305//              Type *objectType = objectDecl->get_type();
     306//              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     307//              if ( structType ) return structType->get_baseStruct();
     308//              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     309//              if ( unionType ) return unionType->get_baseUnion();
     310//
     311//              return NULL;
     312//      }
     313//
     314//      /// Finds the declaration with the given name, returning decls.end() if none such
     315//      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     316//              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     317//                      if ( (*decl)->get_name() == name ) return decl;
     318//              }
     319//              return decls.end();
     320//      }
     321//     
     322//      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     323//              // mutate, exiting early if no longer MemberExpr
     324//              Expression *expr = Mutator::mutate( memberExpr );
     325//              memberExpr = dynamic_cast< MemberExpr* >( expr );
     326//              if ( ! memberExpr ) return expr;
     327//
     328//              // get declaration of member and base declaration of member, exiting early if not found
     329//              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     330//              if ( ! memberBase ) return memberExpr;
     331//              DeclarationWithType *memberDecl = memberExpr->get_member();
     332//              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     333//              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     334//              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     335//              if ( ! baseDecl ) return memberExpr;
     336//
     337//              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     338//              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     339//              SymTab::Indexer dummy;
     340//              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     341//              else return new CastExpr( memberExpr, memberDecl->get_type() );
     342//      }
    225343       
    226344        void Instantiate::doBeginScope() {
    227345                DeclMutator::doBeginScope();
    228                 // push a new concrete type scope
    229346                instantiations.beginScope();
    230347        }
     
    232349        void Instantiate::doEndScope() {
    233350                DeclMutator::doEndScope();
    234                 // pop the last concrete type scope
    235351                instantiations.endScope();
    236352        }
  • src/GenPoly/Lvalue.cc

    rcf16f94 r4389966  
    3535                const std::list<Label> noLabels;
    3636
     37                /// Replace uses of lvalue returns with appropriate pointers
    3738                class Pass1 : public Mutator {
    3839                  public:
     
    4647                };
    4748
     49                /// Replace declarations of lvalue returns with appropriate pointers
    4850                class Pass2 : public Visitor {
    4951                  public:
  • src/GenPoly/ScrubTyVars.cc

    rcf16f94 r4389966  
    1414//
    1515
     16#include <sstream>
     17#include <string>
     18
    1619#include "GenPoly.h"
    1720#include "ScrubTyVars.h"
     21
     22#include "SymTab/Mangler.h"
    1823
    1924#include "SynTree/Mutator.h"
     
    4247
    4348        Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    44                 // sizeof( T ) => T parameter, which is the size of T
     49                // sizeof( T ) => _sizeof_T parameter, which is the size of T
    4550                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
    46                         Expression *expr = new NameExpr( typeInst->get_name() );
     51                        Expression *expr = new NameExpr( sizeofName( typeInst ) );
    4752                        return expr;
    4853                } else {
    4954                        return Mutator::mutate( szeof );
     55                } // if
     56        }
     57
     58        Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
     59                // alignof( T ) => _alignof_T parameter, which is the alignment of T
     60                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) {
     61                        Expression *expr = new NameExpr( alignofName( typeInst ) );
     62                        return expr;
     63                } else {
     64                        return Mutator::mutate( algnof );
    5065                } // if
    5166        }
     
    6378                return Mutator::mutate( pointer );
    6479        }
     80       
     81        std::string sizeofName( Type *ty ) {
     82                return std::string( "_sizeof_" ) + SymTab::Mangler::mangle( ty, false, false );
     83        }
     84
     85        std::string alignofName( Type *ty ) {
     86                return std::string( "_alignof_" ) + SymTab::Mangler::mangle( ty, false, false );
     87        }
    6588} // namespace GenPoly
    6689
  • src/GenPoly/ScrubTyVars.h

    rcf16f94 r4389966  
    1717#define _SCRUBTYVARS_H
    1818
     19#include <string>
     20
    1921#include "GenPoly.h"
    2022
     
    2628          public:
    2729                ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
    28  
     30
     31                /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
    2932                template< typename SynTreeClass >
    3033                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
    3135                template< typename SynTreeClass >
    3236                static SynTreeClass *scrub( SynTreeClass *target );
     
    3438                virtual Type* mutate( TypeInstType *typeInst );
    3539                Expression* mutate( SizeofExpr *szeof );
     40                Expression* mutate( AlignofExpr *algnof );
    3641                virtual Type* mutate( PointerType *pointer );
    3742          private:
     
    5459                return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
    5560        }
     61
     62        /// Gets the name of the sizeof parameter for the type
     63        std::string sizeofName( Type *ty );
     64
     65        /// Gets the name of the alignof parameter for the type
     66        std::string alignofName( Type *ty );
    5667} // namespace GenPoly
    5768
Note: See TracChangeset for help on using the changeset viewer.