// // 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 : Fri Jul 24 13:49:28 2015 // Update Count : 18 // #ifndef EXPRESSION_H #define EXPRESSION_H #include #include "SynTree.h" #include "Visitor.h" #include "Mutator.h" #include "Constant.h" class Expression { public: Expression(Expression *_aname = 0 ); Expression( const Expression &other ); virtual ~Expression(); std::list& get_results() { return results; } void add_result( Type *t ); 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; } 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: std::list results; TypeSubstitution *env; Expression* argName; // if expression is used as an argument, it can be "designated" by this name }; // 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 ) {} ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ) {} ParamEntry( const ParamEntry &other ); ~ParamEntry(); ParamEntry &operator=( const ParamEntry &other ); UniqueId decl; Type *actualType; Type *formalType; Expression* expr; }; typedef std::map< UniqueId, ParamEntry > InferredParams; // 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, Expression *_aname = 0 ); UntypedExpr( const UntypedExpr &other ); UntypedExpr( Expression *function, std::list &args, Expression *_aname = 0 ); 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; } 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; }; // this class contains a name whose meaning is still not determined class NameExpr : public Expression { public: NameExpr( std::string name, Expression *_aname = 0 ); 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 = 0 ); 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; }; class LabelAddressExpr : public Expression { public: LabelAddressExpr( Expression *arg ); LabelAddressExpr( const AddressExpr &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 = 0 ); CastExpr( Expression *arg, Type *toType, Expression *_aname = 0 ); 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( std::string member, Expression *aggregate, Expression *_aname = 0 ); UntypedMemberExpr( const UntypedMemberExpr &other ); virtual ~UntypedMemberExpr(); std::string get_member() const { return member; } void set_member( const std::string &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: std::string member; Expression *aggregate; }; // MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer class MemberExpr : public Expression { public: MemberExpr( DeclarationWithType *member, Expression *aggregate, Expression *_aname = 0 ); 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 class VariableExpr : public Expression { public: VariableExpr( DeclarationWithType *var, Expression *_aname = 0 ); 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 = 0 ); 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 = 0 ); SizeofExpr( const SizeofExpr &other ); SizeofExpr( Type *type, Expression *_aname = 0 ); 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; }; // AttrExpr represents an @attribute expression (like sizeof, but user-defined) class AttrExpr : public Expression { public: AttrExpr(Expression *attr, Expression *expr, Expression *_aname = 0 ); AttrExpr( const AttrExpr &other ); AttrExpr( Expression *attr, Type *type, Expression *_aname = 0 ); 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 = 0 ); 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 = 0 ); 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 = 0 ); 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; }; // TupleExpr represents a tuple expression ( [a, b, c] ) class TupleExpr : public Expression { public: TupleExpr( Expression *_aname = 0 ); TupleExpr( const TupleExpr &other ); virtual ~TupleExpr(); void set_exprs( std::list newValue ) { exprs = newValue; } 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; }; // SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on class SolvedTupleExpr : public Expression { public: SolvedTupleExpr( Expression *_aname = 0 ) : Expression( _aname ) {} SolvedTupleExpr( std::list &, Expression *_aname = 0 ); SolvedTupleExpr( const SolvedTupleExpr &other ); virtual ~SolvedTupleExpr() {} std::list &get_exprs() { return exprs; } virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *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; }; // 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 ) {} 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; }; // ValofExpr represents a GCC 'lambda expression' class UntypedValofExpr : public Expression { public: UntypedValofExpr( Statement *_body, Expression *_aname = 0 ) : Expression( _aname ), body ( _body ) {} virtual ~UntypedValofExpr() {} Expression *get_value(); Statement *get_body() const { return body; } virtual UntypedValofExpr *clone() const { return new UntypedValofExpr( *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: Statement *body; }; #endif // EXPRESSION_H // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //