source: src/SynTree/Type.h @ cd3aee2

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 cd3aee2 was 373d0b5, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

Refactor getAggr as a Type member function

  • Property mode set to 100644
File size: 26.3 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 : Mon Sep 25 14:14:01 2017
13// Update Count     : 154
14//
15
16#pragma once
17
18#include <strings.h>         // for ffs
19#include <cassert>           // for assert, assertf
20#include <list>              // for list, _List_iterator
21#include <ostream>           // for ostream, operator<<, basic_ostream
22#include <string>            // for string
23
24#include "BaseSyntaxNode.h"  // for BaseSyntaxNode
25#include "Common/utility.h"  // for operator+
26#include "Mutator.h"         // for Mutator
27#include "SynTree.h"         // for AST nodes
28#include "Visitor.h"         // for Visitor
29
30class Type : public BaseSyntaxNode {
31  public:
32        // Simulate inheritance because union does not allow it.
33        // Bug in g++-4.9 prevents static field in union
34        //static const char * Names[];
35        #define BFCommon( BFType, N ) \
36                bool operator[]( unsigned int i ) const { return val & (1 << i); } \
37                bool any() const { return val != 0; } \
38                void reset() { val = 0; } \
39                int ffs() { return ::ffs( val ) - 1; } \
40                BFType operator&=( BFType other ) { \
41                        val &= other.val; return *this; \
42                } \
43                BFType operator&( BFType other ) const { \
44                        BFType q = other; \
45                        q &= *this; \
46                        return q; \
47                } \
48                BFType operator|=( BFType other ) { \
49                        val |= other.val; return *this; \
50                } \
51                BFType operator|( BFType other ) const { \
52                        BFType q = other; \
53                        q |= *this; \
54                        return q; \
55                } \
56                BFType operator-=( BFType other ) { \
57                        val &= ~other.val; return *this; \
58                } \
59                void print( std::ostream & os ) const { \
60                        if ( (*this).any() ) { \
61                                for ( unsigned int i = 0; i < N; i += 1 ) { \
62                                        if ( (*this)[i] ) { \
63                                                os << BFType##Names[i] << ' '; \
64                                        } \
65                                } \
66                        } \
67                }
68
69        // enum must remain in the same order as the corresponding bit fields.
70
71        enum { Inline = 1 << 0, Noreturn = 1 << 1, Fortran = 1 << 2, NumFuncSpecifier = 3 };
72        static const char * FuncSpecifiersNames[];
73        union FuncSpecifiers {
74                unsigned int val;
75                struct {
76                        bool is_inline : 1;
77                        bool is_noreturn : 1;
78                        bool is_fortran : 1;
79                };
80                FuncSpecifiers() : val( 0 ) {}
81                FuncSpecifiers( unsigned int val ) : val( val ) {}
82                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
83                BFCommon( FuncSpecifiers, NumFuncSpecifier )
84        }; // FuncSpecifiers
85
86        enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, Threadlocal = 1 << 4, NumStorageClass = 5 };
87        static const char * StorageClassesNames[];
88        union StorageClasses {
89                unsigned int val;
90                struct {
91                        bool is_extern : 1;
92                        bool is_static : 1;
93                        bool is_auto : 1;
94                        bool is_register : 1;
95                        bool is_threadlocal : 1;
96                };
97
98                StorageClasses() : val( 0 ) {}
99                StorageClasses( unsigned int val ) : val( val ) {}
100                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
101                BFCommon( StorageClasses, NumStorageClass )
102        }; // StorageClasses
103
104        enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6 };
105        static const char * QualifiersNames[];
106        union Qualifiers {
107                enum { Mask = ~(Restrict | Lvalue) };
108                unsigned int val;
109                struct {
110                        bool is_const : 1;
111                        bool is_restrict : 1;
112                        bool is_volatile : 1;
113                        bool is_lvalue : 1;
114                        bool is_mutex : 1;
115                        bool is_atomic : 1;
116                };
117
118                Qualifiers() : val( 0 ) {}
119                Qualifiers( unsigned int val ) : val( val ) {}
120                // Complex comparisons provide implicit qualifier downcasting, e.g., T downcast to const T.
121                bool operator==( Qualifiers other ) const { return (val & Mask) == (other.val & Mask); }
122                bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); }
123                bool operator<=( Qualifiers other ) const {
124                        return is_const    <= other.is_const        //Any non-const converts to const without cost
125                                        && is_volatile <= other.is_volatile     //Any non-volatile converts to volatile without cost
126                                        && is_mutex    >= other.is_mutex        //Any mutex converts to non-mutex without cost
127                                        && is_atomic   == other.is_atomic;      //No conversion from atomic to non atomic is free
128                }
129                bool operator<( Qualifiers other ) const { return *this != other && *this <= other; }
130                bool operator>=( Qualifiers other ) const { return ! (*this < other); }
131                bool operator>( Qualifiers other ) const { return *this != other && *this >= other; }
132                BFCommon( Qualifiers, NumTypeQualifier )
133        }; // Qualifiers
134
135        typedef std::list<TypeDecl *> ForallList;
136
137        Qualifiers tq;
138        ForallList forall;
139        std::list< Attribute * > attributes;
140
141        Type( const Qualifiers & tq, const std::list< Attribute * > & attributes );
142        Type( const Type & other );
143        virtual ~Type();
144
145        Qualifiers & get_qualifiers() { return tq; }
146        bool get_const() { return tq.is_const; }
147        bool get_volatile() { return tq.is_volatile; }
148        bool get_restrict() { return tq.is_restrict; }
149        bool get_lvalue() { return tq.is_lvalue; }
150        bool get_mutex() { return tq.is_mutex; }
151        bool get_atomic() { return tq.is_atomic; }
152        void set_const( bool newValue ) { tq.is_const = newValue; }
153        void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
154        void set_restrict( bool newValue ) { tq.is_restrict = newValue; }
155        void set_lvalue( bool newValue ) { tq.is_lvalue = newValue; }
156        void set_mutex( bool newValue ) { tq.is_mutex = newValue; }
157        void set_atomic( bool newValue ) { tq.is_atomic = newValue; }
158
159        ForallList& get_forall() { return forall; }
160
161        std::list< Attribute * >& get_attributes() { return attributes; }
162        const std::list< Attribute * >& get_attributes() const { return attributes; }
163
164        /// How many elemental types are represented by this type
165        virtual unsigned size() const { return 1; };
166        virtual bool isVoid() const { return size() == 0; }
167        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; }
168
169        /// return type without outer pointers and arrays
170        Type * stripDeclarator();
171
172        /// return type without outer references
173        Type * stripReferences();
174
175        /// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types)
176        virtual int referenceDepth() const;
177
178        virtual bool isComplete() const { return true; }
179
180        virtual AggregateDecl * getAggr() {     assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); }
181
182        virtual Type *clone() const = 0;
183        virtual void accept( Visitor & v ) = 0;
184        virtual Type *acceptMutator( Mutator & m ) = 0;
185        virtual void print( std::ostream & os, Indenter indent = {} ) const;
186};
187
188extern const Type::FuncSpecifiers noFuncSpecifiers;
189extern const Type::StorageClasses noStorageClasses;
190extern const Type::Qualifiers noQualifiers;                     // no qualifiers on constants
191
192class VoidType : public Type {
193  public:
194        VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
195
196        virtual unsigned size() const override { return 0; };
197        virtual bool isComplete() const override { return false; }
198
199        virtual VoidType *clone() const override { return new VoidType( *this ); }
200        virtual void accept( Visitor & v ) override { v.visit( this ); }
201        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
202        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
203};
204
205class BasicType : public Type {
206  public:
207        enum Kind {
208                Bool,
209                Char,
210                SignedChar,
211                UnsignedChar,
212                ShortSignedInt,
213                ShortUnsignedInt,
214                SignedInt,
215                UnsignedInt,
216                LongSignedInt,
217                LongUnsignedInt,
218                LongLongSignedInt,
219                LongLongUnsignedInt,
220                Float,
221                Double,
222                LongDouble,
223                FloatComplex,
224                DoubleComplex,
225                LongDoubleComplex,
226                FloatImaginary,
227                DoubleImaginary,
228                LongDoubleImaginary,
229                SignedInt128,
230                UnsignedInt128,
231                NUMBER_OF_BASIC_TYPES
232        } kind;
233
234        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
235
236        BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
237
238        Kind get_kind() { return kind; }
239        void set_kind( Kind newValue ) { kind = newValue; }
240
241        virtual BasicType *clone() const override { return new BasicType( *this ); }
242        virtual void accept( Visitor & v ) override { v.visit( this ); }
243        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
244        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
245
246        bool isInteger() const;
247};
248
249class PointerType : public Type {
250  public:
251        Type *base;
252
253        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
254        Expression *dimension;
255        bool isVarLen;
256        bool isStatic;
257
258        PointerType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
259        PointerType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
260        PointerType( const PointerType& );
261        virtual ~PointerType();
262
263        Type *get_base() { return base; }
264        void set_base( Type *newValue ) { base = newValue; }
265        Expression *get_dimension() { return dimension; }
266        void set_dimension( Expression *newValue ) { dimension = newValue; }
267        bool get_isVarLen() { return isVarLen; }
268        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
269        bool get_isStatic() { return isStatic; }
270        void set_isStatic( bool newValue ) { isStatic = newValue; }
271
272        bool is_array() const { return isStatic || isVarLen || dimension; }
273
274        virtual bool isComplete() const override { return ! isVarLen; }
275
276        virtual PointerType *clone() const override { return new PointerType( *this ); }
277        virtual void accept( Visitor & v ) override { v.visit( this ); }
278        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
279        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
280};
281
282class ArrayType : public Type {
283  public:
284        Type *base;
285        Expression *dimension;
286        bool isVarLen;
287        bool isStatic;
288
289        ArrayType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
290        ArrayType( const ArrayType& );
291        virtual ~ArrayType();
292
293        Type *get_base() { return base; }
294        void set_base( Type *newValue ) { base = newValue; }
295        Expression *get_dimension() { return dimension; }
296        void set_dimension( Expression *newValue ) { dimension = newValue; }
297        bool get_isVarLen() { return isVarLen; }
298        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
299        bool get_isStatic() { return isStatic; }
300        void set_isStatic( bool newValue ) { isStatic = newValue; }
301
302        // array types are complete if they have a dimension expression or are
303        // VLAs ('*' in parameter declaration), and incomplete otherwise.
304        // See 6.7.6.2
305        virtual bool isComplete() const override { return dimension || isVarLen; }
306
307        virtual ArrayType *clone() const override { return new ArrayType( *this ); }
308        virtual void accept( Visitor & v ) override { v.visit( this ); }
309        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
310        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
311};
312
313class ReferenceType : public Type {
314public:
315        Type *base;
316
317        ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
318        ReferenceType( const ReferenceType & );
319        virtual ~ReferenceType();
320
321        Type *get_base() { return base; }
322        void set_base( Type *newValue ) { base = newValue; }
323
324        virtual int referenceDepth() const override;
325
326        // Since reference types act like value types, their size is the size of the base.
327        // This makes it simple to cast the empty tuple to a reference type, since casts that increase
328        // the number of values are disallowed.
329        virtual unsigned size() const override { return base->size(); }
330
331        virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
332        virtual void accept( Visitor & v ) override { v.visit( this ); }
333        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
334        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
335};
336
337class FunctionType : public Type {
338  public:
339        std::list<DeclarationWithType*> returnVals;
340        std::list<DeclarationWithType*> parameters;
341
342        // Does the function accept a variable number of arguments following the arguments specified in the parameters list.
343        // This could be because of
344        // - an ellipsis in a prototype declaration
345        // - an unprototyped declaration
346        bool isVarArgs;
347
348        FunctionType( const Type::Qualifiers & tq, bool isVarArgs, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
349        FunctionType( const FunctionType& );
350        virtual ~FunctionType();
351
352        std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
353        std::list<DeclarationWithType*> & get_parameters() { return parameters; }
354        bool get_isVarArgs() const { return isVarArgs; }
355        void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
356        bool isTtype() const;
357
358        virtual FunctionType *clone() const override { return new FunctionType( *this ); }
359        virtual void accept( Visitor & v ) override { v.visit( this ); }
360        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
361        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
362};
363
364class ReferenceToType : public Type {
365  public:
366        std::list< Expression* > parameters;
367        std::string name;
368        bool hoistType;
369
370        ReferenceToType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes );
371        ReferenceToType( const ReferenceToType & other );
372        virtual ~ReferenceToType();
373
374        const std::string & get_name() const { return name; }
375        void set_name( std::string newValue ) { name = newValue; }
376        std::list< Expression* >& get_parameters() { return parameters; }
377        bool get_hoistType() const { return hoistType; }
378        void set_hoistType( bool newValue ) { hoistType = newValue; }
379
380        virtual ReferenceToType *clone() const override = 0;
381        virtual void accept( Visitor & v ) override = 0;
382        virtual Type *acceptMutator( Mutator & m ) override = 0;
383        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
384
385        virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
386  protected:
387        virtual std::string typeString() const = 0;
388};
389
390class StructInstType : public ReferenceToType {
391        typedef ReferenceToType Parent;
392  public:
393        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
394        // where the structure used in this type is actually defined
395        StructDecl *baseStruct;
396
397        StructInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseStruct( 0 ) {}
398        StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
399        StructInstType( const StructInstType & other ) : Parent( other ), baseStruct( other.baseStruct ) {}
400
401        StructDecl *get_baseStruct() const { return baseStruct; }
402        void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
403
404        /// Accesses generic parameters of base struct (NULL if none such)
405        std::list<TypeDecl*> * get_baseParameters();
406
407        virtual bool isComplete() const override;
408
409        virtual AggregateDecl * getAggr() override;
410
411        /// Looks up the members of this struct named "name" and places them into "foundDecls".
412        /// Clones declarations into "foundDecls", caller responsible for freeing
413        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
414
415        virtual StructInstType *clone() const override { return new StructInstType( *this ); }
416        virtual void accept( Visitor & v ) override { v.visit( this ); }
417        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
418
419        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
420  private:
421        virtual std::string typeString() const override;
422};
423
424class UnionInstType : public ReferenceToType {
425        typedef ReferenceToType Parent;
426  public:
427        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
428        // where the union used in this type is actually defined
429        UnionDecl *baseUnion;
430
431        UnionInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseUnion( 0 ) {}
432        UnionInstType( const Type::Qualifiers & tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
433        UnionInstType( const UnionInstType & other ) : Parent( other ), baseUnion( other.baseUnion ) {}
434
435        UnionDecl *get_baseUnion() const { return baseUnion; }
436        void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; }
437
438        /// Accesses generic parameters of base union (NULL if none such)
439        std::list< TypeDecl * > * get_baseParameters();
440
441        virtual bool isComplete() const override;
442
443        virtual AggregateDecl * getAggr() override;
444
445        /// looks up the members of this union named "name" and places them into "foundDecls"
446        /// Clones declarations into "foundDecls", caller responsible for freeing
447        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
448
449        virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
450        virtual void accept( Visitor & v ) override { v.visit( this ); }
451        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
452
453        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
454  private:
455        virtual std::string typeString() const override;
456};
457
458class EnumInstType : public ReferenceToType {
459        typedef ReferenceToType Parent;
460  public:
461        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
462        // where the union used in this type is actually defined
463        EnumDecl *baseEnum = nullptr;
464
465        EnumInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
466        EnumInstType( const Type::Qualifiers & tq, EnumDecl * baseEnum, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
467        EnumInstType( const EnumInstType & other ) : Parent( other ), baseEnum( other.baseEnum ) {}
468
469        EnumDecl *get_baseEnum() const { return baseEnum; }
470        void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
471
472        virtual bool isComplete() const override;
473
474        virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
475        virtual void accept( Visitor & v ) override { v.visit( this ); }
476        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
477
478        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
479  private:
480        virtual std::string typeString() const override;
481};
482
483class TraitInstType : public ReferenceToType {
484        typedef ReferenceToType Parent;
485  public:
486        // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree,
487        // where the trait used in this type is actually defined
488        TraitDecl * baseTrait = nullptr;
489
490        TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {}
491        TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
492        TraitInstType( const TraitInstType & other );
493        ~TraitInstType();
494
495        virtual bool isComplete() const override;
496
497        virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
498        virtual void accept( Visitor & v ) override { v.visit( this ); }
499        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
500  private:
501        virtual std::string typeString() const override;
502};
503
504class TypeInstType : public ReferenceToType {
505        typedef ReferenceToType Parent;
506  public:
507        // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
508        // where the type used here is actually defined
509        TypeDecl *baseType;
510        bool isFtype;
511
512        TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
513        TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
514        TypeInstType( const TypeInstType & other );
515        ~TypeInstType();
516
517        TypeDecl *get_baseType() const { return baseType; }
518        void set_baseType( TypeDecl *newValue );
519        bool get_isFtype() const { return isFtype; }
520        void set_isFtype( bool newValue ) { isFtype = newValue; }
521
522        virtual bool isComplete() const override;
523
524        virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
525        virtual void accept( Visitor & v ) override { v.visit( this ); }
526        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
527        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
528  private:
529        virtual std::string typeString() const override;
530};
531
532class TupleType : public Type {
533  public:
534        std::list<Type *> types;
535        std::list<Declaration *> members;
536
537        TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
538        TupleType( const TupleType& );
539        virtual ~TupleType();
540
541        typedef std::list<Type*> value_type;
542        typedef value_type::iterator iterator;
543
544        std::list<Type *> & get_types() { return types; }
545        virtual unsigned size() const override { return types.size(); };
546
547        // For now, this is entirely synthetic -- tuple types always have unnamed members.
548        // Eventually, we may allow named tuples, in which case members should subsume types
549        std::list<Declaration *> & get_members() { return members; }
550
551        iterator begin() { return types.begin(); }
552        iterator end() { return types.end(); }
553
554        virtual Type * getComponent( unsigned i ) override {
555                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
556                return *(begin()+i);
557        }
558
559        // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
560
561        virtual TupleType *clone() const override { return new TupleType( *this ); }
562        virtual void accept( Visitor & v ) override { v.visit( this ); }
563        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
564        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
565};
566
567class TypeofType : public Type {
568  public:
569        Expression *expr;
570
571        TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
572        TypeofType( const TypeofType& );
573        virtual ~TypeofType();
574
575        Expression *get_expr() const { return expr; }
576        void set_expr( Expression *newValue ) { expr = newValue; }
577
578        virtual bool isComplete() const override { assert( false ); return false; }
579
580        virtual TypeofType *clone() const override { return new TypeofType( *this ); }
581        virtual void accept( Visitor & v ) override { v.visit( this ); }
582        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
583        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
584};
585
586class AttrType : public Type {
587  public:
588        std::string name;
589        Expression *expr;
590        Type *type;
591        bool isType;
592
593        AttrType( const Type::Qualifiers & tq, const std::string & name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
594        AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
595        AttrType( const AttrType& );
596        virtual ~AttrType();
597
598        const std::string & get_name() const { return name; }
599        void set_name( const std::string & newValue ) { name = newValue; }
600        Expression *get_expr() const { return expr; }
601        void set_expr( Expression *newValue ) { expr = newValue; }
602        Type *get_type() const { return type; }
603        void set_type( Type *newValue ) { type = newValue; }
604        bool get_isType() const { return isType; }
605        void set_isType( bool newValue ) { isType = newValue; }
606
607        virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
608
609        virtual AttrType *clone() const override { return new AttrType( *this ); }
610        virtual void accept( Visitor & v ) override { v.visit( this ); }
611        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
612        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
613};
614
615/// Represents the GCC built-in varargs type
616class VarArgsType : public Type {
617  public:
618        VarArgsType();
619        VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
620
621        virtual bool isComplete() const override{ return true; } // xxx - is this right?
622
623        virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
624        virtual void accept( Visitor & v ) override { v.visit( this ); }
625        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
626        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
627};
628
629/// Represents a zero constant
630class ZeroType : public Type {
631  public:
632        ZeroType();
633        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
634
635        virtual ZeroType *clone() const override { return new ZeroType( *this ); }
636        virtual void accept( Visitor & v ) override { v.visit( this ); }
637        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
638        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
639};
640
641/// Represents a one constant
642class OneType : public Type {
643  public:
644        OneType();
645        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
646
647        virtual OneType *clone() const override { return new OneType( *this ); }
648        virtual void accept( Visitor & v ) override { v.visit( this ); }
649        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
650        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
651};
652
653// Local Variables: //
654// tab-width: 4 //
655// mode: c++ //
656// compile-command: "make install" //
657// End: //
Note: See TracBrowser for help on using the repository browser.