source: src/SynTree/Type.h @ 27f2bef

Last change on this file since 27f2bef was 9feb34b, checked in by Andrew Beach <ajbeach@…>, 16 months ago

Moved toString and toCString to a new header. Updated includes. cassert was somehow getting instances of toString before but that stopped working so I embedded the new smaller include.

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