// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // Expression.h -- // // Author : Richard C. Bilson // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Sat Jul 22 09:53:16 2017 // Update Count : 42 // #pragma once #include #include #include "BaseSyntaxNode.h" #include "Constant.h" #include "Mutator.h" #include "SynTree.h" #include "Visitor.h" #include "Common/UniqueName.h" /// Expression is the root type for all expressions class Expression : public BaseSyntaxNode{ public: Expression( Expression * _aname = nullptr ); Expression( const Expression & other ); virtual ~Expression(); Type *& get_result() { return result; } const Type * get_result() const { return result; } void set_result( Type * newValue ) { result = newValue; } bool has_result() const { return result != nullptr; } TypeSubstitution * get_env() const { return env; } void set_env( TypeSubstitution * newValue ) { env = newValue; } Expression * get_argName() const { return argName; } void set_argName( Expression * name ) { argName = name; } bool get_extension() const { return extension; } Expression * set_extension( bool exten ) { extension = exten; return this; } virtual Expression * clone() const = 0; virtual void accept( Visitor & v ) = 0; virtual Expression * acceptMutator( Mutator & m ) = 0; virtual void print( std::ostream & os, int indent = 0 ) const; protected: Type * result; TypeSubstitution * env; Expression * argName; // if expression is used as an argument, it can be "designated" by this name bool extension = false; }; struct ParamEntry; typedef std::map< UniqueId, ParamEntry > InferredParams; /// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration, /// but subject to decay-to-pointer and type parameter renaming struct ParamEntry { ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ), inferParams( new InferredParams ) {} ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {} ParamEntry( const ParamEntry & other ); ~ParamEntry(); ParamEntry & operator=( const ParamEntry & other ); UniqueId decl; Type * actualType; Type * formalType; Expression* expr; std::unique_ptr< InferredParams > inferParams; }; /// ApplicationExpr represents the application of a function to a set of parameters. This is the result of running an /// UntypedExpr through the expression analyzer. class ApplicationExpr : public Expression { public: ApplicationExpr( Expression * function ); ApplicationExpr( const ApplicationExpr & other ); virtual ~ApplicationExpr(); Expression * get_function() const { return function; } void set_function( Expression * newValue ) { function = newValue; } std::list& get_args() { return args; } InferredParams & get_inferParams() { return inferParams; } virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * function; std::list args; InferredParams inferParams; }; /// UntypedExpr represents the application of a function to a set of parameters, but where the particular overload for /// the function name has not yet been determined. Most operators are converted into functional form automatically, to /// permit operator overloading. class UntypedExpr : public Expression { public: UntypedExpr( Expression * function, const std::list & args = std::list< Expression * >(), Expression *_aname = nullptr ); UntypedExpr( const UntypedExpr & other ); virtual ~UntypedExpr(); Expression * get_function() const { return function; } void set_function( Expression * newValue ) { function = newValue; } void set_args( std::list & listArgs ) { args = listArgs; } std::list::iterator begin_args() { return args.begin(); } std::list::iterator end_args() { return args.end(); } std::list& get_args() { return args; } static UntypedExpr * createDeref( Expression * arg ); static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 ); virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; virtual void printArgs(std::ostream & os, int indent = 0) const; private: Expression * function; std::list args; }; /// NameExpr contains a name whose meaning is still not determined class NameExpr : public Expression { public: NameExpr( std::string name, Expression *_aname = nullptr ); NameExpr( const NameExpr & other ); virtual ~NameExpr(); const std::string & get_name() const { return name; } void set_name( std::string newValue ) { name = newValue; } virtual NameExpr * clone() const { return new NameExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: std::string name; }; // The following classes are used to represent expression types that cannot be converted into // function-call format. /// AddressExpr represents a address-of expression, e.g. & e class AddressExpr : public Expression { public: AddressExpr( Expression * arg, Expression *_aname = nullptr ); AddressExpr( const AddressExpr & other ); virtual ~AddressExpr(); Expression * get_arg() const { return arg; } void set_arg(Expression * newValue ) { arg = newValue; } virtual AddressExpr * clone() const { return new AddressExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg; }; // xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack class LabelAddressExpr : public Expression { public: LabelAddressExpr( Expression * arg ); LabelAddressExpr( const LabelAddressExpr & other ); virtual ~LabelAddressExpr(); Expression * get_arg() const { return arg; } void set_arg(Expression * newValue ) { arg = newValue; } virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg; }; /// CastExpr represents a type cast expression, e.g. (int)e class CastExpr : public Expression { public: CastExpr( Expression * arg, Expression *_aname = nullptr ); CastExpr( Expression * arg, Type * toType, Expression *_aname = nullptr ); CastExpr( const CastExpr & other ); virtual ~CastExpr(); Expression * get_arg() const { return arg; } void set_arg(Expression * newValue ) { arg = newValue; } virtual CastExpr * clone() const { return new CastExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg; }; /// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer class UntypedMemberExpr : public Expression { public: UntypedMemberExpr( Expression * member, Expression * aggregate, Expression *_aname = nullptr ); UntypedMemberExpr( const UntypedMemberExpr & other ); virtual ~UntypedMemberExpr(); Expression * get_member() const { return member; } void set_member( Expression * newValue ) { member = newValue; } Expression * get_aggregate() const { return aggregate; } void set_aggregate( Expression * newValue ) { aggregate = newValue; } virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * member; Expression * aggregate; }; /// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer. /// Does not take ownership of member. class MemberExpr : public Expression { public: MemberExpr( DeclarationWithType * member, Expression * aggregate, Expression *_aname = nullptr ); MemberExpr( const MemberExpr & other ); virtual ~MemberExpr(); DeclarationWithType * get_member() const { return member; } void set_member( DeclarationWithType * newValue ) { member = newValue; } Expression * get_aggregate() const { return aggregate; } void set_aggregate( Expression * newValue ) { aggregate = newValue; } virtual MemberExpr * clone() const { return new MemberExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: DeclarationWithType * member; Expression * aggregate; }; /// VariableExpr represents an expression that simply refers to the value of a named variable. /// Does not take ownership of var. class VariableExpr : public Expression { public: VariableExpr( DeclarationWithType * var, Expression *_aname = nullptr ); VariableExpr( const VariableExpr & other ); virtual ~VariableExpr(); DeclarationWithType * get_var() const { return var; } void set_var( DeclarationWithType * newValue ) { var = newValue; } virtual VariableExpr * clone() const { return new VariableExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: DeclarationWithType * var; }; /// ConstantExpr represents an expression that simply refers to the value of a constant class ConstantExpr : public Expression { public: ConstantExpr( Constant constant, Expression *_aname = nullptr ); ConstantExpr( const ConstantExpr & other ); virtual ~ConstantExpr(); Constant * get_constant() { return & constant; } void set_constant( const Constant & newValue ) { constant = newValue; } virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Constant constant; }; /// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4) class SizeofExpr : public Expression { public: SizeofExpr( Expression * expr, Expression *_aname = nullptr ); SizeofExpr( const SizeofExpr & other ); SizeofExpr( Type * type, Expression *_aname = nullptr ); virtual ~SizeofExpr(); Expression * get_expr() const { return expr; } void set_expr( Expression * newValue ) { expr = newValue; } Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } bool get_isType() const { return isType; } void set_isType( bool newValue ) { isType = newValue; } virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * expr; Type * type; bool isType; }; /// AlignofExpr represents an alignof expression class AlignofExpr : public Expression { public: AlignofExpr( Expression * expr, Expression *_aname = nullptr ); AlignofExpr( const AlignofExpr & other ); AlignofExpr( Type * type, Expression *_aname = nullptr ); virtual ~AlignofExpr(); Expression * get_expr() const { return expr; } void set_expr( Expression * newValue ) { expr = newValue; } Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } bool get_isType() const { return isType; } void set_isType( bool newValue ) { isType = newValue; } virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * expr; Type * type; bool isType; }; /// UntypedOffsetofExpr represents an offsetof expression before resolution class UntypedOffsetofExpr : public Expression { public: UntypedOffsetofExpr( Type * type, const std::string & member, Expression *_aname = nullptr ); UntypedOffsetofExpr( const UntypedOffsetofExpr & other ); virtual ~UntypedOffsetofExpr(); std::string get_member() const { return member; } void set_member( const std::string & newValue ) { member = newValue; } Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Type * type; std::string member; }; /// OffsetofExpr represents an offsetof expression class OffsetofExpr : public Expression { public: OffsetofExpr( Type * type, DeclarationWithType * member, Expression *_aname = nullptr ); OffsetofExpr( const OffsetofExpr & other ); virtual ~OffsetofExpr(); Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } DeclarationWithType * get_member() const { return member; } void set_member( DeclarationWithType * newValue ) { member = newValue; } virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Type * type; DeclarationWithType * member; }; /// Expression representing a pack of field-offsets for a generic type class OffsetPackExpr : public Expression { public: OffsetPackExpr( StructInstType * type_, Expression * aname_ = 0 ); OffsetPackExpr( const OffsetPackExpr & other ); virtual ~OffsetPackExpr(); StructInstType * get_type() const { return type; } void set_type( StructInstType * newValue ) { type = newValue; } virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: StructInstType * type; }; /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) class AttrExpr : public Expression { public: AttrExpr(Expression * attr, Expression * expr, Expression *_aname = nullptr ); AttrExpr( const AttrExpr & other ); AttrExpr( Expression * attr, Type * type, Expression *_aname = nullptr ); virtual ~AttrExpr(); Expression * get_attr() const { return attr; } void set_attr( Expression * newValue ) { attr = newValue; } Expression * get_expr() const { return expr; } void set_expr( Expression * newValue ) { expr = newValue; } Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } bool get_isType() const { return isType; } void set_isType( bool newValue ) { isType = newValue; } virtual AttrExpr * clone() const { return new AttrExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * attr; Expression * expr; Type * type; bool isType; }; /// LogicalExpr represents a short-circuit boolean expression (&& or ||) class LogicalExpr : public Expression { public: LogicalExpr( Expression * arg1, Expression * arg2, bool andp = true, Expression *_aname = nullptr ); LogicalExpr( const LogicalExpr & other ); virtual ~LogicalExpr(); bool get_isAnd() const { return isAnd; } Expression * get_arg1() { return arg1; } void set_arg1( Expression * newValue ) { arg1 = newValue; } Expression * get_arg2() const { return arg2; } void set_arg2( Expression * newValue ) { arg2 = newValue; } virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg1; Expression * arg2; bool isAnd; }; /// ConditionalExpr represents the three-argument conditional ( p ? a : b ) class ConditionalExpr : public Expression { public: ConditionalExpr( Expression * arg1, Expression * arg2, Expression * arg3, Expression *_aname = nullptr ); ConditionalExpr( const ConditionalExpr & other ); virtual ~ConditionalExpr(); Expression * get_arg1() const { return arg1; } void set_arg1( Expression * newValue ) { arg1 = newValue; } Expression * get_arg2() const { return arg2; } void set_arg2( Expression * newValue ) { arg2 = newValue; } Expression * get_arg3() const { return arg3; } void set_arg3( Expression * newValue ) { arg3 = newValue; } virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg1; Expression * arg2; Expression * arg3; }; /// CommaExpr represents the sequence operator ( a, b ) class CommaExpr : public Expression { public: CommaExpr( Expression * arg1, Expression * arg2, Expression *_aname = nullptr ); CommaExpr( const CommaExpr & other ); virtual ~CommaExpr(); Expression * get_arg1() const { return arg1; } void set_arg1( Expression * newValue ) { arg1 = newValue; } Expression * get_arg2() const { return arg2; } void set_arg2( Expression * newValue ) { arg2 = newValue; } virtual CommaExpr * clone() const { return new CommaExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * arg1; Expression * arg2; }; /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter) class TypeExpr : public Expression { public: TypeExpr( Type * type ); TypeExpr( const TypeExpr & other ); virtual ~TypeExpr(); Type * get_type() const { return type; } void set_type( Type * newValue ) { type = newValue; } virtual TypeExpr * clone() const { return new TypeExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Type * type; }; /// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result) class AsmExpr : public Expression { public: AsmExpr( Expression * inout, ConstantExpr * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {} AsmExpr( const AsmExpr & other ); virtual ~AsmExpr() { delete inout; delete constraint; delete operand; }; Expression * get_inout() const { return inout; } void set_inout( Expression * newValue ) { inout = newValue; } ConstantExpr * get_constraint() const { return constraint; } void set_constraint( ConstantExpr * newValue ) { constraint = newValue; } Expression * get_operand() const { return operand; } void set_operand( Expression * newValue ) { operand = newValue; } virtual AsmExpr * clone() const { return new AsmExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints Expression * inout; ConstantExpr * constraint; Expression * operand; }; /// ImplicitCopyCtorExpr represents the application of a function to a set of parameters, /// along with a set of copy constructor calls, one for each argument. class ImplicitCopyCtorExpr : public Expression { public: ImplicitCopyCtorExpr( ApplicationExpr * callExpr ); ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ); virtual ~ImplicitCopyCtorExpr(); ApplicationExpr * get_callExpr() const { return callExpr; } void set_callExpr( ApplicationExpr * newValue ) { callExpr = newValue; } std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; } std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; } std::list< Expression * > & get_dtors() { return dtors; } virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: ApplicationExpr * callExpr; std::list< ObjectDecl * > tempDecls; std::list< ObjectDecl * > returnDecls; std::list< Expression * > dtors; }; /// ConstructorExpr represents the use of a constructor in an expression context, e.g. int * x = malloc() { 5 }; class ConstructorExpr : public Expression { public: ConstructorExpr( Expression * callExpr ); ConstructorExpr( const ConstructorExpr & other ); ~ConstructorExpr(); Expression * get_callExpr() const { return callExpr; } void set_callExpr( Expression * newValue ) { callExpr = newValue; } virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * callExpr; }; /// CompoundLiteralExpr represents a C99 'compound literal' class CompoundLiteralExpr : public Expression { public: CompoundLiteralExpr( Type * type, Initializer * initializer ); CompoundLiteralExpr( const CompoundLiteralExpr & other ); virtual ~CompoundLiteralExpr(); Initializer * get_initializer() const { return initializer; } void set_initializer( Initializer * i ) { initializer = i; } virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Initializer * initializer; }; /// RangeExpr represents a range e.g. '3 ... 5' or '1~10' class RangeExpr : public Expression { public: RangeExpr( Expression * low, Expression * high ); RangeExpr( const RangeExpr & other ); Expression * get_low() const { return low; } Expression * get_high() const { return high; } RangeExpr * set_low( Expression * low ) { RangeExpr::low = low; return this; } RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; } virtual RangeExpr * clone() const { return new RangeExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * low, * high; }; /// UntypedTupleExpr represents a tuple expression ( [a, b, c] ) before resolution class UntypedTupleExpr : public Expression { public: UntypedTupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr ); UntypedTupleExpr( const UntypedTupleExpr & other ); virtual ~UntypedTupleExpr(); std::list& get_exprs() { return exprs; } virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: std::list exprs; }; /// TupleExpr represents a tuple expression ( [a, b, c] ) class TupleExpr : public Expression { public: TupleExpr( const std::list< Expression * > & exprs, Expression *_aname = nullptr ); TupleExpr( const TupleExpr & other ); virtual ~TupleExpr(); std::list& get_exprs() { return exprs; } virtual TupleExpr * clone() const { return new TupleExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: std::list exprs; }; /// TupleIndexExpr represents an element selection operation on a tuple value, e.g. t.3 after processing by the expression analyzer class TupleIndexExpr : public Expression { public: TupleIndexExpr( Expression * tuple, unsigned int index ); TupleIndexExpr( const TupleIndexExpr & other ); virtual ~TupleIndexExpr(); Expression * get_tuple() const { return tuple; } int get_index() const { return index; } TupleIndexExpr * set_tuple( Expression * newValue ) { tuple = newValue; return this; } TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; } virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * tuple; unsigned int index; }; /// TupleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];, a mass assignment operation, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;, or a tuple ctor/dtor expression class TupleAssignExpr : public Expression { public: TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr ); TupleAssignExpr( const TupleAssignExpr & other ); virtual ~TupleAssignExpr(); TupleAssignExpr * set_stmtExpr( StmtExpr * newValue ) { stmtExpr = newValue; return this; } StmtExpr * get_stmtExpr() const { return stmtExpr; } virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: StmtExpr * stmtExpr = nullptr; }; /// StmtExpr represents a GCC 'statement expression', e.g. ({ int x = 5; x; }) class StmtExpr : public Expression { public: StmtExpr( CompoundStmt * statements ); StmtExpr( const StmtExpr & other ); virtual ~StmtExpr(); CompoundStmt * get_statements() const { return statements; } StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; } std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; } std::list< Expression * > & get_dtors() { return dtors; } virtual StmtExpr * clone() const { return new StmtExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: CompoundStmt * statements; std::list< ObjectDecl * > returnDecls; // return variable(s) for stmt expression std::list< Expression * > dtors; // destructor(s) for return variable(s) }; class UniqueExpr : public Expression { public: UniqueExpr( Expression * expr, long long idVal = -1 ); UniqueExpr( const UniqueExpr & other ); ~UniqueExpr(); Expression * get_expr() const { return expr; } UniqueExpr * set_expr( Expression * newValue ) { expr = newValue; return this; } ObjectDecl * get_object() const { return object; } UniqueExpr * set_object( ObjectDecl * newValue ) { object = newValue; return this; } VariableExpr * get_var() const { return var; } UniqueExpr * set_var( VariableExpr * newValue ) { var = newValue; return this; } int get_id() const { return id; } virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * expr; ObjectDecl * object; VariableExpr * var; int id; static long long count; }; struct InitAlternative { public: Type * type = nullptr; Designation * designation = nullptr; InitAlternative( Type * type, Designation * designation ); InitAlternative( const InitAlternative & other ); InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it ~InitAlternative(); }; class UntypedInitExpr : public Expression { public: UntypedInitExpr( Expression * expr, const std::list & initAlts ); UntypedInitExpr( const UntypedInitExpr & other ); ~UntypedInitExpr(); Expression * get_expr() const { return expr; } UntypedInitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; } std::list & get_initAlts() { return initAlts; } virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * expr; std::list initAlts; }; class InitExpr : public Expression { public: InitExpr( Expression * expr, Designation * designation ); InitExpr( const InitExpr & other ); ~InitExpr(); Expression * get_expr() const { return expr; } InitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; } Designation * get_designation() const { return designation; } InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; } virtual InitExpr * clone() const { return new InitExpr( * this ); } virtual void accept( Visitor & v ) { v.visit( this ); } virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); } virtual void print( std::ostream & os, int indent = 0 ) const; private: Expression * expr; Designation * designation; }; std::ostream & operator<<( std::ostream & out, const Expression * expr ); // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //