Changeset 37f0da8 for src/GenPoly
- Timestamp:
- Apr 14, 2016, 3:23:53 PM (10 years ago)
- 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. - Location:
- src/GenPoly
- Files:
-
- 1 added
- 9 edited
-
Box.cc (modified) (44 diffs)
-
ErasableScopedMap.h (added)
-
FindFunction.cc (modified) (3 diffs)
-
GenPoly.cc (modified) (3 diffs)
-
GenPoly.h (modified) (3 diffs)
-
Lvalue.cc (modified) (3 diffs)
-
PolyMutator.cc (modified) (1 diff)
-
ScopedMap.h (modified) (7 diffs)
-
ScopedSet.h (modified) (7 diffs)
-
ScrubTyVars.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r37218fc r37f0da8 205 205 ObjectDecl *makeTemporary( Type *type ); 206 206 207 std::map< std::string, DeclarationWithType *> assignOps;///< Currently known type variable assignment operators207 ScopedMap< std::string, DeclarationWithType *> assignOps; ///< Currently known type variable assignment operators 208 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope … … 292 292 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 293 293 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(); 294 299 295 300 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName … … 385 390 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 386 391 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 388 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 392 std::string paramName = mangleType( ¶mType ); 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 ) ); 389 395 } 390 396 } 391 397 392 398 /// 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 ) { 394 400 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 395 401 // because each unit generates copies of the default routines for each aggregate. 396 402 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 ); 398 404 layoutDecl->fixUniqueId(); 399 405 return layoutDecl; … … 462 468 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 463 469 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 ); 465 471 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 ); 467 473 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 ); 469 475 layoutFnType->get_parameters().push_back( offsetParam ); 470 476 addOtypeParams( layoutFnType, otypeParams ); 471 477 472 478 // build function decl 473 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl ->get_name(), functionNesting, layoutFnType );479 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType ); 474 480 475 481 // calculate struct layout in function body … … 523 529 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 524 530 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 ); 526 532 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 ); 528 534 layoutFnType->get_parameters().push_back( alignParam ); 529 535 addOtypeParams( layoutFnType, otypeParams ); 530 536 531 537 // build function decl 532 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl ->get_name(), functionNesting, layoutFnType );538 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType ); 533 539 534 540 // calculate union layout in function body … … 663 669 if ( functionDecl->get_statements() ) { // empty routine body ? 664 670 doBeginScope(); 665 TyVarMap oldtyVars = scopeTyVars;666 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;671 scopeTyVars.beginScope(); 672 assignOps.beginScope(); 667 673 DeclarationWithType *oldRetval = retval; 668 674 bool oldUseRetval = useRetval; … … 705 711 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 706 712 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(); 714 715 retval = oldRetval; 715 716 useRetval = oldUseRetval; … … 745 746 746 747 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 747 Type *poly Base = hasPolyBase( parmType, exprTyVars );748 if ( poly Base && ! 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; 751 752 752 753 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 754 755 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 755 756 arg++; 756 if ( dynamic_cast< StructInstType* >( poly Base ) ) {757 if ( dynamic_cast< StructInstType* >( polyType ) ) { 757 758 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 758 759 // zero-length arrays are forbidden by C, so don't pass offset for empty struct … … 766 767 } 767 768 768 seenTypes.insert( sizeName );769 seenTypes.insert( typeName ); 769 770 } 770 771 } … … 1124 1125 addAssign->get_args().push_back( appExpr->get_args().front() ); 1125 1126 } // if 1126 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType) ) );1127 addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) ); 1127 1128 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 1128 1129 if ( appExpr->get_env() ) { … … 1151 1152 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1152 1153 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() ) ); 1154 1155 ret->get_args().push_back( appExpr->get_args().front() ); 1155 1156 ret->get_args().push_back( multiply ); … … 1157 1158 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1158 1159 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() ) ); 1160 1161 ret->get_args().push_back( multiply ); 1161 1162 ret->get_args().push_back( appExpr->get_args().back() ); … … 1220 1221 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 1221 1222 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() ) ); 1223 1224 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 1224 1225 if ( appExpr->get_env() ) { … … 1230 1231 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1231 1232 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() ) ); 1233 1234 appExpr->get_args().back() = multiply; 1234 1235 } else if ( baseType2 ) { 1235 1236 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1236 1237 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() ) ); 1238 1239 appExpr->get_args().front() = multiply; 1239 1240 } // if … … 1245 1246 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1246 1247 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() ) ); 1248 1249 appExpr->get_args().back() = multiply; 1249 1250 } // if … … 1282 1283 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1283 1284 1284 TyVarMap exprTyVars ;1285 TyVarMap exprTyVars( (TypeDecl::Kind)-1 ); 1285 1286 makeTyVarMap( function, exprTyVars ); 1286 1287 ReferenceToType *polyRetType = isPolyRet( function ); … … 1305 1306 1306 1307 boxParams( appExpr, function, arg, exprTyVars ); 1307 1308 1308 passAdapters( appExpr, function, exprTyVars ); 1309 1309 … … 1385 1385 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1386 1386 // 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() ); 1388 1388 if ( assignIter == assignOps.end() ) { 1389 1389 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); … … 1419 1419 DeclarationWithType *assertAssign = 0; 1420 1420 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() ); 1422 1422 if ( assertAssignIt == assignOps.end() ) { 1423 1423 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); … … 1460 1460 1461 1461 Type * Pass1::mutate( PointerType *pointerType ) { 1462 TyVarMap oldtyVars = scopeTyVars;1462 scopeTyVars.beginScope(); 1463 1463 makeTyVarMap( pointerType, scopeTyVars ); 1464 1464 1465 1465 Type *ret = Mutator::mutate( pointerType ); 1466 1466 1467 scopeTyVars = oldtyVars;1467 scopeTyVars.endScope(); 1468 1468 return ret; 1469 1469 } 1470 1470 1471 1471 Type * Pass1::mutate( FunctionType *functionType ) { 1472 TyVarMap oldtyVars = scopeTyVars;1472 scopeTyVars.beginScope(); 1473 1473 makeTyVarMap( functionType, scopeTyVars ); 1474 1474 1475 1475 Type *ret = Mutator::mutate( functionType ); 1476 1476 1477 scopeTyVars = oldtyVars;1477 scopeTyVars.endScope(); 1478 1478 return ret; 1479 1479 } … … 1540 1540 1541 1541 Type * Pass2::mutate( PointerType *pointerType ) { 1542 TyVarMap oldtyVars = scopeTyVars;1542 scopeTyVars.beginScope(); 1543 1543 makeTyVarMap( pointerType, scopeTyVars ); 1544 1544 1545 1545 Type *ret = Mutator::mutate( pointerType ); 1546 1546 1547 scopeTyVars = oldtyVars;1547 scopeTyVars.endScope(); 1548 1548 return ret; 1549 1549 } 1550 1550 1551 1551 Type *Pass2::mutate( FunctionType *funcType ) { 1552 TyVarMap oldtyVars = scopeTyVars;1552 scopeTyVars.beginScope(); 1553 1553 makeTyVarMap( funcType, scopeTyVars ); 1554 1554 … … 1572 1572 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1573 1573 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1574 std::string parmName = mangleType( &parmType ); 1574 1575 1575 1576 sizeParm = newObj.clone(); 1576 sizeParm->set_name( sizeofName( &parmType ) );1577 sizeParm->set_name( sizeofName( parmName ) ); 1577 1578 last = funcType->get_parameters().insert( last, sizeParm ); 1578 1579 ++last; 1579 1580 1580 1581 alignParm = newObj.clone(); 1581 alignParm->set_name( alignofName( &parmType ) );1582 alignParm->set_name( alignofName( parmName ) ); 1582 1583 last = funcType->get_parameters().insert( last, alignParm ); 1583 1584 ++last; … … 1594 1595 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1595 1596 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1596 Type *poly Base = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );1597 if ( poly Base && ! 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; 1600 1601 1601 1602 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1602 1603 sizeParm = newObj.clone(); 1603 sizeParm->set_name( size Name);1604 sizeParm->set_name( sizeofName( typeName ) ); 1604 1605 last = funcType->get_parameters().insert( last, sizeParm ); 1605 1606 ++last; 1606 1607 1607 1608 alignParm = newObj.clone(); 1608 alignParm->set_name( alignofName( polyBase ) );1609 alignParm->set_name( alignofName( typeName ) ); 1609 1610 last = funcType->get_parameters().insert( last, alignParm ); 1610 1611 ++last; 1611 1612 1612 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( poly Base ) ) {1613 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyType ) ) { 1613 1614 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1614 1615 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1615 1616 offsetParm = newPtr.clone(); 1616 offsetParm->set_name( offsetofName( polyBase ) );1617 offsetParm->set_name( offsetofName( typeName ) ); 1617 1618 last = funcType->get_parameters().insert( last, offsetParm ); 1618 1619 ++last; … … 1620 1621 } 1621 1622 1622 seenTypes.insert( sizeName );1623 seenTypes.insert( typeName ); 1623 1624 } 1624 1625 } … … 1630 1631 mutateAll( funcType->get_parameters(), *this ); 1631 1632 1632 scopeTyVars = oldtyVars;1633 scopeTyVars.endScope(); 1633 1634 return funcType; 1634 1635 } … … 1823 1824 } 1824 1825 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 } 1826 1836 1827 1837 template< typename DeclClass > 1828 1838 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) { 1829 TyVarMap oldtyVars = scopeTyVars; 1830 makeTyVarMap( type, scopeTyVars ); 1839 beginTypeScope( type ); 1840 knownLayouts.beginScope(); 1841 knownOffsets.beginScope(); 1831 1842 1832 1843 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1833 1844 1834 scopeTyVars = oldtyVars; 1845 knownOffsets.endScope(); 1846 knownLayouts.endScope(); 1847 endTypeScope(); 1835 1848 return ret; 1836 1849 } … … 1854 1867 1855 1868 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) { 1856 TyVarMap oldtyVars = scopeTyVars; 1857 makeTyVarMap( pointerType, scopeTyVars ); 1869 beginTypeScope( pointerType ); 1858 1870 1859 1871 Type *ret = Mutator::mutate( pointerType ); 1860 1872 1861 scopeTyVars = oldtyVars;1873 endTypeScope(); 1862 1874 return ret; 1863 1875 } 1864 1876 1865 1877 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) { 1866 TyVarMap oldtyVars = scopeTyVars; 1867 makeTyVarMap( funcType, scopeTyVars ); 1878 beginTypeScope( funcType ); 1868 1879 1869 1880 // make sure that any type information passed into the function is accounted for 1870 1881 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) { 1871 1882 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1872 Type *poly Base = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );1873 if ( poly Base && ! 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 ) ); 1875 1886 } 1876 1887 } … … 1878 1889 Type *ret = Mutator::mutate( funcType ); 1879 1890 1880 scopeTyVars = oldtyVars;1891 endTypeScope(); 1881 1892 return ret; 1882 1893 } … … 1889 1900 Type *declType = objectDecl->get_type(); 1890 1901 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 ) ) ) ); 1892 1903 1893 1904 delete objectDecl->get_init(); … … 1921 1932 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1922 1933 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 ) ) ) ); 1924 1935 fieldOffset->get_args().push_back( fieldIndex ); 1925 1936 return fieldOffset; … … 1995 2006 if ( findGeneric( *param ) ) { 1996 2007 // 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 ) ) ); 1999 2011 } else { 2000 2012 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); … … 2040 2052 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 2041 2053 // 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; 2044 2056 2045 2057 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 2048 2060 2049 2061 // 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 call2062 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2051 2063 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2052 2064 … … 2054 2066 if ( n_members == 0 ) { 2055 2067 // all empty structs have the same layout - size 1, align 1 2056 makeVar( size Name, 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 ) ) ) ); 2058 2070 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2059 2071 } else { 2060 ObjectDecl *sizeVar = makeVar( size Name, 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 ) ); 2063 2075 2064 2076 // 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() ) ) ); 2066 2078 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2067 2079 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); … … 2075 2087 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 2076 2088 // 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; 2079 2091 2080 2092 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 2083 2095 2084 2096 // 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 call2097 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2086 2098 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2087 2099 2088 ObjectDecl *sizeVar = makeVar( size Name, layoutType );2089 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );2100 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2101 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() ); 2090 2102 2091 2103 // 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() ) ) ); 2093 2105 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2094 2106 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); … … 2106 2118 Type *ty = sizeofExpr->get_type(); 2107 2119 if ( findGeneric( ty ) ) { 2108 Expression *ret = new NameExpr( sizeofName( ty) );2120 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) ); 2109 2121 delete sizeofExpr; 2110 2122 return ret; … … 2116 2128 Type *ty = alignofExpr->get_type(); 2117 2129 if ( findGeneric( ty ) ) { 2118 Expression *ret = new NameExpr( alignofName( ty) );2130 Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) ); 2119 2131 delete alignofExpr; 2120 2132 return ret; … … 2154 2166 if ( findGeneric( ty ) ) { 2155 2167 // pull offset back from generated type information 2156 ret = new NameExpr( offsetofName( ty) );2168 ret = new NameExpr( offsetofName( mangleType( ty ) ) ); 2157 2169 } else { 2158 std::string offsetName = offsetofName( ty);2170 std::string offsetName = offsetofName( mangleType( ty ) ); 2159 2171 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) { 2160 2172 // use the already-generated offsets for this type … … 2196 2208 void PolyGenericCalculator::doEndScope() { 2197 2209 knownLayouts.endScope(); 2198 knownOffsets. beginScope();2210 knownOffsets.endScope(); 2199 2211 } 2200 2212 … … 2203 2215 template< typename DeclClass > 2204 2216 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 2205 TyVarMap oldtyVars = scopeTyVars;2217 scopeTyVars.beginScope(); 2206 2218 makeTyVarMap( type, scopeTyVars ); 2207 2219 … … 2209 2221 ScrubTyVars::scrub( decl, scopeTyVars ); 2210 2222 2211 scopeTyVars = oldtyVars;2223 scopeTyVars.endScope(); 2212 2224 return ret; 2213 2225 } … … 2239 2251 2240 2252 Type * Pass3::mutate( PointerType *pointerType ) { 2241 TyVarMap oldtyVars = scopeTyVars;2253 scopeTyVars.beginScope(); 2242 2254 makeTyVarMap( pointerType, scopeTyVars ); 2243 2255 2244 2256 Type *ret = Mutator::mutate( pointerType ); 2245 2257 2246 scopeTyVars = oldtyVars;2258 scopeTyVars.endScope(); 2247 2259 return ret; 2248 2260 } 2249 2261 2250 2262 Type * Pass3::mutate( FunctionType *functionType ) { 2251 TyVarMap oldtyVars = scopeTyVars;2263 scopeTyVars.beginScope(); 2252 2264 makeTyVarMap( functionType, scopeTyVars ); 2253 2265 2254 2266 Type *ret = Mutator::mutate( functionType ); 2255 2267 2256 scopeTyVars = oldtyVars;2268 scopeTyVars.endScope(); 2257 2269 return ret; 2258 2270 } -
src/GenPoly/FindFunction.cc
r37218fc r37f0da8 55 55 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 56 56 if ( var != tyVars.end() ) { 57 tyVars.erase( var );57 tyVars.erase( var->first ); 58 58 } // if 59 59 } // for … … 61 61 62 62 Type * FindFunction::mutate( FunctionType *functionType ) { 63 TyVarMap oldTyVars = tyVars;63 tyVars.beginScope(); 64 64 handleForall( functionType->get_forall() ); 65 65 mutateAll( functionType->get_returnVals(), *this ); … … 72 72 } // if 73 73 } // if 74 tyVars = oldTyVars;74 tyVars.endScope(); 75 75 return ret; 76 76 } 77 77 78 78 Type * FindFunction::mutate( PointerType *pointerType ) { 79 TyVarMap oldTyVars = tyVars;79 tyVars.beginScope(); 80 80 handleForall( pointerType->get_forall() ); 81 81 Type *ret = Mutator::mutate( pointerType ); 82 tyVars = oldTyVars;82 tyVars.endScope(); 83 83 return ret; 84 84 } -
src/GenPoly/GenPoly.cc
r37218fc r37f0da8 16 16 #include "GenPoly.h" 17 17 18 #include "SymTab/Mangler.h"19 18 #include "SynTree/Expression.h" 20 19 #include "SynTree/Type.h" … … 38 37 ReferenceToType *isPolyRet( FunctionType *function ) { 39 38 if ( ! function->get_returnVals().empty() ) { 40 TyVarMap forallTypes ;39 TyVarMap forallTypes( (TypeDecl::Kind)-1 ); 41 40 makeTyVarMap( function, forallTypes ); 42 41 return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes ); … … 218 217 } 219 218 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 232 219 } // namespace GenPoly 233 220 -
src/GenPoly/GenPoly.h
r37218fc r37f0da8 17 17 #define GENPOLY_H 18 18 19 #include <map>20 19 #include <string> 21 20 #include <iostream> 22 21 #include <utility> 22 23 #include "ErasableScopedMap.h" 24 25 #include "SymTab/Mangler.h" 23 26 24 27 #include "SynTree/Declaration.h" … … 27 30 28 31 namespace GenPoly { 29 typedef std::map< std::string, TypeDecl::Kind > TyVarMap;32 typedef ErasableScopedMap< std::string, TypeDecl::Kind > TyVarMap; 30 33 31 34 /// A function needs an adapter if it returns a polymorphic value or if any of its … … 69 72 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 70 73 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; } 73 79 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; } 76 82 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 79 89 } // namespace GenPoly 80 90 -
src/GenPoly/Lvalue.cc
r37218fc r37f0da8 17 17 18 18 #include "Lvalue.h" 19 20 #include "GenPoly.h" 19 21 20 22 #include "SynTree/Declaration.h" … … 63 65 64 66 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; 71 71 } 72 72 … … 107 107 assert( function ); 108 108 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 } 111 117 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 112 deref->get_results().push_back( app Expr->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 ); 115 121 return deref; 116 122 } else { -
src/GenPoly/PolyMutator.cc
r37218fc r37f0da8 27 27 } 28 28 29 PolyMutator::PolyMutator() : env( 0 ) { 30 } 29 PolyMutator::PolyMutator() : scopeTyVars( (TypeDecl::Kind)-1 ), env( 0 ) {} 31 30 32 31 void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) { -
src/GenPoly/ScopedMap.h
r37218fc r37f0da8 51 51 typedef typename scope_list::size_type size_type; 52 52 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 53 70 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 54 71 : scopes(&_scopes), it(_it), i(_i) {} … … 68 85 --i; 69 86 it = (*scopes)[i].begin(); 70 return *this;71 }72 ++it;73 return *this;87 } else { 88 ++it; 89 } 90 return next_valid(); 74 91 } 75 92 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } … … 82 99 } 83 100 --it; 84 return *this;101 return prev_valid(); 85 102 } 86 103 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } … … 105 122 typedef typename scope_list::size_type size_type; 106 123 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 107 141 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 108 142 : scopes(&_scopes), it(_it), i(_i) {} … … 127 161 --i; 128 162 it = (*scopes)[i].begin(); 129 return *this;130 }131 ++it;132 return *this;163 } else { 164 ++it; 165 } 166 return next_valid(); 133 167 } 134 168 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } … … 141 175 } 142 176 --it; 143 return *this;177 return prev_valid(); 144 178 } 145 179 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } … … 171 205 ScopedMap() { beginScope(); } 172 206 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(); } 176 210 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 177 211 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } -
src/GenPoly/ScopedSet.h
r37218fc r37f0da8 48 48 typedef typename scope_list::size_type size_type; 49 49 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 50 67 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 51 68 : scopes(&_scopes), it(_it), i(_i) {} … … 65 82 --i; 66 83 it = (*scopes)[i].begin(); 67 return *this;68 }69 ++it;70 return *this;84 } else { 85 ++it; 86 } 87 return next_valid(); 71 88 } 72 89 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } … … 79 96 } 80 97 --it; 81 return *this;98 return prev_valid(); 82 99 } 83 100 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } … … 102 119 typedef typename scope_list::size_type size_type; 103 120 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 104 138 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 105 139 : scopes(&_scopes), it(_it), i(_i) {} … … 124 158 --i; 125 159 it = (*scopes)[i].begin(); 126 return *this;127 }128 ++it;129 return *this;160 } else { 161 ++it; 162 } 163 return next_valid(); 130 164 } 131 165 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } … … 138 172 } 139 173 --it; 140 return *this;174 return prev_valid(); 141 175 } 142 176 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } … … 167 201 ScopedSet() { beginScope(); } 168 202 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(); } 172 206 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 173 207 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } -
src/GenPoly/ScrubTyVars.cc
r37218fc r37f0da8 64 64 // sizeof( T ) => _sizeof_T parameter, which is the size of T 65 65 if ( Type *polyType = isPolyType( szeof->get_type() ) ) { 66 Expression *expr = new NameExpr( sizeofName( polyType) );66 Expression *expr = new NameExpr( sizeofName( mangleType( polyType ) ) ); 67 67 return expr; 68 68 } else { … … 74 74 // alignof( T ) => _alignof_T parameter, which is the alignment of T 75 75 if ( Type *polyType = isPolyType( algnof->get_type() ) ) { 76 Expression *expr = new NameExpr( alignofName( polyType) );76 Expression *expr = new NameExpr( alignofName( mangleType( polyType ) ) ); 77 77 return expr; 78 78 } else {
Note:
See TracChangeset
for help on using the changeset viewer.