Changeset f7a4f89 for src/GenPoly


Ignore:
Timestamp:
Nov 24, 2017, 9:02:40 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
cf966b5
Parents:
88ef2af (diff), 3de176d (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/GenPoly
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r88ef2af rf7a4f89  
    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
  • src/GenPoly/InstantiateGeneric.cc

    r88ef2af rf7a4f89  
    2727#include "Common/utility.h"            // for deleteAll, cloneAll
    2828#include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
     29#include "ResolvExpr/typeops.h"
    2930#include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
    3031#include "ScrubTyVars.h"               // for ScrubTyVars
     
    151152                return gt;
    152153        }
     154
     155        /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator
     156        struct FixDtypeStatic final {
     157                Expression * postmutate( MemberExpr * memberExpr );
     158
     159                template<typename AggrInst>
     160                Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr );
     161        };
    153162
    154163        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     
    198207
    199208        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
     209                PassVisitor<FixDtypeStatic> fixer;
    200210                PassVisitor<GenericInstantiator> instantiator;
     211
     212                mutateAll( translationUnit, fixer );
    201213                mutateAll( translationUnit, instantiator );
     214        }
     215
     216        bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) {
     217                return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } );
    202218        }
    203219
     
    479495        }
    480496
     497        template< typename AggrInst >
     498        Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) {
     499                // need to cast dtype-static member expressions to their actual type before that type is erased.
     500                auto & baseParams = *inst->get_baseParameters();
     501                if ( isDtypeStatic( baseParams ) ) {
     502                        if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) {
     503                                // type of member and type of expression differ, so add cast to actual type
     504                                return new CastExpr( memberExpr, memberExpr->result->clone() );
     505                        }
     506                }
     507                return memberExpr;
     508        }
     509
     510        Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) {
     511                Type * aggrType = memberExpr->aggregate->result;
     512                if ( isGenericType( aggrType ) ) {
     513                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) {
     514                                return fixMemberExpr( inst, memberExpr );
     515                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) {
     516                                return fixMemberExpr( inst, memberExpr );
     517                        }
     518                }
     519                return memberExpr;
     520        }
     521
    481522} // namespace GenPoly
    482523
Note: See TracChangeset for help on using the changeset viewer.