source: src/SynTree/Type.h @ 3e7c323

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since 3e7c323 was cdcddfe1, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

add signedness to cost model and _FloatNN

  • Property mode set to 100644
File size: 28.9 KB
RevLine 
[0dd3a2f]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//
[ae63a18]7// Type.h --
[0dd3a2f]8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
[201aeb9]11// Last Modified By : Peter A. Buhr
[cdcddfe1]12// Last Modified On : Fri Feb  8 09:17:09 2019
13// Update Count     : 164
[0dd3a2f]14//
15
[6b0b624]16#pragma once
[51b7345]17
[ea6332d]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
[51b7345]29
[138e29e]30class Type : public BaseSyntaxNode {
[c8ffe20b]31  public:
[6f95000]32        // Simulate inheritance because union does not allow it.
[615a096]33        // Bug in g++-4.9 prevents static field in union
34        //static const char * Names[];
[6f95000]35        #define BFCommon( BFType, N ) \
[d6d747d]36                bool operator[]( unsigned int i ) const { return val & (1 << i); } \
37                bool any() const { return val != 0; } \
[6f95000]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                } \
[d6d747d]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] ) { \
[615a096]63                                                os << BFType##Names[i] << ' '; \
[d6d747d]64                                        } \
65                                } \
66                        } \
67                }
68
[68fe077a]69        // enum must remain in the same order as the corresponding bit fields.
70
[ddfd945]71        enum { Inline = 1 << 0, Noreturn = 1 << 1, Fortran = 1 << 2, NumFuncSpecifier = 3 };
[615a096]72        static const char * FuncSpecifiersNames[];
[ddfd945]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 ) {}
[615a096]82                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
[6f95000]83                BFCommon( FuncSpecifiers, NumFuncSpecifier )
[ddfd945]84        }; // FuncSpecifiers
85
[68fe077a]86        enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, Threadlocal = 1 << 4, NumStorageClass = 5 };
[615a096]87        static const char * StorageClassesNames[];
[68fe077a]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 ) {}
[615a096]100                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
[6f95000]101                BFCommon( StorageClasses, NumStorageClass )
[68fe077a]102        }; // StorageClasses
103
[bf4ac09]104        enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6 };
[615a096]105        static const char * QualifiersNames[];
[bf4ac09]106        union Qualifiers {
107                enum { Mask = ~(Restrict | Lvalue) };
108                unsigned int val;
109                struct {
[615a096]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;
[bf4ac09]116                };
[6e8bd43]117
[bf4ac09]118                Qualifiers() : val( 0 ) {}
119                Qualifiers( unsigned int val ) : val( val ) {}
[615a096]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); }
[d6d747d]123                bool operator<=( Qualifiers other ) const {
[e04b636]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
[bf4ac09]128                }
[6f95000]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 )
[bf4ac09]133        }; // Qualifiers
[0dd3a2f]134
[65cdc1e]135        typedef std::list<TypeDecl *> ForallList;
136
137        Qualifiers tq;
138        ForallList forall;
139        std::list< Attribute * > attributes;
140
[f2e40a9f]141        Type( const Qualifiers & tq, const std::list< Attribute * > & attributes );
142        Type( const Type & other );
[0dd3a2f]143        virtual ~Type();
144
[f2e40a9f]145        Qualifiers & get_qualifiers() { return tq; }
[615a096]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; }
[8c49c0e]158
159        ForallList& get_forall() { return forall; }
[0dd3a2f]160
[c0aa336]161        std::list< Attribute * >& get_attributes() { return attributes; }
162        const std::list< Attribute * >& get_attributes() const { return attributes; }
163
[906e24d]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; }
[7933351]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; }
[906e24d]168
[142cf5d]169        /// return type without outer pointers and arrays
[0698aa1]170        Type * stripDeclarator();
171
172        /// return type without outer references
173        Type * stripReferences();
[6f95000]174
[e6cee92]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
[4a9ccc3]178        virtual bool isComplete() const { return true; }
179
[0b3b2ae]180        virtual AggregateDecl * getAggr() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
[9bfc9da]181
182        virtual TypeSubstitution genericSubstitution() const;
[373d0b5]183
[0dd3a2f]184        virtual Type *clone() const = 0;
[f2e40a9f]185        virtual void accept( Visitor & v ) = 0;
186        virtual Type *acceptMutator( Mutator & m ) = 0;
[50377a4]187        virtual void print( std::ostream & os, Indenter indent = {} ) const;
[51b7345]188};
189
[65cdc1e]190extern const Type::FuncSpecifiers noFuncSpecifiers;
191extern const Type::StorageClasses noStorageClasses;
192extern const Type::Qualifiers noQualifiers;                     // no qualifiers on constants
[4cb935e]193
[c8ffe20b]194class VoidType : public Type {
195  public:
[f2e40a9f]196        VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[51b7345]197
[d67cdb7]198        virtual unsigned size() const override { return 0; };
199        virtual bool isComplete() const override { return false; }
[906e24d]200
[d67cdb7]201        virtual VoidType *clone() const override { return new VoidType( *this ); }
202        virtual void accept( Visitor & v ) override { v.visit( this ); }
203        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]204        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]205};
206
[c8ffe20b]207class BasicType : public Type {
208  public:
[cdcddfe1]209#if 0
[ae63a18]210        enum Kind {
[0dd3a2f]211                Bool,
212                Char,
213                SignedChar,
214                UnsignedChar,
215                ShortSignedInt,
216                ShortUnsignedInt,
217                SignedInt,
218                UnsignedInt,
219                LongSignedInt,
220                LongUnsignedInt,
221                LongLongSignedInt,
222                LongLongUnsignedInt,
223                Float,
224                Double,
225                LongDouble,
226                FloatComplex,
227                DoubleComplex,
228                LongDoubleComplex,
229                FloatImaginary,
230                DoubleImaginary,
231                LongDoubleImaginary,
[201aeb9]232                SignedInt128,
233                UnsignedInt128,
[4ee3b0c1]234                Float80,
235                Float128,
[cdcddfe1]236                _Float16,
237                _Float32,
238                _Float32x,
239                _Float64,
240                _Float64x,
241                _Float128,
242                _Float128x,
243                _Float16Complex,
244                _Float32Complex,
245                _Float32xComplex,
246                _Float64Complex,
247                _Float64xComplex,
248                _Float128Complex,
249                _Float128xComplex,
250                NUMBER_OF_BASIC_TYPES
251        } kind;
252#endif
253        enum Kind {
254                _Bool,
255                Char,
256                SignedChar,
257                UnsignedChar,
258                ShortSignedInt,
259                ShortUnsignedInt,
260                SignedInt,
261                UnsignedInt,
262                LongSignedInt,
263                LongUnsignedInt,
264                LongLongSignedInt,
265                LongLongUnsignedInt,
266                SignedInt128,
267                UnsignedInt128,
268                _Float16,
269                _Float16Complex,
270                _Float32,
271                _Float32Complex,
272                Float,
273                FloatComplex,
274                // FloatImaginary,
275                _Float32x,
276                _Float32xComplex,
277                _Float64,
278                _Float64Complex,
279                Double,
280                DoubleComplex,
281                // DoubleImaginary,
282                _Float64x,
283                _Float64xComplex,
284                __float80,
285                _Float128,
286                _Float128Complex,
287                __float128,
288                LongDouble,
289                LongDoubleComplex,
290                // LongDoubleImaginary,
291                _Float128x,
292                _Float128xComplex,
[0dd3a2f]293                NUMBER_OF_BASIC_TYPES
[65cdc1e]294        } kind;
[0dd3a2f]295
[59db689]296        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
[0dd3a2f]297
[f2e40a9f]298        BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[0dd3a2f]299
300        Kind get_kind() { return kind; }
301        void set_kind( Kind newValue ) { kind = newValue; }
302
[d67cdb7]303        virtual BasicType *clone() const override { return new BasicType( *this ); }
304        virtual void accept( Visitor & v ) override { v.visit( this ); }
305        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]306        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[0dd3a2f]307
308        bool isInteger() const;
[51b7345]309};
310
[c8ffe20b]311class PointerType : public Type {
312  public:
[65cdc1e]313        Type *base;
314
315        // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
316        Expression *dimension;
317        bool isVarLen;
318        bool isStatic;
319
[f2e40a9f]320        PointerType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
321        PointerType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[0dd3a2f]322        PointerType( const PointerType& );
323        virtual ~PointerType();
324
325        Type *get_base() { return base; }
326        void set_base( Type *newValue ) { base = newValue; }
327        Expression *get_dimension() { return dimension; }
328        void set_dimension( Expression *newValue ) { dimension = newValue; }
329        bool get_isVarLen() { return isVarLen; }
330        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
331        bool get_isStatic() { return isStatic; }
332        void set_isStatic( bool newValue ) { isStatic = newValue; }
333
[ed8a0d2]334        bool is_array() const { return isStatic || isVarLen || dimension; }
335
[d67cdb7]336        virtual bool isComplete() const override { return ! isVarLen; }
[ce8c12f]337
[d67cdb7]338        virtual PointerType *clone() const override { return new PointerType( *this ); }
339        virtual void accept( Visitor & v ) override { v.visit( this ); }
340        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]341        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[65cdc1e]342};
[ae63a18]343
[65cdc1e]344class ArrayType : public Type {
345  public:
346        Type *base;
[0dd3a2f]347        Expression *dimension;
348        bool isVarLen;
349        bool isStatic;
[51b7345]350
[f2e40a9f]351        ArrayType( const Type::Qualifiers & tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[0dd3a2f]352        ArrayType( const ArrayType& );
353        virtual ~ArrayType();
354
355        Type *get_base() { return base; }
356        void set_base( Type *newValue ) { base = newValue; }
357        Expression *get_dimension() { return dimension; }
358        void set_dimension( Expression *newValue ) { dimension = newValue; }
359        bool get_isVarLen() { return isVarLen; }
360        void set_isVarLen( bool newValue ) { isVarLen = newValue; }
361        bool get_isStatic() { return isStatic; }
362        void set_isStatic( bool newValue ) { isStatic = newValue; }
363
[99b7d4fc]364        // array types are complete if they have a dimension expression or are
365        // VLAs ('*' in parameter declaration), and incomplete otherwise.
366        // See 6.7.6.2
367        virtual bool isComplete() const override { return dimension || isVarLen; }
[4a9ccc3]368
[d67cdb7]369        virtual ArrayType *clone() const override { return new ArrayType( *this ); }
370        virtual void accept( Visitor & v ) override { v.visit( this ); }
371        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]372        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]373};
374
[c5d7701]375class QualifiedType : public Type {
376public:
[c194661]377        Type * parent;
378        Type * child;
[c5d7701]379
[c194661]380        QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child );
[c5d7701]381        QualifiedType( const QualifiedType & tq );
382        virtual ~QualifiedType();
383
384        virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
385        virtual void accept( Visitor & v ) override { v.visit( this ); }
386        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
387        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
388};
389
[ce8c12f]390class ReferenceType : public Type {
391public:
[9236060]392        Type *base;
393
[ce8c12f]394        ReferenceType( const Type::Qualifiers & tq, Type *base, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
395        ReferenceType( const ReferenceType & );
396        virtual ~ReferenceType();
397
398        Type *get_base() { return base; }
399        void set_base( Type *newValue ) { base = newValue; }
400
[d67cdb7]401        virtual int referenceDepth() const override;
[e6cee92]402
[5ccb10d]403        // Since reference types act like value types, their size is the size of the base.
404        // This makes it simple to cast the empty tuple to a reference type, since casts that increase
405        // the number of values are disallowed.
[d67cdb7]406        virtual unsigned size() const override { return base->size(); }
[5ccb10d]407
[9bfc9da]408        virtual TypeSubstitution genericSubstitution() const override;
409
[d67cdb7]410        virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
411        virtual void accept( Visitor & v ) override { v.visit( this ); }
412        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]413        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[ce8c12f]414};
415
[c8ffe20b]416class FunctionType : public Type {
417  public:
[65cdc1e]418        std::list<DeclarationWithType*> returnVals;
419        std::list<DeclarationWithType*> parameters;
420
421        // Does the function accept a variable number of arguments following the arguments specified in the parameters list.
422        // This could be because of
423        // - an ellipsis in a prototype declaration
424        // - an unprototyped declaration
425        bool isVarArgs;
426
[f2e40a9f]427        FunctionType( const Type::Qualifiers & tq, bool isVarArgs, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[0dd3a2f]428        FunctionType( const FunctionType& );
429        virtual ~FunctionType();
430
[cf16f94]431        std::list<DeclarationWithType*> & get_returnVals() { return returnVals; }
432        std::list<DeclarationWithType*> & get_parameters() { return parameters; }
[8bf784a]433        bool get_isVarArgs() const { return isVarArgs; }
[0dd3a2f]434        void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
[8bf784a]435        bool isTtype() const;
436
[8aa474a]437        bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; }
438
[d67cdb7]439        virtual FunctionType *clone() const override { return new FunctionType( *this ); }
440        virtual void accept( Visitor & v ) override { v.visit( this ); }
441        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]442        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]443};
444
[c8ffe20b]445class ReferenceToType : public Type {
446  public:
[65cdc1e]447        std::list< Expression* > parameters;
448        std::string name;
449        bool hoistType;
450
[f2e40a9f]451        ReferenceToType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes );
452        ReferenceToType( const ReferenceToType & other );
[0dd3a2f]453        virtual ~ReferenceToType();
454
[f2e40a9f]455        const std::string & get_name() const { return name; }
[0dd3a2f]456        void set_name( std::string newValue ) { name = newValue; }
457        std::list< Expression* >& get_parameters() { return parameters; }
[43c89a7]458        bool get_hoistType() const { return hoistType; }
459        void set_hoistType( bool newValue ) { hoistType = newValue; }
[ae63a18]460
[d67cdb7]461        virtual ReferenceToType *clone() const override = 0;
462        virtual void accept( Visitor & v ) override = 0;
463        virtual Type *acceptMutator( Mutator & m ) override = 0;
[50377a4]464        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[6013bd7]465
[b3c36f4]466        virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
[c8ffe20b]467  protected:
[0dd3a2f]468        virtual std::string typeString() const = 0;
[51b7345]469};
470
[c8ffe20b]471class StructInstType : public ReferenceToType {
[0dd3a2f]472        typedef ReferenceToType Parent;
[c8ffe20b]473  public:
[65cdc1e]474        // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
475        // where the structure used in this type is actually defined
476        StructDecl *baseStruct;
477
[f2e40a9f]478        StructInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseStruct( 0 ) {}
479        StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
480        StructInstType( const StructInstType & other ) : Parent( other ), baseStruct( other.baseStruct ) {}
[51b7345]481
[0dd3a2f]482        StructDecl *get_baseStruct() const { return baseStruct; }
483        void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
[37a3b8f9]484
[ed94eac]485        /// Accesses generic parameters of base struct (NULL if none such)
[839ccbb]486        std::list<TypeDecl*> * get_baseParameters();
[9bfc9da]487        const std::list<TypeDecl*> * get_baseParameters() const;
[ae63a18]488
[d67cdb7]489        virtual bool isComplete() const override;
[4a9ccc3]490
[0b3b2ae]491        virtual AggregateDecl * getAggr() const override;
[373d0b5]492
[9bfc9da]493        virtual TypeSubstitution genericSubstitution() const override;
494
[37a3b8f9]495        /// Looks up the members of this struct named "name" and places them into "foundDecls".
496        /// Clones declarations into "foundDecls", caller responsible for freeing
[d67cdb7]497        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
[51b7345]498
[d67cdb7]499        virtual StructInstType *clone() const override { return new StructInstType( *this ); }
500        virtual void accept( Visitor & v ) override { v.visit( this ); }
501        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[5d125e4]502
[50377a4]503        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[c8ffe20b]504  private:
[d67cdb7]505        virtual std::string typeString() const override;
[51b7345]506};
507
[c8ffe20b]508class UnionInstType : public ReferenceToType {
[0dd3a2f]509        typedef ReferenceToType Parent;
[c8ffe20b]510  public:
[65cdc1e]511        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
512        // where the union used in this type is actually defined
513        UnionDecl *baseUnion;
514
[f2e40a9f]515        UnionInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseUnion( 0 ) {}
516        UnionInstType( const Type::Qualifiers & tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
517        UnionInstType( const UnionInstType & other ) : Parent( other ), baseUnion( other.baseUnion ) {}
[0dd3a2f]518
519        UnionDecl *get_baseUnion() const { return baseUnion; }
[c0aa336]520        void set_baseUnion( UnionDecl * newValue ) { baseUnion = newValue; }
[37a3b8f9]521
[ed94eac]522        /// Accesses generic parameters of base union (NULL if none such)
[9bfc9da]523        std::list<TypeDecl*> * get_baseParameters();
524        const std::list<TypeDecl*> * get_baseParameters() const;
[ae63a18]525
[d67cdb7]526        virtual bool isComplete() const override;
[4a9ccc3]527
[0b3b2ae]528        virtual AggregateDecl * getAggr() const override;
[373d0b5]529
[9bfc9da]530        virtual TypeSubstitution genericSubstitution() const override;
531
[37a3b8f9]532        /// looks up the members of this union named "name" and places them into "foundDecls"
533        /// Clones declarations into "foundDecls", caller responsible for freeing
[d67cdb7]534        void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
[0dd3a2f]535
[d67cdb7]536        virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
537        virtual void accept( Visitor & v ) override { v.visit( this ); }
538        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[5d125e4]539
[50377a4]540        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[c8ffe20b]541  private:
[d67cdb7]542        virtual std::string typeString() const override;
[51b7345]543};
544
[c8ffe20b]545class EnumInstType : public ReferenceToType {
[0dd3a2f]546        typedef ReferenceToType Parent;
[c8ffe20b]547  public:
[65cdc1e]548        // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
549        // where the union used in this type is actually defined
550        EnumDecl *baseEnum = nullptr;
551
[f2e40a9f]552        EnumInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
553        EnumInstType( const Type::Qualifiers & tq, EnumDecl * baseEnum, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
554        EnumInstType( const EnumInstType & other ) : Parent( other ), baseEnum( other.baseEnum ) {}
[51b7345]555
[c0aa336]556        EnumDecl *get_baseEnum() const { return baseEnum; }
557        void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
558
[d67cdb7]559        virtual bool isComplete() const override;
[4a9ccc3]560
[2dc6621]561        virtual AggregateDecl * getAggr() const override;
[0b3b2ae]562
[d67cdb7]563        virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
564        virtual void accept( Visitor & v ) override { v.visit( this ); }
565        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[6137fbb]566
567        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[c8ffe20b]568  private:
[d67cdb7]569        virtual std::string typeString() const override;
[51b7345]570};
571
[4040425]572class TraitInstType : public ReferenceToType {
[0dd3a2f]573        typedef ReferenceToType Parent;
[c8ffe20b]574  public:
[be9036d]575        // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree,
576        // where the trait used in this type is actually defined
577        TraitDecl * baseTrait = nullptr;
[65cdc1e]578
[be9036d]579        TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {}
580        TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[f2e40a9f]581        TraitInstType( const TraitInstType & other );
[4040425]582        ~TraitInstType();
[51b7345]583
[d67cdb7]584        virtual bool isComplete() const override;
[4a9ccc3]585
[d67cdb7]586        virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
587        virtual void accept( Visitor & v ) override { v.visit( this ); }
588        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[c8ffe20b]589  private:
[d67cdb7]590        virtual std::string typeString() const override;
[51b7345]591};
592
[c8ffe20b]593class TypeInstType : public ReferenceToType {
[0dd3a2f]594        typedef ReferenceToType Parent;
[c8ffe20b]595  public:
[65cdc1e]596        // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
597        // where the type used here is actually defined
598        TypeDecl *baseType;
599        bool isFtype;
600
[f2e40a9f]601        TypeInstType( const Type::Qualifiers & tq, const std::string & name, TypeDecl *baseType, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
602        TypeInstType( const Type::Qualifiers & tq, const std::string & name, bool isFtype, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
603        TypeInstType( const TypeInstType & other );
[1e8b02f5]604        ~TypeInstType();
[0dd3a2f]605
606        TypeDecl *get_baseType() const { return baseType; }
607        void set_baseType( TypeDecl *newValue );
608        bool get_isFtype() const { return isFtype; }
609        void set_isFtype( bool newValue ) { isFtype = newValue; }
[ae63a18]610
[d67cdb7]611        virtual bool isComplete() const override;
[4a9ccc3]612
[d67cdb7]613        virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
614        virtual void accept( Visitor & v ) override { v.visit( this ); }
615        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]616        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[c8ffe20b]617  private:
[d67cdb7]618        virtual std::string typeString() const override;
[51b7345]619};
620
[c8ffe20b]621class TupleType : public Type {
622  public:
[65cdc1e]623        std::list<Type *> types;
624        std::list<Declaration *> members;
625
[62423350]626        TupleType( const Type::Qualifiers & tq, const std::list< Type * > & types, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
[0dd3a2f]627        TupleType( const TupleType& );
628        virtual ~TupleType();
[51b7345]629
[0362d42]630        typedef std::list<Type*> value_type;
631        typedef value_type::iterator iterator;
632
[62423350]633        std::list<Type *> & get_types() { return types; }
[d67cdb7]634        virtual unsigned size() const override { return types.size(); };
[51b7345]635
[62423350]636        // For now, this is entirely synthetic -- tuple types always have unnamed members.
637        // Eventually, we may allow named tuples, in which case members should subsume types
638        std::list<Declaration *> & get_members() { return members; }
639
[0362d42]640        iterator begin() { return types.begin(); }
641        iterator end() { return types.end(); }
642
[d67cdb7]643        virtual Type * getComponent( unsigned i ) override {
[7933351]644                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
645                return *(begin()+i);
646        }
647
[d67cdb7]648        // virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
[4a9ccc3]649
[d67cdb7]650        virtual TupleType *clone() const override { return new TupleType( *this ); }
651        virtual void accept( Visitor & v ) override { v.visit( this ); }
652        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]653        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]654};
655
[c8ffe20b]656class TypeofType : public Type {
657  public:
[f441c88]658        Expression *expr;    ///< expression to take the type of
659        bool is_basetypeof;  ///< true iff is basetypeof type
[65cdc1e]660
[f441c88]661        TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
662        TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 
663                const std::list< Attribute * > & attributes = std::list< Attribute * >() );
[0dd3a2f]664        TypeofType( const TypeofType& );
665        virtual ~TypeofType();
[51b7345]666
[0dd3a2f]667        Expression *get_expr() const { return expr; }
668        void set_expr( Expression *newValue ) { expr = newValue; }
[51b7345]669
[d67cdb7]670        virtual bool isComplete() const override { assert( false ); return false; }
[4a9ccc3]671
[d67cdb7]672        virtual TypeofType *clone() const override { return new TypeofType( *this ); }
673        virtual void accept( Visitor & v ) override { v.visit( this ); }
674        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]675        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]676};
677
[c8ffe20b]678class AttrType : public Type {
679  public:
[65cdc1e]680        std::string name;
681        Expression *expr;
682        Type *type;
683        bool isType;
684
[f2e40a9f]685        AttrType( const Type::Qualifiers & tq, const std::string & name, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
686        AttrType( const Type::Qualifiers & tq, const std::string & name, Type *type, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
[0dd3a2f]687        AttrType( const AttrType& );
688        virtual ~AttrType();
689
[f2e40a9f]690        const std::string & get_name() const { return name; }
691        void set_name( const std::string & newValue ) { name = newValue; }
[0dd3a2f]692        Expression *get_expr() const { return expr; }
693        void set_expr( Expression *newValue ) { expr = newValue; }
694        Type *get_type() const { return type; }
695        void set_type( Type *newValue ) { type = newValue; }
696        bool get_isType() const { return isType; }
697        void set_isType( bool newValue ) { isType = newValue; }
698
[d67cdb7]699        virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
[4a9ccc3]700
[d67cdb7]701        virtual AttrType *clone() const override { return new AttrType( *this ); }
702        virtual void accept( Visitor & v ) override { v.visit( this ); }
703        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]704        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[51b7345]705};
706
[44b7088]707/// Represents the GCC built-in varargs type
708class VarArgsType : public Type {
[90c3b1c]709  public:
[44b7088]710        VarArgsType();
[c0aa336]711        VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
[44b7088]712
[d67cdb7]713        virtual bool isComplete() const override{ return true; } // xxx - is this right?
[4a9ccc3]714
[d67cdb7]715        virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
716        virtual void accept( Visitor & v ) override { v.visit( this ); }
717        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]718        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[44b7088]719};
720
[89e6ffc]721/// Represents a zero constant
722class ZeroType : public Type {
723  public:
724        ZeroType();
[c0aa336]725        ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
[89e6ffc]726
[d67cdb7]727        virtual ZeroType *clone() const override { return new ZeroType( *this ); }
728        virtual void accept( Visitor & v ) override { v.visit( this ); }
729        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]730        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[89e6ffc]731};
732
733/// Represents a one constant
734class OneType : public Type {
735  public:
736        OneType();
[c0aa336]737        OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
[89e6ffc]738
[d67cdb7]739        virtual OneType *clone() const override { return new OneType( *this ); }
740        virtual void accept( Visitor & v ) override { v.visit( this ); }
741        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
[50377a4]742        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
[89e6ffc]743};
744
[47498bd]745class GlobalScopeType : public Type {
746  public:
747        GlobalScopeType();
748
749        virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
750        virtual void accept( Visitor & v ) override { v.visit( this ); }
751        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
752        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
753};
754
[0dd3a2f]755// Local Variables: //
756// tab-width: 4 //
757// mode: c++ //
758// compile-command: "make install" //
759// End: //
Note: See TracBrowser for help on using the repository browser.