Changeset b58affe7
- Timestamp:
- Jun 24, 2019, 11:24:31 AM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 0e464f6, 3253c32
- Parents:
- 4d978d5 (diff), c1ea11b (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:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Node.hpp
r4d978d5 rb58affe7 100 100 101 101 /// Mutate a node field (only clones if not equal to existing value) 102 template<typename node_t, typename field_t, typename assn_t>103 const node_t * mutate_field( const node_t * node, field_t node_t::* field, assn_t && val ) {102 template<typename node_t, typename parent_t, typename field_t, typename assn_t> 103 const node_t * mutate_field( const node_t * node, field_t parent_t::* field, assn_t && val ) { 104 104 // skip mutate if equivalent 105 105 if ( node->*field == val ) return node; … … 112 112 113 113 /// Mutate a single index of a node field (only clones if not equal to existing value) 114 template<typename node_t, typename coll_t, typename ind_t, typename field_t>114 template<typename node_t, typename parent_t, typename coll_t, typename ind_t, typename field_t> 115 115 const node_t * mutate_field_index( 116 const node_t * node, coll_t node_t::* field, ind_t i, field_t && val116 const node_t * node, coll_t parent_t::* field, ind_t i, field_t && val 117 117 ) { 118 118 // skip mutate if equivalent -
src/ResolvExpr/CandidateFinder.cpp
r4d978d5 rb58affe7 1003 1003 assert( toType ); 1004 1004 toType = resolveTypeof( toType, symtab ); 1005 toType = SymTab::validateType( toType, symtab );1005 toType = SymTab::validateType( castExpr->location, toType, symtab ); 1006 1006 toType = adjustExprType( toType, tenv, symtab ); 1007 1007 … … 1410 1410 // calculate target type 1411 1411 const ast::Type * toType = resolveTypeof( initAlt.type, symtab ); 1412 toType = SymTab::validateType( toType, symtab );1412 toType = SymTab::validateType( initExpr->location, toType, symtab ); 1413 1413 toType = adjustExprType( toType, tenv, symtab ); 1414 1414 // The call to find must occur inside this loop, otherwise polymorphic return -
src/ResolvExpr/Resolver.cc
r4d978d5 rb58affe7 1154 1154 return findKindExpression( untyped, symtab ); 1155 1155 } 1156 1157 /// Resolve `untyped` to the single expression whose candidate is the best match for the 1158 /// given type. 1156 } // anonymous namespace 1157 1159 1158 ast::ptr< ast::Expr > findSingleExpression( 1160 1159 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab … … 1167 1166 } 1168 1167 1168 namespace { 1169 1169 /// Predicate for "Candidate has integral type" 1170 1170 bool hasIntegralType( const Candidate & i ) { -
src/ResolvExpr/Resolver.h
r4d978d5 rb58affe7 35 35 class StmtExpr; 36 36 class SymbolTable; 37 class Type; 37 38 class TypeEnvironment; 38 39 } // namespace ast … … 61 62 ast::ptr< ast::Expr > resolveInVoidContext( 62 63 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env ); 64 /// Resolve `untyped` to the single expression whose candidate is the best match for the 65 /// given type. 66 ast::ptr< ast::Expr > findSingleExpression( 67 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab ); 63 68 /// Resolves a constructor init expression 64 69 ast::ptr< ast::Init > resolveCtorInit( -
src/SymTab/Validate.cc
r4d978d5 rb58affe7 44 44 #include <list> // for list 45 45 #include <string> // for string 46 #include <unordered_map> // for unordered_map 46 47 #include <utility> // for pair 47 48 49 #include "AST/Chain.hpp" 48 50 #include "AST/Decl.hpp" 49 51 #include "AST/Node.hpp" … … 54 56 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 55 57 #include "ControlStruct/Mutate.h" // for ForExprMutator 58 #include "Common/CodeLocation.h" // for CodeLocation 56 59 #include "Common/Stats.h" // for Stats::Heap 57 60 #include "Common/PassVisitor.h" // for PassVisitor, WithDeclsToAdd … … 1428 1431 1429 1432 /// Associates forward declarations of aggregates with their definitions 1430 structLinkReferenceToTypes_new final1433 class LinkReferenceToTypes_new final 1431 1434 : public ast::WithSymbolTable, public ast::WithGuards, public 1432 1435 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1433 1436 1434 const ast::SymbolTable * localSyms; 1435 1436 LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {} 1437 1438 #warning incomplete 1437 // these maps of uses of forward declarations of types need to have the actual type 1438 // declaration switched in *after* they have been traversed. To enable this in the 1439 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1440 // before it is placed in the map, properly updating its parents in the usual traversal, 1441 // then can have the actual mutation applied later 1442 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1443 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1444 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1445 1446 const CodeLocation & location; 1447 const ast::SymbolTable * localSymtab; 1448 1449 ForwardEnumsType forwardEnums; 1450 ForwardStructsType forwardStructs; 1451 ForwardUnionsType forwardUnions; 1452 1453 /// true if currently in a generic type body, so that type parameter instances can be 1454 /// renamed appropriately 1455 bool inGeneric = false; 1456 1457 public: 1458 /// contstruct using running symbol table 1459 LinkReferenceToTypes_new( const CodeLocation & loc ) 1460 : location( loc ), localSymtab( &symtab ) {} 1461 1462 /// construct using provided symbol table 1463 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1464 : location( loc ), localSymtab( &syms ) {} 1465 1466 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) { 1467 // ensure generic parameter instances are renamed like the base type 1468 if ( inGeneric && typeInst->base ) { 1469 typeInst = ast::mutate_field( 1470 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1471 } 1472 1473 if ( 1474 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1475 localSymtab->lookupType( typeInst->name ) ) 1476 ) { 1477 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); 1478 } 1479 1480 return typeInst; 1481 } 1482 1483 const ast::Type * postvisit( const ast::EnumInstType * inst ) { 1484 const ast::EnumDecl * decl = localSymtab->lookupEnum( inst->name ); 1485 // not a semantic error if the enum is not found, just an implicit forward declaration 1486 if ( decl ) { 1487 inst = ast::mutate_field( inst, &ast::EnumInstType::base, decl ); 1488 } 1489 if ( ! decl || ! decl->body ) { 1490 // forward declaration 1491 auto mut = mutate( inst ); 1492 forwardEnums.emplace( inst->name, mut ); 1493 inst = mut; 1494 } 1495 return inst; 1496 } 1497 1498 void checkGenericParameters( const ast::ReferenceToType * inst ) { 1499 for ( const ast::Expr * param : inst->params ) { 1500 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1501 SemanticError( 1502 location, inst, "Expression parameters for generic types are currently " 1503 "unsupported: " ); 1504 } 1505 } 1506 } 1507 1508 const ast::StructInstType * postvisit( const ast::StructInstType * inst ) { 1509 const ast::StructDecl * decl = localSymtab->lookupStruct( inst->name ); 1510 // not a semantic error if the struct is not found, just an implicit forward declaration 1511 if ( decl ) { 1512 inst = ast::mutate_field( inst, &ast::StructInstType::base, decl ); 1513 } 1514 if ( ! decl || ! decl->body ) { 1515 // forward declaration 1516 auto mut = mutate( inst ); 1517 forwardStructs.emplace( inst->name, mut ); 1518 inst = mut; 1519 } 1520 checkGenericParameters( inst ); 1521 return inst; 1522 } 1523 1524 const ast::UnionInstType * postvisit( const ast::UnionInstType * inst ) { 1525 const ast::UnionDecl * decl = localSymtab->lookupUnion( inst->name ); 1526 // not a semantic error if the struct is not found, just an implicit forward declaration 1527 if ( decl ) { 1528 inst = ast::mutate_field( inst, &ast::UnionInstType::base, decl ); 1529 } 1530 if ( ! decl || ! decl->body ) { 1531 // forward declaration 1532 auto mut = mutate( inst ); 1533 forwardUnions.emplace( inst->name, mut ); 1534 inst = mut; 1535 } 1536 checkGenericParameters( inst ); 1537 return inst; 1538 } 1539 1540 const ast::Type * postvisit( const ast::TraitInstType * traitInst ) { 1541 // handle other traits 1542 const ast::TraitDecl * traitDecl = localSymtab->lookupTrait( traitInst->name ); 1543 if ( ! traitDecl ) { 1544 SemanticError( location, "use of undeclared trait " + traitInst->name ); 1545 } 1546 if ( traitDecl->params.size() != traitInst->params.size() ) { 1547 SemanticError( location, traitInst, "incorrect number of trait parameters: " ); 1548 } 1549 traitInst = ast::mutate_field( traitInst, &ast::TraitInstType::base, traitDecl ); 1550 1551 // need to carry over the "sized" status of each decl in the instance 1552 for ( unsigned i = 0; i < traitDecl->params.size(); ++i ) { 1553 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1554 if ( ! expr ) { 1555 SemanticError( 1556 traitInst->params[i].get(), "Expression parameters for trait instances " 1557 "are currently unsupported: " ); 1558 } 1559 1560 if ( auto inst = expr->type.as< ast::TypeInstType >() ) { 1561 if ( traitDecl->params[i]->sized && ! inst->base->sized ) { 1562 // traitInst = ast::mutate_field_index( 1563 // traitInst, &ast::TraitInstType::params, i, 1564 // ... 1565 // ); 1566 ast::TraitInstType * mut = ast::mutate( traitInst ); 1567 ast::chain_mutate( mut->params[i] ) 1568 ( &ast::TypeExpr::type ) 1569 ( &ast::TypeInstType::base )->sized = true; 1570 traitInst = mut; 1571 } 1572 } 1573 } 1574 1575 return traitInst; 1576 } 1577 1578 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1579 1580 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1581 // linking only makes sense for the "oldest ancestor" of the qualified type 1582 return ast::mutate_field( 1583 qualType, &ast::QualifiedType::parent, qualType->parent->accept( *visitor ) ); 1584 } 1585 1586 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1587 // visit enum members first so that the types of self-referencing members are updated 1588 // properly 1589 if ( ! enumDecl->body ) return enumDecl; 1590 1591 // update forward declarations to point here 1592 auto fwds = forwardEnums.equal_range( enumDecl->name ); 1593 if ( fwds.first != fwds.second ) { 1594 auto inst = fwds.first; 1595 do { 1596 // forward decl is stored *mutably* in map, can thus be updated 1597 inst->second->base = enumDecl; 1598 } while ( ++inst != fwds.second ); 1599 forwardEnums.erase( fwds.first, fwds.second ); 1600 } 1601 1602 // ensure that enumerator initializers are properly set 1603 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1604 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1605 if ( field->init ) { 1606 // need to resolve enumerator initializers early so that other passes that 1607 // determine if an expression is constexpr have appropriate information 1608 auto init = field->init.strict_as< ast::SingleInit >(); 1609 1610 enumDecl = ast::mutate_field_index( 1611 enumDecl, &ast::EnumDecl::members, i, 1612 ast::mutate_field( field, &ast::ObjectDecl::init, 1613 ast::mutate_field( init, &ast::SingleInit::value, 1614 ResolvExpr::findSingleExpression( 1615 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1616 symtab ) ) ) ); 1617 } 1618 } 1619 1620 return enumDecl; 1621 } 1622 1623 /// rename generic type parameters uniquely so that they do not conflict with user defined 1624 /// function forall parameters, e.g. the T in Box and the T in f, below 1625 /// forall(otype T) 1626 /// struct Box { 1627 /// T x; 1628 /// }; 1629 /// forall(otype T) 1630 /// void f(Box(T) b) { 1631 /// ... 1632 /// } 1633 template< typename AggrDecl > 1634 const AggrDecl * renameGenericParams( const AggrDecl * aggr ) { 1635 GuardValue( inGeneric ); 1636 inGeneric = ! aggr->params.empty(); 1637 1638 for ( unsigned i = 0; i < aggr->params.size(); ++i ) { 1639 const ast::TypeDecl * td = aggr->params[i]; 1640 1641 aggr = ast::mutate_field_index( 1642 aggr, &AggrDecl::params, i, 1643 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1644 } 1645 return aggr; 1646 } 1647 1648 const ast::StructDecl * previsit( const ast::StructDecl * structDecl ) { 1649 return renameGenericParams( structDecl ); 1650 } 1651 1652 void postvisit( const ast::StructDecl * structDecl ) { 1653 // visit struct members first so that the types of self-referencing members are 1654 // updated properly 1655 if ( ! structDecl->body ) return; 1656 1657 // update forward declarations to point here 1658 auto fwds = forwardStructs.equal_range( structDecl->name ); 1659 if ( fwds.first != fwds.second ) { 1660 auto inst = fwds.first; 1661 do { 1662 // forward decl is stored *mutably* in map, can thus be updated 1663 inst->second->base = structDecl; 1664 } while ( ++inst != fwds.second ); 1665 forwardStructs.erase( fwds.first, fwds.second ); 1666 } 1667 } 1668 1669 const ast::UnionDecl * previsit( const ast::UnionDecl * unionDecl ) { 1670 return renameGenericParams( unionDecl ); 1671 } 1672 1673 void postvisit( const ast::UnionDecl * unionDecl ) { 1674 // visit union members first so that the types of self-referencing members are updated 1675 // properly 1676 if ( ! unionDecl->body ) return; 1677 1678 // update forward declarations to point here 1679 auto fwds = forwardUnions.equal_range( unionDecl->name ); 1680 if ( fwds.first != fwds.second ) { 1681 auto inst = fwds.first; 1682 do { 1683 // forward decl is stored *mutably* in map, can thus be updated 1684 inst->second->base = unionDecl; 1685 } while ( ++inst != fwds.second ); 1686 forwardUnions.erase( fwds.first, fwds.second ); 1687 } 1688 } 1689 1690 const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) { 1691 // set the "sized" status for the special "sized" trait 1692 if ( traitDecl->name != "sized" ) return traitDecl; 1693 1694 assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect number " 1695 "of parameters: %zd", traitDecl->params.size() ); 1696 1697 return ast::mutate_field_index( 1698 traitDecl, &ast::TraitDecl::params, 0, 1699 ast::mutate_field( 1700 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1701 } 1439 1702 }; 1440 1703 … … 1446 1709 } // anonymous namespace 1447 1710 1448 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) { 1711 const ast::Type * validateType( 1712 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1449 1713 ast::Pass< EnumAndPointerDecay_new > epc; 1450 ast::Pass< LinkReferenceToTypes_new > lrt{ symtab };1714 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab }; 1451 1715 ast::Pass< ForallPointerDecay_new > fpd; 1452 1716 -
src/SymTab/Validate.h
r4d978d5 rb58affe7 19 19 #include <list> // for list 20 20 21 class CodeLocation; 21 22 class Declaration; 22 23 class Type; … … 34 35 void validateType( Type *type, const Indexer *indexer ); 35 36 36 const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ); 37 const ast::Type * validateType( 38 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ); 37 39 } // namespace SymTab 38 40
Note: See TracChangeset
for help on using the changeset viewer.