source: src/SynTree/Type.h @ 294647b

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 294647b was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

third attempt at gcc attributes

  • Property mode set to 100644
File size: 21.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Type.h --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb  2 17:43:01 2017
13// Update Count     : 33
14//
15
16#ifndef TYPE_H
17#define TYPE_H
18
19#include "SynTree.h"
20#include "Visitor.h"
21#include "Mutator.h"
22#include "Common/utility.h"
23
24class Type {
25  public:
26        struct Qualifiers {
27                Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ) {}
28                Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ) {}
29
30                Qualifiers &operator&=( const Qualifiers &other );
31                Qualifiers &operator+=( const Qualifiers &other );
32                Qualifiers &operator-=( const Qualifiers &other );
33                Qualifiers operator+( const Type::Qualifiers &other );
34                bool operator==( const Qualifiers &other );
35                bool operator!=( const Qualifiers &other );
36                bool operator<=( const Qualifiers &other );
37                bool operator>=( const Qualifiers &other );
38                bool operator<( const Qualifiers &other );
39                bool operator>( const Qualifiers &other );
40                void print( std::ostream &os, int indent = 0 ) const;
41
42                bool isConst;
43                bool isVolatile;
44                bool isRestrict;
45                bool isLvalue;
46                bool isAtomic;
47        };
48
49        Type( const Qualifiers &tq, const std::list< Attribute * > & attributes );
50        Type( const Type &other );
51        virtual ~Type();
52
53        Qualifiers &get_qualifiers() { return tq; }
54        bool get_isConst() { return tq.isConst; }
55        bool get_isVolatile() { return tq.isVolatile; }
56        bool get_isRestrict() { return tq.isRestrict; }
57        bool get_isLvalue() { return tq.isLvalue; }
58        bool get_isAtomic() { return tq.isAtomic; }
59        void set_isConst( bool newValue ) { tq.isConst = newValue; }
60        void set_isVolatile( bool newValue ) { tq.isVolatile = newValue; }
61        void set_isRestrict( bool newValue ) { tq.isRestrict = newValue; }
62        void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; }
63        void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; }
64
65        typedef std::list<TypeDecl *> ForallList;
66        ForallList& get_forall() { return forall; }
67
68        std::list< Attribute * >& get_attributes() { return attributes; }
69        const std::list< Attribute * >& get_attributes() const { return attributes; }
70
71        /// How many elemental types are represented by this type
72        virtual unsigned size() const { return 1; };
73        virtual bool isVoid() const { return size() == 0; }
74        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
75
76        virtual bool isComplete() const { return true; }
77
78        virtual Type *clone() const = 0;
79        virtual void accept( Visitor &v ) = 0;
80        virtual Type *acceptMutator( Mutator &m ) = 0;
81        virtual void print( std::ostream &os, int indent = 0 ) const;
82  private:
83        Qualifiers tq;
84        ForallList forall;
85        std::list< Attribute * > attributes;
86};
87
88extern Type::Qualifiers emptyQualifiers;                                // no qualifiers on constants
89
90class VoidType : public Type {
91  public:
92        VoidType( const Type::Qualifiers &tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
93
94        virtual unsigned size() const { return 0; };
95        virtual bool isComplete() const { return false; }
96
97        virtual VoidType *clone() const { return new VoidType( *this ); }
98        virtual void accept( Visitor &v ) { v.visit( this ); }
99        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
100        virtual void print( std::ostream &os, int indent = 0 ) const;
101};
102
103class BasicType : public Type {
104  public:
105        enum Kind {
106                Bool,
107                Char,
108                SignedChar,
109                UnsignedChar,
110                ShortSignedInt,
111                ShortUnsignedInt,
112                SignedInt,
113                UnsignedInt,
114                LongSignedInt,
115                LongUnsignedInt,
116                LongLongSignedInt,
117                LongLongUnsignedInt,
118                Float,
119                Double,
120                LongDouble,
121                FloatComplex,
122                DoubleComplex,
123                LongDoubleComplex,
124                FloatImaginary,
125                DoubleImaginary,
126                LongDoubleImaginary,
127                NUMBER_OF_BASIC_TYPES
128        };
129
130        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
131
132        BasicType( const Type::Qualifiers &tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
133
134        Kind get_kind() { return kind; }
135        void set_kind( Kind newValue ) { kind = newValue; }
136
137        virtual BasicType *clone() const { return new BasicType( *this ); }
138        virtual void accept( Visitor &v ) { v.visit( this ); }
139        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
140        virtual void print( std::ostream &os, int indent = 0 ) const;
141
142        bool isInteger() const;
143  private:
144        Kind kind;
145};
146
147class PointerType : public Type {
148  public:
149        PointerType( const Type::Qualifiers &tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
150        PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
151        PointerType( const PointerType& );
152        virtual ~PointerType();
153
154        Type *get_base() { return base; }
155        void set_base( Type *newValue ) { base = newValue; }
156        Expression *get_dimension() { return dimension; }
157        void set_dimension( Expression *newValue ) { dimension = newValue; }
158        bool get_isVarLen() { return isVarLen; }
159        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
160        bool get_isStatic() { return isStatic; }
161        void set_isStatic( bool newValue ) { isStatic = newValue; }
162
163        virtual PointerType *clone() const { return new PointerType( *this ); }
164        virtual void accept( Visitor &v ) { v.visit( this ); }
165        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
166        virtual void print( std::ostream &os, int indent = 0 ) const;
167  private:
168        Type *base;
169
170        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
171        Expression *dimension;
172        bool isVarLen;
173        bool isStatic;
174};
175
176class ArrayType : public Type {
177  public:
178        ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
179        ArrayType( const ArrayType& );
180        virtual ~ArrayType();
181
182        Type *get_base() { return base; }
183        void set_base( Type *newValue ) { base = newValue; }
184        Expression *get_dimension() { return dimension; }
185        void set_dimension( Expression *newValue ) { dimension = newValue; }
186        bool get_isVarLen() { return isVarLen; }
187        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
188        bool get_isStatic() { return isStatic; }
189        void set_isStatic( bool newValue ) { isStatic = newValue; }
190
191        virtual bool isComplete() const { return ! isVarLen; }
192
193        virtual ArrayType *clone() const { return new ArrayType( *this ); }
194        virtual void accept( Visitor &v ) { v.visit( this ); }
195        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
196        virtual void print( std::ostream &os, int indent = 0 ) const;
197  private:
198        Type *base;
199        Expression *dimension;
200        bool isVarLen;
201        bool isStatic;
202};
203
204class FunctionType : public Type {
205  public:
206        FunctionType( const Type::Qualifiers &tq, bool isVarArgs, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
207        FunctionType( const FunctionType& );
208        virtual ~FunctionType();
209
210        std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
211        std::list<DeclarationWithType*> & get_parameters() { return parameters; }
212        bool get_isVarArgs() const { return isVarArgs; }
213        void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
214
215        bool isTtype() const;
216
217        virtual FunctionType *clone() const { return new FunctionType( *this ); }
218        virtual void accept( Visitor &v ) { v.visit( this ); }
219        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
220        virtual void print( std::ostream &os, int indent = 0 ) const;
221  private:
222        std::list<DeclarationWithType*> returnVals;
223        std::list<DeclarationWithType*> parameters;
224
225        // Does the function accept a variable number of arguments following the arguments specified in the parameters list.
226        // This could be because of
227        // - an ellipsis in a prototype declaration
228        // - an unprototyped declaration
229        bool isVarArgs;
230};
231
232class ReferenceToType : public Type {
233  public:
234        ReferenceToType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes );
235        ReferenceToType( const ReferenceToType &other );
236        virtual ~ReferenceToType();
237
238        const std::string &get_name() const { return name; }
239        void set_name( std::string newValue ) { name = newValue; }
240        std::list< Expression* >& get_parameters() { return parameters; }
241
242        virtual ReferenceToType *clone() const = 0;
243        virtual void accept( Visitor &v ) = 0;
244        virtual Type *acceptMutator( Mutator &m ) = 0;
245        virtual void print( std::ostream &os, int indent = 0 ) const;
246  protected:
247        virtual std::string typeString() const = 0;
248        std::list< Expression* > parameters;
249        std::string name;
250  private:
251};
252
253class StructInstType : public ReferenceToType {
254        typedef ReferenceToType Parent;
255  public:
256        StructInstType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseStruct( 0 ) {}
257        StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
258        StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
259
260        StructDecl *get_baseStruct() const { return baseStruct; }
261        void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
262
263        /// Accesses generic parameters of base struct (NULL if none such)
264        std::list<TypeDecl*> * get_baseParameters();
265
266        virtual bool isComplete() const;
267
268        /// Looks up the members of this struct named "name" and places them into "foundDecls".
269        /// Clones declarations into "foundDecls", caller responsible for freeing
270        void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
271
272        virtual StructInstType *clone() const { return new StructInstType( *this ); }
273        virtual void accept( Visitor &v ) { v.visit( this ); }
274        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
275
276        virtual void print( std::ostream &os, int indent = 0 ) const;
277  private:
278        virtual std::string typeString() const;
279
280        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
281        // where the structure used in this type is actually defined
282        StructDecl *baseStruct;
283};
284
285class UnionInstType : public ReferenceToType {
286        typedef ReferenceToType Parent;
287  public:
288        UnionInstType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseUnion( 0 ) {}
289        UnionInstType( const Type::Qualifiers &tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
290        UnionInstType( const UnionInstType &other ) : Parent( other ), baseUnion( other.baseUnion ) {}
291
292        UnionDecl *get_baseUnion() const { return baseUnion; }
293        void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; }
294
295        /// Accesses generic parameters of base union (NULL if none such)
296        std::list< TypeDecl * > * get_baseParameters();
297
298        virtual bool isComplete() const;
299
300        /// looks up the members of this union named "name" and places them into "foundDecls"
301        /// Clones declarations into "foundDecls", caller responsible for freeing
302        void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
303
304        virtual UnionInstType *clone() const { return new UnionInstType( *this ); }
305        virtual void accept( Visitor &v ) { v.visit( this ); }
306        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
307
308        virtual void print( std::ostream &os, int indent = 0 ) const;
309  private:
310        virtual std::string typeString() const;
311
312        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
313        // where the union used in this type is actually defined
314        UnionDecl *baseUnion;
315};
316
317class EnumInstType : public ReferenceToType {
318        typedef ReferenceToType Parent;
319  public:
320        EnumInstType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
321        EnumInstType( const Type::Qualifiers &tq, EnumDecl * baseEnum, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
322        EnumInstType( const EnumInstType &other ) : Parent( other ), baseEnum( other.baseEnum ) {}
323
324        EnumDecl *get_baseEnum() const { return baseEnum; }
325        void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
326
327        virtual bool isComplete() const;
328
329        virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
330        virtual void accept( Visitor &v ) { v.visit( this ); }
331        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
332  private:
333        virtual std::string typeString() const;
334
335        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
336        // where the union used in this type is actually defined
337        EnumDecl *baseEnum = nullptr;
338};
339
340class TraitInstType : public ReferenceToType {
341        typedef ReferenceToType Parent;
342  public:
343        TraitInstType( const Type::Qualifiers &tq, const std::string &name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
344        TraitInstType( const TraitInstType &other );
345        ~TraitInstType();
346
347        std::list< Declaration* >& get_members() { return members; }
348
349        virtual bool isComplete() const;
350
351        virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
352        virtual void accept( Visitor &v ) { v.visit( this ); }
353        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
354  private:
355        virtual std::string typeString() const;
356
357        // this member is filled in by the validate pass, which instantiates the members of the correponding
358        // aggregate with the actual type parameters specified for this use of the context
359        std::list< Declaration* > members;
360};
361
362class TypeInstType : public ReferenceToType {
363        typedef ReferenceToType Parent;
364  public:
365        TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
366        TypeInstType( const Type::Qualifiers &tq, const std::string &name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
367        TypeInstType( const TypeInstType &other );
368        ~TypeInstType();
369
370        TypeDecl *get_baseType() const { return baseType; }
371        void set_baseType( TypeDecl *newValue );
372        bool get_isFtype() const { return isFtype; }
373        void set_isFtype( bool newValue ) { isFtype = newValue; }
374
375        virtual bool isComplete() const;
376
377        virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
378        virtual void accept( Visitor &v ) { v.visit( this ); }
379        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
380        virtual void print( std::ostream &os, int indent = 0 ) const;
381  private:
382        virtual std::string typeString() const;
383        // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
384        // where the type used here is actually defined
385        TypeDecl *baseType;
386        bool isFtype;
387};
388
389class TupleType : public Type {
390  public:
391        TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >(), const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
392        TupleType( const TupleType& );
393        virtual ~TupleType();
394
395        typedef std::list<Type*> value_type;
396        typedef value_type::iterator iterator;
397
398        std::list<Type*>& get_types() { return types; }
399        virtual unsigned size() const { return types.size(); };
400
401        iterator begin() { return types.begin(); }
402        iterator end() { return types.end(); }
403
404        virtual Type * getComponent( unsigned i ) {
405                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
406                return *(begin()+i);
407        }
408
409        // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
410
411        virtual TupleType *clone() const { return new TupleType( *this ); }
412        virtual void accept( Visitor &v ) { v.visit( this ); }
413        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
414        virtual void print( std::ostream &os, int indent = 0 ) const;
415  private:
416        std::list<Type*> types;
417};
418
419class TypeofType : public Type {
420  public:
421        TypeofType( const Type::Qualifiers &tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
422        TypeofType( const TypeofType& );
423        virtual ~TypeofType();
424
425        Expression *get_expr() const { return expr; }
426        void set_expr( Expression *newValue ) { expr = newValue; }
427
428        virtual bool isComplete() const { assert( false ); return false; }
429
430        virtual TypeofType *clone() const { return new TypeofType( *this ); }
431        virtual void accept( Visitor &v ) { v.visit( this ); }
432        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
433        virtual void print( std::ostream &os, int indent = 0 ) const;
434  private:
435        Expression *expr;
436};
437
438class AttrType : public Type {
439  public:
440        AttrType( const Type::Qualifiers &tq, const std::string &name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
441        AttrType( const Type::Qualifiers &tq, const std::string &name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
442        AttrType( const AttrType& );
443        virtual ~AttrType();
444
445        const std::string &get_name() const { return name; }
446        void set_name( const std::string &newValue ) { name = newValue; }
447        Expression *get_expr() const { return expr; }
448        void set_expr( Expression *newValue ) { expr = newValue; }
449        Type *get_type() const { return type; }
450        void set_type( Type *newValue ) { type = newValue; }
451        bool get_isType() const { return isType; }
452        void set_isType( bool newValue ) { isType = newValue; }
453
454        virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
455
456        virtual AttrType *clone() const { return new AttrType( *this ); }
457        virtual void accept( Visitor &v ) { v.visit( this ); }
458        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
459        virtual void print( std::ostream &os, int indent = 0 ) const;
460  private:
461        std::string name;
462        Expression *expr;
463        Type *type;
464        bool isType;
465};
466
467/// Represents the GCC built-in varargs type
468class VarArgsType : public Type {
469  public:
470        VarArgsType();
471        VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
472
473        virtual bool isComplete() const{ return true; } // xxx - is this right?
474
475        virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
476        virtual void accept( Visitor &v ) { v.visit( this ); }
477        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
478        virtual void print( std::ostream &os, int indent = 0 ) const;
479};
480
481/// Represents a zero constant
482class ZeroType : public Type {
483  public:
484        ZeroType();
485        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
486
487        virtual ZeroType *clone() const { return new ZeroType( *this ); }
488        virtual void accept( Visitor &v ) { v.visit( this ); }
489        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
490        virtual void print( std::ostream &os, int indent = 0 ) const;
491};
492
493/// Represents a one constant
494class OneType : public Type {
495  public:
496        OneType();
497        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
498
499        virtual OneType *clone() const { return new OneType( *this ); }
500        virtual void accept( Visitor &v ) { v.visit( this ); }
501        virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
502        virtual void print( std::ostream &os, int indent = 0 ) const;
503};
504
505inline Type::Qualifiers &Type::Qualifiers::operator&=( const Type::Qualifiers &other ) {
506        isConst &= other.isConst;
507        isVolatile &= other.isVolatile;
508        isRestrict &= other.isRestrict;
509        isLvalue &= other.isLvalue;
510        isAtomic &= other.isAtomic;
511        return *this;
512}
513
514inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) {
515        isConst |= other.isConst;
516        isVolatile |= other.isVolatile;
517        isRestrict |= other.isRestrict;
518        isLvalue |= other.isLvalue;
519        isAtomic |= other.isAtomic;
520        return *this;
521}
522
523inline Type::Qualifiers &Type::Qualifiers::operator-=( const Type::Qualifiers &other ) {
524        if ( other.isConst ) isConst = 0;
525        if ( other.isVolatile ) isVolatile = 0;
526        if ( other.isRestrict ) isRestrict = 0;
527        if ( other.isAtomic ) isAtomic = 0;
528        return *this;
529}
530
531inline Type::Qualifiers Type::Qualifiers::operator+( const Type::Qualifiers &other ) {
532        Qualifiers q = other;
533        q += *this;
534        return q;
535}
536
537inline bool Type::Qualifiers::operator==( const Qualifiers &other ) {
538        return isConst == other.isConst
539                && isVolatile == other.isVolatile
540//              && isRestrict == other.isRestrict
541//              && isLvalue == other.isLvalue
542                && isAtomic == other.isAtomic;
543}
544
545inline bool Type::Qualifiers::operator!=( const Qualifiers &other ) {
546        return isConst != other.isConst
547                || isVolatile != other.isVolatile
548//              || isRestrict != other.isRestrict
549//              || isLvalue != other.isLvalue
550                || isAtomic != other.isAtomic;
551}
552
553inline bool Type::Qualifiers::operator<=( const Type::Qualifiers &other ) {
554        return isConst <= other.isConst
555                && isVolatile <= other.isVolatile
556//              && isRestrict <= other.isRestrict
557//              && isLvalue >= other.isLvalue
558                && isAtomic == other.isAtomic;
559}
560
561inline bool Type::Qualifiers::operator>=( const Type::Qualifiers &other ) {
562        return isConst >= other.isConst
563                && isVolatile >= other.isVolatile
564//              && isRestrict >= other.isRestrict
565//              && isLvalue <= other.isLvalue
566                && isAtomic == other.isAtomic;
567}
568
569inline bool Type::Qualifiers::operator<( const Type::Qualifiers &other ) {
570        return operator!=( other ) && operator<=( other );
571}
572
573inline bool Type::Qualifiers::operator>( const Type::Qualifiers &other ) {
574        return operator!=( other ) && operator>=( other );
575}
576
577std::ostream & operator<<( std::ostream & out, const Type * type );
578
579#endif // TYPE_H
580
581// Local Variables: //
582// tab-width: 4 //
583// mode: c++ //
584// compile-command: "make install" //
585// End: //
Note: See TracBrowser for help on using the repository browser.