Changeset b8524ca


Ignore:
Timestamp:
Jun 20, 2019, 6:50:42 PM (2 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
9af00d23
Parents:
234b1cb
Message:

new AST porting

  • mostly InitTweak? autogeneration
  • added some convenience methods
    • nullptr assignment for ast::ptr
    • convenience wrapper ctors for AddressExpr?, CastExpr? that draw location from first arg
Location:
src
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.hpp

    r234b1cb rb8524ca  
    248248        AddressExpr( const CodeLocation & loc, const Expr * a );
    249249
     250        /// Generate AddressExpr wrapping given expression at same location
     251        AddressExpr( const Expr * a ) : AddressExpr( a->location, a ) {}
     252
    250253        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    251254private:
     
    281284        /// Cast-to-void
    282285        CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast );
     286
     287        /// Wrap a cast expression around an existing expression (always generated)
     288        CastExpr( const Expr * a, const Type * to ) : CastExpr( a->location, a, to, GeneratedCast ) {}
     289
     290        /// Wrap a cast-to-void expression around an existing expression (always generated)
     291        CastExpr( const Expr * a ) : CastExpr( a->location, a, GeneratedCast ) {}
    283292
    284293        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Node.hpp

    r234b1cb rb8524ca  
    1717
    1818#include <cassert>
     19#include <cstddef>     // for nullptr_t
    1920#include <iosfwd>
    2021#include <type_traits> // for remove_reference
     
    181182        }
    182183
     184        ptr_base & operator=( std::nullptr_t ) {
     185                if ( node ) _dec(node);
     186                node = nullptr;
     187                return *this;
     188        }
     189
    183190        ptr_base & operator=( const ptr_base & o ) {
    184191                assign(o.node);
  • src/AST/Stmt.hpp

    r234b1cb rb8524ca  
    6161        CompoundStmt( CompoundStmt&& o ) = default;
    6262
    63         void push_back( Stmt * s ) { kids.emplace_back( s ); }
    64         void push_front( Stmt * s ) { kids.emplace_front( s ); }
     63        void push_back( const Stmt * s ) { kids.emplace_back( s ); }
     64        void push_front( const Stmt * s ) { kids.emplace_front( s ); }
    6565
    6666        const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/InitTweak/FixInit.cc

    r234b1cb rb8524ca  
    11111111                                                arg2 = new MemberExpr( field, new VariableExpr( params.back() ) );
    11121112                                        }
    1113                                         InitExpander srcParam( arg2 );
     1113                                        InitExpander_old srcParam( arg2 );
    11141114                                        // cast away reference type and construct field.
    11151115                                        Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() );
  • src/InitTweak/GenInit.cc

    r234b1cb rb8524ca  
    1818#include <algorithm>                   // for any_of
    1919#include <cassert>                     // for assert, strict_dynamic_cast, assertf
     20#include <deque>
    2021#include <iterator>                    // for back_inserter, inserter, back_inse...
    2122#include <list>                        // for _List_iterator, list
    2223
     24#include "AST/Decl.hpp"
     25#include "AST/Init.hpp"
     26#include "AST/Node.hpp"
     27#include "AST/Stmt.hpp"
    2328#include "CodeGen/OperatorTable.h"
    2429#include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
     
    274279                assertf( objDecl, "genCtorDtor passed null objDecl" );
    275280                std::list< Statement * > stmts;
    276                 InitExpander srcParam( maybeClone( arg ) );
     281                InitExpander_old srcParam( maybeClone( arg ) );
    277282                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
    278283                assert( stmts.size() <= 1 );
     
    286291                std::list< Statement * > dtor;
    287292
    288                 InitExpander srcParam( objDecl->get_init() );
    289                 InitExpander nullParam( (Initializer *)NULL );
     293                InitExpander_old srcParam( objDecl->get_init() );
     294                InitExpander_old nullParam( (Initializer *)NULL );
    290295                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
    291296                SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
     
    354359        }
    355360
    356 ast::ConstructorInit * genCtorInit( const ast::ObjectDecl * objDecl ) {
    357         #warning unimplemented
    358         (void)objDecl;
    359         assert( false );
     361ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) {
     362        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each
     363        // constructable object
     364        InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
     365       
     366        ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall(
     367                srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
     368        ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall(
     369                nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl,
     370                SymTab::LoopBackward );
     371       
     372        // check that either both ctor and dtor are present, or neither
     373        assert( (bool)ctor == (bool)dtor );
     374
     375        if ( ctor ) {
     376                // need to remember init expression, in case no ctors exist. If ctor does exist, want to
     377                // use ctor expression instead of init.
     378                ctor.strict_as< ast::ImplicitCtorDtorStmt >();
     379                dtor.strict_as< ast::ImplicitCtorDtorStmt >();
     380
     381                return new ast::ConstructorInit{ loc, ctor, dtor, objDecl->init };
     382        }
     383
    360384        return nullptr;
    361385}
  • src/InitTweak/GenInit.h

    r234b1cb rb8524ca  
    2020
    2121#include "AST/Fwd.hpp"
     22#include "Common/CodeLocation.h"
    2223#include "GenPoly/ScopedSet.h" // for ScopedSet
    2324#include "SynTree/SynTree.h"   // for Visitor Nodes
     
    3536        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    3637        ConstructorInit * genCtorInit( ObjectDecl * objDecl );
    37         ast::ConstructorInit * genCtorInit( const ast::ObjectDecl * objDecl );
     38        ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl );
    3839
    3940        class ManagedTypes {
  • src/InitTweak/InitTweak.cc

    r234b1cb rb8524ca  
    2222
    2323#include "AST/Expr.hpp"
     24#include "AST/Node.hpp"
    2425#include "AST/Stmt.hpp"
    2526#include "AST/Type.hpp"
     
    112113        }
    113114
    114         class InitExpander::ExpanderImpl {
     115std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
     116        #warning unimplmented
     117        (void)init;
     118        assert(false);
     119        return {};
     120}
     121
     122        class InitExpander_old::ExpanderImpl {
    115123        public:
    116124                virtual ~ExpanderImpl() = default;
     
    119127        };
    120128
    121         class InitImpl : public InitExpander::ExpanderImpl {
     129        class InitImpl_old : public InitExpander_old::ExpanderImpl {
    122130        public:
    123                 InitImpl( Initializer * init ) : init( init ) {}
    124                 virtual ~InitImpl() = default;
     131                InitImpl_old( Initializer * init ) : init( init ) {}
     132                virtual ~InitImpl_old() = default;
    125133
    126134                virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) {
     
    136144        };
    137145
    138         class ExprImpl : public InitExpander::ExpanderImpl {
     146        class ExprImpl_old : public InitExpander_old::ExpanderImpl {
    139147        public:
    140                 ExprImpl( Expression * expr ) : arg( expr ) {}
    141                 virtual ~ExprImpl() { delete arg; }
     148                ExprImpl_old( Expression * expr ) : arg( expr ) {}
     149                virtual ~ExprImpl_old() { delete arg; }
    142150
    143151                virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
     
    163171        };
    164172
    165         InitExpander::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}
    166 
    167         InitExpander::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}
    168 
    169         std::list< Expression * > InitExpander::operator*() {
     173        InitExpander_old::InitExpander_old( Initializer * init ) : expander( new InitImpl_old( init ) ) {}
     174
     175        InitExpander_old::InitExpander_old( Expression * expr ) : expander( new ExprImpl_old( expr ) ) {}
     176
     177        std::list< Expression * > InitExpander_old::operator*() {
    170178                return cur;
    171179        }
    172180
    173         InitExpander & InitExpander::operator++() {
     181        InitExpander_old & InitExpander_old::operator++() {
    174182                cur = expander->next( indices );
    175183                return *this;
     
    177185
    178186        // use array indices list to build switch statement
    179         void InitExpander::addArrayIndex( Expression * index, Expression * dimension ) {
     187        void InitExpander_old::addArrayIndex( Expression * index, Expression * dimension ) {
    180188                indices.push_back( index );
    181189                indices.push_back( dimension );
    182190        }
    183191
    184         void InitExpander::clearArrayIndices() {
     192        void InitExpander_old::clearArrayIndices() {
    185193                deleteAll( indices );
    186194                indices.clear();
    187195        }
    188196
    189         bool InitExpander::addReference() {
     197        bool InitExpander_old::addReference() {
    190198                bool added = false;
    191199                for ( Expression *& expr : cur ) {
     
    218226
    219227                template< typename OutIterator >
    220                 void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
     228                void build( UntypedExpr * callExpr, InitExpander_old::IndexList::iterator idx, InitExpander_old::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
    221229                        if ( idx == idxEnd ) return;
    222230                        Expression * index = *idx++;
     
    275283        // remaining elements.
    276284        // To accomplish this, generate switch statement, consuming all of expander's elements
    277         Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
     285        Statement * InitImpl_old::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    278286                if ( ! init ) return nullptr;
    279287                CompoundStmt * block = new CompoundStmt();
     
    288296        }
    289297
    290         Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
     298        Statement * ExprImpl_old::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
    291299                return nullptr;
    292300        }
    293301
    294         Statement * InitExpander::buildListInit( UntypedExpr * dst ) {
     302        Statement * InitExpander_old::buildListInit( UntypedExpr * dst ) {
    295303                return expander->buildListInit( dst, indices );
    296304        }
     305
     306class InitExpander_new::ExpanderImpl {
     307public:
     308        virtual ~ExpanderImpl() = default;
     309        virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
     310        virtual ast::ptr< ast::Stmt > buildListInit(
     311                const ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
     312};
     313
     314namespace {
     315        class InitImpl_new final : public InitExpander_new::ExpanderImpl {
     316                ast::ptr< ast::Init > init;
     317        public:
     318                InitImpl_new( const ast::Init * i ) : init( i ) {}
     319
     320                std::vector< ast::ptr< ast::Expr > > next( InitExpander_new::IndexList & ) override {
     321                        return makeInitList( init );
     322                }
     323               
     324                ast::ptr< ast::Stmt > buildListInit(
     325                        const ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
     326                ) override {
     327                        #warning unimplemented
     328                        (void)callExpr; (void)indices;
     329                        assert(false);
     330                        return {};
     331                }
     332        };
     333
     334        class ExprImpl_new final : public InitExpander_new::ExpanderImpl {
     335                ast::ptr< ast::Expr > arg;
     336        public:
     337                ExprImpl_new( const ast::Expr * a ) : arg( a ) {}
     338
     339                std::vector< ast::ptr< ast::Expr > > next(
     340                        InitExpander_new::IndexList & indices
     341                ) override {
     342                        #warning unimplemented
     343                        (void)indices;
     344                        assert(false);
     345                        return {};
     346                }
     347               
     348                ast::ptr< ast::Stmt > buildListInit(
     349                        const ast::UntypedExpr *, InitExpander_new::IndexList &
     350                ) override {
     351                        return {};
     352                }
     353        };
     354} // anonymous namespace
     355
     356InitExpander_new::InitExpander_new( const ast::Init * init )
     357: expander( new InitImpl_new{ init } ), crnt(), indices() {}
     358
     359InitExpander_new::InitExpander_new( const ast::Expr * expr )
     360: expander( new ExprImpl_new{ expr } ), crnt(), indices() {}
     361
     362std::vector< ast::ptr< ast::Expr > > InitExpander_new::operator* () { return crnt; }
     363
     364InitExpander_new & InitExpander_new::operator++ () {
     365        crnt = expander->next( indices );
     366        return *this;
     367}
     368
     369/// builds statement which has the same semantics as a C-style list initializer (for array
     370/// initializers) using callExpr as the base expression to perform initialization
     371ast::ptr< ast::Stmt > InitExpander_new::buildListInit( const ast::UntypedExpr * callExpr ) {
     372        return expander->buildListInit( callExpr, indices );
     373}
     374
     375void InitExpander_new::addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ) {
     376        indices.emplace_back( index );
     377        indices.emplace_back( dimension );
     378}
     379
     380void InitExpander_new::clearArrayIndices() { indices.clear(); }
     381
     382bool InitExpander_new::addReference() {
     383        for ( ast::ptr< ast::Expr > & expr : crnt ) {
     384                expr = new ast::AddressExpr{ expr };
     385        }
     386        return ! crnt.empty();
     387}
    297388
    298389        Type * getTypeofThis( FunctionType * ftype ) {
  • src/InitTweak/InitTweak.h

    r234b1cb rb8524ca  
    4444        /// transform Initializer into an argument list that can be passed to a call expression
    4545        std::list< Expression * > makeInitList( Initializer * init );
     46        std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init );
    4647
    4748        /// True if the resolver should try to construct dwt
     
    101102        bool isConstExpr( Initializer * init );
    102103
    103         class InitExpander {
     104        class InitExpander_old {
    104105        public:
    105106                // expand by stepping through init to get each list of arguments
    106                 InitExpander( Initializer * init );
     107                InitExpander_old( Initializer * init );
    107108
    108109                // always expand to expr
    109                 InitExpander( Expression * expr );
     110                InitExpander_old( Expression * expr );
    110111
    111112                // iterator-like interface
    112113                std::list< Expression * > operator*();
    113                 InitExpander & operator++();
     114                InitExpander_old & operator++();
    114115
    115116                // builds statement which has the same semantics as a C-style list initializer
     
    130131                IndexList indices;
    131132        };
     133
     134        class InitExpander_new {
     135        public:
     136                using IndexList = std::vector< ast::ptr< ast::Expr > >;
     137                class ExpanderImpl;
     138
     139        private:
     140                std::shared_ptr< ExpanderImpl > expander;
     141                std::vector< ast::ptr< ast::Expr > > crnt;
     142                // invariant: list of size 2N (elements come in pairs [index, dimension])
     143                IndexList indices;
     144
     145        public:
     146                /// Expand by stepping through init to get each list of arguments
     147                InitExpander_new( const ast::Init * init );
     148
     149                /// Always expand to expression
     150                InitExpander_new( const ast::Expr * expr );
     151
     152                std::vector< ast::ptr< ast::Expr > > operator* ();
     153                InitExpander_new & operator++ ();
     154
     155                /// builds statement which has the same semantics as a C-style list initializer (for array
     156                /// initializers) using callExpr as the base expression to perform initialization
     157                ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr );
     158
     159                void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension );
     160
     161                void clearArrayIndices();
     162
     163                bool addReference();
     164        };
    132165} // namespace
    133166
  • src/ResolvExpr/CandidateFinder.cpp

    r234b1cb rb8524ca  
    5757                // cast away reference from expr
    5858                cost.incReference();
    59                 return new ast::CastExpr{ expr->location, expr, expr->result->stripReferences() };
     59                return new ast::CastExpr{ expr, expr->result->stripReferences() };
    6060        }
    6161       
     
    126126                        ast::ptr< ast::Type > newType = paramType;
    127127                        env.apply( newType );
    128                         return new ast::CastExpr{ arg->location, arg, newType };
     128                        return new ast::CastExpr{ arg, newType };
    129129
    130130                        // xxx - *should* be able to resolve this cast, but at the moment pointers are not
     
    793793                       
    794794                        if ( aggrType.as< ast::ReferenceType >() ) {
    795                                 aggrExpr =
    796                                         new ast::CastExpr{ aggrExpr->location, aggrExpr, aggrType->stripReferences() };
     795                                aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() };
    797796                        }
    798797
  • src/ResolvExpr/Resolver.cc

    r234b1cb rb8524ca  
    11091109               
    11101110                // set up and resolve expression cast to void
    1111                 ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr };
     1111                ast::CastExpr * untyped = new ast::CastExpr{ expr };
    11121112                CandidateRef choice = findUnfinishedKindExpression(
    11131113                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
     
    11611161                ) {
    11621162                        assert( untyped && type );
    1163                         ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped->location, untyped, type };
     1163                        ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
    11641164                        ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
    11651165                        removeExtraneousCast( newExpr, symtab );
  • src/SymTab/Autogen.cc

    r234b1cb rb8524ca  
    2424#include <vector>                  // for vector
    2525
     26#include "AST/Decl.hpp"
    2627#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    2728#include "Common/PassVisitor.h"    // for PassVisitor
     
    209210        }
    210211
     212        bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {
     213                return obj && obj->name.empty() && obj->bitfieldWidth;
     214        }
     215
    211216        /// inserts a forward declaration for functionDecl into declsToAdd
    212217        void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
     
    388393
    389394        void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) {
    390                 InitTweak::InitExpander srcParam( src );
     395                InitTweak::InitExpander_old srcParam( src );
    391396
    392397                // assign to destination
  • src/SymTab/Autogen.h

    r234b1cb rb8524ca  
    1717
    1818#include <cassert>                // for assert
     19#include <iterator>               // for back_inserter
    1920#include <string>                 // for string
    2021
     22#include "AST/Decl.hpp"
     23#include "AST/Expr.hpp"
     24#include "AST/Init.hpp"
     25#include "AST/Node.hpp"
     26#include "AST/Stmt.hpp"
     27#include "AST/Type.hpp"
    2128#include "CodeGen/OperatorTable.h"
    2229#include "Common/UniqueName.h"    // for UniqueName
     30#include "Common/utility.h"       // for splice
    2331#include "InitTweak/InitTweak.h"  // for InitExpander
    2432#include "SynTree/Constant.h"     // for Constant
     
    3644        /// returns true if obj's name is the empty string and it has a bitfield width
    3745        bool isUnnamedBitfield( ObjectDecl * obj );
     46        bool isUnnamedBitfield( const ast::ObjectDecl * obj );
    3847
    3948        /// generate the type of an assignment function for paramType.
     
    4958        FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true );
    5059
     60        /// Enum for loop direction
     61        enum LoopDirection { LoopBackward, LoopForward };
     62
    5163        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    5264        template< typename OutputIterator >
    53         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     65        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     66
     67        template< typename OutIter >
     68        ast::ptr< ast::Stmt > genCall(
     69                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     70                const CodeLocation & loc, const std::string & fname, OutIter && out,
     71                const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward );
    5472
    5573        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    5674        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    5775        template< typename OutputIterator >
    58         Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
     76        Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
    5977                bool isReferenceCtorDtor = false;
    6078                if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     
    106124        }
    107125
     126        /// inserts into out a generated call expression to function fname with arguments dstParam and
     127        /// srcParam. Should only be called with non-array types.
     128        /// optionally returns a statement which must be inserted prior to the containing loop, if
     129        /// there is one
     130        template< typename OutIter >
     131        ast::ptr< ast::Stmt > genScalarCall(
     132                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     133                const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type,
     134                const ast::Type * addCast = nullptr
     135        ) {
     136                bool isReferenceCtorDtor = false;
     137                if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     138                        // reference constructors are essentially application of the rebind operator.
     139                        // apply & to both arguments, do not need a cast
     140                        fname = "?=?";
     141                        dstParam = new ast::AddressExpr{ dstParam };
     142                        addCast = nullptr;
     143                        isReferenceCtorDtor = true;
     144                }
     145
     146                // want to be able to generate assignment, ctor, and dtor generically, so fname is one of
     147                // "?=?", "?{}", or "^?{}"
     148                ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } };
     149
     150                if ( addCast ) {
     151                        // cast to T& with qualifiers removed, so that qualified objects can be constructed and
     152                        // destructed with the same functions as non-qualified objects. Unfortunately, lvalue
     153                        // is considered a qualifier - for AddressExpr to resolve, its argument must have an
     154                        // lvalue-qualified type, so remove all qualifiers except lvalue.
     155                        // xxx -- old code actually removed lvalue too...
     156                        ast::ptr< ast::Type > guard = addCast;  // prevent castType from mutating addCast
     157                        ast::ptr< ast::Type > castType = addCast;
     158                        ast::remove_qualifiers(
     159                                castType,
     160                                ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic );
     161                        dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } };
     162                }
     163                fExpr->args.emplace_back( dstParam );
     164
     165                const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
     166
     167                // fetch next set of arguments
     168                ++srcParam;
     169
     170                // return if adding reference fails -- will happen on default ctor and dtor
     171                if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit;
     172
     173                std::vector< ast::ptr< ast::Expr > > args = *srcParam;
     174                splice( fExpr->args, args );
     175
     176                *out++ = new ast::ExprStmt{ loc, fExpr };
     177
     178                srcParam.clearArrayIndices();
     179               
     180                return listInit;
     181        }
     182
    108183        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    109184        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    110185        template< typename OutputIterator >
    111         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
     186        void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
    112187                static UniqueName indexName( "_index" );
    113188
     
    170245        }
    171246
     247        /// Store in out a loop which calls fname on each element of the array with srcParam and
     248        /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0
     249        template< typename OutIter >
     250        void genArrayCall(
     251                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     252                const CodeLocation & loc, const std::string & fname, OutIter && out,
     253                const ast::ArrayType * array, const ast::Type * addCast = nullptr,
     254                LoopDirection forward = LoopForward
     255        ) {
     256                static UniqueName indexName( "_index" );
     257
     258                // for a flexible array member nothing is done -- user must define own assignment
     259                if ( ! array->dimension ) return;
     260
     261                if ( addCast ) {
     262                        // peel off array layer from cast
     263                        addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base;
     264                }
     265
     266                ast::ptr< ast::Expr > begin, end, cmp, update;
     267
     268                if ( forward ) {
     269                        // generate: for ( int i = 0; i < N; ++i )
     270                        begin = ast::ConstantExpr::from_int( loc, 0 );
     271                        end = array->dimension;
     272                        cmp = new ast::NameExpr{ loc, "?<?" };
     273                        update = new ast::NameExpr{ loc, "++?" };
     274                } else {
     275                        // generate: for ( int i = N-1; i >= 0; --i )
     276                        begin = new ast::UntypedExpr{
     277                                loc, new ast::NameExpr{ loc, "?-?" },
     278                                { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } };
     279                        end = ast::ConstantExpr::from_int( loc, 0 );
     280                        cmp = new ast::NameExpr{ loc, "?>=?" };
     281                        update = new ast::NameExpr{ loc, "--?" };
     282                }
     283
     284                ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{
     285                        loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt },
     286                        new ast::SingleInit{ loc, begin } };
     287               
     288                ast::ptr< ast::Expr > cond = new ast::UntypedExpr{
     289                        loc, cmp, { new ast::VariableExpr{ loc, index }, end } };
     290               
     291                ast::ptr< ast::Expr > inc = new ast::UntypedExpr{
     292                        loc, update, { new ast::VariableExpr{ loc, index } } };
     293               
     294                ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{
     295                        loc, new ast::NameExpr{ loc, "?[?]" },
     296                        { dstParam, new ast::VariableExpr{ loc, index } } };
     297               
     298                // srcParam must keep track of the array indices to build the source parameter and/or
     299                // array list initializer
     300                srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );
     301
     302                // for stmt's body, eventually containing call
     303                ast::CompoundStmt * body = new ast::CompoundStmt{ loc };
     304                ast::ptr< ast::Stmt > listInit = genCall(
     305                        srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast,
     306                        forward );
     307               
     308                // block containing the stmt and index variable
     309                ast::CompoundStmt * block = new ast::CompoundStmt{ loc };
     310                block->push_back( new ast::DeclStmt{ loc, index } );
     311                if ( listInit ) { block->push_back( listInit ); }
     312                block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } );
     313
     314                *out++ = block;
     315        }
     316
    172317        template< typename OutputIterator >
    173         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
     318        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
    174319                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    175320                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     
    180325        }
    181326
     327        template< typename OutIter >
     328        ast::ptr< ast::Stmt > genCall(
     329                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     330                const CodeLocation & loc, const std::string & fname, OutIter && out,
     331                const ast::Type * type, const ast::Type * addCast, LoopDirection forward
     332        ) {
     333                if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
     334                        genArrayCall(
     335                                srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast,
     336                                forward );
     337                        return {};
     338                } else {
     339                        return genScalarCall(
     340                                srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast );
     341                }
     342        }
     343
    182344        /// inserts into out a generated call expression to function fname with arguments dstParam
    183345        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     
    185347        /// ImplicitCtorDtorStmt node.
    186348        template< typename OutputIterator >
    187         void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     349        void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    188350                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    189351                assert( obj );
     
    213375                }
    214376        }
     377
     378        static inline ast::ptr< ast::Stmt > genImplicitCall(
     379                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     380                const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj,
     381                LoopDirection forward = LoopForward
     382        ) {
     383                // unnamed bit fields are not copied as they cannot be accessed
     384                if ( isUnnamedBitfield( obj ) ) return {};
     385
     386                ast::ptr< ast::Type > addCast = nullptr;
     387                if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
     388                        assert( dstParam->result );
     389                        addCast = dstParam->result;
     390                }
     391
     392                std::vector< ast::ptr< ast::Stmt > > stmts;
     393                genCall(
     394                        srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward );
     395
     396                if ( stmts.empty() ) {
     397                        return {};
     398                } else if ( stmts.size() == 1 ) {
     399                        const ast::Stmt * callStmt = stmts.front();
     400                        if ( addCast ) {
     401                                // implicitly generated ctor/dtor calls should be wrapped so that later passes are
     402                                // aware they were generated.
     403                                callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt };
     404                        }
     405                        return callStmt;
     406                } else {
     407                        assert( false );
     408                        return {};
     409                }
     410        }
    215411} // namespace SymTab
    216412
  • src/Tuples/Explode.cc

    r234b1cb rb8524ca  
    133133                        if ( first ) {
    134134                                castAdded = true;
    135                                 const ast::Expr * tuple = new ast::TupleExpr(
    136                                         tupleExpr->location, std::move( exprs ) );
    137                                 return new ast::CastExpr( tuple->location,
    138                                         tuple, new ast::ReferenceType( tuple->result.get(), ast::CV::Qualifiers() ) );
     135                                const ast::Expr * tuple = new ast::TupleExpr{
     136                                        tupleExpr->location, std::move( exprs ) };
     137                                return new ast::CastExpr{ tuple, new ast::ReferenceType{ tuple->result } };
    139138                        } else {
    140139                                return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) );
     
    145144                } else {
    146145                        castAdded = true;
    147                         return new ast::CastExpr( expr->location, expr,
    148                                 new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );
     146                        return new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
    149147                }
    150148        }
     
    164162                        castAdded = false;
    165163                        const ast::Type * newType = getReferenceBase( newNode->result );
    166                         return new ast::CastExpr( newNode->location, node, newType );
     164                        return new ast::CastExpr{ newNode->location, node, newType };
    167165                }
    168166                return newNode;
     
    183181        expr = expr->accept( exploder );
    184182        if ( ! exploder.pass.foundUniqueExpr ) {
    185                 expr = new ast::CastExpr( expr->location, expr,
    186                         new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );
     183                expr = new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
    187184        }
    188185        return expr;
  • src/Tuples/Explode.h

    r234b1cb rb8524ca  
    211211                        // Cast a reference away to a value-type to allow further explosion.
    212212                        if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) {
    213                                 local = new ast::CastExpr( local->location, local, tupleType );
     213                                local = new ast::CastExpr{ local, tupleType };
    214214                        }
    215215                        // Now we have to go across the tuple via indexing.
  • src/Tuples/TupleAssignment.cc

    r234b1cb rb8524ca  
    464464                                        // resolve ctor/dtor for the new object
    465465                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
    466                                                         InitTweak::genCtorInit( ret ), spotter.crntFinder.symtab );
     466                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab );
    467467                                        // remove environments from subexpressions of stmtExpr
    468468                                        ast::Pass< EnvRemover > rm{ env };
     
    550550                                        // is && and RHS is lvalue
    551551                                        auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
    552                                         rhsCand->expr = new ast::CastExpr{
    553                                                 rhsCand->expr->location, rhsCand->expr, lhsType->base };
     552                                        rhsCand->expr = new ast::CastExpr{ rhsCand->expr, lhsType->base };
    554553                                        ast::ptr< ast::ObjectDecl > lobj = newObject( lhsNamer, lhsCand->expr );
    555554                                        ast::ptr< ast::ObjectDecl > robj = newObject( rhsNamer, rhsCand->expr );
     
    604603                                        if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
    605604                                                lhsCand->expr = new ast::CastExpr{
    606                                                         lhsCand->expr->location, lhsCand->expr,
    607                                                         new ast::ReferenceType{ lhsCand->expr->result } };
     605                                                        lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
    608606                                        }
    609607
     
    616614                                                if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
    617615                                                        cand->expr = new ast::CastExpr{
    618                                                                 cand->expr->location, cand->expr,
    619                                                                 new ast::ReferenceType{ cand->expr->result } };
     616                                                                cand->expr, new ast::ReferenceType{ cand->expr->result } };
    620617                                                }
    621618                                        }
Note: See TracChangeset for help on using the changeset viewer.