source: src/AST/Type.hpp @ b0ec971

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since b0ec971 was b0ec971, checked in by Aaron Moss <a3moss@…>, 3 years ago

Added ast::Type printers

  • Property mode set to 100644
File size: 15.6 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.hpp --
8//
9// Author           : Aaron B. Moss
10// Created On       : Thu May 9 10:00:00 2019
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Thu May 9 10:00:00 2019
13// Update Count     : 1
14//
15
16#pragma once
17
18#include <cassert>
19#include <cstddef>           // for nullptr_t
20#include <cstdint>           // for uintptr_t
21#include <utility>           // for move
22#include <vector>
23
24#include "CVQualifiers.hpp"
25#include "Decl.hpp"          // for AggregateDecl subclasses
26#include "Fwd.hpp"
27#include "Node.hpp"          // for Node, ptr
28#include "TypeVar.hpp"
29#include "Visitor.hpp"
30
31// Must be included in *all* AST classes; should be #undef'd at the end of the file
32#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
33
34namespace ast {
35
36class Type : public Node {
37public:
38        CV::Qualifiers qualifiers;
39
40        Type( CV::Qualifiers q = {} ) : qualifiers(q) {}
41
42        bool is_const() const { return qualifiers.is_const; }
43        bool is_volatile() const { return qualifiers.is_volatile; }
44        bool is_restrict() const { return qualifiers.is_restrict; }
45        bool is_lvalue() const { return qualifiers.is_lvalue; }
46        bool is_mutex() const { return qualifiers.is_mutex; }
47        bool is_atomic() const { return qualifiers.is_atomic; }
48
49        Type * set_const( bool v ) { qualifiers.is_const = v; return this; }
50        Type * set_restrict( bool v ) { qualifiers.is_restrict = v; return this; }
51        Type * set_lvalue( bool v ) { qualifiers.is_lvalue = v; return this; }
52        Type * set_mutex( bool v ) { qualifiers.is_mutex = v; return this; }
53        Type * set_atomic( bool v ) { qualifiers.is_atomic = v; return this; }
54
55        /// How many elemental types are represented by this type
56        virtual unsigned size() const { return 1; }
57        /// Is this a void type?
58        virtual bool isVoid() const { return size() == 0; }
59        /// Get the i'th component of this type
60        virtual const Type * getComponent( unsigned i );
61
62        /// type without outer pointers and arrays
63        const Type * stripDeclarator();
64        /// type without outer references
65        const Type * stripReferences();
66        /// number of reference occuring consecutively on the outermost layer of this type
67        /// (i.e. do not count references nested within other types)
68        virtual unsigned referenceDepth() const { return 0; }
69        /// true iff type is complete type (i.e. compiler knows the size, alignment, and layout)
70        virtual bool isComplete() const { return true; }
71
72        virtual const Type * accept( Visitor & v ) const override = 0;
73private:
74        virtual Type * clone() const override = 0;
75        MUTATE_FRIEND
76};
77
78/// `void`
79class VoidType final : public Type {
80public:
81        VoidType( CV::Qualifiers q = {} ) : Type( q ) {}
82
83        unsigned size() const override { return 0; }
84        bool isVoid() const override { return true; }
85        bool isComplete() const override { return false; }
86
87        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
88private:
89        VoidType * clone() const override { return new VoidType{ *this }; }
90        MUTATE_FRIEND
91};
92
93/// Built-in arithmetic type
94class BasicType final : public Type {
95public:
96        // GENERATED START, DO NOT EDIT
97        // GENERATED BY BasicTypes-gen.cc
98        enum Kind {
99                Bool,
100                Char,
101                SignedChar,
102                UnsignedChar,
103                ShortSignedInt,
104                ShortUnsignedInt,
105                SignedInt,
106                UnsignedInt,
107                LongSignedInt,
108                LongUnsignedInt,
109                LongLongSignedInt,
110                LongLongUnsignedInt,
111                SignedInt128,
112                UnsignedInt128,
113                uFloat16,
114                uFloat16Complex,
115                uFloat32,
116                uFloat32Complex,
117                Float,
118                FloatComplex,
119                uFloat32x,
120                uFloat32xComplex,
121                uFloat64,
122                uFloat64Complex,
123                Double,
124                DoubleComplex,
125                uFloat64x,
126                uFloat64xComplex,
127                uuFloat80,
128                uFloat128,
129                uFloat128Complex,
130                uuFloat128,
131                LongDouble,
132                LongDoubleComplex,
133                uFloat128x,
134                uFloat128xComplex,
135                NUMBER_OF_BASIC_TYPES
136        } kind;
137        // GENERATED END
138
139        /// xxx -- MAX_INTEGER_TYPE should probably be in BasicTypes-gen.cc, rather than hardcoded here
140        enum { MAX_INTEGER_TYPE = UnsignedInt128 };
141
142        /// string names of basic types; generated to match with Kind
143        static const char *typeNames[];
144
145        BasicType( Kind k, CV::Qualifiers q = {} ) : Type(q), kind(k) {}
146
147        /// Check if this type represents an integer type
148        bool isInteger() const { return (unsigned)kind <= (unsigned)MAX_INTEGER_TYPE; }
149
150        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
151private:
152        BasicType * clone() const override { return new BasicType{ *this }; }
153        MUTATE_FRIEND
154};
155
156/// Pointer/array variable length?
157enum LengthFlag { FixedLen, VariableLen };
158
159/// Pointer/array static dimension?
160enum DimensionFlag { DynamicDim, StaticDim };
161
162/// Pointer type `T*`
163class PointerType final : public Type {
164public:
165        ptr<Type> base;
166
167        // In C99, pointer types can be qualified in many ways, e.g. `int a[ static 3 ]`
168        ptr<Expr> dimension;
169        LengthFlag isVarLen = FixedLen;
170        DimensionFlag isStatic = DynamicDim;
171
172        PointerType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b), dimension() {}
173        PointerType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
174                CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
175
176        // true if this pointer is actually an array
177        bool isArray() const { return isVarLen || isStatic || dimension; }
178
179        bool isComplete() const override { return ! isVarLen; }
180
181        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
182private:
183        PointerType * clone() const override { return new PointerType{ *this }; }
184        MUTATE_FRIEND
185};
186
187/// Array type `T[]`
188class ArrayType final : public Type {
189public:
190        ptr<Type> base;
191        ptr<Expr> dimension;
192        LengthFlag isVarLen;
193        DimensionFlag isStatic;
194
195        ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
196                CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
197
198        // array types are complete if they have a dimension expression or are
199        // VLAs ('*' in parameter declaration), and incomplete otherwise.
200        // See 6.7.6.2
201        bool isComplete() const override { return dimension || isVarLen; }
202
203        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
204private:
205        ArrayType * clone() const override { return new ArrayType{ *this }; }
206        MUTATE_FRIEND
207};
208
209/// Reference type `T&`
210class ReferenceType final : public Type {
211public:
212        ptr<Type> base;
213
214        ReferenceType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b) {}
215
216        unsigned referenceDepth() const override { return base->referenceDepth() + 1; }
217
218        // Since reference types act like value types, their size is the size of the base.
219        // This makes it simple to cast the empty tuple to a reference type, since casts that increase
220        // the number of values are disallowed.
221        unsigned size() const override { return base->size(); }
222
223        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
224private:
225        ReferenceType * clone() const override { return new ReferenceType{ *this }; }
226        MUTATE_FRIEND
227};
228
229/// Qualified type `P.C`
230class QualifiedType final : public Type {
231public:
232        ptr<Type> parent;
233        ptr<Type> child;
234
235        QualifiedType( const Type * p, const Type * c, CV::Qualifiers q = {} )
236        : Type(q), parent(p), child(c) {}
237
238        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
239private:
240        QualifiedType * clone() const override { return new QualifiedType{ *this }; }
241        MUTATE_FRIEND
242};
243
244/// Base type for potentially forall-qualified types
245class ParameterizedType : public Type {
246public:
247        using ForallList = std::vector<ptr<TypeDecl>>;
248
249        ForallList forall;
250
251        ParameterizedType( ForallList&& fs = {}, CV::Qualifiers q = {} )
252        : Type(q), forall(std::move(fs)) {}
253        ParameterizedType( CV::Qualifiers q ) : Type(q), forall() {}
254
255private:
256        virtual ParameterizedType * clone() const override = 0;
257        MUTATE_FRIEND
258};
259
260/// Function variable arguments flag
261enum ArgumentFlag { FixedArgs, VariableArgs };
262
263/// Type of a function `[R1, R2](*)(P1, P2, P3)`
264class FunctionType final : public ParameterizedType {
265public:
266        std::vector<ptr<DeclWithType>> returns;
267        std::vector<ptr<DeclWithType>> params;
268
269        /// Does the function accept a variable number of arguments following the arguments specified
270        /// in the parameters list.
271        /// This could be because of
272        /// - an ellipsis in a prototype declaration
273        /// - an unprototyped declaration
274        ArgumentFlag isVarArgs;
275
276        FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} )
277        : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
278
279        /// true if either the parameters or return values contain a tttype
280        bool isTtype() const;
281        /// true if function parameters are unconstrained by prototype
282        bool isUnprototyped() const { return isVarArgs && params.size() == 0; }
283
284        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
285private:
286        FunctionType * clone() const override { return new FunctionType{ *this }; }
287        MUTATE_FRIEND
288};
289
290/// base class for types that refer to types declared elsewhere (aggregates and typedefs)
291class ReferenceToType : public ParameterizedType {
292public:
293        std::vector<ptr<Expr>> params;
294        std::vector<ptr<Attribute>> attributes;
295        std::string name;
296        bool hoistType = false;
297
298        ReferenceToType( const std::string& n, CV::Qualifiers q = {},
299                std::vector<ptr<Attribute>> && as = {} )
300        : ParameterizedType(q), params(), attributes(std::move(as)), name(n) {}
301
302        /// Gets aggregate declaration this type refers to
303        virtual const AggregateDecl * aggr() const = 0;
304        /// Looks up member declarations with given name
305        std::vector<readonly<Decl>> lookup( const std::string & name ) const;
306
307private:
308        virtual ReferenceToType * clone() const override = 0;
309        MUTATE_FRIEND
310};
311
312/// instance of struct type
313class StructInstType final : public ReferenceToType {
314public:
315        readonly<StructDecl> base;
316
317        StructInstType( const std::string& n, CV::Qualifiers q = {},
318                std::vector<ptr<Attribute>> && as = {} )
319        : ReferenceToType( n, q, std::move(as) ), base() {}
320        StructInstType( const StructDecl * b, CV::Qualifiers q = {},
321                std::vector<ptr<Attribute>> && as = {} );
322
323        bool isComplete() const override;
324
325        const StructDecl * aggr() const override { return base; }
326
327        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
328private:
329        StructInstType * clone() const override { return new StructInstType{ *this }; }
330        MUTATE_FRIEND
331};
332
333/// instance of union type
334class UnionInstType final : public ReferenceToType {
335public:
336        readonly<UnionDecl> base;
337
338        UnionInstType( const std::string& n, CV::Qualifiers q = {},
339                std::vector<ptr<Attribute>> && as = {} )
340        : ReferenceToType( n, q, std::move(as) ), base() {}
341        UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
342                std::vector<ptr<Attribute>> && as = {} );
343
344        bool isComplete() const override;
345
346        const UnionDecl * aggr() const override { return base; }
347
348        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
349private:
350        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
351        MUTATE_FRIEND
352};
353
354/// instance of enum type
355class EnumInstType final : public ReferenceToType {
356public:
357        readonly<EnumDecl> base;
358
359        EnumInstType( const std::string& n, CV::Qualifiers q = {},
360                std::vector<ptr<Attribute>> && as = {} )
361        : ReferenceToType( n, q, std::move(as) ), base() {}
362        EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
363                std::vector<ptr<Attribute>> && as = {} );
364
365        bool isComplete() const override;
366
367        const EnumDecl * aggr() const override { return base; }
368
369        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
370private:
371        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
372        MUTATE_FRIEND
373};
374
375/// instance of trait type
376class TraitInstType final : public ReferenceToType {
377public:
378        readonly<TraitDecl> base;
379
380        TraitInstType( const std::string& n, CV::Qualifiers q = {},
381                std::vector<ptr<Attribute>> && as = {} )
382        : ReferenceToType( n, q, std::move(as) ), base() {}
383        TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
384                std::vector<ptr<Attribute>> && as = {} );
385
386        // not meaningful for TraitInstType
387        bool isComplete() const override { assert(false); }
388
389        const TraitDecl * aggr() const override { return base; }
390
391        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
392private:
393        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
394        MUTATE_FRIEND
395};
396
397/// instance of named type alias (typedef or variable)
398class TypeInstType final : public ReferenceToType {
399public:
400        readonly<TypeDecl> base;
401        TypeVar::Kind kind;
402
403        TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
404                std::vector<ptr<Attribute>> && as = {} )
405        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
406        TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
407                std::vector<ptr<Attribute>> && as = {} )
408        : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
409
410        /// sets `base`, updating `kind` correctly
411        void set_base( const TypeDecl * );
412
413        bool isComplete() const override;
414
415        // not meaningful for TypeInstType
416        const AggregateDecl * aggr() const override { assert(false); }
417
418        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
419private:
420        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
421        MUTATE_FRIEND
422};
423
424/// tuple type e.g. `[int, char]`
425class TupleType final : public Type {
426public:
427        std::vector<ptr<Type>> types;
428        std::vector<ptr<Decl>> members;
429
430        TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} );
431
432        // collection simulation
433        using iterator = std::vector<ptr<Type>>::const_iterator;
434        iterator begin() const { return types.begin(); }
435        iterator end() const { return types.end(); }
436
437        unsigned size() const override { return types.size(); }
438
439        const Type * getComponent( unsigned i ) override {
440                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d",
441                        i, size() );
442                return *(begin()+i);
443        }
444
445        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
446private:
447        TupleType * clone() const override { return new TupleType{ *this }; }
448        MUTATE_FRIEND
449};
450
451/// Type of unresolved `typeof()` expression
452class TypeofType : public Type {
453public:
454        ptr<Expr> expr;
455        enum Kind { Typeof, Basetypeof } kind;
456
457        TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} )
458        : Type(q), expr(e), kind(k) {}
459
460        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
461private:
462        TypeofType * clone() const override { return new TypeofType{ *this }; }
463        MUTATE_FRIEND
464};
465
466/// GCC built-in varargs type
467class VarArgsType final : public Type {
468public:
469        VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {}
470
471        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
472private:
473        VarArgsType * clone() const override { return new VarArgsType{ *this }; }
474        MUTATE_FRIEND
475};
476
477/// Type of zero constant `0`
478class ZeroType final : public Type {
479public:
480        ZeroType( CV::Qualifiers q = {} ) : Type( q ) {}
481
482        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
483private:
484        ZeroType * clone() const override { return new ZeroType{ *this }; }
485        MUTATE_FRIEND
486};
487
488/// Type of one constant `1`
489class OneType final : public Type {
490public:
491        OneType( CV::Qualifiers q = {} ) : Type( q ) {}
492
493        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
494private:
495        OneType * clone() const override { return new OneType{ *this }; }
496        MUTATE_FRIEND
497};
498
499/// Parent type for scope-qualified types at global scope
500class GlobalScopeType final : public Type {
501public:
502        GlobalScopeType() : Type() {}
503
504        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
505private:
506        GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
507        MUTATE_FRIEND
508};
509
510}
511
512#undef MUTATE_FRIEND
513
514// Local Variables: //
515// tab-width: 4 //
516// mode: c++ //
517// compile-command: "make install" //
518// End: //
Note: See TracBrowser for help on using the repository browser.