Changes in / [c1ea11b:9e0a360]


Ignore:
Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Node.hpp

    rc1ea11b r9e0a360  
    100100
    101101/// Mutate a node field (only clones if not equal to existing value)
    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 ) {
     102template<typename node_t, typename field_t, typename assn_t>
     103const node_t * mutate_field( const node_t * node, field_t node_t::* field, assn_t && val ) {
    104104        // skip mutate if equivalent
    105105        if ( node->*field == val ) return node;
     
    112112
    113113/// Mutate a single index of a node field (only clones if not equal to existing value)
    114 template<typename node_t, typename parent_t, typename coll_t, typename ind_t, typename field_t>
     114template<typename node_t, typename coll_t, typename ind_t, typename field_t>
    115115const node_t * mutate_field_index(
    116         const node_t * node, coll_t parent_t::* field, ind_t i, field_t && val
     116        const node_t * node, coll_t node_t::* field, ind_t i, field_t && val
    117117) {
    118118        // skip mutate if equivalent
  • src/ResolvExpr/CandidateFinder.cpp

    rc1ea11b r9e0a360  
    10031003                        assert( toType );
    10041004                        toType = resolveTypeof( toType, symtab );
    1005                         toType = SymTab::validateType( castExpr->location, toType, symtab );
     1005                        toType = SymTab::validateType( toType, symtab );
    10061006                        toType = adjustExprType( toType, tenv, symtab );
    10071007
     
    14101410                                // calculate target type
    14111411                                const ast::Type * toType = resolveTypeof( initAlt.type, symtab );
    1412                                 toType = SymTab::validateType( initExpr->location, toType, symtab );
     1412                                toType = SymTab::validateType( toType, symtab );
    14131413                                toType = adjustExprType( toType, tenv, symtab );
    14141414                                // The call to find must occur inside this loop, otherwise polymorphic return
  • src/ResolvExpr/Resolver.cc

    rc1ea11b r9e0a360  
    11541154                        return findKindExpression( untyped, symtab );
    11551155                }
    1156         } // anonymous namespace
    1157 
     1156
     1157                /// Resolve `untyped` to the single expression whose candidate is the best match for the
     1158                /// given type.
    11581159                ast::ptr< ast::Expr > findSingleExpression(
    11591160                        const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
     
    11661167                }
    11671168
    1168         namespace {
    11691169                /// Predicate for "Candidate has integral type"
    11701170                bool hasIntegralType( const Candidate & i ) {
  • src/ResolvExpr/Resolver.h

    rc1ea11b r9e0a360  
    3535        class StmtExpr;
    3636        class SymbolTable;
    37         class Type;
    3837        class TypeEnvironment;
    3938} // namespace ast
     
    6261        ast::ptr< ast::Expr > resolveInVoidContext(
    6362                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 );
    6863        /// Resolves a constructor init expression
    6964        ast::ptr< ast::Init > resolveCtorInit(
  • src/SymTab/Validate.cc

    rc1ea11b r9e0a360  
    4444#include <list>                        // for list
    4545#include <string>                      // for string
    46 #include <unordered_map>               // for unordered_map
    4746#include <utility>                     // for pair
    4847
    49 #include "AST/Chain.hpp"
    5048#include "AST/Decl.hpp"
    5149#include "AST/Node.hpp"
     
    5654#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5755#include "ControlStruct/Mutate.h"      // for ForExprMutator
    58 #include "Common/CodeLocation.h"       // for CodeLocation
    5956#include "Common/Stats.h"              // for Stats::Heap
    6057#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
     
    14311428
    14321429        /// Associates forward declarations of aggregates with their definitions
    1433         class LinkReferenceToTypes_new final
     1430        struct LinkReferenceToTypes_new final
    14341431        : public ast::WithSymbolTable, public ast::WithGuards, public
    14351432          ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
    14361433               
    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                 }
     1434                const ast::SymbolTable * localSyms;
     1435
     1436                LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {}
     1437
     1438                #warning incomplete
    17021439        };
    17031440
     
    17091446} // anonymous namespace
    17101447
    1711 const ast::Type * validateType(
    1712                 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
     1448const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
    17131449        ast::Pass< EnumAndPointerDecay_new > epc;
    1714         ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
     1450        ast::Pass< LinkReferenceToTypes_new > lrt{ symtab };
    17151451        ast::Pass< ForallPointerDecay_new > fpd;
    17161452
  • src/SymTab/Validate.h

    rc1ea11b r9e0a360  
    1919#include <list>  // for list
    2020
    21 class CodeLocation;
    2221class Declaration;
    2322class Type;
     
    3534        void validateType( Type *type, const Indexer *indexer );
    3635
    37         const ast::Type * validateType(
    38                 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab );
     36        const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab );
    3937} // namespace SymTab
    4038
Note: See TracChangeset for help on using the changeset viewer.