Changeset c1398e4


Ignore:
Timestamp:
Jun 24, 2019, 1:49:47 PM (2 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
08c0780
Parents:
c1ea11b
Message:

Port necessary parts of validate to new AST

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/AST/TypeSubstitution.hpp

    rc1ea11b rc1398e4  
    200200}
    201201
    202 /// Instantiate each member of the context given the actual parameters specified, and store the
    203 /// instantiations for use by the indexer
    204 template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
    205 void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
    206         TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
    207         for ( auto i = memberBegin; i != memberEnd; ++i ) {
    208                 sub.apply( *i );
    209                 *out++ = *i;
    210         } // for
    211 }
    212 
    213202} // namespace ast
    214203
  • src/SymTab/Validate.cc

    rc1ea11b rc1398e4  
    5353#include "AST/SymbolTable.hpp"
    5454#include "AST/Type.hpp"
     55#include "AST/TypeSubstitution.hpp"
    5556#include "CodeGen/CodeGenerator.h"     // for genName
    5657#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
     
    14301431        };
    14311432
     1433        /// expand assertions from a trait instance, performing appropriate type variable substitutions
     1434        void expandAssertions(
     1435                const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out
     1436        ) {
     1437                assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );
     1438
     1439                // build list of trait members, substituting trait decl parameters for instance parameters
     1440                ast::TypeSubstitution sub{
     1441                        inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };
     1442                // deliberately take ast::ptr by-value to ensure this does not mutate inst->base
     1443                for ( ast::ptr< ast::Decl > decl : inst->base->members ) {
     1444                        auto member = decl.strict_as< ast::DeclWithType >();
     1445                        sub.apply( member );
     1446                        out.emplace_back( member );
     1447                }
     1448        }
     1449
    14321450        /// Associates forward declarations of aggregates with their definitions
    14331451        class LinkReferenceToTypes_new final
     
    16901708                const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) {
    16911709                        // 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 ) );
     1710                        if ( traitDecl->name == "sized" ) {
     1711                                assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect "
     1712                                        "number of parameters: %zd", traitDecl->params.size() );
     1713
     1714                                traitDecl = ast::mutate_field_index(
     1715                                        traitDecl, &ast::TraitDecl::params, 0,
     1716                                        ast::mutate_field(
     1717                                                traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );
     1718                        }
     1719
     1720                        // move assertions from type parameters into the body of the trait
     1721                        std::vector< ast::ptr< ast::DeclWithType > > added;
     1722                        for ( const ast::TypeDecl * td : traitDecl->params ) {
     1723                                for ( const ast::DeclWithType * assn : td->assertions ) {
     1724                                        auto inst = dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
     1725                                        if ( inst ) {
     1726                                                expandAssertions( inst, added );
     1727                                        } else {
     1728                                                added.emplace_back( assn );
     1729                                        }
     1730                                }
     1731                        }
     1732                        if ( ! added.empty() ) {
     1733                                auto mut = mutate( traitDecl );
     1734                                for ( const ast::DeclWithType * decl : added ) {
     1735                                        mut->members.emplace_back( decl );
     1736                                }
     1737                                traitDecl = mut;
     1738                        }
     1739                       
     1740                        return traitDecl;
    17011741                }
    17021742        };
     
    17041744        /// Replaces array and function types in forall lists by appropriate pointer type and assigns
    17051745        /// each object and function declaration a unique ID
    1706         struct ForallPointerDecay_new {
    1707                 #warning incomplete
     1746        class ForallPointerDecay_new {
     1747                const CodeLocation & location;
     1748        public:
     1749                ForallPointerDecay_new( const CodeLocation & loc ) : location( loc ) {}
     1750
     1751                const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {
     1752                        // ensure that operator names only apply to functions or function pointers
     1753                        if (
     1754                                CodeGen::isOperator( obj->name )
     1755                                && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )
     1756                        ) {
     1757                                SemanticError( obj->location, toCString( "operator ", obj->name.c_str(), " is not "
     1758                                        "a function or function pointer." )  );
     1759                        }
     1760
     1761                        // ensure object has unique ID
     1762                        if ( obj->uniqueId ) return obj;
     1763                        auto mut = mutate( obj );
     1764                        mut->fixUniqueId();
     1765                        return mut;
     1766                }
     1767
     1768                const ast::FunctionDecl * previsit( const ast::FunctionDecl * func ) {
     1769                        // ensure function has unique ID
     1770                        if ( func->uniqueId ) return func;
     1771                        auto mut = mutate( func );
     1772                        mut->fixUniqueId();
     1773                        return mut;
     1774                }
     1775
     1776                /// Fix up assertions -- flattens assertion lists, removing all trait instances
     1777                template< typename node_t, typename parent_t >
     1778                static const node_t * forallFixer(
     1779                        const CodeLocation & loc, const node_t * node,
     1780                        ast::ParameterizedType::ForallList parent_t::* forallField
     1781                ) {
     1782                        for ( unsigned i = 0; i < (node->*forallField).size(); ++i ) {
     1783                                const ast::TypeDecl * type = (node->*forallField)[i];
     1784                                if ( type->assertions.empty() ) continue;
     1785
     1786                                std::vector< ast::ptr< ast::DeclWithType > > asserts;
     1787                                asserts.reserve( type->assertions.size() );
     1788
     1789                                // expand trait instances into their members
     1790                                for ( const ast::DeclWithType * assn : type->assertions ) {
     1791                                        auto traitInst =
     1792                                                dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
     1793                                        if ( traitInst ) {
     1794                                                // expand trait instance to all its members
     1795                                                expandAssertions( traitInst, asserts );
     1796                                        } else {
     1797                                                // pass other assertions through
     1798                                                asserts.emplace_back( assn );
     1799                                        }
     1800                                }
     1801
     1802                                // apply FixFunction to every assertion to check for invalid void type
     1803                                for ( ast::ptr< ast::DeclWithType > & assn : asserts ) {
     1804                                        bool isVoid = false;
     1805                                        assn = fixFunction( assn, isVoid );
     1806                                        if ( isVoid ) {
     1807                                                SemanticError( loc, node, "invalid type void in assertion of function " );
     1808                                        }
     1809                                }
     1810
     1811                                // place mutated assertion list in node
     1812                                auto mut = mutate( type );
     1813                                mut->assertions = move( asserts );
     1814                                node = ast::mutate_field_index( node, forallField, i, mut );
     1815                        }
     1816                        return node;
     1817                }
     1818
     1819                const ast::FunctionType * previsit( const ast::FunctionType * ftype ) {
     1820                        return forallFixer( location, ftype, &ast::FunctionType::forall );
     1821                }
     1822
     1823                const ast::StructDecl * previsit( const ast::StructDecl * aggrDecl ) {
     1824                        return forallFixer( aggrDecl->location, aggrDecl, &ast::StructDecl::params );
     1825                }
     1826
     1827                const ast::UnionDecl * previsit( const ast::UnionDecl * aggrDecl ) {
     1828                        return forallFixer( aggrDecl->location, aggrDecl, &ast::UnionDecl::params );
     1829                }
    17081830        };
    17091831} // anonymous namespace
     
    17131835        ast::Pass< EnumAndPointerDecay_new > epc;
    17141836        ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
    1715         ast::Pass< ForallPointerDecay_new > fpd;
     1837        ast::Pass< ForallPointerDecay_new > fpd{ loc };
    17161838
    17171839        return type->accept( epc )->accept( lrt )->accept( fpd );
Note: See TracChangeset for help on using the changeset viewer.