Changeset e67a82d for src/AST/Expr.hpp


Ignore:
Timestamp:
Aug 20, 2020, 11:48:15 PM (5 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
d685cb0
Parents:
67ca73e (diff), 013b028 (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:

fix conflicts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.hpp

    r67ca73e re67a82d  
    3131
    3232// Must be included in *all* AST classes; should be #undef'd at the end of the file
    33 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
     33#define MUTATE_FRIEND \
     34    template<typename node_t> friend node_t * mutate(const node_t * node); \
     35        template<typename node_t> friend node_t * shallowCopy(const node_t * node);
     36
    3437
    3538class ConverterOldToNew;
     
    4245struct ParamEntry {
    4346        UniqueId decl;
    44         ptr<Decl> declptr;
     47        readonly<Decl> declptr;
    4548        ptr<Type> actualType;
    4649        ptr<Type> formalType;
     
    6265class Expr : public ParseNode {
    6366public:
    64         /// Saves space (~16 bytes) by combining ResnSlots and InferredParams
     67        /*
     68         * NOTE: the union approach is incorrect until the case of
     69         * partial resolution in InferMatcher is eliminated.
     70         * it is reverted to allow unresolved and resolved parameters
     71         * to coexist in an expression node.
     72         */
    6573        struct InferUnion {
     74                // mode is now unused
    6675                enum { Empty, Slots, Params } mode;
    67                 union data_t {
    68                         char def;
    69                         ResnSlots resnSlots;
    70                         InferredParams inferParams;
    71 
    72                         data_t() : def('\0') {}
    73                         ~data_t() {}
     76                struct data_t {
     77                        // char def;
     78                        ResnSlots * resnSlots;
     79                        InferredParams * inferParams;
     80
     81                        data_t(): resnSlots(nullptr), inferParams(nullptr) {}
     82                        data_t(const data_t &other) = delete;
     83                        ~data_t() {
     84                                delete resnSlots;
     85                                delete inferParams;
     86                        }
    7487                } data;
    7588
    7689                /// initializes from other InferUnion
    7790                void init_from( const InferUnion& o ) {
    78                         switch ( o.mode ) {
    79                         case Empty:  return;
    80                         case Slots:  new(&data.resnSlots) ResnSlots{ o.data.resnSlots }; return;
    81                         case Params: new(&data.inferParams) InferredParams{ o.data.inferParams }; return;
     91                        if (o.data.resnSlots) {
     92                                data.resnSlots = new ResnSlots(*o.data.resnSlots);
     93                        }
     94                        if (o.data.inferParams) {
     95                                data.inferParams = new InferredParams(*o.data.inferParams);
    8296                        }
    8397                }
     
    8599                /// initializes from other InferUnion (move semantics)
    86100                void init_from( InferUnion&& o ) {
    87                         switch ( o.mode ) {
    88                         case Empty:  return;
    89                         case Slots:  new(&data.resnSlots) ResnSlots{ std::move(o.data.resnSlots) }; return;
    90                         case Params:
    91                                 new(&data.inferParams) InferredParams{ std::move(o.data.inferParams) }; return;
    92                         }
    93                 }
    94 
    95                 /// clears variant fields
    96                 void reset() {
    97                         switch( mode ) {
    98                         case Empty:  return;
    99                         case Slots:  data.resnSlots.~ResnSlots(); return;
    100                         case Params: data.inferParams.~InferredParams(); return;
    101                         }
     101                        data.resnSlots = o.data.resnSlots;
     102                        data.inferParams = o.data.inferParams;
     103                        o.data.resnSlots = nullptr;
     104                        o.data.inferParams = nullptr;
    102105                }
    103106
     
    107110                InferUnion& operator= ( const InferUnion& ) = delete;
    108111                InferUnion& operator= ( InferUnion&& ) = delete;
    109                 ~InferUnion() { reset(); }
     112
     113                bool hasSlots() const { return data.resnSlots; }
    110114
    111115                ResnSlots& resnSlots() {
    112                         switch (mode) {
    113                         case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
    114                         case Slots: return data.resnSlots;
    115                         case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
     116                        if (!data.resnSlots) {
     117                                data.resnSlots = new ResnSlots();
    116118                        }
    117                         assertf(false, "unreachable");
     119                        return *data.resnSlots;
    118120                }
    119121
    120122                const ResnSlots& resnSlots() const {
    121                         if (mode == Slots) {
    122                                 return data.resnSlots;
     123                        if (data.resnSlots) {
     124                                return *data.resnSlots;
    123125                        }
    124126                        assertf(false, "Mode was not already resnSlots");
     
    127129
    128130                InferredParams& inferParams() {
    129                         switch (mode) {
    130                         case Slots: data.resnSlots.~ResnSlots(); // fallthrough
    131                         case Empty: new(&data.inferParams) InferredParams{}; mode = Params; // fallthrough
    132                         case Params: return data.inferParams;
     131                        if (!data.inferParams) {
     132                                data.inferParams = new InferredParams();
    133133                        }
    134                         assertf(false, "unreachable");
     134                        return *data.inferParams;
    135135                }
    136136
    137137                const InferredParams& inferParams() const {
    138                         if (mode == Params) {
    139                                 return data.inferParams;
     138                        if (data.inferParams) {
     139                                return *data.inferParams;
    140140                        }
    141141                        assertf(false, "Mode was not already Params");
     
    143143                }
    144144
    145                 void set_inferParams( InferredParams && ps ) {
    146                         switch(mode) {
    147                         case Slots:
    148                                 data.resnSlots.~ResnSlots();
    149                                 // fallthrough
    150                         case Empty:
    151                                 new(&data.inferParams) InferredParams{ std::move( ps ) };
    152                                 mode = Params;
    153                                 break;
    154                         case Params:
    155                                 data.inferParams = std::move( ps );
    156                                 break;
    157                         }
     145                void set_inferParams( InferredParams * ps ) {
     146                        delete data.resnSlots;
     147                        data.resnSlots = nullptr;
     148                        delete data.inferParams;
     149                        data.inferParams = ps;
    158150                }
    159151
     
    161153                /// and the other is in `Params`.
    162154                void splice( InferUnion && o ) {
    163                         if ( o.mode == Empty ) return;
    164                         if ( mode == Empty ) { init_from( o ); return; }
    165                         assert( mode == o.mode && "attempt to splice incompatible InferUnion" );
    166 
    167                         if ( mode == Slots ){
    168                                 data.resnSlots.insert(
    169                                         data.resnSlots.end(), o.data.resnSlots.begin(), o.data.resnSlots.end() );
    170                         } else if ( mode == Params ) {
    171                                 for ( const auto & p : o.data.inferParams ) {
    172                                         data.inferParams[p.first] = std::move(p.second);
     155                        if (o.data.resnSlots) {
     156                                if (data.resnSlots) {
     157                                        data.resnSlots->insert(
     158                                                data.resnSlots->end(), o.data.resnSlots->begin(), o.data.resnSlots->end() );
     159                                        delete o.data.resnSlots;
    173160                                }
    174                         } else assertf(false, "invalid mode");
     161                                else {
     162                                        data.resnSlots = o.data.resnSlots;
     163                                }
     164                                o.data.resnSlots = nullptr;
     165                        }
     166
     167                        if (o.data.inferParams) {
     168                                if (data.inferParams) {
     169                                        for ( const auto & p : *o.data.inferParams ) {
     170                                                (*data.inferParams)[p.first] = std::move(p.second);
     171                                        }
     172                                        delete o.data.inferParams;
     173                                }
     174                                else {
     175                                        data.inferParams = o.data.inferParams;
     176                                }
     177                                o.data.inferParams = nullptr;
     178                        }
    175179                }
    176180        };
     
    185189
    186190        Expr * set_extension( bool ex ) { extension = ex; return this; }
     191        virtual bool get_lvalue() const;
    187192
    188193        virtual const Expr * accept( Visitor & v ) const override = 0;
     
    201206        ApplicationExpr( const CodeLocation & loc, const Expr * f, std::vector<ptr<Expr>> && as = {} );
    202207
     208        bool get_lvalue() const final;
     209
    203210        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    204211private:
     
    215222        UntypedExpr( const CodeLocation & loc, const Expr * f, std::vector<ptr<Expr>> && as = {} )
    216223        : Expr( loc ), func( f ), args( std::move(as) ) {}
     224
     225        bool get_lvalue() const final;
    217226
    218227        /// Creates a new dereference expression
     
    291300        CastExpr( const Expr * a ) : CastExpr( a->location, a, GeneratedCast ) {}
    292301
     302        bool get_lvalue() const final;
     303
    293304        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    294305private:
     
    338349        : Expr( loc ), member( mem ), aggregate( agg ) { assert( aggregate ); }
    339350
     351        bool get_lvalue() const final;
     352
    340353        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    341354private:
     
    352365        MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg );
    353366
     367        bool get_lvalue() const final;
     368
    354369        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    355370private:
    356371        MemberExpr * clone() const override { return new MemberExpr{ *this }; }
    357372        MUTATE_FRIEND
     373
     374        // Custructor overload meant only for AST conversion
     375        enum NoOpConstruction { NoOpConstructionChosen };
     376        MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg,
     377            NoOpConstruction overloadSelector );
     378        friend class ::ConverterOldToNew;
     379        friend class ::ConverterNewToOld;
    358380};
    359381
     
    365387        VariableExpr( const CodeLocation & loc );
    366388        VariableExpr( const CodeLocation & loc, const DeclWithType * v );
     389
     390        bool get_lvalue() const final;
    367391
    368392        /// generates a function pointer for a given function
     
    532556
    533557        CommaExpr( const CodeLocation & loc, const Expr * a1, const Expr * a2 )
    534         : Expr( loc ), arg1( a1 ), arg2( a2 ) {}
     558        : Expr( loc ), arg1( a1 ), arg2( a2 ) {
     559                this->result = a2->result;
     560        }
     561
     562        bool get_lvalue() const final;
    535563
    536564        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
     
    605633        CompoundLiteralExpr( const CodeLocation & loc, const Type * t, const Init * i );
    606634
     635        bool get_lvalue() const final;
     636
    607637        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    608638private:
     
    660690
    661691        TupleIndexExpr( const CodeLocation & loc, const Expr * t, unsigned i );
     692
     693        bool get_lvalue() const final;
    662694
    663695        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Note: See TracChangeset for help on using the changeset viewer.