Changeset 37f0da8 for src/GenPoly


Ignore:
Timestamp:
Apr 14, 2016, 3:23:53 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, string, with_gc
Children:
0f9e4403, 347c42f, 70a06f6
Parents:
37218fc (diff), baba5d8 (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:/u/cforall/software/cfa/cfa-cc

Location:
src/GenPoly
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r37218fc r37f0da8  
    205205                        ObjectDecl *makeTemporary( Type *type );
    206206
    207                         std::map< std::string, DeclarationWithType *> assignOps;     ///< Currently known type variable assignment operators
     207                        ScopedMap< std::string, DeclarationWithType *> assignOps;    ///< Currently known type variable assignment operators
    208208                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209209                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
     
    292292                        /// adds type parameters to the layout call; will generate the appropriate parameters if needed
    293293                        void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams );
     294
     295                        /// Enters a new scope for type-variables, adding the type variables from ty
     296                        void beginTypeScope( Type *ty );
     297                        /// Exits the type-variable scope
     298                        void endTypeScope();
    294299                       
    295300                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
     
    385390                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    386391                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
    387                         layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    388                         layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
     392                        std::string paramName = mangleType( &paramType );
     393                        layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
     394                        layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    389395                }
    390396        }
    391397
    392398        /// Builds a layout function declaration
    393         FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
     399        FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
    394400                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    395401                // because each unit generates copies of the default routines for each aggregate.
    396402                FunctionDecl *layoutDecl = new FunctionDecl(
    397                         "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
     403                        layoutofName( typeDecl ), functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
    398404                layoutDecl->fixUniqueId();
    399405                return layoutDecl;
     
    462468                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    463469               
    464                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
     470                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    465471                layoutFnType->get_parameters().push_back( sizeParam );
    466                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
     472                ObjectDecl *alignParam = new ObjectDecl( alignofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    467473                layoutFnType->get_parameters().push_back( alignParam );
    468                 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
     474                ObjectDecl *offsetParam = new ObjectDecl( offsetofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    469475                layoutFnType->get_parameters().push_back( offsetParam );
    470476                addOtypeParams( layoutFnType, otypeParams );
    471477
    472478                // build function decl
    473                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
     479                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
    474480
    475481                // calculate struct layout in function body
     
    523529                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    524530               
    525                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
     531                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    526532                layoutFnType->get_parameters().push_back( sizeParam );
    527                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
     533                ObjectDecl *alignParam = new ObjectDecl( alignofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    528534                layoutFnType->get_parameters().push_back( alignParam );
    529535                addOtypeParams( layoutFnType, otypeParams );
    530536
    531537                // build function decl
    532                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
     538                FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
    533539
    534540                // calculate union layout in function body
     
    663669                        if ( functionDecl->get_statements() ) {         // empty routine body ?
    664670                                doBeginScope();
    665                                 TyVarMap oldtyVars = scopeTyVars;
    666                                 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;
     671                                scopeTyVars.beginScope();
     672                                assignOps.beginScope();
    667673                                DeclarationWithType *oldRetval = retval;
    668674                                bool oldUseRetval = useRetval;
     
    705711                                functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
    706712
    707                                 scopeTyVars = oldtyVars;
    708                                 assignOps = oldassignOps;
    709                                 // std::cerr << "end FunctionDecl: ";
    710                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    711                                 //      std::cerr << i->first << " ";
    712                                 // }
    713                                 // std::cerr << "\n";
     713                                scopeTyVars.endScope();
     714                                assignOps.endScope();
    714715                                retval = oldRetval;
    715716                                useRetval = oldUseRetval;
     
    745746
    746747                void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {
    747                         Type *polyBase = hasPolyBase( parmType, exprTyVars );
    748                         if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    749                                 std::string sizeName = sizeofName( polyBase );
    750                                 if ( seenTypes.count( sizeName ) ) return;
     748                        Type *polyType = isPolyType( parmType, exprTyVars );
     749                        if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
     750                                std::string typeName = mangleType( polyType );
     751                                if ( seenTypes.count( typeName ) ) return;
    751752
    752753                                arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
     
    754755                                arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) );
    755756                                arg++;
    756                                 if ( dynamic_cast< StructInstType* >( polyBase ) ) {
     757                                if ( dynamic_cast< StructInstType* >( polyType ) ) {
    757758                                        if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) {
    758759                                                // zero-length arrays are forbidden by C, so don't pass offset for empty struct
     
    766767                                }
    767768
    768                                 seenTypes.insert( sizeName );
     769                                seenTypes.insert( typeName );
    769770                        }
    770771                }
     
    11241125                                addAssign->get_args().push_back( appExpr->get_args().front() );
    11251126                        } // if
    1126                         addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
     1127                        addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) );
    11271128                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    11281129                        if ( appExpr->get_env() ) {
     
    11511152                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    11521153                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1153                                                         multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
     1154                                                        multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
    11541155                                                        ret->get_args().push_back( appExpr->get_args().front() );
    11551156                                                        ret->get_args().push_back( multiply );
     
    11571158                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    11581159                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    1159                                                         multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
     1160                                                        multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
    11601161                                                        ret->get_args().push_back( multiply );
    11611162                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    12201221                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    12211222                                                        divide->get_args().push_back( appExpr );
    1222                                                         divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
     1223                                                        divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
    12231224                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    12241225                                                        if ( appExpr->get_env() ) {
     
    12301231                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    12311232                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1232                                                         multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
     1233                                                        multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
    12331234                                                        appExpr->get_args().back() = multiply;
    12341235                                                } else if ( baseType2 ) {
    12351236                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    12361237                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    1237                                                         multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
     1238                                                        multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
    12381239                                                        appExpr->get_args().front() = multiply;
    12391240                                                } // if
     
    12451246                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    12461247                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    1247                                                         multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
     1248                                                        multiply->get_args().push_back( new SizeofExpr( baseType->clone() ) );
    12481249                                                        appExpr->get_args().back() = multiply;
    12491250                                                } // if
     
    12821283                        std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    12831284
    1284                         TyVarMap exprTyVars;
     1285                        TyVarMap exprTyVars( (TypeDecl::Kind)-1 );
    12851286                        makeTyVarMap( function, exprTyVars );
    12861287                        ReferenceToType *polyRetType = isPolyRet( function );
     
    13051306
    13061307                        boxParams( appExpr, function, arg, exprTyVars );
    1307 
    13081308                        passAdapters( appExpr, function, exprTyVars );
    13091309
     
    13851385                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
    13861386                                        // find assignment operator for type variable
    1387                                         std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
     1387                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    13881388                                        if ( assignIter == assignOps.end() ) {
    13891389                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
     
    14191419                                                DeclarationWithType *assertAssign = 0;
    14201420                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
    1421                                                         std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1421                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
    14221422                                                        if ( assertAssignIt == assignOps.end() ) {
    14231423                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     
    14601460
    14611461                Type * Pass1::mutate( PointerType *pointerType ) {
    1462                         TyVarMap oldtyVars = scopeTyVars;
     1462                        scopeTyVars.beginScope();
    14631463                        makeTyVarMap( pointerType, scopeTyVars );
    14641464
    14651465                        Type *ret = Mutator::mutate( pointerType );
    14661466
    1467                         scopeTyVars = oldtyVars;
     1467                        scopeTyVars.endScope();
    14681468                        return ret;
    14691469                }
    14701470
    14711471                Type * Pass1::mutate( FunctionType *functionType ) {
    1472                         TyVarMap oldtyVars = scopeTyVars;
     1472                        scopeTyVars.beginScope();
    14731473                        makeTyVarMap( functionType, scopeTyVars );
    14741474
    14751475                        Type *ret = Mutator::mutate( functionType );
    14761476
    1477                         scopeTyVars = oldtyVars;
     1477                        scopeTyVars.endScope();
    14781478                        return ret;
    14791479                }
     
    15401540
    15411541                Type * Pass2::mutate( PointerType *pointerType ) {
    1542                         TyVarMap oldtyVars = scopeTyVars;
     1542                        scopeTyVars.beginScope();
    15431543                        makeTyVarMap( pointerType, scopeTyVars );
    15441544
    15451545                        Type *ret = Mutator::mutate( pointerType );
    15461546
    1547                         scopeTyVars = oldtyVars;
     1547                        scopeTyVars.endScope();
    15481548                        return ret;
    15491549                }
    15501550
    15511551                Type *Pass2::mutate( FunctionType *funcType ) {
    1552                         TyVarMap oldtyVars = scopeTyVars;
     1552                        scopeTyVars.beginScope();
    15531553                        makeTyVarMap( funcType, scopeTyVars );
    15541554
     
    15721572                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    15731573                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1574                                        std::string parmName = mangleType( &parmType );
    15741575
    15751576                                        sizeParm = newObj.clone();
    1576                                         sizeParm->set_name( sizeofName( &parmType ) );
     1577                                        sizeParm->set_name( sizeofName( parmName ) );
    15771578                                        last = funcType->get_parameters().insert( last, sizeParm );
    15781579                                        ++last;
    15791580
    15801581                                        alignParm = newObj.clone();
    1581                                         alignParm->set_name( alignofName( &parmType ) );
     1582                                        alignParm->set_name( alignofName( parmName ) );
    15821583                                        last = funcType->get_parameters().insert( last, alignParm );
    15831584                                        ++last;
     
    15941595                        std::set< std::string > seenTypes; // sizeofName for generic types we've seen
    15951596                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
    1596                                 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
    1597                                 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    1598                                         std::string sizeName = sizeofName( polyBase );
    1599                                         if ( seenTypes.count( sizeName ) ) continue;
     1597                                Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
     1598                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
     1599                                        std::string typeName = mangleType( polyType );
     1600                                        if ( seenTypes.count( typeName ) ) continue;
    16001601
    16011602                                        ObjectDecl *sizeParm, *alignParm, *offsetParm;
    16021603                                        sizeParm = newObj.clone();
    1603                                         sizeParm->set_name( sizeName );
     1604                                        sizeParm->set_name( sizeofName( typeName ) );
    16041605                                        last = funcType->get_parameters().insert( last, sizeParm );
    16051606                                        ++last;
    16061607
    16071608                                        alignParm = newObj.clone();
    1608                                         alignParm->set_name( alignofName( polyBase ) );
     1609                                        alignParm->set_name( alignofName( typeName ) );
    16091610                                        last = funcType->get_parameters().insert( last, alignParm );
    16101611                                        ++last;
    16111612
    1612                                         if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) {
     1613                                        if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyType ) ) {
    16131614                                                // NOTE zero-length arrays are illegal in C, so empty structs have no offset array
    16141615                                                if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
    16151616                                                        offsetParm = newPtr.clone();
    1616                                                         offsetParm->set_name( offsetofName( polyBase ) );
     1617                                                        offsetParm->set_name( offsetofName( typeName ) );
    16171618                                                        last = funcType->get_parameters().insert( last, offsetParm );
    16181619                                                        ++last;
     
    16201621                                        }
    16211622
    1622                                         seenTypes.insert( sizeName );
     1623                                        seenTypes.insert( typeName );
    16231624                                }
    16241625                        }
     
    16301631                        mutateAll( funcType->get_parameters(), *this );
    16311632
    1632                         scopeTyVars = oldtyVars;
     1633                        scopeTyVars.endScope();
    16331634                        return funcType;
    16341635                }
     
    18231824                }
    18241825
    1825 ////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
     1826////////////////////////////////////////// PolyGenericCalculator ////////////////////////////////////////////////////
     1827
     1828                void PolyGenericCalculator::beginTypeScope( Type *ty ) {
     1829                        scopeTyVars.beginScope();
     1830                        makeTyVarMap( ty, scopeTyVars );
     1831                }
     1832
     1833                void PolyGenericCalculator::endTypeScope() {
     1834                        scopeTyVars.endScope();
     1835                }
    18261836
    18271837                template< typename DeclClass >
    18281838                DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) {
    1829                         TyVarMap oldtyVars = scopeTyVars;
    1830                         makeTyVarMap( type, scopeTyVars );
     1839                        beginTypeScope( type );
     1840                        knownLayouts.beginScope();
     1841                        knownOffsets.beginScope();
    18311842
    18321843                        DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
    18331844
    1834                         scopeTyVars = oldtyVars;
     1845                        knownOffsets.endScope();
     1846                        knownLayouts.endScope();
     1847                        endTypeScope();
    18351848                        return ret;
    18361849                }
     
    18541867
    18551868                Type * PolyGenericCalculator::mutate( PointerType *pointerType ) {
    1856                         TyVarMap oldtyVars = scopeTyVars;
    1857                         makeTyVarMap( pointerType, scopeTyVars );
     1869                        beginTypeScope( pointerType );
    18581870
    18591871                        Type *ret = Mutator::mutate( pointerType );
    18601872
    1861                         scopeTyVars = oldtyVars;
     1873                        endTypeScope();
    18621874                        return ret;
    18631875                }
    18641876
    18651877                Type * PolyGenericCalculator::mutate( FunctionType *funcType ) {
    1866                         TyVarMap oldtyVars = scopeTyVars;
    1867                         makeTyVarMap( funcType, scopeTyVars );
     1878                        beginTypeScope( funcType );
    18681879
    18691880                        // make sure that any type information passed into the function is accounted for
    18701881                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) {
    18711882                                // condition here duplicates that in Pass2::mutate( FunctionType* )
    1872                                 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
    1873                                 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
    1874                                         knownLayouts.insert( sizeofName( polyBase ) );
     1883                                Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );
     1884                                if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) {
     1885                                        knownLayouts.insert( mangleType( polyType ) );
    18751886                                }
    18761887                        }
     
    18781889                        Type *ret = Mutator::mutate( funcType );
    18791890
    1880                         scopeTyVars = oldtyVars;
     1891                        endTypeScope();
    18811892                        return ret;
    18821893                }
     
    18891900                                        Type *declType = objectDecl->get_type();
    18901901                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1891                                         alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
     1902                                        alloc->get_args().push_back( new NameExpr( sizeofName( mangleType( declType ) ) ) );
    18921903
    18931904                                        delete objectDecl->get_init();
     
    19211932                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
    19221933                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    1923                         fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1934                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) );
    19241935                        fieldOffset->get_args().push_back( fieldIndex );
    19251936                        return fieldOffset;
     
    19952006                                if ( findGeneric( *param ) ) {
    19962007                                        // push size/align vars for a generic parameter back
    1997                                         layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) );
    1998                                         layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) );
     2008                                        std::string paramName = mangleType( *param );
     2009                                        layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) );
     2010                                        layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) );
    19992011                                } else {
    20002012                                        layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
     
    20402052                        } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
    20412053                                // check if this type already has a layout generated for it
    2042                                 std::string sizeName = sizeofName( ty );
    2043                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
     2054                                std::string typeName = mangleType( ty );
     2055                                if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
    20442056
    20452057                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
     
    20482060
    20492061                                // insert local variables for layout and generate call to layout function
    2050                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
     2062                                knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    20512063                                Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    20522064
     
    20542066                                if ( n_members == 0 ) {
    20552067                                        // all empty structs have the same layout - size 1, align 1
    2056                                         makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2057                                         makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
     2068                                        makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
     2069                                        makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    20582070                                        // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    20592071                                } else {
    2060                                         ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    2061                                         ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
    2062                                         ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
     2072                                        ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
     2073                                        ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
     2074                                        ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
    20632075
    20642076                                        // generate call to layout function
    2065                                         UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) );
     2077                                        UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( structTy->get_baseStruct() ) ) );
    20662078                                        layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    20672079                                        layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
     
    20752087                        } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
    20762088                                // check if this type already has a layout generated for it
    2077                                 std::string sizeName = sizeofName( ty );
    2078                                 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
     2089                                std::string typeName = mangleType( ty );
     2090                                if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
    20792091
    20802092                                // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
     
    20832095
    20842096                                // insert local variables for layout and generate call to layout function
    2085                                 knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
     2097                                knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
    20862098                                Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    20872099
    2088                                 ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
    2089                                 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
     2100                                ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
     2101                                ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    20902102
    20912103                                // generate call to layout function
    2092                                 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) );
     2104                                UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( unionTy->get_baseUnion() ) ) );
    20932105                                layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
    20942106                                layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
     
    21062118                        Type *ty = sizeofExpr->get_type();
    21072119                        if ( findGeneric( ty ) ) {
    2108                                 Expression *ret = new NameExpr( sizeofName( ty ) );
     2120                                Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
    21092121                                delete sizeofExpr;
    21102122                                return ret;
     
    21162128                        Type *ty = alignofExpr->get_type();
    21172129                        if ( findGeneric( ty ) ) {
    2118                                 Expression *ret = new NameExpr( alignofName( ty ) );
     2130                                Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
    21192131                                delete alignofExpr;
    21202132                                return ret;
     
    21542166                        if ( findGeneric( ty ) ) {
    21552167                                // pull offset back from generated type information
    2156                                 ret = new NameExpr( offsetofName( ty ) );
     2168                                ret = new NameExpr( offsetofName( mangleType( ty ) ) );
    21572169                        } else {
    2158                                 std::string offsetName = offsetofName( ty );
     2170                                std::string offsetName = offsetofName( mangleType( ty ) );
    21592171                                if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
    21602172                                        // use the already-generated offsets for this type
     
    21962208                void PolyGenericCalculator::doEndScope() {
    21972209                        knownLayouts.endScope();
    2198                         knownOffsets.beginScope();
     2210                        knownOffsets.endScope();
    21992211                }
    22002212
     
    22032215                template< typename DeclClass >
    22042216                DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) {
    2205                         TyVarMap oldtyVars = scopeTyVars;
     2217                        scopeTyVars.beginScope();
    22062218                        makeTyVarMap( type, scopeTyVars );
    22072219
     
    22092221                        ScrubTyVars::scrub( decl, scopeTyVars );
    22102222
    2211                         scopeTyVars = oldtyVars;
     2223                        scopeTyVars.endScope();
    22122224                        return ret;
    22132225                }
     
    22392251
    22402252                Type * Pass3::mutate( PointerType *pointerType ) {
    2241                         TyVarMap oldtyVars = scopeTyVars;
     2253                        scopeTyVars.beginScope();
    22422254                        makeTyVarMap( pointerType, scopeTyVars );
    22432255
    22442256                        Type *ret = Mutator::mutate( pointerType );
    22452257
    2246                         scopeTyVars = oldtyVars;
     2258                        scopeTyVars.endScope();
    22472259                        return ret;
    22482260                }
    22492261
    22502262                Type * Pass3::mutate( FunctionType *functionType ) {
    2251                         TyVarMap oldtyVars = scopeTyVars;
     2263                        scopeTyVars.beginScope();
    22522264                        makeTyVarMap( functionType, scopeTyVars );
    22532265
    22542266                        Type *ret = Mutator::mutate( functionType );
    22552267
    2256                         scopeTyVars = oldtyVars;
     2268                        scopeTyVars.endScope();
    22572269                        return ret;
    22582270                }
  • src/GenPoly/FindFunction.cc

    r37218fc r37f0da8  
    5555                        TyVarMap::iterator var = tyVars.find( (*i)->get_name() );
    5656                        if ( var != tyVars.end() ) {
    57                                 tyVars.erase( var );
     57                                tyVars.erase( var->first );
    5858                        } // if
    5959                } // for
     
    6161
    6262        Type * FindFunction::mutate( FunctionType *functionType ) {
    63                 TyVarMap oldTyVars = tyVars;
     63                tyVars.beginScope();
    6464                handleForall( functionType->get_forall() );
    6565                mutateAll( functionType->get_returnVals(), *this );
     
    7272                        } // if
    7373                } // if
    74                 tyVars = oldTyVars;
     74                tyVars.endScope();
    7575                return ret;
    7676        }
    7777
    7878        Type * FindFunction::mutate( PointerType *pointerType ) {
    79                 TyVarMap oldTyVars = tyVars;
     79                tyVars.beginScope();
    8080                handleForall( pointerType->get_forall() );
    8181                Type *ret = Mutator::mutate( pointerType );
    82                 tyVars = oldTyVars;
     82                tyVars.endScope();
    8383                return ret;
    8484        }
  • src/GenPoly/GenPoly.cc

    r37218fc r37f0da8  
    1616#include "GenPoly.h"
    1717
    18 #include "SymTab/Mangler.h"
    1918#include "SynTree/Expression.h"
    2019#include "SynTree/Type.h"
     
    3837        ReferenceToType *isPolyRet( FunctionType *function ) {
    3938                if ( ! function->get_returnVals().empty() ) {
    40                         TyVarMap forallTypes;
     39                        TyVarMap forallTypes( (TypeDecl::Kind)-1 );
    4140                        makeTyVarMap( function, forallTypes );
    4241                        return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes );
     
    218217        }
    219218
    220         std::string sizeofName( Type *ty ) {
    221                 return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
    222         }
    223 
    224         std::string alignofName( Type *ty ) {
    225                 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
    226         }
    227 
    228         std::string offsetofName( Type* ty ) {
    229                 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );
    230         }
    231 
    232219} // namespace GenPoly
    233220
  • src/GenPoly/GenPoly.h

    r37218fc r37f0da8  
    1717#define GENPOLY_H
    1818
    19 #include <map>
    2019#include <string>
    2120#include <iostream>
    2221#include <utility>
     22
     23#include "ErasableScopedMap.h"
     24
     25#include "SymTab/Mangler.h"
    2326
    2427#include "SynTree/Declaration.h"
     
    2730
    2831namespace GenPoly {
    29         typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
     32        typedef ErasableScopedMap< std::string, TypeDecl::Kind > TyVarMap;
    3033
    3134        /// A function needs an adapter if it returns a polymorphic value or if any of its
     
    6972        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
    7073
    71         /// Gets the name of the sizeof parameter for the type
    72         std::string sizeofName( Type *ty );
     74        /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
     75        inline std::string mangleType( Type *ty ) { return SymTab::Mangler::mangleType( ty ); }
     76       
     77        /// Gets the name of the sizeof parameter for the type, given its mangled name
     78        inline std::string sizeofName( const std::string &name ) { return std::string( "_sizeof_" ) + name; }
    7379
    74         /// Gets the name of the alignof parameter for the type
    75         std::string alignofName( Type *ty );
     80        /// Gets the name of the alignof parameter for the type, given its mangled name
     81        inline std::string alignofName( const std::string &name ) { return std::string( "_alignof_" ) + name; }
    7682
    77         /// Gets the name of the offsetof parameter for the type
    78         std::string offsetofName( Type *ty );
     83        /// Gets the name of the offsetof parameter for the type, given its mangled name
     84        inline std::string offsetofName( const std::string &name ) { return std::string( "_offsetof_" ) + name; }
     85
     86        /// Gets the name of the layout function for a given aggregate type, given its declaration
     87        inline std::string layoutofName( AggregateDecl *decl ) { return std::string( "_layoutof_" ) + decl->get_name(); }
     88       
    7989} // namespace GenPoly
    8090
  • src/GenPoly/Lvalue.cc

    r37218fc r37f0da8  
    1717
    1818#include "Lvalue.h"
     19
     20#include "GenPoly.h"
    1921
    2022#include "SynTree/Declaration.h"
     
    6365
    6466        namespace {
    65                 bool isLvalueRet( FunctionType *function ) {
    66                         if ( ! function->get_returnVals().empty() ) {
    67                                 return function->get_returnVals().front()->get_type()->get_isLvalue();
    68                         } else {
    69                                 return false;
    70                         } // if
     67                Type* isLvalueRet( FunctionType *function ) {
     68                        if ( function->get_returnVals().empty() ) return 0;
     69                        Type *ty = function->get_returnVals().front()->get_type();
     70                        return ty->get_isLvalue() ? ty : 0;
    7171                }
    7272
     
    107107                        assert( function );
    108108
    109                         std::string typeName;
    110                         if ( isLvalueRet( function ) && ! isIntrinsicApp( appExpr ) ) {
     109                        Type *funType = isLvalueRet( function );
     110                        if ( funType && ! isIntrinsicApp( appExpr ) ) {
     111                                Expression *expr = appExpr;
     112                                Type *appType = appExpr->get_results().front();
     113                                if ( isPolyType( funType ) && ! isPolyType( appType ) ) {
     114                                        // make sure cast for polymorphic type is inside dereference
     115                                        expr = new CastExpr( appExpr, new PointerType( Type::Qualifiers(), appType->clone() ) );
     116                                }
    111117                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    112                                 deref->get_results().push_back( appExpr->get_results().front() );
    113                                 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone() );
    114                                 deref->get_args().push_back( appExpr );
     118                                deref->get_results().push_back( appType->clone() );
     119                                appExpr->get_results().front() = new PointerType( Type::Qualifiers(), appType );
     120                                deref->get_args().push_back( expr );
    115121                                return deref;
    116122                        } else {
  • src/GenPoly/PolyMutator.cc

    r37218fc r37f0da8  
    2727        }
    2828
    29         PolyMutator::PolyMutator() : env( 0 ) {
    30         }
     29        PolyMutator::PolyMutator() : scopeTyVars( (TypeDecl::Kind)-1 ), env( 0 ) {}
    3130
    3231        void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) {
  • src/GenPoly/ScopedMap.h

    r37218fc r37f0da8  
    5151                        typedef typename scope_list::size_type size_type;
    5252
     53                        /// Checks if this iterator points to a valid item
     54                        bool is_valid() const {
     55                                return it != (*scopes)[i].end();
     56                        }
     57
     58                        /// Increments on invalid
     59                        iterator& next_valid() {
     60                                if ( ! is_valid() ) { ++(*this); }
     61                                return *this;
     62                        }
     63
     64                        /// Decrements on invalid
     65                        iterator& prev_valid() {
     66                                if ( ! is_valid() ) { --(*this); }
     67                                return *this;
     68                        }
     69
    5370                        iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i)
    5471                                : scopes(&_scopes), it(_it), i(_i) {}
     
    6885                                        --i;
    6986                                        it = (*scopes)[i].begin();
    70                                         return *this;
    71                                 }
    72                                 ++it;
    73                                 return *this;
     87                                } else {
     88                                        ++it;
     89                                }
     90                                return next_valid();
    7491                        }
    7592                        iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
     
    8299                                }
    83100                                --it;
    84                                 return *this;
     101                                return prev_valid();
    85102                        }
    86103                        iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
     
    105122                        typedef typename scope_list::size_type size_type;
    106123
     124                        /// Checks if this iterator points to a valid item
     125                        bool is_valid() const {
     126                                return it != (*scopes)[i].end();
     127                        }
     128
     129                        /// Increments on invalid
     130                        const_iterator& next_valid() {
     131                                if ( ! is_valid() ) { ++(*this); }
     132                                return *this;
     133                        }
     134
     135                        /// Decrements on invalid
     136                        const_iterator& prev_valid() {
     137                                if ( ! is_valid() ) { --(*this); }
     138                                return *this;
     139                        }
     140
    107141                        const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i)
    108142                                : scopes(&_scopes), it(_it), i(_i) {}
     
    127161                                        --i;
    128162                                        it = (*scopes)[i].begin();
    129                                         return *this;
    130                                 }
    131                                 ++it;
    132                                 return *this;
     163                                } else {
     164                                        ++it;
     165                                }
     166                                return next_valid();
    133167                        }
    134168                        const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
     
    141175                                }
    142176                                --it;
    143                                 return *this;
     177                                return prev_valid();
    144178                        }
    145179                        const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
     
    171205                ScopedMap() { beginScope(); }
    172206
    173                 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1); }
    174                 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1); }
    175                 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1); }
     207                iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
     208                const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
     209                const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
    176210                iterator end() { return iterator(scopes, scopes[0].end(), 0); }
    177211                const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
  • src/GenPoly/ScopedSet.h

    r37218fc r37f0da8  
    4848                        typedef typename scope_list::size_type size_type;
    4949
     50                        /// Checks if this iterator points to a valid item
     51                        bool is_valid() const {
     52                                return it != (*scopes)[i].end();
     53                        }
     54
     55                        /// Increments on invalid
     56                        iterator& next_valid() {
     57                                if ( ! is_valid() ) { ++(*this); }
     58                                return *this;
     59                        }
     60
     61                        /// Decrements on invalid
     62                        iterator& prev_valid() {
     63                                if ( ! is_valid() ) { --(*this); }
     64                                return *this;
     65                        }
     66
    5067                        iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i)
    5168                                : scopes(&_scopes), it(_it), i(_i) {}
     
    6582                                        --i;
    6683                                        it = (*scopes)[i].begin();
    67                                         return *this;
    68                                 }
    69                                 ++it;
    70                                 return *this;
     84                                } else {
     85                                        ++it;
     86                                }
     87                                return next_valid();
    7188                        }
    7289                        iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
     
    7996                                }
    8097                                --it;
    81                                 return *this;
     98                                return prev_valid();
    8299                        }
    83100                        iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
     
    102119                        typedef typename scope_list::size_type size_type;
    103120
     121                        /// Checks if this iterator points to a valid item
     122                        bool is_valid() const {
     123                                return it != (*scopes)[i].end();
     124                        }
     125
     126                        /// Increments on invalid
     127                        const_iterator& next_valid() {
     128                                if ( ! is_valid() ) { ++(*this); }
     129                                return *this;
     130                        }
     131
     132                        /// Decrements on invalid
     133                        const_iterator& prev_valid() {
     134                                if ( ! is_valid() ) { --(*this); }
     135                                return *this;
     136                        }
     137
    104138                        const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i)
    105139                                : scopes(&_scopes), it(_it), i(_i) {}
     
    124158                                        --i;
    125159                                        it = (*scopes)[i].begin();
    126                                         return *this;
    127                                 }
    128                                 ++it;
    129                                 return *this;
     160                                } else {
     161                                        ++it;
     162                                }
     163                                return next_valid();
    130164                        }
    131165                        const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
     
    138172                                }
    139173                                --it;
    140                                 return *this;
     174                                return prev_valid();
    141175                        }
    142176                        const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
     
    167201                ScopedSet() { beginScope(); }
    168202
    169                 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1); }
    170                 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1); }
    171                 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1); }
     203                iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
     204                const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
     205                const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); }
    172206                iterator end() { return iterator(scopes, scopes[0].end(), 0); }
    173207                const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
  • src/GenPoly/ScrubTyVars.cc

    r37218fc r37f0da8  
    6464                // sizeof( T ) => _sizeof_T parameter, which is the size of T
    6565                if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
    66                         Expression *expr = new NameExpr( sizeofName( polyType ) );
     66                        Expression *expr = new NameExpr( sizeofName( mangleType( polyType ) ) );
    6767                        return expr;
    6868                } else {
     
    7474                // alignof( T ) => _alignof_T parameter, which is the alignment of T
    7575                if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
    76                         Expression *expr = new NameExpr( alignofName( polyType ) );
     76                        Expression *expr = new NameExpr( alignofName( mangleType( polyType ) ) );
    7777                        return expr;
    7878                } else {
Note: See TracChangeset for help on using the changeset viewer.