source: src/SynTree/Type.h @ 28bc8c8

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 28bc8c8 was 8aa474a, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add isUnprototyped member to FunctionType?

  • Property mode set to 100644
File size: 26.4 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        bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
359
360        virtual FunctionType *clone() const override { return new FunctionType( *this ); }
361        virtual void accept( Visitor & v ) override { v.visit( this ); }
362        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
363        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
364};
365
366class ReferenceToType : public Type {
367  public:
368        std::list< Expression* > parameters;
369        std::string name;
370        bool hoistType;
371
372        ReferenceToType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes );
373        ReferenceToType( const ReferenceToType & other );
374        virtual ~ReferenceToType();
375
376        const std::string & get_name() const { return name; }
377        void set_name( std::string newValue ) { name = newValue; }
378        std::list< Expression* >& get_parameters() { return parameters; }
379        bool get_hoistType() const { return hoistType; }
380        void set_hoistType( bool newValue ) { hoistType = newValue; }
381
382        virtual ReferenceToType *clone() const override = 0;
383        virtual void accept( Visitor & v ) override = 0;
384        virtual Type *acceptMutator( Mutator & m ) override = 0;
385        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
386
387        virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
388  protected:
389        virtual std::string typeString() const = 0;
390};
391
392class StructInstType : public ReferenceToType {
393        typedef ReferenceToType Parent;
394  public:
395        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
396        // where the structure used in this type is actually defined
397        StructDecl *baseStruct;
398
399        StructInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseStruct( 0 ) {}
400        StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
401        StructInstType( const StructInstType & other ) : Parent( other ), baseStruct( other.baseStruct ) {}
402
403        StructDecl *get_baseStruct() const { return baseStruct; }
404        void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
405
406        /// Accesses generic parameters of base struct (NULL if none such)
407        std::list<TypeDecl*> * get_baseParameters();
408
409        virtual bool isComplete() const override;
410
411        virtual AggregateDecl * getAggr() override;
412
413        /// Looks up the members of this struct named "name" and places them into "foundDecls".
414        /// Clones declarations into "foundDecls", caller responsible for freeing
415        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
416
417        virtual StructInstType *clone() const override { return new StructInstType( *this ); }
418        virtual void accept( Visitor & v ) override { v.visit( this ); }
419        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
420
421        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
422  private:
423        virtual std::string typeString() const override;
424};
425
426class UnionInstType : public ReferenceToType {
427        typedef ReferenceToType Parent;
428  public:
429        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
430        // where the union used in this type is actually defined
431        UnionDecl *baseUnion;
432
433        UnionInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseUnion( 0 ) {}
434        UnionInstType( const Type::Qualifiers & tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
435        UnionInstType( const UnionInstType & other ) : Parent( other ), baseUnion( other.baseUnion ) {}
436
437        UnionDecl *get_baseUnion() const { return baseUnion; }
438        void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; }
439
440        /// Accesses generic parameters of base union (NULL if none such)
441        std::list< TypeDecl * > * get_baseParameters();
442
443        virtual bool isComplete() const override;
444
445        virtual AggregateDecl * getAggr() override;
446
447        /// looks up the members of this union named "name" and places them into "foundDecls"
448        /// Clones declarations into "foundDecls", caller responsible for freeing
449        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
450
451        virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
452        virtual void accept( Visitor & v ) override { v.visit( this ); }
453        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
454
455        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
456  private:
457        virtual std::string typeString() const override;
458};
459
460class EnumInstType : public ReferenceToType {
461        typedef ReferenceToType Parent;
462  public:
463        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
464        // where the union used in this type is actually defined
465        EnumDecl *baseEnum = nullptr;
466
467        EnumInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
468        EnumInstType( const Type::Qualifiers & tq, EnumDecl * baseEnum, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
469        EnumInstType( const EnumInstType & other ) : Parent( other ), baseEnum( other.baseEnum ) {}
470
471        EnumDecl *get_baseEnum() const { return baseEnum; }
472        void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
473
474        virtual bool isComplete() const override;
475
476        virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
477        virtual void accept( Visitor & v ) override { v.visit( this ); }
478        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
479
480        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
481  private:
482        virtual std::string typeString() const override;
483};
484
485class TraitInstType : public ReferenceToType {
486        typedef ReferenceToType Parent;
487  public:
488        // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree,
489        // where the trait used in this type is actually defined
490        TraitDecl * baseTrait = nullptr;
491
492        TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {}
493        TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
494        TraitInstType( const TraitInstType & other );
495        ~TraitInstType();
496
497        virtual bool isComplete() const override;
498
499        virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
500        virtual void accept( Visitor & v ) override { v.visit( this ); }
501        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
502  private:
503        virtual std::string typeString() const override;
504};
505
506class TypeInstType : public ReferenceToType {
507        typedef ReferenceToType Parent;
508  public:
509        // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
510        // where the type used here is actually defined
511        TypeDecl *baseType;
512        bool isFtype;
513
514        TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
515        TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
516        TypeInstType( const TypeInstType & other );
517        ~TypeInstType();
518
519        TypeDecl *get_baseType() const { return baseType; }
520        void set_baseType( TypeDecl *newValue );
521        bool get_isFtype() const { return isFtype; }
522        void set_isFtype( bool newValue ) { isFtype = newValue; }
523
524        virtual bool isComplete() const override;
525
526        virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
527        virtual void accept( Visitor & v ) override { v.visit( this ); }
528        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
529        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
530  private:
531        virtual std::string typeString() const override;
532};
533
534class TupleType : public Type {
535  public:
536        std::list<Type *> types;
537        std::list<Declaration *> members;
538
539        TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
540        TupleType( const TupleType& );
541        virtual ~TupleType();
542
543        typedef std::list<Type*> value_type;
544        typedef value_type::iterator iterator;
545
546        std::list<Type *> & get_types() { return types; }
547        virtual unsigned size() const override { return types.size(); };
548
549        // For now, this is entirely synthetic -- tuple types always have unnamed members.
550        // Eventually, we may allow named tuples, in which case members should subsume types
551        std::list<Declaration *> & get_members() { return members; }
552
553        iterator begin() { return types.begin(); }
554        iterator end() { return types.end(); }
555
556        virtual Type * getComponent( unsigned i ) override {
557                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
558                return *(begin()+i);
559        }
560
561        // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
562
563        virtual TupleType *clone() const override { return new TupleType( *this ); }
564        virtual void accept( Visitor & v ) override { v.visit( this ); }
565        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
566        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
567};
568
569class TypeofType : public Type {
570  public:
571        Expression *expr;
572
573        TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
574        TypeofType( const TypeofType& );
575        virtual ~TypeofType();
576
577        Expression *get_expr() const { return expr; }
578        void set_expr( Expression *newValue ) { expr = newValue; }
579
580        virtual bool isComplete() const override { assert( false ); return false; }
581
582        virtual TypeofType *clone() const override { return new TypeofType( *this ); }
583        virtual void accept( Visitor & v ) override { v.visit( this ); }
584        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
585        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
586};
587
588class AttrType : public Type {
589  public:
590        std::string name;
591        Expression *expr;
592        Type *type;
593        bool isType;
594
595        AttrType( const Type::Qualifiers & tq, const std::string & name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
596        AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
597        AttrType( const AttrType& );
598        virtual ~AttrType();
599
600        const std::string & get_name() const { return name; }
601        void set_name( const std::string & newValue ) { name = newValue; }
602        Expression *get_expr() const { return expr; }
603        void set_expr( Expression *newValue ) { expr = newValue; }
604        Type *get_type() const { return type; }
605        void set_type( Type *newValue ) { type = newValue; }
606        bool get_isType() const { return isType; }
607        void set_isType( bool newValue ) { isType = newValue; }
608
609        virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
610
611        virtual AttrType *clone() const override { return new AttrType( *this ); }
612        virtual void accept( Visitor & v ) override { v.visit( this ); }
613        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
614        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
615};
616
617/// Represents the GCC built-in varargs type
618class VarArgsType : public Type {
619  public:
620        VarArgsType();
621        VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
622
623        virtual bool isComplete() const override{ return true; } // xxx - is this right?
624
625        virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
626        virtual void accept( Visitor & v ) override { v.visit( this ); }
627        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
628        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
629};
630
631/// Represents a zero constant
632class ZeroType : public Type {
633  public:
634        ZeroType();
635        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
636
637        virtual ZeroType *clone() const override { return new ZeroType( *this ); }
638        virtual void accept( Visitor & v ) override { v.visit( this ); }
639        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
640        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
641};
642
643/// Represents a one constant
644class OneType : public Type {
645  public:
646        OneType();
647        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
648
649        virtual OneType *clone() const override { return new OneType( *this ); }
650        virtual void accept( Visitor & v ) override { v.visit( this ); }
651        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
652        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
653};
654
655// Local Variables: //
656// tab-width: 4 //
657// mode: c++ //
658// compile-command: "make install" //
659// End: //
Note: See TracBrowser for help on using the repository browser.