Changeset c76bd34 for src


Ignore:
Timestamp:
Oct 7, 2020, 4:31:43 PM (5 years ago)
Author:
Colby Alexander Parsons <caparsons@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
848439f
Parents:
ae2c27a (diff), 597c5d18 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc into master

Location:
src
Files:
6 added
34 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rae2c27a rc76bd34  
    177177        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
    178178                if ( inCache( node ) ) return nullptr;
     179
     180                // function decl contains real variables that the type must use.
     181                // the structural change means function type in and out of decl
     182                // must be handled **differently** on convert back to old.
     183                auto ftype = new FunctionType(
     184                        cv(node->type),
     185                        (bool)node->type->isVarArgs
     186                );
     187                ftype->returnVals = get<DeclarationWithType>().acceptL(node->returns);
     188                ftype->parameters = get<DeclarationWithType>().acceptL(node->params);
     189
     190                ftype->forall = get<TypeDecl>().acceptL( node->type->forall );
     191
     192                visitType(node->type, ftype);
     193
    179194                auto decl = new FunctionDecl(
    180195                        node->name,
    181196                        Type::StorageClasses( node->storage.val ),
    182197                        LinkageSpec::Spec( node->linkage.val ),
    183                         get<FunctionType>().accept1( node->type ),
     198                        ftype,
     199                        //get<FunctionType>().accept1( node->type ),
    184200                        {},
    185201                        get<Attribute>().acceptL( node->attributes ),
     
    11521168
    11531169        const ast::Type * visit( const ast::FunctionType * node ) override final {
     1170                static std::string dummy_paramvar_prefix = "__param_";
     1171                static std::string dummy_returnvar_prefix = "__retval_";
     1172
    11541173                auto ty = new FunctionType {
    11551174                        cv( node ),
    11561175                        (bool)node->isVarArgs
    11571176                };
    1158                 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
    1159                 ty->parameters = get<DeclarationWithType>().acceptL( node->params );
     1177                auto returns = get<Type>().acceptL(node->returns);
     1178                auto params = get<Type>().acceptL(node->params);
     1179
     1180                int ret_index = 0;
     1181                for (auto t: returns) {
     1182                        // xxx - LinkageSpec shouldn't matter but needs to be something
     1183                        ObjectDecl * dummy = new ObjectDecl(dummy_returnvar_prefix + std::to_string(ret_index++), {}, LinkageSpec::C, nullptr, t, nullptr);
     1184                        ty->returnVals.push_back(dummy);
     1185                }
     1186                int param_index = 0;
     1187                for (auto t: params) {
     1188                        ObjectDecl * dummy = new ObjectDecl(dummy_paramvar_prefix + std::to_string(param_index++), {}, LinkageSpec::C, nullptr, t, nullptr);
     1189                        ty->parameters.push_back(dummy);
     1190                }
     1191
     1192                // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
     1193                // ty->parameters = get<DeclarationWithType>().acceptL( node->params );
    11601194                ty->forall = get<TypeDecl>().acceptL( node->forall );
    11611195                return visitType( node, ty );
    11621196        }
    11631197
    1164         const ast::Type * postvisit( const ast::ReferenceToType * old, ReferenceToType * ty ) {
     1198        const ast::Type * postvisit( const ast::BaseInstType * old, ReferenceToType * ty ) {
    11651199                ty->forall = get<TypeDecl>().acceptL( old->forall );
    11661200                ty->parameters = get<Expression>().acceptL( old->params );
     
    13741408        ast::Node * node = nullptr;
    13751409        /// cache of nodes that might be referenced by readonly<> for de-duplication
    1376         std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {};
     1410        /// in case that some nodes are dropped by conversion (due to possible structural change)
     1411        /// use smart pointers in cache value to prevent accidental invalidation.
     1412        /// at conversion stage, all created nodes are guaranteed to be unique, therefore
     1413        /// const_casting out of smart pointers is permitted.
     1414        std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {};
    13771415
    13781416        // Local Utilities:
     
    14471485                auto it = cache.find( old );
    14481486                if ( it == cache.end() ) return false;
    1449                 node = it->second;
     1487                node = const_cast<ast::Node *>(it->second.get());
    14501488                return true;
    14511489        }
     
    14861524        virtual void visit( const FunctionDecl * old ) override final {
    14871525                if ( inCache( old ) ) return;
     1526                auto paramVars = GET_ACCEPT_V(type->parameters, DeclWithType);
     1527                auto returnVars = GET_ACCEPT_V(type->returnVals, DeclWithType);
     1528                auto forall = GET_ACCEPT_V(type->forall, TypeDecl);
     1529
     1530                // function type is now derived from parameter decls instead of storing them
     1531                auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type));
     1532                ftype->params.reserve(paramVars.size());
     1533                ftype->returns.reserve(returnVars.size());
     1534
     1535                for (auto & v: paramVars) {
     1536                        ftype->params.emplace_back(v->get_type());
     1537                }
     1538                for (auto & v: returnVars) {
     1539                        ftype->returns.emplace_back(v->get_type());
     1540                }
     1541                ftype->forall = std::move(forall);
     1542                visitType(old->type, ftype);
     1543
    14881544                auto decl = new ast::FunctionDecl{
    14891545                        old->location,
    14901546                        old->name,
    1491                         GET_ACCEPT_1(type, FunctionType),
     1547                        // GET_ACCEPT_1(type, FunctionType),
     1548                        std::move(paramVars),
     1549                        std::move(returnVars),
    14921550                        {},
    14931551                        { old->storageClasses.val },
     
    14961554                        { old->get_funcSpec().val }
    14971555                };
     1556
     1557                decl->type = ftype;
    14981558                cache.emplace( old, decl );
     1559
    14991560                decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
    15001561                decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
     
    25152576                        cv( old )
    25162577                };
    2517                 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
    2518                 ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     2578                auto returnVars = GET_ACCEPT_V(returnVals, DeclWithType);
     2579                auto paramVars = GET_ACCEPT_V(parameters, DeclWithType);
     2580                // ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
     2581                // ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     2582                for (auto & v: returnVars) {
     2583                        ty->returns.emplace_back(v->get_type());
     2584                }
     2585                for (auto & v: paramVars) {
     2586                        ty->params.emplace_back(v->get_type());
     2587                }
    25192588                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
    25202589                visitType( old, ty );
    25212590        }
    25222591
    2523         void postvisit( const ReferenceToType * old, ast::ReferenceToType * ty ) {
     2592        void postvisit( const ReferenceToType * old, ast::BaseInstType * ty ) {
    25242593                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
    25252594                ty->params = GET_ACCEPT_V( parameters, Expr );
  • src/AST/Decl.hpp

    rae2c27a rc76bd34  
    124124class FunctionDecl : public DeclWithType {
    125125public:
     126        std::vector<ptr<DeclWithType>> params;
     127        std::vector<ptr<DeclWithType>> returns;
     128        // declared type, derived from parameter declarations
    126129        ptr<FunctionType> type;
    127130        ptr<CompoundStmt> stmts;
    128131        std::vector< ptr<Expr> > withExprs;
    129132
    130         FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type,
     133        FunctionDecl( const CodeLocation & loc, const std::string & name,
     134                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
    131135                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C,
    132136                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {})
    133         : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
     137        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
    134138          stmts( stmts ) {}
    135139
  • src/AST/ForallSubstitutor.hpp

    rae2c27a rc76bd34  
    3333        }
    3434
     35        template<typename node_t >
     36        std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {
     37                std::vector<ptr<node_t>> n;
     38                n.reserve(o.size());
     39                for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }
     40                return n;
     41        }
     42       
     43        /*
     44
    3545        /// Substitute parameter/return type
    3646        std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) {
     
    4858                return n;
    4959        }
     60
     61        */
    5062};
    5163
  • src/AST/Fwd.hpp

    rae2c27a rc76bd34  
    107107class QualifiedType;
    108108class FunctionType;
    109 class ReferenceToType;
     109class BaseInstType;
    110110template<typename decl_t> class SueInstType;
    111111using StructInstType = SueInstType<StructDecl>;
  • src/AST/GenericSubstitution.cpp

    rae2c27a rc76bd34  
    4242        private:
    4343                // make substitution for generic type
    44                 void makeSub( const ReferenceToType * ty ) {
     44                void makeSub( const BaseInstType * ty ) {
    4545                        visit_children = false;
    4646                        const AggregateDecl * aggr = ty->aggr();
  • src/AST/Node.cpp

    rae2c27a rc76bd34  
    266266template class ast::ptr_base< ast::FunctionType, ast::Node::ref_type::weak >;
    267267template class ast::ptr_base< ast::FunctionType, ast::Node::ref_type::strong >;
    268 template class ast::ptr_base< ast::ReferenceToType, ast::Node::ref_type::weak >;
    269 template class ast::ptr_base< ast::ReferenceToType, ast::Node::ref_type::strong >;
     268template class ast::ptr_base< ast::BaseInstType, ast::Node::ref_type::weak >;
     269template class ast::ptr_base< ast::BaseInstType, ast::Node::ref_type::strong >;
    270270template class ast::ptr_base< ast::StructInstType, ast::Node::ref_type::weak >;
    271271template class ast::ptr_base< ast::StructInstType, ast::Node::ref_type::strong >;
  • src/AST/Pass.hpp

    rae2c27a rc76bd34  
    5050// | PureVisitor           - makes the visitor pure, it never modifies nodes in place and always
    5151//                           clones nodes it needs to make changes to
    52 // | WithTypeSubstitution  - provides polymorphic const TypeSubstitution * env for the
     52// | WithConstTypeSubstitution - provides polymorphic const TypeSubstitution * typeSubs for the
    5353//                           current expression
    5454// | WithStmtsToAdd        - provides the ability to insert statements before or after the current
     
    6767// | WithSymbolTable       - provides symbol table functionality
    6868// | WithForallSubstitutor - maintains links between TypeInstType and TypeDecl under mutation
     69//
     70// Other Special Members:
     71// | result                - Either a method that takes no parameters or a field. If a method (or
     72//                           callable field) get_result calls it, otherwise the value is returned.
    6973//-------------------------------------------------------------------------------------------------
    7074template< typename core_t >
     
    8993        virtual ~Pass() = default;
    9094
     95        /// Storage for the actual pass.
     96        core_t core;
     97
     98        /// If the core defines a result, call it if possible, otherwise return it.
     99        inline auto get_result() -> decltype( __pass::get_result( core, '0' ) ) {
     100                return __pass::get_result( core, '0' );
     101        }
     102
    91103        /// Construct and run a pass on a translation unit.
    92104        template< typename... Args >
     
    96108        }
    97109
     110        /// Contruct and run a pass on a pointer to extract a value.
     111        template< typename node_type, typename... Args >
     112        static auto read( node_type const * node, Args&&... args ) {
     113                Pass<core_t> visitor( std::forward<Args>( args )... );
     114                node_type const * temp = node->accept( visitor );
     115                assert( temp == node );
     116                return visitor.get_result();
     117        }
     118
     119        // Versions of the above for older compilers.
    98120        template< typename... Args >
    99121        static void run( std::list< ptr<Decl> > & decls ) {
     
    102124        }
    103125
    104         /// Storage for the actual pass
    105         core_t core;
     126        template< typename node_type, typename... Args >
     127        static auto read( node_type const * node ) {
     128                Pass<core_t> visitor;
     129                node_type const * temp = node->accept( visitor );
     130                assert( temp == node );
     131                return visitor.get_result();
     132        }
    106133
    107134        /// Visit function declarations
     
    267294//-------------------------------------------------------------------------------------------------
    268295
    269 /// Keep track of the polymorphic const TypeSubstitution * env for the current expression
    270 
    271296/// If used the visitor will always clone nodes.
    272297struct PureVisitor {};
    273298
     299/// Keep track of the polymorphic const TypeSubstitution * typeSubs for the current expression.
    274300struct WithConstTypeSubstitution {
    275         const TypeSubstitution * env = nullptr;
     301        const TypeSubstitution * typeSubs = nullptr;
    276302};
    277303
  • src/AST/Pass.impl.hpp

    rae2c27a rc76bd34  
    154154                __pedantic_pass_assert( expr );
    155155
    156                 const ast::TypeSubstitution ** env_ptr = __pass::env( core, 0);
    157                 if ( env_ptr && expr->env ) {
    158                         *env_ptr = expr->env;
     156                const ast::TypeSubstitution ** typeSubs_ptr = __pass::typeSubs( core, 0 );
     157                if ( typeSubs_ptr && expr->env ) {
     158                        *typeSubs_ptr = expr->env;
    159159                }
    160160
     
    177177
    178178                // These may be modified by subnode but most be restored once we exit this statemnet.
    179                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( core, 0) );
     179                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::typeSubs( core, 0 ) );
    180180                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
    181181                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
     
    465465                        __pass::symtab::addId( core, 0, func );
    466466                        VISIT(
     467                                // parameter declarations are now directly here
     468                                maybe_accept( node, &FunctionDecl::params );
     469                                maybe_accept( node, &FunctionDecl::returns );
     470                                // foralls are still in function type
    467471                                maybe_accept( node, &FunctionDecl::type );
    468472                                // function body needs to have the same scope as parameters - CompoundStmt will not enter
     
    14881492
    14891493                // These may be modified by subnode but most be restored once we exit this statemnet.
    1490                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::env( core, 0) );
     1494                ValueGuardPtr< const ast::TypeSubstitution * > __old_env( __pass::typeSubs( core, 0 ) );
    14911495                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) >::type > __old_decls_before( stmts_before );
    14921496                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) >::type > __old_decls_after ( stmts_after  );
  • src/AST/Pass.proto.hpp

    rae2c27a rc76bd34  
    236236
    237237        // List of fields and their expected types
    238         FIELD_PTR( env, const ast::TypeSubstitution * )
     238        FIELD_PTR( typeSubs, const ast::TypeSubstitution * )
    239239        FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > )
    240240        FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > )
     
    421421
    422422        } // namespace forall
     423
     424        template<typename core_t>
     425        static inline auto get_result( core_t & core, char ) -> decltype( core.result() ) {
     426                return core.result();
     427        }
     428
     429        template<typename core_t>
     430        static inline auto get_result( core_t & core, int ) -> decltype( core.result ) {
     431                return core.result;
     432        }
     433
     434        template<typename core_t>
     435        static inline void get_result( core_t &, long ) {}
    423436} // namespace __pass
    424437} // namespace ast
  • src/AST/Print.cpp

    rae2c27a rc76bd34  
    270270        }
    271271
    272         void preprint( const ast::ReferenceToType * node ) {
     272        void preprint( const ast::BaseInstType * node ) {
    273273                print( node->forall );
    274274                print( node->attributes );
  • src/AST/SymbolTable.cpp

    rae2c27a rc76bd34  
    313313                if ( ! expr->result ) continue;
    314314                const Type * resTy = expr->result->stripReferences();
    315                 auto aggrType = dynamic_cast< const ReferenceToType * >( resTy );
     315                auto aggrType = dynamic_cast< const BaseInstType * >( resTy );
    316316                assertf( aggrType, "WithStmt expr has non-aggregate type: %s",
    317317                        toString( expr->result ).c_str() );
     
    335335}
    336336
     337/*
    337338void SymbolTable::addFunctionType( const FunctionType * ftype ) {
    338339        addTypes( ftype->forall );
     
    340341        addIds( ftype->params );
    341342}
     343*/
    342344
    343345void SymbolTable::lazyInitScope() {
     
    368370                assert( ! params.empty() );
    369371                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    370                 const Type * base = InitTweak::getPointerBase( params.front()->get_type() );
     372                const Type * base = InitTweak::getPointerBase( params.front() );
    371373                assert( base );
    372374                return Mangle::mangle( base );
     
    654656                        if ( dwt->name == "" ) {
    655657                                const Type * t = dwt->get_type()->stripReferences();
    656                                 if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) {
     658                                if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) {
    657659                                        if ( ! dynamic_cast<const StructInstType *>(rty)
    658660                                                && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
  • src/AST/SymbolTable.hpp

    rae2c27a rc76bd34  
    145145
    146146        /// convenience function for adding all of the declarations in a function type to the indexer
    147         void addFunctionType( const FunctionType * ftype );
     147        // void addFunctionType( const FunctionType * ftype );
    148148
    149149private:
  • src/AST/Type.cpp

    rae2c27a rc76bd34  
    102102// --- FunctionType
    103103
     104
    104105FunctionType::FunctionType( const FunctionType & o )
    105106: ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(),
     
    112113
    113114namespace {
    114         bool containsTtype( const std::vector<ptr<DeclWithType>> & l ) {
     115        bool containsTtype( const std::vector<ptr<Type>> & l ) {
    115116                if ( ! l.empty() ) {
    116                         return Tuples::isTtype( l.back()->get_type() );
     117                        return Tuples::isTtype( l.back() );
    117118                }
    118119                return false;
     
    124125}
    125126
    126 // --- ReferenceToType
    127 
    128 void ReferenceToType::initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub ) {
     127// --- BaseInstType
     128
     129void BaseInstType::initWithSub( const BaseInstType & o, Pass< ForallSubstitutor > & sub ) {
    129130        ParameterizedType::initWithSub( o, sub ); // initialize substitution
    130131        params = sub.core( o.params );            // apply to parameters
    131132}
    132133
    133 ReferenceToType::ReferenceToType( const ReferenceToType & o )
     134BaseInstType::BaseInstType( const BaseInstType & o )
    134135: ParameterizedType( o.qualifiers, copy( o.attributes ) ), params(), name( o.name ),
    135136  hoistType( o.hoistType ) {
     
    138139}
    139140
    140 std::vector<readonly<Decl>> ReferenceToType::lookup( const std::string& name ) const {
     141std::vector<readonly<Decl>> BaseInstType::lookup( const std::string& name ) const {
    141142        assertf( aggr(), "Must have aggregate to perform lookup" );
    142143
     
    153154SueInstType<decl_t>::SueInstType(
    154155        const decl_t * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    155 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     156: BaseInstType( b->name, q, move(as) ), base( b ) {}
    156157
    157158template<typename decl_t>
     
    168169TraitInstType::TraitInstType(
    169170        const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
    170 : ReferenceToType( b->name, q, move(as) ), base( b ) {}
     171: BaseInstType( b->name, q, move(as) ), base( b ) {}
    171172
    172173// --- TypeInstType
    173174
    174175TypeInstType::TypeInstType( const TypeInstType & o )
    175 : ReferenceToType( o.name, o.qualifiers, copy( o.attributes ) ), base(), kind( o.kind ) {
     176: BaseInstType( o.name, o.qualifiers, copy( o.attributes ) ), base(), kind( o.kind ) {
    176177        Pass< ForallSubstitutor > sub;
    177178        initWithSub( o, sub );      // initialize substitution
  • src/AST/Type.hpp

    rae2c27a rc76bd34  
    302302class FunctionType final : public ParameterizedType {
    303303public:
    304         std::vector<ptr<DeclWithType>> returns;
    305         std::vector<ptr<DeclWithType>> params;
     304//      std::vector<ptr<DeclWithType>> returns;
     305//      std::vector<ptr<DeclWithType>> params;
     306
     307        std::vector<ptr<Type>> returns;
     308        std::vector<ptr<Type>> params;
    306309
    307310        /// Does the function accept a variable number of arguments following the arguments specified
     
    329332
    330333/// base class for types that refer to types declared elsewhere (aggregates and typedefs)
    331 class ReferenceToType : public ParameterizedType {
     334class BaseInstType : public ParameterizedType {
    332335protected:
    333336        /// Initializes forall and parameters based on substitutor
    334         void initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub );
     337        void initWithSub( const BaseInstType & o, Pass< ForallSubstitutor > & sub );
    335338public:
    336339        std::vector<ptr<Expr>> params;
     
    338341        bool hoistType = false;
    339342
    340         ReferenceToType(
     343        BaseInstType(
    341344                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    342345        : ParameterizedType(q, std::move(as)), params(), name(n) {}
    343346
    344         ReferenceToType( const ReferenceToType & o );
     347        BaseInstType( const BaseInstType & o );
    345348
    346349        /// Gets aggregate declaration this type refers to
     
    350353
    351354private:
    352         virtual ReferenceToType * clone() const override = 0;
     355        virtual BaseInstType * clone() const override = 0;
    353356        MUTATE_FRIEND
    354357};
     
    356359// Common implementation for the SUE instance types. Not to be used directly.
    357360template<typename decl_t>
    358 class SueInstType final : public ReferenceToType {
     361class SueInstType final : public BaseInstType {
    359362public:
    360363        using base_type = decl_t;
     
    363366        SueInstType(
    364367                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    365         : ReferenceToType( n, q, std::move(as) ), base() {}
     368        : BaseInstType( n, q, std::move(as) ), base() {}
    366369
    367370        SueInstType(
     
    388391
    389392/// An instance of a trait type.
    390 class TraitInstType final : public ReferenceToType {
     393class TraitInstType final : public BaseInstType {
    391394public:
    392395        readonly<TraitDecl> base;
     
    394397        TraitInstType(
    395398                const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} )
    396         : ReferenceToType( n, q, std::move(as) ), base() {}
     399        : BaseInstType( n, q, std::move(as) ), base() {}
    397400
    398401        TraitInstType(
     
    411414
    412415/// instance of named type alias (typedef or variable)
    413 class TypeInstType final : public ReferenceToType {
     416class TypeInstType final : public BaseInstType {
    414417public:
    415418        readonly<TypeDecl> base;
     
    419422                const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
    420423                std::vector<ptr<Attribute>> && as = {} )
    421         : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
     424        : BaseInstType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
    422425        TypeInstType( const std::string& n, TypeDecl::Kind k, CV::Qualifiers q = {},
    423426                std::vector<ptr<Attribute>> && as = {} )
    424         : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
     427        : BaseInstType( n, q, std::move(as) ), base(), kind( k ) {}
    425428
    426429        TypeInstType( const TypeInstType & o );
  • src/AST/TypeSubstitution.cpp

    rae2c27a rc76bd34  
    176176}
    177177
    178 void TypeSubstitution::Substituter::handleAggregateType( const ReferenceToType * type ) {
     178void TypeSubstitution::Substituter::handleAggregateType( const BaseInstType * type ) {
    179179        GuardValue( boundVars );
    180180        // bind type variables from forall-qualifiers
  • src/AST/TypeSubstitution.hpp

    rae2c27a rc76bd34  
    169169                void previsit( const ParameterizedType * type );
    170170                /// Records type variable bindings from forall-statements and instantiations of generic types
    171                 void handleAggregateType( const ReferenceToType * type );
     171                void handleAggregateType( const BaseInstType * type );
    172172
    173173                void previsit( const StructInstType * aggregateUseType );
  • src/Common/Stats/Stats.cc

    rae2c27a rc76bd34  
    3535        }
    3636
     37        namespace ResolveTime {
     38                bool enabled = false;
     39        }
     40
    3741        struct {
    3842                const char * const opt;
     
    4347                { "heap"    , Heap::enabled },
    4448                { "time"    , Time::enabled },
     49                { "resolve" , ResolveTime::enabled },
    4550        };
    4651
  • src/Common/module.mk

    rae2c27a rc76bd34  
    2222      Common/ErrorObjects.h \
    2323      Common/Eval.cc \
     24      Common/Examine.cc \
     25      Common/Examine.h \
    2426      Common/FilterCombos.h \
    2527      Common/Indenter.h \
     
    3840      Common/Stats/Heap.cc \
    3941      Common/Stats/Heap.h \
     42      Common/Stats/ResolveTime.cc \
     43      Common/Stats/ResolveTime.h \
    4044      Common/Stats/Stats.cc \
    4145      Common/Stats/Time.cc \
  • src/Concurrency/Keywords.cc

    rae2c27a rc76bd34  
    1919#include <string>                         // for string, operator==
    2020
     21#include <iostream>
     22
     23#include "Common/Examine.h"               // for isMainFor
    2124#include "Common/PassVisitor.h"           // for PassVisitor
    2225#include "Common/SemanticError.h"         // for SemanticError
     
    3437#include "SynTree/Type.h"                 // for StructInstType, Type, PointerType
    3538#include "SynTree/Visitor.h"              // for Visitor, acceptAll
     39#include "Virtual/Tables.h"
    3640
    3741class Attribute;
    3842
    3943namespace Concurrency {
     44        inline static std::string getVTableName( std::string const & exception_name ) {
     45                return exception_name.empty() ? std::string() : Virtual::vtableTypeName(exception_name);
     46        }
     47
    4048        //=============================================================================================
    4149        // Pass declarations
     
    5462          public:
    5563
    56                 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate cast_target ) :
    57                   type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
     64                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name,
     65                        std::string&& getter_name, std::string&& context_error, std::string&& exception_name,
     66                        bool needs_main, AggregateDecl::Aggregate cast_target ) :
     67                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
     68                  context_error( context_error ), vtable_name( getVTableName( exception_name ) ),
     69                  needs_main( needs_main ), cast_target( cast_target ) {}
    5870
    5971                virtual ~ConcurrentSueKeyword() {}
     
    6375
    6476                void handle( StructDecl * );
     77                void addVtableForward( StructDecl * );
    6578                FunctionDecl * forwardDeclare( StructDecl * );
    6679                ObjectDecl * addField( StructDecl * );
     
    7689                const std::string getter_name;
    7790                const std::string context_error;
     91                const std::string vtable_name;
    7892                bool needs_main;
    7993                AggregateDecl::Aggregate cast_target;
     
    8195                StructDecl   * type_decl = nullptr;
    8296                FunctionDecl * dtor_decl = nullptr;
     97                StructDecl * vtable_decl = nullptr;
    8398        };
    8499
     
    101116                        "get_thread",
    102117                        "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
     118                        "",
    103119                        true,
    104120                        AggregateDecl::Thread
     
    133149                        "get_coroutine",
    134150                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
     151                        "CoroutineCancelled",
    135152                        true,
    136153                        AggregateDecl::Coroutine
     
    167184                        "get_monitor",
    168185                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
     186                        "",
    169187                        false,
    170188                        AggregateDecl::Monitor
     
    198216                        "get_generator",
    199217                        "Unable to find builtin type $generator\n",
     218                        "",
    200219                        true,
    201220                        AggregateDecl::Generator
     
    231250
    232251        private:
    233                 DeclarationWithType * is_main( FunctionDecl * );
    234252                bool is_real_suspend( FunctionDecl * );
    235253
     
    359377                        handle( decl );
    360378                }
     379                else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
     380                        vtable_decl = decl;
     381                }
     382                // Might be able to get ride of is target.
     383                assert( is_target(decl) == (cast_target == decl->kind) );
    361384                return decl;
    362385        }
    363386
    364387        DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) {
    365                 if( !type_decl ) return decl;
    366                 if( !CodeGen::isDestructor( decl->name ) ) return decl;
    367 
    368                 auto params = decl->type->parameters;
    369                 if( params.size() != 1 ) return decl;
    370 
    371                 auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() );
    372                 if( !type ) return decl;
    373 
    374                 auto stype = dynamic_cast<StructInstType*>( type->base );
    375                 if( !stype ) return decl;
    376                 if( stype->baseStruct != type_decl ) return decl;
    377 
    378                 if( !dtor_decl ) dtor_decl = decl;
     388                if ( type_decl && isDestructorFor( decl, type_decl ) )
     389                        dtor_decl = decl;
     390                else if ( vtable_name.empty() )
     391                        ;
     392                else if ( auto param = isMainFor( decl, cast_target ) ) {
     393                        // This should never trigger.
     394                        assert( vtable_decl );
     395                        // Should be safe because of isMainFor.
     396                        StructInstType * struct_type = static_cast<StructInstType *>(
     397                                static_cast<ReferenceType *>( param->get_type() )->base );
     398                        assert( struct_type );
     399
     400                        declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, {
     401                                new TypeExpr( struct_type->clone() ),
     402                        }, struct_type, nullptr ) );
     403                }
     404
    379405                return decl;
    380406        }
     
    400426                if( !dtor_decl ) SemanticError( decl, context_error );
    401427
     428                addVtableForward( decl );
    402429                FunctionDecl * func = forwardDeclare( decl );
    403430                ObjectDecl * field = addField( decl );
    404431                addRoutines( field, func );
     432        }
     433
     434        void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
     435                if ( vtable_decl ) {
     436                        declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, {
     437                                new TypeExpr( new StructInstType( noQualifiers, decl ) ),
     438                        } ) );
     439                // Its only an error if we want a vtable and don't have one.
     440                } else if ( ! vtable_name.empty() ) {
     441                        SemanticError( decl, context_error );
     442                }
    405443        }
    406444
     
    528566        // Suspend keyword implementation
    529567        //=============================================================================================
    530         DeclarationWithType * SuspendKeyword::is_main( FunctionDecl * func) {
    531                 if(func->name != "main") return nullptr;
    532                 if(func->type->parameters.size() != 1) return nullptr;
    533 
    534                 auto param = func->type->parameters.front();
    535 
    536                 auto type  = dynamic_cast<ReferenceType * >(param->get_type());
    537                 if(!type) return nullptr;
    538 
    539                 auto obj   = dynamic_cast<StructInstType *>(type->base);
    540                 if(!obj) return nullptr;
    541 
    542                 if(!obj->baseStruct->is_generator()) return nullptr;
    543 
    544                 return param;
    545         }
    546 
    547568        bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) {
    548569                if(isMangled(func->linkage)) return false; // the real suspend isn't mangled
     
    565586
    566587                // Is this the main of a generator?
    567                 auto param = is_main( func );
     588                auto param = isMainFor( func, AggregateDecl::Aggregate::Generator );
    568589                if(!param) return;
    569590
     
    910931                                        {
    911932                                                new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
    912                                                 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) )
     933                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ),
     934                                                new SingleInit( new ConstantExpr( Constant::from_bool( false ) ) )
    913935                                        },
    914936                                        noDesignators,
     
    10331055// tab-width: 4 //
    10341056// End: //
     1057
  • src/GenPoly/InstantiateGeneric.cc

    rae2c27a rc76bd34  
    172172                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
    173173                /// Set of types which are dtype-only generic (and therefore have static layout)
    174                 ScopedSet< AggregateDecl* > dtypeStatics;
     174                std::set<AggregateDecl *> dtypeStatics;
    175175                /// Namer for concrete types
    176176                UniqueName typeNamer;
     
    505505        void GenericInstantiator::beginScope() {
    506506                instantiations.beginScope();
    507                 dtypeStatics.beginScope();
    508507        }
    509508
    510509        void GenericInstantiator::endScope() {
    511510                instantiations.endScope();
    512                 dtypeStatics.endScope();
    513511        }
    514512
  • src/InitTweak/InitTweak.cc

    rae2c27a rc76bd34  
    10261026                if ( ftype->params.size() != 2 ) return false;
    10271027
    1028                 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() );
     1028                const ast::Type * t1 = getPointerBase( ftype->params.front() );
    10291029                if ( ! t1 ) return false;
    1030                 const ast::Type * t2 = ftype->params.back()->get_type();
     1030                const ast::Type * t2 = ftype->params.back();
    10311031
    10321032                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
  • src/Parser/lex.ll

    rae2c27a rc76bd34  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sat Feb 15 11:05:50 2020
    13  * Update Count     : 737
     12 * Last Modified On : Tue Oct  6 18:15:41 2020
     13 * Update Count     : 743
    1414 */
    1515
     
    6262#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    6363
    64 #ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     64#ifdef HAVE_KEYWORDS_FLOATXX                                                    // GCC >= 7 => keyword, otherwise typedef
    6565#define FLOATXX(v) KEYWORD_RETURN(v);
    6666#else
     
    292292__restrict__    { KEYWORD_RETURN(RESTRICT); }                   // GCC
    293293return                  { KEYWORD_RETURN(RETURN); }
    294         /* resume                       { KEYWORD_RETURN(RESUME); }                             // CFA */
     294 /* resume                      { KEYWORD_RETURN(RESUME); }                             // CFA */
    295295short                   { KEYWORD_RETURN(SHORT); }
    296296signed                  { KEYWORD_RETURN(SIGNED); }
  • src/Parser/parser.yy

    rae2c27a rc76bd34  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 28 12:11:45 2020
    13 // Update Count     : 4500
     12// Last Modified On : Tue Oct  6 18:24:18 2020
     13// Update Count     : 4610
    1414//
    1515
     
    278278%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    279279%token SIZEOF OFFSETOF
    280 // %token RESUME                                                                        // CFA
    281 %token SUSPEND                                                                  // CFA
     280// %token RESUME                                                                                        // CFA
     281%token SUSPEND                                                                                  // CFA
    282282%token ATTRIBUTE EXTENSION                                                              // GCC
    283283%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
     
    329329%type<en> conditional_expression                constant_expression                     assignment_expression           assignment_expression_opt
    330330%type<en> comma_expression                              comma_expression_opt
    331 %type<en> argument_expression_list_opt          argument_expression                     default_initialize_opt
     331%type<en> argument_expression_list_opt  argument_expression                     default_initialize_opt
    332332%type<ifctl> if_control_expression
    333333%type<fctl> for_control_expression              for_control_expression_list
     
    370370%type<decl> assertion assertion_list assertion_list_opt
    371371
    372 %type<en>   bit_subrange_size_opt bit_subrange_size
     372%type<en> bit_subrange_size_opt bit_subrange_size
    373373
    374374%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    793793        | '(' aggregate_control '&' ')' cast_expression         // CFA
    794794                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    795                 // VIRTUAL cannot be opt because of look ahead issues
    796795        | '(' VIRTUAL ')' cast_expression                                       // CFA
    797796                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     
    920919        | unary_expression assignment_operator assignment_expression
    921920                {
    922                         if ( $2 == OperKinds::AtAssn ) {
    923                                 SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    924                         } else {
     921//                      if ( $2 == OperKinds::AtAssn ) {
     922//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
     923//                      } else {
    925924                                $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
    926                         } // if
     925//                      } // if
    927926                }
    928927        | unary_expression '=' '{' initializer_list_opt comma_opt '}'
     
    16761675
    16771676typedef_expression:
    1678                 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
     1677                // deprecated GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
    16791678        TYPEDEF identifier '=' assignment_expression
    16801679                {
    1681                         // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    1682                         SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
     1680                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    16831681                }
    16841682        | typedef_expression pop ',' push identifier '=' assignment_expression
    16851683                {
    1686                         // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    1687                         SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    1688                 }
    1689         ;
    1690 
    1691 //c_declaration:
    1692 //      declaring_list pop ';'
    1693 //      | typedef_declaration pop ';'
    1694 //      | typedef_expression pop ';'                                            // GCC, naming expression type
    1695 //      | sue_declaration_specifier pop ';'
    1696 //      ;
    1697 //
    1698 //declaring_list:
    1699 //              // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    1700 //              // storage-class
    1701 //       declarator asm_name_opt initializer_opt
    1702 //              {
    1703 //                      typedefTable.addToEnclosingScope( IDENTIFIER );
    1704 //                      $$ = ( $2->addType( $1 ))->addAsmName( $3 )->addInitializer( $4 );
    1705 //              }
    1706 //      | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    1707 //              {
    1708 //                      typedefTable.addToEnclosingScope( IDENTIFIER );
    1709 //                      $$ = $1->appendList( $1->cloneBaseType( $4->addAsmName( $5 )->addInitializer( $6 ) ) );
    1710 //              }
    1711 //      ;
     1684                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1685                }
     1686        ;
    17121687
    17131688c_declaration:
     
    17151690                { $$ = distAttr( $1, $2 ); }
    17161691        | typedef_declaration
    1717         | typedef_expression                                                            // GCC, naming expression type
     1692        | typedef_expression                                                            // deprecated GCC, naming expression type
    17181693        | sue_declaration_specifier
    17191694        ;
     
    20942069                { yyy = true; $$ = AggregateDecl::Union; }
    20952070        | EXCEPTION                                                                                     // CFA
    2096                 { yyy = true; $$ = AggregateDecl::Exception; }
     2071                // { yyy = true; $$ = AggregateDecl::Exception; }
     2072                { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    20972073        ;
    20982074
  • src/ResolvExpr/CandidateFinder.cpp

    rae2c27a rc76bd34  
    188188
    189189                        // mark conversion cost and also specialization cost of param type
    190                         const ast::Type * paramType = (*param)->get_type();
     190                        // const ast::Type * paramType = (*param)->get_type();
    191191                        cand->expr = ast::mutate_field_index(
    192192                                appExpr, &ast::ApplicationExpr::args, i,
    193193                                computeExpressionConversionCost(
    194                                         args[i], paramType, symtab, cand->env, convCost ) );
    195                         convCost.decSpec( specCost( paramType ) );
     194                                        args[i], *param, symtab, cand->env, convCost ) );
     195                        convCost.decSpec( specCost( *param ) );
    196196                        ++param;  // can't be in for-loop update because of the continue
    197197                }
     
    698698                        if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) {
    699699                                // attempt to narrow based on expected target type
    700                                 const ast::Type * returnType = funcType->returns.front()->get_type();
     700                                const ast::Type * returnType = funcType->returns.front();
    701701                                if ( ! unify(
    702702                                        returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab )
     
    712712                        std::size_t genStart = 0;
    713713
    714                         for ( const ast::DeclWithType * param : funcType->params ) {
    715                                 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param );
     714                        // xxx - how to handle default arg after change to ftype representation?
     715                        if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) {
     716                                if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) {
     717                                        // function may have default args only if directly calling by name
     718                                        // must use types on candidate however, due to RenameVars substitution
     719                                        auto nParams = funcType->params.size();
     720
     721                                        for (size_t i=0; i<nParams; ++i) {
     722                                                auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
     723                                                if (!instantiateArgument(
     724                                                        funcType->params[i], obj->init, args, results, genStart, symtab)) return;
     725                                        }
     726                                        goto endMatch;
     727                                }
     728                        }
     729                        for ( const auto & param : funcType->params ) {
    716730                                // Try adding the arguments corresponding to the current parameter to the existing
    717731                                // matches
     732                                // no default args for indirect calls
    718733                                if ( ! instantiateArgument(
    719                                         obj->type, obj->init, args, results, genStart, symtab ) ) return;
    720                         }
    721 
     734                                        param, nullptr, args, results, genStart, symtab ) ) return;
     735                        }
     736
     737                        endMatch:
    722738                        if ( funcType->isVarArgs ) {
    723739                                // append any unused arguments to vararg pack
     
    816832                /// Adds aggregate member interpretations
    817833                void addAggMembers(
    818                         const ast::ReferenceToType * aggrInst, const ast::Expr * expr,
     834                        const ast::BaseInstType * aggrInst, const ast::Expr * expr,
    819835                        const Candidate & cand, const Cost & addedCost, const std::string & name
    820836                ) {
     
    12631279
    12641280                void postvisit( const ast::UntypedOffsetofExpr * offsetofExpr ) {
    1265                         const ast::ReferenceToType * aggInst;
     1281                        const ast::BaseInstType * aggInst;
    12661282                        if (( aggInst = offsetofExpr->type.as< ast::StructInstType >() )) ;
    12671283                        else if (( aggInst = offsetofExpr->type.as< ast::UnionInstType >() )) ;
  • src/ResolvExpr/ConversionCost.cc

    rae2c27a rc76bd34  
    520520                return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
    521521        } else {
    522                 ast::Pass<ConversionCost_new> converter( dst, srcIsLvalue, symtab, env, localConversionCost );
    523                 src->accept( converter );
    524                 return converter.core.cost;
     522                return ast::Pass<ConversionCost_new>::read( src, dst, srcIsLvalue, symtab, env, localConversionCost );
    525523        }
    526524}
     
    563561                        }
    564562                } else {
    565                         ast::Pass<ConversionCost_new> converter( dst, srcIsLvalue, symtab, env, localConversionCost );
    566                         src->accept( converter );
    567                         return converter.core.cost;
     563                        return ast::Pass<ConversionCost_new>::read( src, dst, srcIsLvalue, symtab, env, localConversionCost );
    568564                }
    569565        } else {
  • src/ResolvExpr/ConversionCost.h

    rae2c27a rc76bd34  
    8888        static size_t traceId;
    8989        Cost cost;
     90        Cost result() { return cost; }
    9091
    9192        ConversionCost_new( const ast::Type * dst, bool srcIsLvalue, const ast::SymbolTable & symtab,
  • src/ResolvExpr/CurrentObject.cc

    rae2c27a rc76bd34  
    594594        class SimpleIterator final : public MemberIterator {
    595595                CodeLocation location;
    596                 readonly< Type > type = nullptr;
     596                const Type * type = nullptr;
    597597        public:
    598598                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
     
    630630        class ArrayIterator final : public MemberIterator {
    631631                CodeLocation location;
    632                 readonly< ArrayType > array = nullptr;
    633                 readonly< Type > base = nullptr;
     632                const ArrayType * array = nullptr;
     633                const Type * base = nullptr;
    634634                size_t index = 0;
    635635                size_t size = 0;
     
    923923
    924924        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) {
    925                 if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) {
     925                if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) {
    926926                        if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) {
    927927                                return new StructIterator{ loc, sit };
     
    932932                                        dynamic_cast< const EnumInstType * >( type )
    933933                                                || dynamic_cast< const TypeInstType * >( type ),
    934                                         "Encountered unhandled ReferenceToType in createMemberIterator: %s",
     934                                        "Encountered unhandled BaseInstType in createMemberIterator: %s",
    935935                                                toString( type ).c_str() );
    936936                                return new SimpleIterator{ loc, type };
     
    965965                                        DesignatorChain & d = *dit;
    966966                                        PRINT( std::cerr << "____actual: " << t << std::endl; )
    967                                         if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) {
     967                                        if ( auto refType = dynamic_cast< const BaseInstType * >( t ) ) {
    968968                                                // concatenate identical field names
    969969                                                for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
  • src/ResolvExpr/Resolver.cc

    rae2c27a rc76bd34  
    3838#include "Common/PassVisitor.h"          // for PassVisitor
    3939#include "Common/SemanticError.h"        // for SemanticError
     40#include "Common/Stats/ResolveTime.h"    // for ResolveTime::start(), ResolveTime::stop()
    4041#include "Common/utility.h"              // for ValueGuard, group_iterate
    4142#include "InitTweak/GenInit.h"
     
    965966                /// Finds deleted expressions in an expression tree
    966967                struct DeleteFinder_new final : public ast::WithShortCircuiting {
    967                         const ast::DeletedExpr * delExpr = nullptr;
     968                        const ast::DeletedExpr * result = nullptr;
    968969
    969970                        void previsit( const ast::DeletedExpr * expr ) {
    970                                 if ( delExpr ) { visit_children = false; }
    971                                 else { delExpr = expr; }
     971                                if ( result ) { visit_children = false; }
     972                                else { result = expr; }
    972973                        }
    973974
    974975                        void previsit( const ast::Expr * ) {
    975                                 if ( delExpr ) { visit_children = false; }
     976                                if ( result ) { visit_children = false; }
    976977                        }
    977978                };
     
    980981        /// Check if this expression is or includes a deleted expression
    981982        const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
    982                 ast::Pass<DeleteFinder_new> finder;
    983                 expr->accept( finder );
    984                 return finder.core.delExpr;
     983                return ast::Pass<DeleteFinder_new>::read( expr );
    985984        }
    986985
     
    11711170                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11721171                ) {
    1173                         return findKindExpression( untyped, symtab );
     1172                        Stats::ResolveTime::start( untyped );
     1173                        auto res = findKindExpression( untyped, symtab );
     1174                        Stats::ResolveTime::stop();
     1175                        return res;
    11741176                }
    11751177        } // anonymous namespace
     
    12211223                template<typename Iter>
    12221224                inline bool nextMutex( Iter & it, const Iter & end ) {
    1223                         while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1225                        while ( it != end && ! (*it)->is_mutex() ) { ++it; }
    12241226                        return it != end;
    12251227                }
     
    12611263                const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
    12621264                const ast::CatchStmt *       previsit( const ast::CatchStmt * );
     1265                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12631266                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
    12641267
     
    14931496
    14941497        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    1495                 // TODO: This will need a fix for the decl/cond scoping problem.
     1498                // Until we are very sure this invarent (ifs that move between passes have thenPart)
     1499                // holds, check it. This allows a check for when to decode the mangling.
     1500                if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) {
     1501                        assert( ifStmt->thenPart );
     1502                }
     1503                // Encode the catchStmt so the condition can see the declaration.
    14961504                if ( catchStmt->cond ) {
    1497                         ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1498                         catchStmt = ast::mutate_field(
    1499                                 catchStmt, &ast::CatchStmt::cond,
    1500                                 findSingleExpression( catchStmt->cond, boolType, symtab ) );
     1505                        ast::CatchStmt * stmt = mutate( catchStmt );
     1506                        stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body );
     1507                        stmt->cond = nullptr;
     1508                        return stmt;
     1509                }
     1510                return catchStmt;
     1511        }
     1512
     1513        const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) {
     1514                // Decode the catchStmt so everything is stored properly.
     1515                const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>();
     1516                if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) {
     1517                        assert( ifStmt->cond );
     1518                        assert( ifStmt->elsePart );
     1519                        ast::CatchStmt * stmt = ast::mutate( catchStmt );
     1520                        stmt->cond = ifStmt->cond;
     1521                        stmt->body = ifStmt->elsePart;
     1522                        // ifStmt should be implicately deleted here.
     1523                        return stmt;
    15011524                }
    15021525                return catchStmt;
     
    16151638                                                                // Check if the argument matches the parameter type in the current
    16161639                                                                // scope
    1617                                                                 ast::ptr< ast::Type > paramType = (*param)->get_type();
     1640                                                                // ast::ptr< ast::Type > paramType = (*param)->get_type();
    16181641                                                                if (
    16191642                                                                        ! unify(
    1620                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
     1643                                                                                arg->expr->result, *param, resultEnv, need, have, open,
    16211644                                                                                symtab )
    16221645                                                                ) {
     
    16251648                                                                        ss << "candidate function not viable: no known conversion "
    16261649                                                                                "from '";
    1627                                                                         ast::print( ss, (*param)->get_type() );
     1650                                                                        ast::print( ss, *param );
    16281651                                                                        ss << "' to '";
    16291652                                                                        ast::print( ss, arg->expr->result );
  • src/ResolvExpr/SatisfyAssertions.cpp

    rae2c27a rc76bd34  
    318318                                        if ( ! func ) continue;
    319319
    320                                         for ( const ast::DeclWithType * param : func->params ) {
    321                                                 cost.decSpec( specCost( param->get_type() ) );
     320                                        for ( const auto & param : func->params ) {
     321                                                cost.decSpec( specCost( param ) );
    322322                                        }
    323323
  • src/ResolvExpr/SpecCost.cc

    rae2c27a rc76bd34  
    178178                void previsit( const ast::FunctionType * fty ) {
    179179                        int minCount = std::numeric_limits<int>::max();
    180                         updateMinimumPresent( minCount, fty->params, decl_type );
    181                         updateMinimumPresent( minCount, fty->returns, decl_type );
     180                        updateMinimumPresent( minCount, fty->params, type_deref );
     181                        updateMinimumPresent( minCount, fty->returns, type_deref );
    182182                        // Add another level to minCount if set.
    183183                        count = toNoneOrInc( minCount );
  • src/ResolvExpr/Unify.cc

    rae2c27a rc76bd34  
    395395
    396396        template< typename Iterator1, typename Iterator2 >
    397         bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     397        bool unifyTypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    398398                auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
    399399                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
     
    489489                                        || flatOther->isTtype()
    490490                        ) {
    491                                 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    492                                         if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     491                                if ( unifyTypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     492                                        if ( unifyTypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    493493
    494494                                                // the original types must be used in mark assertions, since pointer comparisons are used
     
    784784
    785785                /// returns flattened version of `src`
    786                 static std::vector< ast::ptr< ast::DeclWithType > > flattenList(
    787                         const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env
     786                static std::vector< ast::ptr< ast::Type > > flattenList(
     787                        const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
    788788                ) {
    789                         std::vector< ast::ptr< ast::DeclWithType > > dst;
     789                        std::vector< ast::ptr< ast::Type > > dst;
    790790                        dst.reserve( src.size() );
    791                         for ( const ast::DeclWithType * d : src ) {
     791                        for ( const auto & d : src ) {
    792792                                ast::Pass<TtypeExpander_new> expander{ env };
    793793                                // TtypeExpander pass is impure (may mutate nodes in place)
    794794                                // need to make nodes shared to prevent accidental mutation
    795                                 ast::ptr<ast::DeclWithType> dc = d->accept(expander);
    796                                 auto types = flatten( dc->get_type() );
     795                                ast::ptr<ast::Type> dc = d->accept(expander);
     796                                auto types = flatten( dc );
    797797                                for ( ast::ptr< ast::Type > & t : types ) {
    798798                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play
     
    803803                                        // requirements than a non-mutex function
    804804                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
    805                                         dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } );
     805                                        dst.emplace_back( t );
    806806                                }
    807807                        }
     
    811811                /// Creates a tuple type based on a list of DeclWithType
    812812                template< typename Iter >
    813                 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) {
     813                static ast::ptr< ast::Type > tupleFromTypes( Iter crnt, Iter end ) {
    814814                        std::vector< ast::ptr< ast::Type > > types;
    815815                        while ( crnt != end ) {
    816816                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    817817                                // that this results in a flat tuple
    818                                 flatten( (*crnt)->get_type(), types );
     818                                flatten( *crnt, types );
    819819
    820820                                ++crnt;
     
    825825
    826826                template< typename Iter >
    827                 static bool unifyDeclList(
     827                static bool unifyTypeList(
    828828                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
    829829                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     
    831831                ) {
    832832                        while ( crnt1 != end1 && crnt2 != end2 ) {
    833                                 const ast::Type * t1 = (*crnt1)->get_type();
    834                                 const ast::Type * t2 = (*crnt2)->get_type();
     833                                const ast::Type * t1 = *crnt1;
     834                                const ast::Type * t2 = *crnt2;
    835835                                bool isTuple1 = Tuples::isTtype( t1 );
    836836                                bool isTuple2 = Tuples::isTtype( t2 );
     
    840840                                        // combine remainder of list2, then unify
    841841                                        return unifyExact(
    842                                                 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     842                                                t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    843843                                                noWiden(), symtab );
    844844                                } else if ( ! isTuple1 && isTuple2 ) {
    845845                                        // combine remainder of list1, then unify
    846846                                        return unifyExact(
    847                                                 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     847                                                tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    848848                                                noWiden(), symtab );
    849849                                }
     
    860860                        if ( crnt1 != end1 ) {
    861861                                // try unifying empty tuple with ttype
    862                                 const ast::Type * t1 = (*crnt1)->get_type();
     862                                const ast::Type * t1 = *crnt1;
    863863                                if ( ! Tuples::isTtype( t1 ) ) return false;
    864864                                return unifyExact(
    865                                         t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     865                                        t1, tupleFromTypes( crnt2, end2 ), env, need, have, open,
    866866                                        noWiden(), symtab );
    867867                        } else if ( crnt2 != end2 ) {
    868868                                // try unifying empty tuple with ttype
    869                                 const ast::Type * t2 = (*crnt2)->get_type();
     869                                const ast::Type * t2 = *crnt2;
    870870                                if ( ! Tuples::isTtype( t2 ) ) return false;
    871871                                return unifyExact(
    872                                         tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     872                                        tupleFromTypes( crnt1, end1 ), t2, env, need, have, open,
    873873                                        noWiden(), symtab );
    874874                        }
     
    877877                }
    878878
    879                 static bool unifyDeclList(
    880                         const std::vector< ast::ptr< ast::DeclWithType > > & list1,
    881                         const std::vector< ast::ptr< ast::DeclWithType > > & list2,
     879                static bool unifyTypeList(
     880                        const std::vector< ast::ptr< ast::Type > > & list1,
     881                        const std::vector< ast::ptr< ast::Type > > & list2,
    882882                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    883883                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    884884                ) {
    885                         return unifyDeclList(
     885                        return unifyTypeList(
    886886                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
    887887                                symtab );
     
    928928                        ) return;
    929929
    930                         if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
    931                         if ( ! unifyDeclList(
     930                        if ( ! unifyTypeList( params, params2, tenv, need, have, open, symtab ) ) return;
     931                        if ( ! unifyTypeList(
    932932                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    933933
     
    12321232        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {
    12331233                if ( func->returns.empty() ) return new ast::VoidType{};
    1234                 if ( func->returns.size() == 1 ) return func->returns[0]->get_type();
     1234                if ( func->returns.size() == 1 ) return func->returns[0];
    12351235
    12361236                std::vector<ast::ptr<ast::Type>> tys;
    1237                 for ( const ast::DeclWithType * decl : func->returns ) {
    1238                         tys.emplace_back( decl->get_type() );
     1237                for ( const auto & decl : func->returns ) {
     1238                        tys.emplace_back( decl );
    12391239                }
    12401240                return new ast::TupleType{ std::move(tys) };
  • src/SymTab/Mangler.cc

    rae2c27a rc76bd34  
    437437                  private:
    438438                        void mangleDecl( const ast::DeclWithType *declaration );
    439                         void mangleRef( const ast::ReferenceToType *refType, std::string prefix );
     439                        void mangleRef( const ast::BaseInstType *refType, std::string prefix );
    440440
    441441                        void printQualifiers( const ast::Type *type );
     
    551551                        GuardValue( inFunctionType );
    552552                        inFunctionType = true;
    553                         std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns );
    554                         if (returnTypes.empty()) mangleName << Encoding::void_t;
    555                         else accept_each( returnTypes, *visitor );
     553                        if (functionType->returns.empty()) mangleName << Encoding::void_t;
     554                        else accept_each( functionType->returns, *visitor );
    556555                        mangleName << "_";
    557                         std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
    558                         accept_each( paramTypes, *visitor );
     556                        accept_each( functionType->params, *visitor );
    559557                        mangleName << "_";
    560558                }
    561559
    562                 void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) {
     560                void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) {
    563561                        printQualifiers( refType );
    564562
  • src/SymTab/Validate.cc

    rae2c27a rc76bd34  
    960960        }
    961961
     962        static bool isNonParameterAttribute( Attribute * attr ) {
     963                static const std::vector<std::string> bad_names = {
     964                        "aligned", "__aligned__",
     965                };
     966                for ( auto name : bad_names ) {
     967                        if ( name == attr->name ) {
     968                                return true;
     969                        }
     970                }
     971                return false;
     972        }
     973
    962974        Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) {
    963975                // instances of typedef types will come here. If it is an instance
     
    968980                        ret->location = typeInst->location;
    969981                        ret->get_qualifiers() |= typeInst->get_qualifiers();
    970                         // attributes are not carried over from typedef to function parameters/return values
    971                         if ( ! inFunctionType ) {
    972                                 ret->attributes.splice( ret->attributes.end(), typeInst->attributes );
    973                         } else {
    974                                 deleteAll( ret->attributes );
    975                                 ret->attributes.clear();
    976                         }
     982                        // GCC ignores certain attributes if they arrive by typedef, this mimics that.
     983                        if ( inFunctionType ) {
     984                                ret->attributes.remove_if( isNonParameterAttribute );
     985                        }
     986                        ret->attributes.splice( ret->attributes.end(), typeInst->attributes );
    977987                        // place instance parameters on the typedef'd type
    978988                        if ( ! typeInst->parameters.empty() ) {
     
    13741384        /// Replaces enum types by int, and function/array types in function parameter and return
    13751385        /// lists by appropriate pointers
     1386        /*
    13761387        struct EnumAndPointerDecay_new {
    13771388                const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
     
    14241435                }
    14251436        };
     1437        */
    14261438
    14271439        /// expand assertions from a trait instance, performing appropriate type variable substitutions
     
    15081520                }
    15091521
    1510                 void checkGenericParameters( const ast::ReferenceToType * inst ) {
     1522                void checkGenericParameters( const ast::BaseInstType * inst ) {
    15111523                        for ( const ast::Expr * param : inst->params ) {
    15121524                                if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {
     
    18271839const ast::Type * validateType(
    18281840                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
    1829         ast::Pass< EnumAndPointerDecay_new > epc;
     1841        // ast::Pass< EnumAndPointerDecay_new > epc;
    18301842        ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
    18311843        ast::Pass< ForallPointerDecay_new > fpd{ loc };
    18321844
    1833         return type->accept( epc )->accept( lrt )->accept( fpd );
     1845        return type->accept( lrt )->accept( fpd );
    18341846}
    18351847
  • src/Virtual/module.mk

    rae2c27a rc76bd34  
    1515###############################################################################
    1616
    17 SRC += Virtual/ExpandCasts.cc Virtual/ExpandCasts.h
     17SRC += Virtual/ExpandCasts.cc Virtual/ExpandCasts.h \
     18        Virtual/Tables.cc Virtual/Tables.h
     19
     20SRCDEMANGLE += Virtual/Tables.cc
Note: See TracChangeset for help on using the changeset viewer.