Changeset 8dceeb7


Ignore:
Timestamp:
Nov 23, 2017, 4:41:05 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
178e4ec
Parents:
1ba5803
Message:

Monomorphize polymorphic aggregate (but not generic) members [fixes #61]

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r1ba5803 r8dceeb7  
    167167                        Expression *postmutate( OffsetofExpr *offsetofExpr );
    168168                        Expression *postmutate( OffsetPackExpr *offsetPackExpr );
     169                        void premutate( StructDecl * );
     170                        void premutate( UnionDecl * );
    169171
    170172                        void beginScope();
     
    178180                        /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    179181                        void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
     182                        /// change the type of generic aggregate members to char[]
     183                        void mutateMembers( AggregateDecl * aggrDecl );
    180184
    181185                        /// Enters a new scope for type-variables, adding the type variables from ty
     
    14141418
    14151419                void PolyGenericCalculator::premutate( TypedefDecl *typedefDecl ) {
     1420                        assert(false);
    14161421                        beginTypeScope( typedefDecl->get_base() );
    14171422                }
     
    14601465                }
    14611466
     1467                /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T]
     1468                Type * polyToMonoType( Type * declType ) {
     1469                        Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char);
     1470                        Expression * size = new NameExpr( sizeofName( mangleType(declType) ) );
     1471                        Attribute * aligned = new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } );
     1472                        return new ArrayType( Type::Qualifiers(), charType, size,
     1473                                true, false, std::list<Attribute *>{ aligned } );
     1474                }
     1475
     1476                void PolyGenericCalculator::mutateMembers( AggregateDecl * aggrDecl ) {
     1477                        std::set< std::string > genericParams;
     1478                        for ( TypeDecl * td : aggrDecl->parameters ) {
     1479                                genericParams.insert( td->name );
     1480                        }
     1481                        for ( Declaration * decl : aggrDecl->members ) {
     1482                                if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( decl ) ) {
     1483                                        Type * ty = replaceTypeInst( field->type, env );
     1484                                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {
     1485                                                // do not try to monomorphize generic parameters
     1486                                                if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) {
     1487                                                        // polymorphic aggregate members should be converted into monomorphic members.
     1488                                                        // Using char[size_T] here respects the expected sizing rules of an aggregate type.
     1489                                                        Type * newType = polyToMonoType( field->type );
     1490                                                        delete field->type;
     1491                                                        field->type = newType;
     1492                                                }
     1493                                        }
     1494                                }
     1495                        }
     1496                }
     1497
     1498                void PolyGenericCalculator::premutate( StructDecl * structDecl ) {
     1499                        mutateMembers( structDecl );
     1500                }
     1501
     1502                void PolyGenericCalculator::premutate( UnionDecl * unionDecl ) {
     1503                        mutateMembers( unionDecl );
     1504                }
     1505
    14621506                void PolyGenericCalculator::premutate( DeclStmt *declStmt ) {
    14631507                        if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
     
    14651509                                        // change initialization of a polymorphic value object to allocate via a VLA
    14661510                                        // (alloca was previously used, but can't be safely used in loops)
    1467                                         Type *declType = objectDecl->get_type();
    1468                                         ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0,
    1469                                                 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
    1470                                                 true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
     1511                                        ObjectDecl *newBuf = ObjectDecl::newObject( bufNamer.newName(), polyToMonoType( objectDecl->type ), nullptr );
    14711512                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, newBuf ) );
    14721513
Note: See TracChangeset for help on using the changeset viewer.