source: src/SynTree/Type.h@ fe26fbf

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since fe26fbf was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 9 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.