Changes in / [67130fe:c6a1e8a]


Ignore:
Location:
src
Files:
5 added
23 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Bitfield.hpp

    r67130fe rc6a1e8a  
    99// Author           : Aaron B. Moss
    1010// Created On       : Thu May 9 10:00:00 2019
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Thu May 9 10:00:00 2019
    13 // Update Count     : 1
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 5 10:00:00 2019
     13// Update Count     : 2
    1414//
    1515
    1616#pragma once
    1717
    18 #include <strings.h>  // for ffs
     18#include <strings.h>   // for ffs
     19#include <type_traits> // for is_unsigned
    1920
    2021/// Make a type a bitfield.
     
    2425template<typename T>
    2526struct bitfield : public T {
    26         static_assert(sizeof(T) == sizeof(unsigned int), "Type has incorrect size");
    2727        using T::val;
    2828        using val_t = decltype(val);
     29        static_assert(sizeof(T) == sizeof(unsigned int), "Type has incorrect size");
     30        static_assert(std::is_unsigned<val_t>::value, "Bitfield val field is not unsigned.");
    2931
    3032        constexpr bitfield() : T( 0 ) {}
  • src/AST/Convert.cpp

    r67130fe rc6a1e8a  
    749749                        break;
    750750                case ast::ConstantExpr::String:
    751                         rslt = new ConstantExpr{Constant::from_string( node->rep )};
     751                        rslt = new ConstantExpr{Constant{
     752                                get<Type>().accept1( node->result ),
     753                                node->rep,
     754                                (long long unsigned int)0
     755                        }};
    752756                        break;
    753757                }
     
    21502154                                GET_ACCEPT_1(result, Type),
    21512155                                old->constant.get_value(),
    2152                                 (unsigned long long) old->intValue()
     2156                                (unsigned long long) old->intValue(),
     2157                                ast::ConstantExpr::Kind::Integer
    21532158                        );
    21542159                } else if (isFloatlikeConstantType(old->result)) {
     
    21602165                        );
    21612166                } else if (isStringlikeConstantType(old->result)) {
    2162                         rslt = ast::ConstantExpr::from_string(
    2163                                 old->location,
    2164                                 old->constant.get_value()
     2167                        rslt = new ast::ConstantExpr(
     2168                                old->location,
     2169                                GET_ACCEPT_1(result, Type),
     2170                                old->constant.get_value(),
     2171                                0,
     2172                                ast::ConstantExpr::Kind::String
    21652173                        );
    21662174                }
  • src/AST/Decl.hpp

    r67130fe rc6a1e8a  
    103103
    104104        ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
    105                 Init * init = nullptr, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    106                 Expr * bitWd = nullptr, std::vector< ptr<Attribute> > && attrs = {},
    107                 Function::Specs fs = {} )
     105                const Init * init = nullptr, Storage::Classes storage = {},
     106                Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,
     107                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
    108108        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
    109109          init( init ), bitfieldWidth( bitWd ) {}
  • src/AST/Node.cpp

    r67130fe rc6a1e8a  
    3434template< typename node_t, enum ast::Node::ref_type ref_t >
    3535void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node ) { node->decrement(ref_t); }
     36
     37template< typename node_t, enum ast::Node::ref_type ref_t >
     38void ast::ptr_base<node_t, ref_t>::_check() const { if(node) assert(node->was_ever_strong == false || node->strong_count > 0); }
    3639
    3740template< typename node_t, enum ast::Node::ref_type ref_t >
  • src/AST/Node.hpp

    r67130fe rc6a1e8a  
    4646        };
    4747
     48        bool unique() const { return strong_count == 1; }
     49
    4850private:
    4951        /// Make a copy of this node; should be overridden in subclass with more precise return type
     
    5658        mutable size_t strong_count = 0;
    5759        mutable size_t weak_count = 0;
     60        mutable bool was_ever_strong = false;
    5861
    5962        void increment(ref_type ref) const {
    6063                switch (ref) {
    61                         case ref_type::strong: strong_count++; break;
     64                        case ref_type::strong: strong_count++; was_ever_strong = true; break;
    6265                        case ref_type::weak  : weak_count  ++; break;
    6366                }
     
    176179        }
    177180
    178         const node_t * get() const { return  node; }
    179         const node_t * operator->() const { return  node; }
    180         const node_t & operator* () const { return *node; }
    181         explicit operator bool() const { return node; }
    182         operator const node_t * () const { return node; }
     181        const node_t * get() const { _check(); return  node; }
     182        const node_t * operator->() const { _check(); return  node; }
     183        const node_t & operator* () const { _check(); return *node; }
     184        explicit operator bool() const { _check(); return node; }
     185        operator const node_t * () const { _check(); return node; }
    183186
    184187        /// wrapper for convenient access to dynamic_cast
    185188        template<typename o_node_t>
    186         const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); }
     189        const o_node_t * as() const { _check(); return dynamic_cast<const o_node_t *>(node); }
    187190
    188191        /// wrapper for convenient access to strict_dynamic_cast
     
    208211        void _inc( const node_t * other );
    209212        void _dec( const node_t * other );
     213        void _check() const;
    210214
    211215protected:
  • src/AST/Pass.hpp

    r67130fe rc6a1e8a  
    3333#include "AST/Visitor.hpp"
    3434
    35 #include "SymTab/Indexer.h"
     35#include "AST/SymbolTable.hpp"
    3636
    3737// Private prelude header, needed for some of the magic tricks this class pulls off
     
    6161//                          postvisit/postmutate teminates.
    6262// | WithVisitorRef       - provides an pointer to the templated visitor wrapper
    63 // | WithIndexer          - provides indexer functionality (i.e. up-to-date symbol table)
     63// | WithSymbolTable      - provides symbol table functionality
    6464//-------------------------------------------------------------------------------------------------
    6565template< typename pass_t >
     
    206206
    207207private:
    208         /// Internal RAII guard for indexer features
    209         struct guard_indexer {
    210                 guard_indexer( Pass<pass_t> & pass ): pass( pass ) { __pass::indexer::enter(pass, 0); }
    211                 ~guard_indexer()                                   { __pass::indexer::leave(pass, 0); }
     208        /// Internal RAII guard for symbol table features
     209        struct guard_symtab {
     210                guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass, 0); }
     211                ~guard_symtab()                                   { __pass::symtab::leave(pass, 0); }
    212212                Pass<pass_t> & pass;
    213213        };
     
    294294};
    295295
    296 /// Use when the templated visitor should update the indexer
    297 struct WithIndexer {
    298         SymTab::Indexer indexer;
     296/// Use when the templated visitor should update the symbol table
     297struct WithSymbolTable {
     298        SymbolTable symtab;
    299299};
    300300}
  • src/AST/Pass.impl.hpp

    r67130fe rc6a1e8a  
    398398        VISIT(
    399399                {
    400                         guard_indexer guard { *this };
     400                        guard_symtab guard { *this };
    401401                        maybe_accept( node, &ObjectDecl::type );
    402402                }
     
    406406        )
    407407
    408         __pass::indexer::addId( pass, 0, node );
     408        __pass::symtab::addId( pass, 0, node );
    409409
    410410        VISIT_END( DeclWithType, node );
     
    417417        VISIT_START( node );
    418418
    419         __pass::indexer::addId( pass, 0, node );
     419        __pass::symtab::addId( pass, 0, node );
    420420
    421421        VISIT(maybe_accept( node, &FunctionDecl::withExprs );)
    422422        {
    423423                // with clause introduces a level of scope (for the with expression members).
    424                 // with clause exprs are added to the indexer before parameters so that parameters
     424                // with clause exprs are added to the symbol table before parameters so that parameters
    425425                // shadow with exprs and not the other way around.
    426                 guard_indexer guard { *this };
    427                 __pass::indexer::addWith( pass, 0, node->withExprs, node );
     426                guard_symtab guard { *this };
     427                __pass::symtab::addWith( pass, 0, node->withExprs, node );
    428428                {
    429                         guard_indexer guard { *this };
     429                        guard_symtab guard { *this };
    430430                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
    431431                        static ast::ObjectDecl func(
     
    436436                                )
    437437                        );
    438                         __pass::indexer::addId( pass, 0, &func );
     438                        __pass::symtab::addId( pass, 0, &func );
    439439                        VISIT(
    440440                                maybe_accept( node, &FunctionDecl::type );
     
    460460        // make up a forward declaration and add it before processing the members
    461461        // needs to be on the heap because addStruct saves the pointer
    462         __pass::indexer::addStructFwd( pass, 0, node );
    463 
    464         VISIT({
    465                 guard_indexer guard { * this };
     462        __pass::symtab::addStructFwd( pass, 0, node );
     463
     464        VISIT({
     465                guard_symtab guard { * this };
    466466                maybe_accept( node, &StructDecl::params  );
    467467                maybe_accept( node, &StructDecl::members );
     
    469469
    470470        // this addition replaces the forward declaration
    471         __pass::indexer::addStruct( pass, 0, node );
     471        __pass::symtab::addStruct( pass, 0, node );
    472472
    473473        VISIT_END( Decl, node );
     
    481481
    482482        // make up a forward declaration and add it before processing the members
    483         __pass::indexer::addUnionFwd( pass, 0, node );
    484 
    485         VISIT({
    486                 guard_indexer guard { * this };
     483        __pass::symtab::addUnionFwd( pass, 0, node );
     484
     485        VISIT({
     486                guard_symtab guard { * this };
    487487                maybe_accept( node, &UnionDecl::params  );
    488488                maybe_accept( node, &UnionDecl::members );
    489489        })
    490490
    491         __pass::indexer::addUnion( pass, 0, node );
     491        __pass::symtab::addUnion( pass, 0, node );
    492492
    493493        VISIT_END( Decl, node );
     
    500500        VISIT_START( node );
    501501
    502         __pass::indexer::addEnum( pass, 0, node );
     502        __pass::symtab::addEnum( pass, 0, node );
    503503
    504504        VISIT(
     
    518518
    519519        VISIT({
    520                 guard_indexer guard { *this };
     520                guard_symtab guard { *this };
    521521                maybe_accept( node, &TraitDecl::params  );
    522522                maybe_accept( node, &TraitDecl::members );
    523523        })
    524524
    525         __pass::indexer::addTrait( pass, 0, node );
     525        __pass::symtab::addTrait( pass, 0, node );
    526526
    527527        VISIT_END( Decl, node );
     
    535535
    536536        VISIT({
    537                 guard_indexer guard { *this };
     537                guard_symtab guard { *this };
    538538                maybe_accept( node, &TypeDecl::params );
    539539                maybe_accept( node, &TypeDecl::base   );
     
    543543        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
    544544        // and may depend on the type itself
    545         __pass::indexer::addType( pass, 0, node );
     545        __pass::symtab::addType( pass, 0, node );
    546546
    547547        VISIT(
     
    549549
    550550                {
    551                         guard_indexer guard { *this };
     551                        guard_symtab guard { *this };
    552552                        maybe_accept( node, &TypeDecl::init );
    553553                }
     
    564564
    565565        VISIT({
    566                 guard_indexer guard { *this };
     566                guard_symtab guard { *this };
    567567                maybe_accept( node, &TypedefDecl::params );
    568568                maybe_accept( node, &TypedefDecl::base   );
    569569        })
    570570
    571         __pass::indexer::addType( pass, 0, node );
     571        __pass::symtab::addType( pass, 0, node );
    572572
    573573        VISIT( maybe_accept( node, &TypedefDecl::assertions ); )
     
    611611                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
    612612                auto guard1 = makeFuncGuard( [this, inFunction = this->inFunction]() {
    613                         if ( ! inFunction ) __pass::indexer::enter(pass, 0);
     613                        if ( ! inFunction ) __pass::symtab::enter(pass, 0);
    614614                }, [this, inFunction = this->inFunction]() {
    615                         if ( ! inFunction ) __pass::indexer::leave(pass, 0);
     615                        if ( ! inFunction ) __pass::symtab::leave(pass, 0);
    616616                });
    617617                ValueGuard< bool > guard2( inFunction );
     
    669669        VISIT({
    670670                // if statements introduce a level of scope (for the initialization)
    671                 guard_indexer guard { *this };
     671                guard_symtab guard { *this };
    672672                maybe_accept( node, &IfStmt::inits    );
    673673                maybe_accept( node, &IfStmt::cond     );
     
    687687        VISIT({
    688688                // while statements introduce a level of scope (for the initialization)
    689                 guard_indexer guard { *this };
     689                guard_symtab guard { *this };
    690690                maybe_accept( node, &WhileStmt::inits );
    691691                maybe_accept( node, &WhileStmt::cond  );
     
    704704        VISIT({
    705705                // for statements introduce a level of scope (for the initialization)
    706                 guard_indexer guard { *this };
     706                guard_symtab guard { *this };
    707707                maybe_accept( node, &ForStmt::inits );
    708708                maybe_accept( node, &ForStmt::cond  );
     
    800800        VISIT({
    801801                // catch statements introduce a level of scope (for the caught exception)
    802                 guard_indexer guard { *this };
     802                guard_symtab guard { *this };
    803803                maybe_accept( node, &CatchStmt::decl );
    804804                maybe_accept( node, &CatchStmt::cond );
     
    901901                {
    902902                        // catch statements introduce a level of scope (for the caught exception)
    903                         guard_indexer guard { *this };
    904                         __pass::indexer::addWith( pass, 0, node->exprs, node );
     903                        guard_symtab guard { *this };
     904                        __pass::symtab::addWith( pass, 0, node->exprs, node );
    905905                        maybe_accept( node, &WithStmt::stmt );
    906906                }
     
    953953        VISIT(
    954954                {
    955                         guard_indexer guard { *this };
     955                        guard_symtab guard { *this };
    956956                        maybe_accept( node, &ApplicationExpr::result );
    957957                }
     
    971971        VISIT(
    972972                {
    973                         guard_indexer guard { *this };
     973                        guard_symtab guard { *this };
    974974                        maybe_accept( node, &UntypedExpr::result );
    975975                }
     
    988988
    989989        VISIT({
    990                 guard_indexer guard { *this };
     990                guard_symtab guard { *this };
    991991                maybe_accept( node, &NameExpr::result );
    992992        })
     
    10021002
    10031003        VISIT({
    1004                         guard_indexer guard { *this };
     1004                        guard_symtab guard { *this };
    10051005                        maybe_accept( node, &CastExpr::result );
    10061006                }
     
    10181018
    10191019        VISIT({
    1020                         guard_indexer guard { *this };
     1020                        guard_symtab guard { *this };
    10211021                        maybe_accept( node, &KeywordCastExpr::result );
    10221022                }
     
    10341034
    10351035        VISIT({
    1036                         guard_indexer guard { *this };
     1036                        guard_symtab guard { *this };
    10371037                        maybe_accept( node, &VirtualCastExpr::result );
    10381038                }
     
    10501050
    10511051        VISIT({
    1052                         guard_indexer guard { *this };
     1052                        guard_symtab guard { *this };
    10531053                        maybe_accept( node, &AddressExpr::result );
    10541054                }
     
    10661066
    10671067        VISIT({
    1068                 guard_indexer guard { *this };
     1068                guard_symtab guard { *this };
    10691069                maybe_accept( node, &LabelAddressExpr::result );
    10701070        })
     
    10801080
    10811081        VISIT({
    1082                         guard_indexer guard { *this };
     1082                        guard_symtab guard { *this };
    10831083                        maybe_accept( node, &UntypedMemberExpr::result );
    10841084                }
     
    10971097
    10981098        VISIT({
    1099                         guard_indexer guard { *this };
     1099                        guard_symtab guard { *this };
    11001100                        maybe_accept( node, &MemberExpr::result );
    11011101                }
     
    11131113
    11141114        VISIT({
    1115                 guard_indexer guard { *this };
     1115                guard_symtab guard { *this };
    11161116                maybe_accept( node, &VariableExpr::result );
    11171117        })
     
    11271127
    11281128        VISIT({
    1129                 guard_indexer guard { *this };
     1129                guard_symtab guard { *this };
    11301130                maybe_accept( node, &ConstantExpr::result );
    11311131        })
     
    11411141
    11421142        VISIT({
    1143                         guard_indexer guard { *this };
     1143                        guard_symtab guard { *this };
    11441144                        maybe_accept( node, &SizeofExpr::result );
    11451145                }
     
    11611161
    11621162        VISIT({
    1163                         guard_indexer guard { *this };
     1163                        guard_symtab guard { *this };
    11641164                        maybe_accept( node, &AlignofExpr::result );
    11651165                }
     
    11811181
    11821182        VISIT({
    1183                         guard_indexer guard { *this };
     1183                        guard_symtab guard { *this };
    11841184                        maybe_accept( node, &UntypedOffsetofExpr::result );
    11851185                }
     
    11971197
    11981198        VISIT({
    1199                         guard_indexer guard { *this };
     1199                        guard_symtab guard { *this };
    12001200                        maybe_accept( node, &OffsetofExpr::result );
    12011201                }
     
    12131213
    12141214        VISIT({
    1215                         guard_indexer guard { *this };
     1215                        guard_symtab guard { *this };
    12161216                        maybe_accept( node, &OffsetPackExpr::result );
    12171217                }
     
    12291229
    12301230        VISIT({
    1231                         guard_indexer guard { *this };
     1231                        guard_symtab guard { *this };
    12321232                        maybe_accept( node, &LogicalExpr::result );
    12331233                }
     
    12461246
    12471247        VISIT({
    1248                         guard_indexer guard { *this };
     1248                        guard_symtab guard { *this };
    12491249                        maybe_accept( node, &ConditionalExpr::result );
    12501250                }
     
    12641264
    12651265        VISIT({
    1266                         guard_indexer guard { *this };
     1266                        guard_symtab guard { *this };
    12671267                        maybe_accept( node, &CommaExpr::result );
    12681268                }
     
    12811281
    12821282        VISIT({
    1283                         guard_indexer guard { *this };
     1283                        guard_symtab guard { *this };
    12841284                        maybe_accept( node, &TypeExpr::result );
    12851285                }
     
    12971297
    12981298        VISIT({
    1299                         guard_indexer guard { *this };
     1299                        guard_symtab guard { *this };
    13001300                        maybe_accept( node, &AsmExpr::result );
    13011301                }
     
    13151315
    13161316        VISIT({
    1317                         guard_indexer guard { *this };
     1317                        guard_symtab guard { *this };
    13181318                        maybe_accept( node, &ImplicitCopyCtorExpr::result );
    13191319                }
     
    13311331
    13321332        VISIT({
    1333                         guard_indexer guard { *this };
     1333                        guard_symtab guard { *this };
    13341334                        maybe_accept( node, &ConstructorExpr::result );
    13351335                }
     
    13471347
    13481348        VISIT({
    1349                         guard_indexer guard { *this };
     1349                        guard_symtab guard { *this };
    13501350                        maybe_accept( node, &CompoundLiteralExpr::result );
    13511351                }
     
    13631363
    13641364        VISIT({
    1365                         guard_indexer guard { *this };
     1365                        guard_symtab guard { *this };
    13661366                        maybe_accept( node, &RangeExpr::result );
    13671367                }
     
    13801380
    13811381        VISIT({
    1382                         guard_indexer guard { *this };
     1382                        guard_symtab guard { *this };
    13831383                        maybe_accept( node, &UntypedTupleExpr::result );
    13841384                }
     
    13961396
    13971397        VISIT({
    1398                         guard_indexer guard { *this };
     1398                        guard_symtab guard { *this };
    13991399                        maybe_accept( node, &TupleExpr::result );
    14001400                }
     
    14121412
    14131413        VISIT({
    1414                         guard_indexer guard { *this };
     1414                        guard_symtab guard { *this };
    14151415                        maybe_accept( node, &TupleIndexExpr::result );
    14161416                }
     
    14281428
    14291429        VISIT({
    1430                         guard_indexer guard { *this };
     1430                        guard_symtab guard { *this };
    14311431                        maybe_accept( node, &TupleAssignExpr::result );
    14321432                }
     
    14541454
    14551455                {
    1456                         guard_indexer guard { *this };
     1456                        guard_symtab guard { *this };
    14571457                        maybe_accept( node, &StmtExpr::result );
    14581458                }
     
    14721472
    14731473        VISIT({
    1474                         guard_indexer guard { *this };
     1474                        guard_symtab guard { *this };
    14751475                        maybe_accept( node, &UniqueExpr::result );
    14761476                }
     
    14881488
    14891489        VISIT({
    1490                         guard_indexer guard { *this };
     1490                        guard_symtab guard { *this };
    14911491                        maybe_accept( node, &UntypedInitExpr::result );
    14921492                }
     
    15051505
    15061506        VISIT({
    1507                         guard_indexer guard { *this };
     1507                        guard_symtab guard { *this };
    15081508                        maybe_accept( node, &InitExpr::result );
    15091509                }
     
    15221522
    15231523        VISIT({
    1524                         guard_indexer guard { *this };
     1524                        guard_symtab guard { *this };
    15251525                        maybe_accept( node, &DeletedExpr::result );
    15261526                }
     
    15391539
    15401540        VISIT({
    1541                         guard_indexer guard { *this };
     1541                        guard_symtab guard { *this };
    15421542                        maybe_accept( node, &DefaultArgExpr::result );
    15431543                }
     
    15551555
    15561556        VISIT({
    1557                         guard_indexer guard { *this };
     1557                        guard_symtab guard { *this };
    15581558                        maybe_accept( node, &GenericExpr::result );
    15591559                }
     
    15661566                        const Type * type = nullptr;
    15671567                        if( assoc.type ) {
    1568                                 guard_indexer guard { *this };
     1568                                guard_symtab guard { *this };
    15691569                                type = assoc.type->accept( *this );
    15701570                                if( type != assoc.type ) mutated = true;
     
    16821682        VISIT_START( node );
    16831683
    1684         __pass::indexer::addStruct( pass, 0, node->name );
    1685 
    1686         VISIT({
    1687                 guard_indexer guard { *this };
     1684        __pass::symtab::addStruct( pass, 0, node->name );
     1685
     1686        VISIT({
     1687                guard_symtab guard { *this };
    16881688                maybe_accept( node, &StructInstType::forall );
    16891689                maybe_accept( node, &StructInstType::params );
     
    16991699        VISIT_START( node );
    17001700
    1701         __pass::indexer::addStruct( pass, 0, node->name );
     1701        __pass::symtab::addStruct( pass, 0, node->name );
    17021702
    17031703        {
    1704                 guard_indexer guard { *this };
     1704                guard_symtab guard { *this };
    17051705                maybe_accept( node, &UnionInstType::forall );
    17061706                maybe_accept( node, &UnionInstType::params );
     
    18931893                        std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
    18941894                        for ( const auto & p : node->typeEnv ) {
    1895                                 guard_indexer guard { *this };
     1895                                guard_symtab guard { *this };
    18961896                                auto new_node = p.second->accept( *this );
    18971897                                if (new_node != p.second) mutated = false;
     
    19091909                        std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
    19101910                        for ( const auto & p : node->varEnv ) {
    1911                                 guard_indexer guard { *this };
     1911                                guard_symtab guard { *this };
    19121912                                auto new_node = p.second->accept( *this );
    19131913                                if (new_node != p.second) mutated = false;
  • src/AST/Pass.proto.hpp

    r67130fe rc6a1e8a  
    265265        };
    266266
    267         // Finally certain pass desire an up to date indexer automatically
    268         // detect the presence of a member name indexer and call all the members appropriately
    269         namespace indexer {
     267        // Finally certain pass desire an up to date symbol table automatically
     268        // detect the presence of a member name `symtab` and call all the members appropriately
     269        namespace symtab {
    270270                // Some simple scoping rules
    271271                template<typename pass_t>
    272                 static inline auto enter( pass_t & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) {
    273                         pass.indexer.enterScope();
     272                static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab.enterScope(), void() ) {
     273                        pass.symtab.enterScope();
    274274                }
    275275
     
    278278
    279279                template<typename pass_t>
    280                 static inline auto leave( pass_t & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) {
    281                         pass.indexer.leaveScope();
     280                static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab.leaveScope(), void() ) {
     281                        pass.symtab.leaveScope();
    282282                }
    283283
     
    285285                static inline auto leave( pass_t &, long ) {}
    286286
    287                 // The indexer has 2 kind of functions mostly, 1 argument and 2 arguments
     287                // The symbol table has 2 kind of functions mostly, 1 argument and 2 arguments
    288288                // Create macro to condense these common patterns
    289                 #define INDEXER_FUNC1( func, type ) \
     289                #define SYMTAB_FUNC1( func, type ) \
    290290                template<typename pass_t> \
    291                 static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {\
    292                         pass.indexer.func( arg ); \
     291                static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.symtab.func( arg ), void() ) {\
     292                        pass.symtab.func( arg ); \
    293293                } \
    294294                \
     
    296296                static inline void func( pass_t &, long, type ) {}
    297297
    298                 #define INDEXER_FUNC2( func, type1, type2 ) \
     298                #define SYMTAB_FUNC2( func, type1, type2 ) \
    299299                template<typename pass_t> \
    300                 static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void () ) {\
    301                         pass.indexer.func( arg1, arg2 ); \
     300                static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.symtab.func( arg1, arg2 ), void () ) {\
     301                        pass.symtab.func( arg1, arg2 ); \
    302302                } \
    303303                        \
     
    305305                static inline void func( pass_t &, long, type1, type2 ) {}
    306306
    307                 INDEXER_FUNC1( addId     , const DeclWithType *  );
    308                 INDEXER_FUNC1( addType   , const NamedTypeDecl * );
    309                 INDEXER_FUNC1( addStruct , const StructDecl *    );
    310                 INDEXER_FUNC1( addEnum   , const EnumDecl *      );
    311                 INDEXER_FUNC1( addUnion  , const UnionDecl *     );
    312                 INDEXER_FUNC1( addTrait  , const TraitDecl *     );
    313                 INDEXER_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
     307                SYMTAB_FUNC1( addId     , const DeclWithType *  );
     308                SYMTAB_FUNC1( addType   , const NamedTypeDecl * );
     309                SYMTAB_FUNC1( addStruct , const StructDecl *    );
     310                SYMTAB_FUNC1( addEnum   , const EnumDecl *      );
     311                SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
     312                SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
     313                SYMTAB_FUNC2( addWith   , const std::vector< ptr<Expr> > &, const Node * );
    314314
    315315                // A few extra functions have more complicated behaviour, they are hand written
    316316                template<typename pass_t>
    317                 static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
     317                static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.symtab.addStruct( decl ), void() ) {
    318318                        ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name );
    319319                        fwd->params = decl->params;
    320                         pass.indexer.addStruct( fwd );
     320                        pass.symtab.addStruct( fwd );
    321321                }
    322322
     
    325325
    326326                template<typename pass_t>
    327                 static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
     327                static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass.symtab.addUnion( decl ), void() ) {
    328328                        UnionDecl * fwd = new UnionDecl( decl->location, decl->name );
    329329                        fwd->params = decl->params;
    330                         pass.indexer.addUnion( fwd );
     330                        pass.symtab.addUnion( fwd );
    331331                }
    332332
     
    335335
    336336                template<typename pass_t>
    337                 static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) {
    338                         if ( ! pass.indexer.lookupStruct( str ) ) {
    339                                 pass.indexer.addStruct( str );
     337                static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.symtab.addStruct( str ), void() ) {
     338                        if ( ! pass.symtab.lookupStruct( str ) ) {
     339                                pass.symtab.addStruct( str );
    340340                        }
    341341                }
     
    345345
    346346                template<typename pass_t>
    347                 static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
    348                         if ( ! pass.indexer.lookupUnion( str ) ) {
    349                                 pass.indexer.addUnion( str );
     347                static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.symtab.addUnion( str ), void() ) {
     348                        if ( ! pass.symtab.lookupUnion( str ) ) {
     349                                pass.symtab.addUnion( str );
    350350                        }
    351351                }
     
    354354                static inline void addUnion( pass_t &, long, const std::string & ) {}
    355355
    356                 #undef INDEXER_FUNC1
    357                 #undef INDEXER_FUNC2
     356                #undef SYMTAB_FUNC1
     357                #undef SYMTAB_FUNC2
    358358        };
    359359};
  • src/AST/Print.hpp

    r67130fe rc6a1e8a  
    2929void print( std::ostream & os, const ast::Node * node, Indenter indent = {} );
    3030
    31 /// Wrap any standard format printer (matching above) with integer Indenter constructor
    32 template<typename T>
    33 inline void print( std::ostream & os, T && x, unsigned int indent ) {
    34     print( os, std::forward<T>(x), Indenter{ Indenter::tabsize, indent });
    35 }
    36 
    3731/// Print a declaration in its short form
    3832void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} );
    3933
    4034inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) {
    41     printShort( os, node, Indenter{ Indenter::tabsize, indent } );
     35    printShort( os, node, Indenter{ indent } );
    4236}
    4337
  • src/AST/SymbolTable.hpp

    r67130fe rc6a1e8a  
    8585
    8686public:
    87         explicit SymbolTable();
     87        SymbolTable();
    8888        ~SymbolTable();
    8989
     
    123123        void addType( const NamedTypeDecl * decl );
    124124        /// Adds a struct declaration to the symbol table by name
    125         void addStruct( const std::string &id );
     125        void addStruct( const std::string & id );
    126126        /// Adds a struct declaration to the symbol table
    127127        void addStruct( const StructDecl * decl );
    128128        /// Adds an enum declaration to the symbol table
    129         void addEnum( const EnumDecl *decl );
     129        void addEnum( const EnumDecl * decl );
    130130        /// Adds a union declaration to the symbol table by name
    131         void addUnion( const std::string &id );
     131        void addUnion( const std::string & id );
    132132        /// Adds a union declaration to the symbol table
    133133        void addUnion( const UnionDecl * decl );
  • src/AST/porting.md

    r67130fe rc6a1e8a  
    109109    * `SymTab::Indexer` => `ast::SymbolTable`
    110110    * `SymTab/Indexer.{h,cc}` => `AST/SymbolTable.{hpp,cpp}`
    111     * **TODO** `WithIndexer` => `WithSymbolTable`
     111    * `WithIndexer` => `WithSymbolTable`
    112112      * `indexer` => `symTab`
    113113    * `IdData::deleteStmt` => `IdData::deleter`
    114114    * `lookupId()` now returns a vector rather than an out-param list
    115     * To avoid name collisions:
    116       * `SymTab::Mangler` => `Mangle`
     115  * To avoid name collisions:
     116    * `SymTab::Mangler` => `Mangle`
    117117  * `ResolvExpr::TypeEnvironment` => `ast::TypeEnvironment`
    118118    * in `AST/TypeEnvironment.hpp`
     
    295295* changed `WidenMode widenMode` => `WidenMode widen`
    296296
     297`Alternative` => `Candidate`
     298* `openVars` => `open`
     299
    297300[1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes
    298301
  • src/Common/Indenter.h

    r67130fe rc6a1e8a  
    1818
    1919struct Indenter {
    20         static unsigned tabsize;
     20        static unsigned tabsize;  ///< default number of spaces in one level of indentation
    2121
    22         Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {}
    23         unsigned int amt;  // amount 1 level increases indent by (i.e. how much to increase by in operator++)
    24         unsigned int indent;
     22        unsigned int indent;      ///< number of spaces to indent
     23        unsigned int amt;         ///< spaces in one level of indentation
    2524
     25        Indenter( unsigned int indent = 0, unsigned int amt = tabsize )
     26        : indent( indent*amt ), amt( amt ) {}
     27       
    2628        Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; }
    2729        Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; }
  • src/InitTweak/FixInit.cc

    r67130fe rc6a1e8a  
    715715                                stmtsToAddBefore.push_back( new DeclStmt( ret ) );
    716716
    717                                 if(!stmtExpr->resultExpr) {
    718                                         SemanticError(stmtExpr, "Statment-Expression should have a resulting expression");
    719                                 }
     717                                assertf(
     718                                        stmtExpr->resultExpr,
     719                                        "Statement-Expression should have a resulting expression at %s:%d",
     720                                        stmtExpr->location.filename.c_str(),
     721                                        stmtExpr->location.first_line
     722                                );
     723
    720724                                ExprStmt * last = stmtExpr->resultExpr;
    721725                                try {
    722726                                        last->expr = makeCtorDtor( "?{}", ret, last->expr );
    723727                                } catch(...) {
    724                                         std::cerr << "=======================" << std::endl;
    725                                         std::cerr << "ERROR, can't resolve" << std::endl;
    726                                         ret->print(std::cerr);
    727                                         std::cerr << std::endl << "---" << std::endl;
    728                                         last->expr->print(std::cerr);
     728                                        std::cerr << "*CFA internal error: ";
     729                                        std::cerr << "can't resolve implicit constructor";
     730                                        std::cerr << " at " << stmtExpr->location.filename;
     731                                        std::cerr << ":" << stmtExpr->location.first_line << std::endl;
    729732
    730733                                        abort();
  • src/Makefile.in

    r67130fe rc6a1e8a  
    189189        ResolvExpr/Alternative.$(OBJEXT) \
    190190        ResolvExpr/AlternativeFinder.$(OBJEXT) \
     191        ResolvExpr/Candidate.$(OBJEXT) \
     192        ResolvExpr/CandidateFinder.$(OBJEXT) \
    191193        ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \
    192194        ResolvExpr/ConversionCost.$(OBJEXT) \
     
    622624      ResolvExpr/Alternative.cc \
    623625      ResolvExpr/AlternativeFinder.cc \
     626      ResolvExpr/Candidate.cpp \
     627      ResolvExpr/CandidateFinder.cpp \
    624628      ResolvExpr/CastCost.cc \
    625629      ResolvExpr/CommonType.cc \
     
    872876ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    873877        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     878ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     879        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     880ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     881        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    874882ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    875883        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     
    12541262@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@
    12551263@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@
     1264@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@
     1265@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@
    12561266@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@
    12571267@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@
  • src/ResolvExpr/AlternativeFinder.cc

    r67130fe rc6a1e8a  
    136136
    137137        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
    138                 Indenter indent = { Indenter::tabsize, indentAmt };
     138                Indenter indent = { indentAmt };
    139139                for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    140140                        i->print( os, indent );
  • src/ResolvExpr/ResolveAssertions.cc

    r67130fe rc6a1e8a  
    365365                                        // fail early if any assertion is not resolvable
    366366                                        if ( ! resolveAssertion( assn, resn ) ) {
    367                                                 Indenter tabs{ Indenter::tabsize, 3 };
     367                                                Indenter tabs{ 3 };
    368368                                                std::ostringstream ss;
    369369                                                ss << tabs << "Unsatisfiable alternative:\n";
     
    391391                                        // fail early if no mutually-compatible assertion satisfaction
    392392                                        if ( compatible.empty() ) {
    393                                                 Indenter tabs{ Indenter::tabsize, 3 };
     393                                                Indenter tabs{ 3 };
    394394                                                std::ostringstream ss;
    395395                                                ss << tabs << "Unsatisfiable alternative:\n";
  • src/ResolvExpr/Resolver.cc

    r67130fe rc6a1e8a  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Candidate.hpp"
     24#include "CandidateFinder.hpp"
    2325#include "CurrentObject.h"               // for CurrentObject
    2426#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    2729#include "typeops.h"                     // for extractResultType
    2830#include "Unify.h"                       // for unify
     31#include "AST/Chain.hpp"
     32#include "AST/Decl.hpp"
     33#include "AST/Init.hpp"
    2934#include "AST/Pass.hpp"
     35#include "AST/Print.hpp"
    3036#include "AST/SymbolTable.hpp"
    3137#include "Common/PassVisitor.h"          // for PassVisitor
     
    113119
    114120        namespace {
    115                 struct DeleteFinder : public WithShortCircuiting        {
     121                struct DeleteFinder_old : public WithShortCircuiting    {
    116122                        DeletedExpr * delExpr = nullptr;
    117123                        void previsit( DeletedExpr * expr ) {
     
    127133
    128134        DeletedExpr * findDeletedExpr( Expression * expr ) {
    129                 PassVisitor<DeleteFinder> finder;
     135                PassVisitor<DeleteFinder_old> finder;
    130136                expr->accept( finder );
    131137                return finder.pass.delExpr;
     
    133139
    134140        namespace {
    135                 struct StripCasts {
     141                struct StripCasts_old {
    136142                        Expression * postmutate( CastExpr * castExpr ) {
    137143                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     
    146152
    147153                        static void strip( Expression *& expr ) {
    148                                 PassVisitor<StripCasts> stripper;
     154                                PassVisitor<StripCasts_old> stripper;
    149155                                expr = expr->acceptMutator( stripper );
    150156                        }
     
    154160                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    155161                        env.makeSubstitution( *expr->env );
    156                         StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
     162                        StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression
    157163                }
    158164
     
    405411
    406412        void Resolver_old::previsit( ObjectDecl * objectDecl ) {
    407                 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 
    408                 // class-variable initContext is changed multiple time because the LHS is analysed twice. 
    409                 // The second analysis changes initContext because of a function type can contain object 
    410                 // declarations in the return and parameter types. So each value of initContext is 
     413                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that
     414                // class-variable initContext is changed multiple time because the LHS is analysed twice.
     415                // The second analysis changes initContext because of a function type can contain object
     416                // declarations in the return and parameter types. So each value of initContext is
    411417                // retained, so the type on the first analysis is preserved and used for selecting the RHS.
    412418                GuardValue( currentObject );
     
    445451
    446452        void Resolver_old::postvisit( FunctionDecl * functionDecl ) {
    447                 // default value expressions have an environment which shouldn't be there and trips up 
     453                // default value expressions have an environment which shouldn't be there and trips up
    448454                // later passes.
    449455                // xxx - it might be necessary to somehow keep the information from this environment, but I
     
    937943        ///////////////////////////////////////////////////////////////////////////
    938944
    939         class Resolver_new final
    940         : public ast::WithIndexer, public ast::WithGuards, public ast::WithVisitorRef<Resolver_new>,
    941           public ast::WithShortCircuiting, public ast::WithStmtsToAdd<> {
    942                  
    943         public:
     945        namespace {
     946                /// Finds deleted expressions in an expression tree
     947                struct DeleteFinder_new final : public ast::WithShortCircuiting {
     948                        const ast::DeletedExpr * delExpr = nullptr;
     949
     950                        void previsit( const ast::DeletedExpr * expr ) {
     951                                if ( delExpr ) { visit_children = false; }
     952                                else { delExpr = expr; }
     953                        }
     954
     955                        void previsit( const ast::Expr * ) {
     956                                if ( delExpr ) { visit_children = false; }
     957                        }
     958                };
     959
     960                /// Check if this expression is or includes a deleted expression
     961                const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
     962                        ast::Pass<DeleteFinder_new> finder;
     963                        expr->accept( finder );
     964                        return finder.pass.delExpr;
     965                }
     966
     967                /// Calls the CandidateFinder and finds the single best candidate
     968                CandidateRef findUnfinishedKindExpression(
     969                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     970                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     971                ) {
     972                        if ( ! untyped ) return nullptr;
     973
     974                        // xxx - this isn't thread-safe, but should work until we parallelize the resolver
     975                        static unsigned recursion_level = 0;
     976
     977                        ++recursion_level;
     978                        ast::TypeEnvironment env;
     979                        CandidateFinder finder{ symtab, env };
     980                        finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
     981                        --recursion_level;
     982
     983                        // produce a filtered list of candidates
     984                        CandidateList candidates;
     985                        for ( auto & cand : finder.candidates ) {
     986                                if ( pred( *cand ) ) { candidates.emplace_back( cand ); }
     987                        }
     988
     989                        // produce invalid error if no candidates
     990                        if ( candidates.empty() ) {
     991                                SemanticError( untyped,
     992                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
     993                                        "expression: ") );
     994                        }
     995
     996                        // search for cheapest candidate
     997                        CandidateList winners;
     998                        bool seen_undeleted = false;
     999                        for ( CandidateRef & cand : candidates ) {
     1000                                int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );
     1001
     1002                                if ( c > 0 ) continue;  // skip more expensive than winner
     1003
     1004                                if ( c < 0 ) {
     1005                                        // reset on new cheapest
     1006                                        seen_undeleted = ! findDeletedExpr( cand->expr );
     1007                                        winners.clear();
     1008                                } else /* if ( c == 0 ) */ {
     1009                                        if ( findDeletedExpr( cand->expr ) ) {
     1010                                                // skip deleted expression if already seen one equivalent-cost not
     1011                                                if ( seen_undeleted ) continue;
     1012                                        } else if ( ! seen_undeleted ) {
     1013                                                // replace list of equivalent-cost deleted expressions with one non-deleted
     1014                                                winners.clear();
     1015                                                seen_undeleted = true;
     1016                                        }
     1017                                }
     1018
     1019                                winners.emplace_back( std::move( cand ) );
     1020                        }
     1021
     1022                        // promote candidate.cvtCost to .cost
     1023                        for ( CandidateRef & cand : winners ) {
     1024                                cand->cost = cand->cvtCost;
     1025                        }
     1026
     1027                        // produce ambiguous errors, if applicable
     1028                        if ( winners.size() != 1 ) {
     1029                                std::ostringstream stream;
     1030                                stream << "Cannot choose between " << winners.size() << " alternatives for "
     1031                                        << kind << (kind != "" ? " " : "") << "expression\n";
     1032                                ast::print( stream, untyped );
     1033                                stream << " Alternatives are:\n";
     1034                                print( stream, winners, 1 );
     1035                                SemanticError( untyped->location, stream.str() );
     1036                        }
     1037
     1038                        // single selected choice
     1039                        CandidateRef & choice = winners.front();
     1040
     1041                        // fail on only expression deleted
     1042                        if ( ! seen_undeleted ) {
     1043                                SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "
     1044                                "includes deleted identifier in " );
     1045                        }
     1046
     1047                        return std::move( choice );
     1048                }
     1049
     1050                /// Strips extraneous casts out of an expression
     1051                struct StripCasts_new final {
     1052                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
     1053                                if (
     1054                                        castExpr->isGenerated
     1055                                        && typesCompatible( castExpr->arg->result, castExpr->result )
     1056                                ) {
     1057                                        // generated cast is the same type as its argument, remove it after keeping env
     1058                                        ast::ptr<ast::Expr> arg = castExpr->arg;
     1059                                        arg.get_and_mutate()->env = castExpr->env;
     1060                                        return arg;
     1061                                }
     1062                                return castExpr;
     1063                        }
     1064
     1065                        static void strip( ast::ptr< ast::Expr > & expr ) {
     1066                                ast::Pass< StripCasts_new > stripper;
     1067                                expr = expr->accept( stripper );
     1068                        }
     1069                };
     1070
     1071                /// Establish post-resolver invariants for expressions
     1072                void finishExpr(
     1073                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     1074                        const ast::TypeSubstitution * oldenv = nullptr
     1075                ) {
     1076                        // set up new type substitution for expression
     1077                        ast::ptr< ast::TypeSubstitution > newenv =
     1078                                 oldenv ? oldenv : new ast::TypeSubstitution{};
     1079                        env.writeToSubstitution( *newenv.get_and_mutate() );
     1080                        expr.get_and_mutate()->env = std::move( newenv );
     1081                        // remove unncecessary casts
     1082                        StripCasts_new::strip( expr );
     1083                }
     1084               
     1085                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     1086                /// lowest cost, returning the resolved version
     1087                ast::ptr< ast::Expr > findKindExpression(
     1088                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     1089                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     1090                ) {
     1091                        if ( ! untyped ) return {};
     1092                        CandidateRef choice =
     1093                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
     1094                        finishExpr( choice->expr, choice->env, untyped->env );
     1095                        return std::move( choice->expr );
     1096                }
     1097
     1098                /// Predicate for "Candidate has integral type"
     1099                bool hasIntegralType( const Candidate & i ) {
     1100                        const ast::Type * type = i.expr->result;
     1101                       
     1102                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
     1103                                return bt->isInteger();
     1104                        } else if (
     1105                                dynamic_cast< const ast::EnumInstType * >( type )
     1106                                || dynamic_cast< const ast::ZeroType * >( type )
     1107                                || dynamic_cast< const ast::OneType * >( type )
     1108                        ) {
     1109                                return true;
     1110                        } else return false;
     1111                }
     1112
     1113                /// Resolve `untyped` as an integral expression, returning the resolved version
     1114                ast::ptr< ast::Expr > findIntegralExpression(
     1115                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1116                ) {
     1117                        return findKindExpression( untyped, symtab, "condition", hasIntegralType );
     1118                }
     1119        }
     1120
     1121        class Resolver_new final
     1122        : public ast::WithSymbolTable, public ast::WithGuards,
     1123          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     1124          public ast::WithStmtsToAdd<> {
     1125
     1126                ast::ptr< ast::Type > functionReturn = nullptr;
     1127                // ast::CurrentObject currentObject = nullptr;
     1128                bool inEnumDecl = false;
     1129
     1130        public:
    9441131                Resolver_new() = default;
    945                 Resolver_new( const ast::SymbolTable & syms ) { /*symtab = syms;*/ }
    946 
    947                 void previsit( ast::FunctionDecl * functionDecl );
    948                 ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl );
    949                 void previsit( ast::ObjectDecl * objectDecl );
    950                 void previsit( ast::EnumDecl * enumDecl );
    951                 void previsit( ast::StaticAssertDecl * assertDecl );
    952 
    953                 void previsit( ast::ArrayType * at );
    954                 void previsit( ast::PointerType * pt );
    955 
    956                 void previsit( ast::ExprStmt * exprStmt );
    957                 void previsit( ast::AsmExpr * asmExpr );
    958                 void previsit( ast::AsmStmt * asmStmt );
    959                 void previsit( ast::IfStmt * ifStmt );
    960                 void previsit( ast::WhileStmt * whileStmt );
    961                 void previsit( ast::ForStmt * forStmt );
    962                 void previsit( ast::SwitchStmt * switchStmt );
    963                 void previsit( ast::CaseStmt * caseStmt );
    964                 void previsit( ast::BranchStmt * branchStmt );
    965                 void previsit( ast::ReturnStmt * returnStmt );
    966                 void previsit( ast::ThrowStmt * throwStmt );
    967                 void previsit( ast::CatchStmt * catchStmt );
    968                 void previsit( ast::WaitForStmt * stmt );
    969 
    970                 void previsit( ast::SingleInit * singleInit );
    971                 void previsit( ast::ListInit * listInit );
    972                 void previsit( ast::ConstructorInit * ctorInit );
     1132                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     1133
     1134                void previsit( const ast::FunctionDecl * );
     1135                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
     1136                void previsit( const ast::ObjectDecl * );
     1137                void previsit( const ast::EnumDecl * );
     1138                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     1139
     1140                void previsit( const ast::ArrayType * );
     1141                void previsit( const ast::PointerType * );
     1142
     1143                void previsit( const ast::ExprStmt * );
     1144                void previsit( const ast::AsmExpr * );
     1145                void previsit( const ast::AsmStmt * );
     1146                void previsit( const ast::IfStmt * );
     1147                void previsit( const ast::WhileStmt * );
     1148                void previsit( const ast::ForStmt * );
     1149                void previsit( const ast::SwitchStmt * );
     1150                void previsit( const ast::CaseStmt * );
     1151                void previsit( const ast::BranchStmt * );
     1152                void previsit( const ast::ReturnStmt * );
     1153                void previsit( const ast::ThrowStmt * );
     1154                void previsit( const ast::CatchStmt * );
     1155                void previsit( const ast::WaitForStmt * );
     1156
     1157                void previsit( const ast::SingleInit * );
     1158                void previsit( const ast::ListInit * );
     1159                void previsit( const ast::ConstructorInit * );
    9731160        };
    9741161
     
    9781165        }
    9791166
    980         void previsit( ast::FunctionDecl * functionDecl ) {
    981                 #warning unimplemented; Resolver port in progress
    982                 (void)functionDecl;
    983                 assert(false);
    984         }
    985 
    986         ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl ) {
    987                 #warning unimplemented; Resolver port in progress
    988                 (void)functionDecl;
    989                 assert(false);
    990                 return nullptr;
    991         }
    992 
    993         void previsit( ast::ObjectDecl * objectDecl ) {
     1167        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1168                GuardValue( functionReturn );
     1169                functionReturn = extractResultType( functionDecl->type );
     1170        }
     1171
     1172        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
     1173                // default value expressions have an environment which shouldn't be there and trips up
     1174                // later passes.
     1175                ast::ptr< ast::FunctionDecl > ret = functionDecl;
     1176                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
     1177                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
     1178
     1179                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     1180                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
     1181                                        if ( init->value->env == nullptr ) continue;
     1182                                        // clone initializer minus the initializer environment
     1183                                        ast::chain_mutate( ret )
     1184                                                ( &ast::FunctionDecl::type )
     1185                                                        ( &ast::FunctionType::params )[i]
     1186                                                                ( &ast::ObjectDecl::init )
     1187                                                                        ( &ast::SingleInit::value )->env = nullptr;
     1188
     1189                                        assert( functionDecl != ret.get() || functionDecl->unique() );
     1190                                        assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
     1191                                }
     1192                        }
     1193                }
     1194                return ret.get();
     1195        }
     1196
     1197        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    9941198                #warning unimplemented; Resolver port in progress
    9951199                (void)objectDecl;
     
    9971201        }
    9981202
    999         void previsit( ast::EnumDecl * enumDecl ) {
    1000                 #warning unimplemented; Resolver port in progress
    1001                 (void)enumDecl;
    1002                 assert(false);
    1003         }
    1004 
    1005         void previsit( ast::StaticAssertDecl * assertDecl ) {
    1006                 #warning unimplemented; Resolver port in progress
    1007                 (void)assertDecl;
    1008                 assert(false);
    1009         }
    1010 
    1011         void previsit( ast::ArrayType * at ) {
     1203        void Resolver_new::previsit( const ast::EnumDecl * ) {
     1204                // in case we decide to allow nested enums
     1205                GuardValue( inEnumDecl );
     1206                inEnumDecl = false;
     1207        }
     1208
     1209        const ast::StaticAssertDecl * Resolver_new::previsit(
     1210                const ast::StaticAssertDecl * assertDecl
     1211        ) {
     1212                ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab );
     1213                if ( cond == assertDecl->cond ) return assertDecl;
     1214               
     1215                ast::StaticAssertDecl * ret = mutate( assertDecl );
     1216                ret->cond = cond;
     1217                return ret;
     1218        }
     1219
     1220        void Resolver_new::previsit( const ast::ArrayType * at ) {
    10121221                #warning unimplemented; Resolver port in progress
    10131222                (void)at;
     
    10151224        }
    10161225
    1017         void previsit( ast::PointerType * pt ) {
     1226        void Resolver_new::previsit( const ast::PointerType * pt ) {
    10181227                #warning unimplemented; Resolver port in progress
    10191228                (void)pt;
     
    10211230        }
    10221231
    1023         void previsit( ast::ExprStmt * exprStmt ) {
     1232        void Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
    10241233                #warning unimplemented; Resolver port in progress
    10251234                (void)exprStmt;
     
    10271236        }
    10281237
    1029         void previsit( ast::AsmExpr * asmExpr ) {
     1238        void Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
    10301239                #warning unimplemented; Resolver port in progress
    10311240                (void)asmExpr;
     
    10331242        }
    10341243
    1035         void previsit( ast::AsmStmt * asmStmt ) {
     1244        void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
    10361245                #warning unimplemented; Resolver port in progress
    10371246                (void)asmStmt;
     
    10391248        }
    10401249
    1041         void previsit( ast::IfStmt * ifStmt ) {
     1250        void Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
    10421251                #warning unimplemented; Resolver port in progress
    10431252                (void)ifStmt;
     
    10451254        }
    10461255
    1047         void previsit( ast::WhileStmt * whileStmt ) {
     1256        void Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    10481257                #warning unimplemented; Resolver port in progress
    10491258                (void)whileStmt;
     
    10511260        }
    10521261
    1053         void previsit( ast::ForStmt * forStmt ) {
     1262        void Resolver_new::previsit( const ast::ForStmt * forStmt ) {
    10541263                #warning unimplemented; Resolver port in progress
    10551264                (void)forStmt;
     
    10571266        }
    10581267
    1059         void previsit( ast::SwitchStmt * switchStmt ) {
     1268        void Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
    10601269                #warning unimplemented; Resolver port in progress
    10611270                (void)switchStmt;
     
    10631272        }
    10641273
    1065         void previsit( ast::CaseStmt * caseStmt ) {
     1274        void Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    10661275                #warning unimplemented; Resolver port in progress
    10671276                (void)caseStmt;
     
    10691278        }
    10701279
    1071         void previsit( ast::BranchStmt * branchStmt ) {
     1280        void Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
    10721281                #warning unimplemented; Resolver port in progress
    10731282                (void)branchStmt;
     
    10751284        }
    10761285
    1077         void previsit( ast::ReturnStmt * returnStmt ) {
     1286        void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
    10781287                #warning unimplemented; Resolver port in progress
    10791288                (void)returnStmt;
     
    10811290        }
    10821291
    1083         void previsit( ast::ThrowStmt * throwStmt ) {
     1292        void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
    10841293                #warning unimplemented; Resolver port in progress
    10851294                (void)throwStmt;
     
    10871296        }
    10881297
    1089         void previsit( ast::CatchStmt * catchStmt ) {
     1298        void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    10901299                #warning unimplemented; Resolver port in progress
    10911300                (void)catchStmt;
     
    10931302        }
    10941303
    1095         void previsit( ast::WaitForStmt * stmt ) {
     1304        void Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
    10961305                #warning unimplemented; Resolver port in progress
    10971306                (void)stmt;
     
    10991308        }
    11001309
    1101         void previsit( ast::SingleInit * singleInit ) {
     1310        void Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    11021311                #warning unimplemented; Resolver port in progress
    11031312                (void)singleInit;
     
    11051314        }
    11061315
    1107         void previsit( ast::ListInit * listInit ) {
     1316        void Resolver_new::previsit( const ast::ListInit * listInit ) {
    11081317                #warning unimplemented; Resolver port in progress
    11091318                (void)listInit;
     
    11111320        }
    11121321
    1113         void previsit( ast::ConstructorInit * ctorInit ) {
     1322        void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
    11141323                #warning unimplemented; Resolver port in progress
    11151324                (void)ctorInit;
  • src/ResolvExpr/module.mk

    r67130fe rc6a1e8a  
    1919      ResolvExpr/Alternative.cc \
    2020      ResolvExpr/AlternativeFinder.cc \
     21      ResolvExpr/Candidate.cpp \
     22      ResolvExpr/CandidateFinder.cpp \
    2123      ResolvExpr/CastCost.cc \
    2224      ResolvExpr/CommonType.cc \
  • src/ResolvExpr/typeops.h

    r67130fe rc6a1e8a  
    103103
    104104        bool typesCompatible(
    105                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     105                const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
    106106                const ast::TypeEnvironment & env = {} );
    107107       
  • src/SynTree/BaseSyntaxNode.h

    r67130fe rc6a1e8a  
    4141  /// * Expressions should not finish with a newline, since the expression's parent has better information.
    4242        virtual void print( std::ostream & os, Indenter indent = {} ) const = 0;
    43   void print( std::ostream & os, unsigned int indent ) {
    44     print( os, Indenter{ Indenter::tabsize, indent });
    45   }
    4643};
    4744
  • src/SynTree/DeclReplacer.cc

    r67130fe rc6a1e8a  
    3030                        bool debug;
    3131                public:
     32                        size_t replaced;
     33
     34                public:
    3235                        DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
    3336
     
    4548                        bool debug;
    4649                public:
     50                        size_t replaced;
     51
     52                public:
    4753                        ExprDeclReplacer( const ExprMap & exprMap, bool debug = false );
    4854
     
    5258        }
    5359
    54         void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {
     60        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {
    5561                PassVisitor<DeclReplacer> replacer( declMap, typeMap, debug );
    5662                maybeAccept( node, replacer );
     63                return replacer.pass.replaced;
    5764        }
    5865
    59         void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {
     66        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {
    6067                TypeMap typeMap;
    61                 replace( node, declMap, typeMap, debug );
     68                return replace( node, declMap, typeMap, debug );
    6269        }
    6370
    64         void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {
     71        size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {
    6572                DeclMap declMap;
    66                 replace( node, declMap, typeMap, debug );
     73                return replace( node, declMap, typeMap, debug );
    6774        }
    6875
    69         void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) {
     76        size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) {
    7077                PassVisitor<ExprDeclReplacer> replacer( exprMap, debug );
    7178                node = maybeMutate( node, replacer );
     79                return replacer.pass.replaced;
    7280        }
    7381
    7482        namespace {
    75                 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ) {}
     83                DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ), replaced( 0 ) {}
    7684
    7785                // replace variable with new node from decl map
     
    7987                        // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
    8088                        if ( declMap.count( varExpr->var ) ) {
     89                                replaced++;
    8190                                auto replacement = declMap.at( varExpr->var );
    8291                                if ( debug ) {
     
    8998                void DeclReplacer::previsit( TypeInstType * inst ) {
    9099                        if ( typeMap.count( inst->baseType ) ) {
     100                                replaced++;
    91101                                auto replacement = typeMap.at( inst->baseType );
    92102                                if ( debug ) {
     
    97107                }
    98108
    99                 ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ) {}
     109                ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ), replaced( 0 ) {}
    100110
    101111                Expression * ExprDeclReplacer::postmutate( VariableExpr * varExpr ) {
    102112                        if ( exprMap.count( varExpr->var ) ) {
     113                                replaced++;
    103114                                Expression * replacement = exprMap.at( varExpr->var )->clone();
    104115                                if ( debug ) {
  • src/SynTree/DeclReplacer.h

    r67130fe rc6a1e8a  
    2828        typedef std::map< DeclarationWithType *, Expression * > ExprMap;
    2929
    30         void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
    31         void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );
    32         void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
     30        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
     31        size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );
     32        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
    3333
    34         void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false);
     34        size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false);
    3535        template<typename T>
    3636                void replace( T *& node, const ExprMap & exprMap, bool debug = false ) {
  • src/main.cc

    r67130fe rc6a1e8a  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  3 17:35:59 2019
    13 // Update Count     : 600
     12// Last Modified On : Wed Jun  5 20:35:13 2019
     13// Update Count     : 601
    1414//
    1515
     
    406406
    407407
    408 static const char optstring[] = ":hlLmNn:pP:S:twW:D:F:";
     408static const char optstring[] = ":hlLmNnpP:S:twW:D:F:";
    409409
    410410enum { PreludeDir = 128 };
Note: See TracChangeset for help on using the changeset viewer.