Changeset 7dc09294
- Timestamp:
- Sep 13, 2017, 7:27:12 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 982832e
- Parents:
- ada0eb06 (diff), 4639b0d (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
- Files:
-
- 1 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rada0eb06 r7dc09294 258 258 259 259 void CodeGenerator::visit( TraitDecl * traitDecl ) { 260 assertf( ! genC, "TraitDecl nodes should not reach code generation." );260 assertf( ! genC, "TraitDecls should not reach code generation." ); 261 261 extension( traitDecl ); 262 262 handleAggregate( traitDecl, "trait " ); … … 271 271 272 272 void CodeGenerator::visit( TypeDecl * typeDecl ) { 273 if ( genC ) { 274 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, 275 // still to be done 276 extension( typeDecl ); 277 output << "extern unsigned long " << typeDecl->get_name(); 278 if ( typeDecl->get_base() ) { 279 output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty, genC ) << " )"; 280 } // if 281 } else { 282 output << typeDecl->genTypeString() << " " << typeDecl->get_name(); 283 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) { 284 output << " | sized(" << typeDecl->get_name() << ")"; 285 } 286 if ( ! typeDecl->get_assertions().empty() ) { 287 output << " | { "; 288 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() ); 289 output << " }"; 290 } 273 assertf( ! genC, "TypeDecls should not reach code generation." ); 274 output << typeDecl->genTypeString() << " " << typeDecl->get_name(); 275 if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) { 276 output << " | sized(" << typeDecl->get_name() << ")"; 277 } 278 if ( ! typeDecl->get_assertions().empty() ) { 279 output << " | { "; 280 genCommaList( typeDecl->get_assertions().begin(), typeDecl->get_assertions().end() ); 281 output << " }"; 291 282 } 292 283 } -
src/Common/PassVisitor.h
rada0eb06 r7dc09294 145 145 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override final; 146 146 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override final; 147 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override final;147 virtual Declaration* mutate( TypeDecl *typeDecl ) override final; 148 148 virtual Declaration* mutate( TypedefDecl *typeDecl ) override final; 149 149 virtual AsmDecl* mutate( AsmDecl *asmDecl ) override final; -
src/Common/PassVisitor.impl.h
rada0eb06 r7dc09294 976 976 977 977 template< typename pass_type > 978 TypeDecl* PassVisitor< pass_type >::mutate( TypeDecl * node ) {979 MUTATE_BODY( TypeDecl, node );978 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) { 979 MUTATE_BODY( Declaration, node ); 980 980 } 981 981 -
src/Common/utility.h
rada0eb06 r7dc09294 370 370 } 371 371 372 // ----------------------------------------------------------------------------- 373 // Helper struct and function to support 374 // for ( val : lazy_map( container1, f ) ) {} 375 // syntax to have a for each that iterates a container, mapping each element by applying f 376 template< typename T, typename Func > 377 struct lambda_iterate_t { 378 const T & ref; 379 std::function<Func> f; 380 381 struct iterator { 382 typedef decltype(begin(ref)) Iter; 383 Iter it; 384 std::function<Func> f; 385 iterator( Iter it, std::function<Func> f ) : it(it), f(f) {} 386 iterator & operator++() { 387 ++it; return *this; 388 } 389 bool operator!=( const iterator &other ) const { return it != other.it; } 390 auto operator*() const -> decltype(f(*it)) { return f(*it); } 391 }; 392 393 lambda_iterate_t( const T & ref, std::function<Func> f ) : ref(ref), f(f) {} 394 395 auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); } 396 auto end() const -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); } 397 }; 398 399 template< typename... Args > 400 lambda_iterate_t<Args...> lazy_map( const Args &... args ) { 401 return lambda_iterate_t<Args...>( args...); 402 } 403 404 405 372 406 // Local Variables: // 373 407 // tab-width: 4 // -
src/GenPoly/Box.cc
rada0eb06 r7dc09294 27 27 28 28 #include "CodeGen/OperatorTable.h" 29 #include "Common/PassVisitor.h" // for PassVisitor 29 30 #include "Common/ScopedMap.h" // for ScopedMap, ScopedMap<>::iter... 30 31 #include "Common/SemanticError.h" // for SemanticError … … 157 158 /// * Calculates polymorphic offsetof expressions from offset array 158 159 /// * Inserts dynamic calculation of polymorphic type layouts where needed 159 class PolyGenericCalculator final : public PolyMutator{160 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution { 160 161 public: 161 typedef PolyMutator Parent;162 using Parent::mutate;163 164 162 PolyGenericCalculator(); 165 163 166 template< typename DeclClass > 167 DeclClass *handleDecl( DeclClass *decl, Type *type ); 168 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 169 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 170 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override; 171 virtual TypeDecl *mutate( TypeDecl *objectDecl ) override; 172 virtual Statement *mutate( DeclStmt *declStmt ) override; 173 virtual Type *mutate( PointerType *pointerType ) override; 174 virtual Type *mutate( FunctionType *funcType ) override; 175 virtual Expression *mutate( MemberExpr *memberExpr ) override; 176 virtual Expression *mutate( SizeofExpr *sizeofExpr ) override; 177 virtual Expression *mutate( AlignofExpr *alignofExpr ) override; 178 virtual Expression *mutate( OffsetofExpr *offsetofExpr ) override; 179 virtual Expression *mutate( OffsetPackExpr *offsetPackExpr ) override; 180 181 virtual void doBeginScope() override; 182 virtual void doEndScope() override; 164 void premutate( ObjectDecl *objectDecl ); 165 void premutate( FunctionDecl *functionDecl ); 166 void premutate( TypedefDecl *objectDecl ); 167 void premutate( TypeDecl *objectDecl ); 168 Declaration * postmutate( TypeDecl *TraitDecl ); 169 void premutate( PointerType *pointerType ); 170 void premutate( FunctionType *funcType ); 171 void premutate( DeclStmt *declStmt ); 172 Expression *postmutate( MemberExpr *memberExpr ); 173 Expression *postmutate( SizeofExpr *sizeofExpr ); 174 Expression *postmutate( AlignofExpr *alignofExpr ); 175 Expression *postmutate( OffsetofExpr *offsetofExpr ); 176 Expression *postmutate( OffsetPackExpr *offsetPackExpr ); 177 178 void beginScope(); 179 void endScope(); 183 180 184 181 private: … … 194 191 /// Exits the type-variable scope 195 192 void endTypeScope(); 193 /// Enters a new scope for knowLayouts and knownOffsets and queues exit calls 194 void beginGenericScope(); 196 195 197 196 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 198 197 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 199 198 UniqueName bufNamer; ///< Namer for VLA buffers 199 TyVarMap scopeTyVars; 200 200 }; 201 201 … … 250 250 Pass1 pass1; 251 251 Pass2 pass2; 252 P olyGenericCalculatorpolyCalculator;252 PassVisitor<PolyGenericCalculator> polyCalculator; 253 253 Pass3 pass3; 254 254 … … 256 256 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 257 257 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 258 mutate TranslationUnit/*All*/( translationUnit, polyCalculator );258 mutateAll( translationUnit, polyCalculator ); 259 259 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 260 260 } … … 555 555 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 556 556 addToTyVarMap( typeDecl, scopeTyVars ); 557 return Mutator::mutate( typeDecl);557 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 558 558 } 559 559 … … 762 762 } else if ( arg->get_result()->get_lvalue() ) { 763 763 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 764 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 765 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 766 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 767 // return; 768 // } 769 // } 764 770 arg = generalizedLvalue( new AddressExpr( arg ) ); 765 771 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { … … 1353 1359 return handleDecl( typeDecl ); 1354 1360 } else { 1355 return Parent::mutate( typeDecl);1361 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) ); 1356 1362 } 1357 1363 } … … 1466 1472 1467 1473 PolyGenericCalculator::PolyGenericCalculator() 1468 : Parent(), knownLayouts(), knownOffsets(), bufNamer( "_buf") {}1474 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {} 1469 1475 1470 1476 void PolyGenericCalculator::beginTypeScope( Type *ty ) { 1471 scopeTyVars.beginScope();1477 GuardScope( scopeTyVars ); 1472 1478 makeTyVarMap( ty, scopeTyVars ); 1473 1479 } 1474 1480 1475 void PolyGenericCalculator::endTypeScope() { 1476 scopeTyVars.endScope(); 1477 } 1478 1479 template< typename DeclClass > 1480 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) { 1481 beginTypeScope( type ); 1482 // knownLayouts.beginScope(); 1483 // knownOffsets.beginScope(); 1484 1485 DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) ); 1486 1487 // knownOffsets.endScope(); 1488 // knownLayouts.endScope(); 1489 endTypeScope(); 1490 return ret; 1491 } 1492 1493 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) { 1494 return handleDecl( objectDecl, objectDecl->get_type() ); 1495 } 1496 1497 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) { 1498 knownLayouts.beginScope(); 1499 knownOffsets.beginScope(); 1500 1501 DeclarationWithType * decl = handleDecl( functionDecl, functionDecl->get_functionType() ); 1502 knownOffsets.endScope(); 1503 knownLayouts.endScope(); 1504 return decl; 1505 } 1506 1507 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) { 1508 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1509 } 1510 1511 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) { 1481 void PolyGenericCalculator::beginGenericScope() { 1482 GuardScope( *this ); 1483 } 1484 1485 void PolyGenericCalculator::premutate( ObjectDecl *objectDecl ) { 1486 beginTypeScope( objectDecl->get_type() ); 1487 } 1488 1489 void PolyGenericCalculator::premutate( FunctionDecl *functionDecl ) { 1490 beginGenericScope(); 1491 1492 beginTypeScope( functionDecl->get_functionType() ); 1493 } 1494 1495 void PolyGenericCalculator::premutate( TypedefDecl *typedefDecl ) { 1496 beginTypeScope( typedefDecl->get_base() ); 1497 } 1498 1499 void PolyGenericCalculator::premutate( TypeDecl * typeDecl ) { 1512 1500 addToTyVarMap( typeDecl, scopeTyVars ); 1513 return Parent::mutate( typeDecl ); 1514 } 1515 1516 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) { 1501 } 1502 1503 Declaration * PolyGenericCalculator::postmutate( TypeDecl *typeDecl ) { 1504 if ( Type * base = typeDecl->base ) { 1505 // add size/align variables for opaque type declarations 1506 TypeInstType inst( Type::Qualifiers(), typeDecl->name, typeDecl ); 1507 std::string typeName = mangleType( &inst ); 1508 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1509 1510 ObjectDecl * sizeDecl = ObjectDecl::newObject( sizeofName( typeName ), layoutType, new SingleInit( new SizeofExpr( base->clone() ) ) ); 1511 ObjectDecl * alignDecl = ObjectDecl::newObject( alignofName( typeName ), layoutType->clone(), new SingleInit( new AlignofExpr( base->clone() ) ) ); 1512 1513 // ensure that the initializing sizeof/alignof exprs are properly mutated 1514 sizeDecl->acceptMutator( *visitor ); 1515 alignDecl->acceptMutator( *visitor ); 1516 1517 // can't use makeVar, because it inserts into stmtsToAdd and TypeDecls can occur at global scope 1518 declsToAddAfter.push_back( alignDecl ); 1519 // replace with sizeDecl 1520 return sizeDecl; 1521 } 1522 return typeDecl; 1523 } 1524 1525 void PolyGenericCalculator::premutate( PointerType *pointerType ) { 1517 1526 beginTypeScope( pointerType ); 1518 1519 Type *ret = Parent::mutate( pointerType ); 1520 1521 endTypeScope(); 1522 return ret; 1523 } 1524 1525 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) { 1527 } 1528 1529 void PolyGenericCalculator::premutate( FunctionType *funcType ) { 1526 1530 beginTypeScope( funcType ); 1527 1531 … … 1534 1538 } 1535 1539 } 1536 1537 Type *ret = Parent::mutate( funcType ); 1538 1539 endTypeScope(); 1540 return ret; 1541 } 1542 1543 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) { 1540 } 1541 1542 void PolyGenericCalculator::premutate( DeclStmt *declStmt ) { 1544 1543 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1545 1544 if ( findGeneric( objectDecl->get_type() ) ) { … … 1550 1549 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ), 1551 1550 true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 ); 1552 stmtsToAdd .push_back( new DeclStmt( noLabels, newBuf ) );1551 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newBuf ) ); 1553 1552 1554 1553 delete objectDecl->get_init(); … … 1556 1555 } 1557 1556 } 1558 return Parent::mutate( declStmt );1559 1557 } 1560 1558 … … 1583 1581 } 1584 1582 1585 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1586 // mutate, exiting early if no longer MemberExpr 1587 Expression *expr = Parent::mutate( memberExpr ); 1588 memberExpr = dynamic_cast< MemberExpr* >( expr ); 1589 if ( ! memberExpr ) return expr; 1590 1583 Expression *PolyGenericCalculator::postmutate( MemberExpr *memberExpr ) { 1591 1584 // only mutate member expressions for polymorphic types 1592 1585 int tyDepth; … … 1635 1628 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1636 1629 ObjectDecl *newObj = new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init ); 1637 stmtsToAdd .push_back( new DeclStmt( noLabels, newObj ) );1630 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 1638 1631 return newObj; 1639 1632 } … … 1714 1707 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1715 1708 1716 stmtsToAdd .push_back( new ExprStmt( noLabels, layoutCall ) );1709 stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) ); 1717 1710 } 1718 1711 … … 1740 1733 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1741 1734 1742 stmtsToAdd .push_back( new ExprStmt( noLabels, layoutCall ) );1735 stmtsToAddBefore.push_back( new ExprStmt( noLabels, layoutCall ) ); 1743 1736 1744 1737 return true; … … 1748 1741 } 1749 1742 1750 Expression *PolyGenericCalculator:: mutate( SizeofExpr *sizeofExpr ) {1743 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 1751 1744 Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1752 1745 if ( findGeneric( ty ) ) { … … 1758 1751 } 1759 1752 1760 Expression *PolyGenericCalculator:: mutate( AlignofExpr *alignofExpr ) {1753 Expression *PolyGenericCalculator::postmutate( AlignofExpr *alignofExpr ) { 1761 1754 Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result(); 1762 1755 if ( findGeneric( ty ) ) { … … 1768 1761 } 1769 1762 1770 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) { 1771 // mutate, exiting early if no longer OffsetofExpr 1772 Expression *expr = Parent::mutate( offsetofExpr ); 1773 offsetofExpr = dynamic_cast< OffsetofExpr* >( expr ); 1774 if ( ! offsetofExpr ) return expr; 1775 1763 Expression *PolyGenericCalculator::postmutate( OffsetofExpr *offsetofExpr ) { 1776 1764 // only mutate expressions for polymorphic structs/unions 1777 1765 Type *ty = offsetofExpr->get_type(); … … 1793 1781 } 1794 1782 1795 Expression *PolyGenericCalculator:: mutate( OffsetPackExpr *offsetPackExpr ) {1783 Expression *PolyGenericCalculator::postmutate( OffsetPackExpr *offsetPackExpr ) { 1796 1784 StructInstType *ty = offsetPackExpr->get_type(); 1797 1785 … … 1832 1820 } 1833 1821 1834 void PolyGenericCalculator:: doBeginScope() {1822 void PolyGenericCalculator::beginScope() { 1835 1823 knownLayouts.beginScope(); 1836 1824 knownOffsets.beginScope(); 1837 1825 } 1838 1826 1839 void PolyGenericCalculator:: doEndScope() {1827 void PolyGenericCalculator::endScope() { 1840 1828 knownLayouts.endScope(); 1841 1829 knownOffsets.endScope(); … … 1894 1882 1895 1883 addToTyVarMap( typeDecl, scopeTyVars ); 1896 return Mutator::mutate( typeDecl);1884 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 1897 1885 } 1898 1886 -
src/Parser/DeclarationNode.cc
rada0eb06 r7dc09294 333 333 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) { 334 334 DeclarationNode * newnode = new DeclarationNode; 335 newnode->name = name; 335 336 newnode->type = new TypeData( TypeData::Symbolic ); 336 337 newnode->type->symbolic.isTypedef = false; 337 338 newnode->type->symbolic.params = typeParams; 338 newnode->type->symbolic.name = name;339 339 return newnode; 340 340 } // DeclarationNode::newTypeDecl -
src/ResolvExpr/CastCost.cc
rada0eb06 r7dc09294 45 45 } 46 46 } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { 47 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );48 47 // all typedefs should be gone by this point 49 assert( type );48 TypeDecl *type = safe_dynamic_cast< TypeDecl* >( namedType ); 50 49 if ( type->get_base() ) { 51 50 return castCost( src, type->get_base(), indexer, env ) + Cost::safe; -
src/ResolvExpr/ConversionCost.cc
rada0eb06 r7dc09294 92 92 93 93 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 94 PRINT( std::cerr << "convert to reference cost... "<< std::endl; )94 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; ) 95 95 if ( diff > 0 ) { 96 96 // TODO: document this … … 128 128 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 129 129 assert( diff == -1 && destAsRef ); 130 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 130 131 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) { 131 132 PRINT( std::cerr << "converting compatible base type" << std::endl; ) -
src/SymTab/Autogen.cc
rada0eb06 r7dc09294 163 163 // Routines at global scope marked "static" to prevent multiple definitions in separate translation units 164 164 // because each unit generates copies of the default routines for each aggregate. 165 // DeclarationNode::StorageClass sc = functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static;166 165 Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ); 167 166 LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen; … … 186 185 /// using map and t, determines if is constructable, etc. 187 186 bool lookup( const TypeMap & map, Type * t ) { 187 assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() ); 188 188 if ( dynamic_cast< PointerType * >( t ) ) { 189 189 // will need more complicated checking if we want this to work with pointer types, since currently … … 200 200 201 201 /// using map and aggr, examines each member to determine if constructor, etc. should be generated 202 template<typename AggrDecl> 203 bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) { 204 for ( Declaration * dcl : aggr->get_members() ) { 205 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) { 206 if ( ! lookup( map, dwt->get_type() ) ) return false; 207 } 202 template<typename Container> 203 bool shouldGenerate( const TypeMap & map, const Container & container ) { 204 for ( Type * t : container ) { 205 if ( ! lookup( map, t ) ) return false; 208 206 } 209 207 return true; … … 211 209 212 210 /// data structure for abstracting the generation of special functions 213 template< typename OutputIterator >211 template< typename OutputIterator, typename Container > 214 212 struct FuncGenerator { 215 StructDecl *aggregateDecl;216 StructInstType *refType;213 const Container & container; 214 Type *refType; 217 215 unsigned int functionNesting; 218 216 const std::list< TypeDecl* > & typeParams; 219 217 OutputIterator out; 220 FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}218 FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {} 221 219 222 220 /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map. 223 221 void gen( const FuncData & data, bool concurrent_type ) { 224 if ( ! shouldGenerate( data.map, aggregateDecl) ) return;222 if ( ! shouldGenerate( data.map, container ) ) return; 225 223 FunctionType * ftype = data.genType( refType ); 226 224 227 225 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 228 ftype-> get_parameters().front()->get_type()->set_mutex( true );229 } 230 231 cloneAll( typeParams, ftype-> get_forall());226 ftype->parameters.front()->get_type()->set_mutex( true ); 227 } 228 229 cloneAll( typeParams, ftype->forall ); 232 230 *out++ = genFunc( data.fname, ftype, functionNesting ); 233 231 data.map.insert( Mangler::mangleType( refType ), true ); … … 235 233 }; 236 234 237 template< typename OutputIterator >238 FuncGenerator<OutputIterator > makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {239 return FuncGenerator<OutputIterator >( aggregateDecl, refType, functionNesting, typeParams, out );235 template< typename OutputIterator, typename Container > 236 FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) { 237 return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out ); 240 238 } 241 239 … … 393 391 } 394 392 393 Type * declToType( Declaration * decl ) { 394 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 395 return dwt->get_type(); 396 } 397 return nullptr; 398 } 399 395 400 /// generates struct constructors, destructor, and assignment functions 396 401 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { … … 406 411 // generate each of the functions based on the supplied FuncData objects 407 412 std::list< FunctionDecl * > newFuncs; 408 auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 413 // structure that iterates aggregate decl members, returning their types 414 auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 409 415 for ( const FuncData & d : data ) { 410 416 generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() ); … … 605 611 } 606 612 613 Type * declToTypeDeclBase( Declaration * decl ) { 614 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) { 615 return td->base; 616 } 617 return nullptr; 618 } 619 620 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 607 621 void AutogenerateRoutines::visit( TypeDecl *typeDecl ) { 608 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false ); 609 typeInst->set_baseType( typeDecl ); 610 ObjectDecl *src = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, typeInst->clone(), nullptr ); 611 ObjectDecl *dst = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), typeInst->clone() ), nullptr ); 612 613 std::list< Statement * > stmts; 614 if ( typeDecl->get_base() ) { 615 // xxx - generate ctor/dtors for typedecls, e.g. 616 // otype T = int *; 617 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 618 assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) ); 619 assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) ); 620 stmts.push_back( new ReturnStmt( std::list< Label >(), assign ) ); 621 } // if 622 FunctionType *type = new FunctionType( Type::Qualifiers(), false ); 623 type->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, typeInst, 0 ) ); 624 type->get_parameters().push_back( dst ); 625 type->get_parameters().push_back( src ); 626 FunctionDecl *func = genFunc( "?=?", type, functionNesting ); 627 func->get_statements()->get_kids() = stmts; 628 declsToAddAfter.push_back( func ); 622 if ( ! typeDecl->base ) return; 623 624 // generate each of the functions based on the supplied FuncData objects 625 std::list< FunctionDecl * > newFuncs; 626 std::list< Declaration * > tds { typeDecl }; 627 std::list< TypeDecl * > typeParams; 628 TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl ); 629 auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 630 for ( const FuncData & d : data ) { 631 generator.gen( d, false ); 632 } 633 634 if ( functionNesting == 0 ) { 635 // forward declare if top-level struct, so that 636 // type is complete as soon as its body ends 637 // Note: this is necessary if we want structs which contain 638 // generic (otype) structs as members. 639 for ( FunctionDecl * dcl : newFuncs ) { 640 addForwardDecl( dcl, declsToAddAfter ); 641 } 642 } 643 644 for ( FunctionDecl * dcl : newFuncs ) { 645 FunctionType * ftype = dcl->type; 646 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 647 DeclarationWithType * dst = ftype->parameters.front(); 648 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 649 // generate appropriate calls to member ctor, assignment 650 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 651 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 652 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 653 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 654 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 655 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 656 // assignment needs to return a value 657 FunctionType * assignType = dcl->type; 658 assert( assignType->parameters.size() == 2 ); 659 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->parameters.back() ); 660 dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 661 } 662 declsToAddAfter.push_back( dcl ); 663 } 629 664 } 630 665 -
src/SymTab/Validate.cc
rada0eb06 r7dc09294 176 176 }; 177 177 178 class EliminateTypedef : public Mutator { 179 public: 178 struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards { 180 179 EliminateTypedef() : scopeLevel( 0 ) {} 181 180 /// Replaces typedefs by forward declarations 182 181 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 182 183 Type * postmutate( TypeInstType * aggregateUseType ); 184 Declaration * postmutate( TypedefDecl * typeDecl ); 185 void premutate( TypeDecl * typeDecl ); 186 void premutate( FunctionDecl * funcDecl ); 187 void premutate( ObjectDecl * objDecl ); 188 DeclarationWithType * postmutate( ObjectDecl * objDecl ); 189 190 void premutate( CastExpr * castExpr ); 191 192 void premutate( CompoundStmt * compoundStmt ); 193 CompoundStmt * postmutate( CompoundStmt * compoundStmt ); 194 195 void premutate( StructDecl * structDecl ); 196 Declaration * postmutate( StructDecl * structDecl ); 197 void premutate( UnionDecl * unionDecl ); 198 Declaration * postmutate( UnionDecl * unionDecl ); 199 void premutate( EnumDecl * enumDecl ); 200 Declaration * postmutate( EnumDecl * enumDecl ); 201 Declaration * postmutate( TraitDecl * contextDecl ); 202 183 203 private: 184 virtual Declaration *mutate( TypedefDecl *typeDecl );185 virtual TypeDecl *mutate( TypeDecl *typeDecl );186 virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );187 virtual DeclarationWithType *mutate( ObjectDecl *objDecl );188 virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );189 virtual Type *mutate( TypeInstType *aggregateUseType );190 virtual Expression *mutate( CastExpr *castExpr );191 192 virtual Declaration *mutate( StructDecl * structDecl );193 virtual Declaration *mutate( UnionDecl * unionDecl );194 virtual Declaration *mutate( EnumDecl * enumDecl );195 virtual Declaration *mutate( TraitDecl * contextDecl );196 197 204 template<typename AggDecl> 198 205 AggDecl *handleAggregate( AggDecl * aggDecl ); … … 667 674 668 675 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 669 EliminateTypedefeliminator;676 PassVisitor<EliminateTypedef> eliminator; 670 677 mutateAll( translationUnit, eliminator ); 671 if ( eliminator. typedefNames.count( "size_t" ) ) {678 if ( eliminator.pass.typedefNames.count( "size_t" ) ) { 672 679 // grab and remember declaration of size_t 673 SizeType = eliminator. typedefNames["size_t"].first->get_base()->clone();680 SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone(); 674 681 } else { 675 682 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong … … 681 688 } 682 689 683 Type * EliminateTypedef::mutate( TypeInstType * typeInst ) {690 Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) { 684 691 // instances of typedef types will come here. If it is an instance 685 692 // of a typdef type, link the instance to its actual type. … … 696 703 rtt->get_parameters().clear(); 697 704 cloneAll( typeInst->get_parameters(), rtt->get_parameters() ); 698 mutateAll( rtt->get_parameters(), * this); // recursively fix typedefs on parameters705 mutateAll( rtt->get_parameters(), *visitor ); // recursively fix typedefs on parameters 699 706 } // if 700 707 delete typeInst; … … 708 715 } 709 716 710 Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) { 711 Declaration *ret = Mutator::mutate( tyDecl ); 712 717 Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) { 713 718 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 714 719 // typedef to the same name from the same scope … … 741 746 return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 742 747 } else { 743 return ret->clone();744 } // if 745 } 746 747 TypeDecl *EliminateTypedef::mutate( TypeDecl * typeDecl ) {748 return tyDecl->clone(); 749 } // if 750 } 751 752 void EliminateTypedef::premutate( TypeDecl * typeDecl ) { 748 753 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() ); 749 754 if ( i != typedefNames.end() ) { … … 752 757 753 758 typedeclNames[ typeDecl->get_name() ] = typeDecl; 754 return Mutator::mutate( typeDecl ); 755 } 756 757 DeclarationWithType *EliminateTypedef::mutate( FunctionDecl * funcDecl ) { 758 typedefNames.beginScope(); 759 DeclarationWithType *ret = Mutator::mutate( funcDecl ); 760 typedefNames.endScope(); 761 return ret; 762 } 763 764 DeclarationWithType *EliminateTypedef::mutate( ObjectDecl * objDecl ) { 765 typedefNames.beginScope(); 766 DeclarationWithType *ret = Mutator::mutate( objDecl ); 767 typedefNames.endScope(); 768 769 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) { // function type? 759 } 760 761 void EliminateTypedef::premutate( FunctionDecl * ) { 762 GuardScope( typedefNames ); 763 } 764 765 void EliminateTypedef::premutate( ObjectDecl * ) { 766 GuardScope( typedefNames ); 767 } 768 769 DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) { 770 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type? 770 771 // replace the current object declaration with a function declaration 771 FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClasses(), ret->get_linkage(), funtype, 0, objDecl->get_attributes(), ret->get_funcSpec() );772 FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() ); 772 773 objDecl->get_attributes().clear(); 773 774 objDecl->set_type( nullptr ); … … 775 776 return newDecl; 776 777 } // if 777 return ret; 778 } 779 780 Expression *EliminateTypedef::mutate( CastExpr * castExpr ) { 781 typedefNames.beginScope(); 782 Expression *ret = Mutator::mutate( castExpr ); 783 typedefNames.endScope(); 784 return ret; 785 } 786 787 CompoundStmt *EliminateTypedef::mutate( CompoundStmt * compoundStmt ) { 788 typedefNames.beginScope(); 778 return objDecl; 779 } 780 781 void EliminateTypedef::premutate( CastExpr * ) { 782 GuardScope( typedefNames ); 783 } 784 785 void EliminateTypedef::premutate( CompoundStmt * ) { 786 GuardScope( typedefNames ); 789 787 scopeLevel += 1; 790 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 791 scopeLevel -= 1; 788 GuardAction( [this](){ scopeLevel -= 1; } ); 789 } 790 791 CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) { 792 792 // remove and delete decl stmts 793 793 filter( compoundStmt->kids, [](Statement * stmt) { … … 799 799 return false; 800 800 }, true); 801 typedefNames.endScope(); 802 return ret; 801 return compoundStmt; 803 802 } 804 803 … … 827 826 } 828 827 829 Declaration *EliminateTypedef::mutate( StructDecl * structDecl ) {828 void EliminateTypedef::premutate( StructDecl * structDecl ) { 830 829 addImplicitTypedef( structDecl ); 831 Mutator::mutate( structDecl ); 830 } 831 832 833 Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) { 832 834 return handleAggregate( structDecl ); 833 835 } 834 836 835 Declaration *EliminateTypedef::mutate( UnionDecl * unionDecl ) {837 void EliminateTypedef::premutate( UnionDecl * unionDecl ) { 836 838 addImplicitTypedef( unionDecl ); 837 Mutator::mutate( unionDecl ); 839 } 840 841 Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) { 838 842 return handleAggregate( unionDecl ); 839 843 } 840 844 841 Declaration *EliminateTypedef::mutate( EnumDecl * enumDecl ) {845 void EliminateTypedef::premutate( EnumDecl * enumDecl ) { 842 846 addImplicitTypedef( enumDecl ); 843 Mutator::mutate( enumDecl ); 847 } 848 849 Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) { 844 850 return handleAggregate( enumDecl ); 845 851 } 846 852 847 Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) { 848 Mutator::mutate( contextDecl ); 849 return handleAggregate( contextDecl ); 853 Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) { 854 return handleAggregate( traitDecl ); 850 855 } 851 856 -
src/SynTree/Declaration.h
rada0eb06 r7dc09294 136 136 Expression *get_bitfieldWidth() const { return bitfieldWidth; } 137 137 void set_bitfieldWidth( Expression *newValue ) { bitfieldWidth = newValue; } 138 139 static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init ); 138 140 139 141 virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); } … … 230 232 virtual TypeDecl *clone() const { return new TypeDecl( *this ); } 231 233 virtual void accept( Visitor &v ) { v.visit( this ); } 232 virtual TypeDecl*acceptMutator( Mutator &m ) { return m.mutate( this ); }234 virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); } 233 235 virtual void print( std::ostream &os, int indent = 0 ) const; 234 236 -
src/SynTree/Mutator.cc
rada0eb06 r7dc09294 78 78 } 79 79 80 TypeDecl* Mutator::mutate( TypeDecl *typeDecl ) {80 Declaration * Mutator::mutate( TypeDecl *typeDecl ) { 81 81 handleNamedTypeDecl( typeDecl ); 82 82 typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) ); -
src/SynTree/Mutator.h
rada0eb06 r7dc09294 31 31 virtual Declaration* mutate( EnumDecl *aggregateDecl ); 32 32 virtual Declaration* mutate( TraitDecl *aggregateDecl ); 33 virtual TypeDecl* mutate( TypeDecl *typeDecl );33 virtual Declaration* mutate( TypeDecl *typeDecl ); 34 34 virtual Declaration* mutate( TypedefDecl *typeDecl ); 35 35 virtual AsmDecl* mutate( AsmDecl *asmDecl ); -
src/SynTree/ObjectDecl.cc
rada0eb06 r7dc09294 38 38 delete init; 39 39 delete bitfieldWidth; 40 } 41 42 ObjectDecl * ObjectDecl::newObject( const std::string & name, Type * type, Initializer * init ) { 43 return new ObjectDecl( name, Type::StorageClasses(), LinkageSpec::C, 0, type, init ); 40 44 } 41 45 -
src/SynTree/Statement.cc
rada0eb06 r7dc09294 472 472 } 473 473 474 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}475 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}474 NullStmt::NullStmt( std::list<Label> labels ) : Statement( labels ) {} 475 NullStmt::NullStmt() : Statement( std::list<Label>() ) {} 476 476 477 477 void NullStmt::print( std::ostream &os, __attribute__((unused)) int indent ) const { -
src/SynTree/Statement.h
rada0eb06 r7dc09294 67 67 }; 68 68 69 class NullStmt : public CompoundStmt {69 class NullStmt : public Statement { 70 70 public: 71 71 NullStmt();
Note: See TracChangeset
for help on using the changeset viewer.