// // 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. // // Type.h -- // // Author : Richard C. Bilson // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Fri Nov 27 17:54:31 2015 // Update Count : 16 // #ifndef TYPE_H #define TYPE_H #include "SynTree.h" #include "Visitor.h" #include "Mutator.h" class Type { public: struct Qualifiers { Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ), isAttribute( false ) {} Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic, bool isAttribute ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute ) {} Qualifiers &operator+=( const Qualifiers &other ); Qualifiers &operator-=( const Qualifiers &other ); Qualifiers operator+( const Type::Qualifiers &other ); bool operator==( const Qualifiers &other ); bool operator!=( const Qualifiers &other ); bool operator<=( const Qualifiers &other ); bool operator>=( const Qualifiers &other ); bool operator<( const Qualifiers &other ); bool operator>( const Qualifiers &other ); bool isConst; bool isVolatile; bool isRestrict; bool isLvalue; bool isAtomic; bool isAttribute; }; Type( const Qualifiers &tq ); Type( const Type &other ); virtual ~Type(); Qualifiers &get_qualifiers() { return tq; } bool get_isConst() { return tq.isConst; } bool get_isVolatile() { return tq.isVolatile; } bool get_isRestrict() { return tq.isRestrict; } bool get_isLvalue() { return tq.isLvalue; } bool get_isAtomic() { return tq.isAtomic; } bool get_isAttribute() { return tq.isAttribute; } void set_isConst( bool newValue ) { tq.isConst = newValue; } void set_isVolatile( bool newValue ) { tq.isVolatile = newValue; } void set_isRestrict( bool newValue ) { tq.isRestrict = newValue; } void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; } void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; } void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; } std::list& get_forall() { return forall; } virtual Type *clone() const = 0; virtual void accept( Visitor &v ) = 0; virtual Type *acceptMutator( Mutator &m ) = 0; virtual void print( std::ostream &os, int indent = 0 ) const; private: Qualifiers tq; std::list forall; }; class VoidType : public Type { public: VoidType( const Type::Qualifiers &tq ); virtual VoidType *clone() const { return new VoidType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; }; class BasicType : public Type { public: enum Kind { Bool, Char, SignedChar, UnsignedChar, ShortSignedInt, ShortUnsignedInt, SignedInt, UnsignedInt, LongSignedInt, LongUnsignedInt, LongLongSignedInt, LongLongUnsignedInt, Float, Double, LongDouble, FloatComplex, DoubleComplex, LongDoubleComplex, FloatImaginary, DoubleImaginary, LongDoubleImaginary, NUMBER_OF_BASIC_TYPES }; static const char *typeNames[]; // string names for basic types, MUST MATCH with Kind BasicType( const Type::Qualifiers &tq, Kind bt ); Kind get_kind() { return kind; } void set_kind( Kind newValue ) { kind = newValue; } virtual BasicType *clone() const { return new BasicType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; bool isInteger() const; private: Kind kind; }; class PointerType : public Type { public: PointerType( const Type::Qualifiers &tq, Type *base ); PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); PointerType( const PointerType& ); virtual ~PointerType(); Type *get_base() { return base; } void set_base( Type *newValue ) { base = newValue; } Expression *get_dimension() { return dimension; } void set_dimension( Expression *newValue ) { dimension = newValue; } bool get_isVarLen() { return isVarLen; } void set_isVarLen( bool newValue ) { isVarLen = newValue; } bool get_isStatic() { return isStatic; } void set_isStatic( bool newValue ) { isStatic = newValue; } virtual PointerType *clone() const { return new PointerType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: Type *base; // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] ) Expression *dimension; bool isVarLen; bool isStatic; }; class ArrayType : public Type { public: ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); ArrayType( const ArrayType& ); virtual ~ArrayType(); Type *get_base() { return base; } void set_base( Type *newValue ) { base = newValue; } Expression *get_dimension() { return dimension; } void set_dimension( Expression *newValue ) { dimension = newValue; } bool get_isVarLen() { return isVarLen; } void set_isVarLen( bool newValue ) { isVarLen = newValue; } bool get_isStatic() { return isStatic; } void set_isStatic( bool newValue ) { isStatic = newValue; } virtual ArrayType *clone() const { return new ArrayType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: Type *base; Expression *dimension; bool isVarLen; bool isStatic; }; class FunctionType : public Type { public: FunctionType( const Type::Qualifiers &tq, bool isVarArgs ); FunctionType( const FunctionType& ); virtual ~FunctionType(); std::list & get_returnVals() { return returnVals; } std::list & get_parameters() { return parameters; } bool get_isVarArgs() { return isVarArgs; } void set_isVarArgs( bool newValue ) { isVarArgs = newValue; } virtual FunctionType *clone() const { return new FunctionType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: std::list returnVals; std::list parameters; // Does the function accept a variable number of arguments following the arguments specified in the parameters list. // This could be because of // - an ellipsis in a prototype declaration // - an unprototyped declaration bool isVarArgs; }; class ReferenceToType : public Type { public: ReferenceToType( const Type::Qualifiers &tq, const std::string &name ); ReferenceToType( const ReferenceToType &other ); virtual ~ReferenceToType(); const std::string &get_name() const { return name; } void set_name( std::string newValue ) { name = newValue; } std::list< Expression* >& get_parameters() { return parameters; } virtual ReferenceToType *clone() const = 0; virtual void accept( Visitor &v ) = 0; virtual Type *acceptMutator( Mutator &m ) = 0; virtual void print( std::ostream &os, int indent = 0 ) const; protected: virtual std::string typeString() const = 0; std::list< Expression* > parameters; private: std::string name; }; class StructInstType : public ReferenceToType { typedef ReferenceToType Parent; public: StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {} StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {} StructDecl *get_baseStruct() const { return baseStruct; } void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; } /// Accesses generic parameters of base struct (NULL if none such) std::list * get_baseParameters(); /// Looks up the members of this struct named "name" and places them into "foundDecls". /// Clones declarations into "foundDecls", caller responsible for freeing void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const; virtual StructInstType *clone() const { return new StructInstType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } private: virtual std::string typeString() const; // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree, // where the structure used in this type is actually defined StructDecl *baseStruct; }; class UnionInstType : public ReferenceToType { typedef ReferenceToType Parent; public: UnionInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseUnion( 0 ) {} UnionInstType( const UnionInstType &other ) : Parent( other ), baseUnion( other.baseUnion ) {} UnionDecl *get_baseUnion() const { return baseUnion; } void set_baseUnion( UnionDecl *newValue ) { baseUnion = newValue; } /// Accesses generic parameters of base union (NULL if none such) std::list * get_baseParameters(); /// looks up the members of this union named "name" and places them into "foundDecls" /// Clones declarations into "foundDecls", caller responsible for freeing void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const; virtual UnionInstType *clone() const { return new UnionInstType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } private: virtual std::string typeString() const; // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree, // where the union used in this type is actually defined UnionDecl *baseUnion; }; class EnumInstType : public ReferenceToType { typedef ReferenceToType Parent; public: EnumInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {} EnumInstType( const EnumInstType &other ) : Parent( other ) {} virtual EnumInstType *clone() const { return new EnumInstType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } private: virtual std::string typeString() const; }; class ContextInstType : public ReferenceToType { typedef ReferenceToType Parent; public: ContextInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {} ContextInstType( const ContextInstType &other ); ~ContextInstType(); std::list< Declaration* >& get_members() { return members; } virtual ContextInstType *clone() const { return new ContextInstType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } private: virtual std::string typeString() const; // this member is filled in by the validate pass, which instantiates the members of the correponding // aggregate with the actual type parameters specified for this use of the context std::list< Declaration* > members; }; class TypeInstType : public ReferenceToType { typedef ReferenceToType Parent; public: TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ); TypeInstType( const Type::Qualifiers &tq, const std::string &name, bool isFtype ); TypeInstType( const TypeInstType &other ) : Parent( other ), baseType( other.baseType ), isFtype( other.isFtype ) {} TypeDecl *get_baseType() const { return baseType; } void set_baseType( TypeDecl *newValue ); bool get_isFtype() const { return isFtype; } void set_isFtype( bool newValue ) { isFtype = newValue; } virtual TypeInstType *clone() const { return new TypeInstType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: virtual std::string typeString() const; // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree, // where the type used here is actually defined TypeDecl *baseType; bool isFtype; }; class TupleType : public Type { public: TupleType( const Type::Qualifiers &tq ); TupleType( const TupleType& ); virtual ~TupleType(); std::list& get_types() { return types; } virtual TupleType *clone() const { return new TupleType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: std::list types; }; class TypeofType : public Type { public: TypeofType( const Type::Qualifiers &tq, Expression *expr ); TypeofType( const TypeofType& ); virtual ~TypeofType(); Expression *get_expr() const { return expr; } void set_expr( Expression *newValue ) { expr = newValue; } virtual TypeofType *clone() const { return new TypeofType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: Expression *expr; }; class AttrType : public Type { public: AttrType( const Type::Qualifiers &tq, const std::string &name, Expression *expr ); AttrType( const Type::Qualifiers &tq, const std::string &name, Type *type ); AttrType( const AttrType& ); virtual ~AttrType(); const std::string &get_name() const { return name; } void set_name( const std::string &newValue ) { name = 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 AttrType *clone() const { return new AttrType( *this ); } virtual void accept( Visitor &v ) { v.visit( this ); } virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); } virtual void print( std::ostream &os, int indent = 0 ) const; private: std::string name; Expression *expr; Type *type; bool isType; }; inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) { isConst |= other.isConst; isVolatile |= other.isVolatile; isRestrict |= other.isRestrict; isLvalue |= other.isLvalue; isAtomic |= other.isAtomic; return *this; } inline Type::Qualifiers &Type::Qualifiers::operator-=( const Type::Qualifiers &other ) { if ( other.isConst ) isConst = 0; if ( other.isVolatile ) isVolatile = 0; if ( other.isRestrict ) isRestrict = 0; if ( other.isAtomic ) isAtomic = 0; return *this; } inline Type::Qualifiers Type::Qualifiers::operator+( const Type::Qualifiers &other ) { Qualifiers q = other; q += *this; return q; } inline bool Type::Qualifiers::operator==( const Qualifiers &other ) { return isConst == other.isConst && isVolatile == other.isVolatile // && isRestrict == other.isRestrict // && isLvalue == other.isLvalue && isAtomic == other.isAtomic; } inline bool Type::Qualifiers::operator!=( const Qualifiers &other ) { return isConst != other.isConst || isVolatile != other.isVolatile // || isRestrict != other.isRestrict // || isLvalue != other.isLvalue || isAtomic != other.isAtomic; } inline bool Type::Qualifiers::operator<=( const Type::Qualifiers &other ) { return isConst <= other.isConst && isVolatile <= other.isVolatile // && isRestrict <= other.isRestrict // && isLvalue >= other.isLvalue && isAtomic == other.isAtomic; } inline bool Type::Qualifiers::operator>=( const Type::Qualifiers &other ) { return isConst >= other.isConst && isVolatile >= other.isVolatile // && isRestrict >= other.isRestrict // && isLvalue <= other.isLvalue && isAtomic == other.isAtomic; } inline bool Type::Qualifiers::operator<( const Type::Qualifiers &other ) { return operator!=( other ) && operator<=( other ); } inline bool Type::Qualifiers::operator>( const Type::Qualifiers &other ) { return operator!=( other ) && operator>=( other ); } #endif // TYPE_H // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //