source: src/AST/Type.hpp @ acd80b4

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since acd80b4 was acd80b4, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Fixed several compilation errors

  • Property mode set to 100644
File size: 15.9 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"
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        void set_const( bool v ) { qualifiers.is_const = v; }
50        void set_restrict( bool v ) { qualifiers.is_restrict = v; }
51        void set_lvalue( bool v ) { qualifiers.is_lvalue = v; }
52        void set_mutex( bool v ) { qualifiers.is_mutex = v; }
53        void set_atomic( bool v ) { qualifiers.is_atomic = v; }
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
311protected:
312        /// Name for the kind of type this is
313        virtual std::string typeString() const = 0;
314};
315
316/// instance of struct type
317class StructInstType final : public ReferenceToType {
318public:
319        readonly<StructDecl> base;
320
321        StructInstType( const std::string& n, CV::Qualifiers q = {},
322                std::vector<ptr<Attribute>> && as = {} )
323        : ReferenceToType( n, q, std::move(as) ), base() {}
324        StructInstType( const StructDecl * b, CV::Qualifiers q = {},
325                std::vector<ptr<Attribute>> && as = {} );
326
327        bool isComplete() const override;
328
329        const StructDecl * aggr() const override { return base; }
330
331        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
332private:
333        StructInstType * clone() const override { return new StructInstType{ *this }; }
334        MUTATE_FRIEND
335
336        std::string typeString() const override { return "struct"; }
337};
338
339/// instance of union type
340class UnionInstType final : public ReferenceToType {
341public:
342        readonly<UnionDecl> base;
343
344        UnionInstType( const std::string& n, CV::Qualifiers q = {},
345                std::vector<ptr<Attribute>> && as = {} )
346        : ReferenceToType( n, q, std::move(as) ), base() {}
347        UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
348                std::vector<ptr<Attribute>> && as = {} );
349
350        bool isComplete() const override;
351
352        const UnionDecl * aggr() const override { return base; }
353
354        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
355private:
356        UnionInstType * clone() const override { return new UnionInstType{ *this }; }
357        MUTATE_FRIEND
358
359        std::string typeString() const override { return "union"; }
360};
361
362/// instance of enum type
363class EnumInstType final : public ReferenceToType {
364public:
365        readonly<EnumDecl> base;
366
367        EnumInstType( const std::string& n, CV::Qualifiers q = {},
368                std::vector<ptr<Attribute>> && as = {} )
369        : ReferenceToType( n, q, std::move(as) ), base() {}
370        EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
371                std::vector<ptr<Attribute>> && as = {} );
372
373        bool isComplete() const override;
374
375        const EnumDecl * aggr() const override { return base; }
376
377        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
378private:
379        EnumInstType * clone() const override { return new EnumInstType{ *this }; }
380        MUTATE_FRIEND
381
382        std::string typeString() const override { return "enum"; }
383};
384
385/// instance of trait type
386class TraitInstType final : public ReferenceToType {
387public:
388        readonly<TraitDecl> base;
389
390        TraitInstType( const std::string& n, CV::Qualifiers q = {},
391                std::vector<ptr<Attribute>> && as = {} )
392        : ReferenceToType( n, q, std::move(as) ), base() {}
393        TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
394                std::vector<ptr<Attribute>> && as = {} );
395
396        // not meaningful for TraitInstType
397        bool isComplete() const override { assert(false); }
398
399        const TraitDecl * aggr() const override { return base; }
400
401        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
402private:
403        TraitInstType * clone() const override { return new TraitInstType{ *this }; }
404        MUTATE_FRIEND
405
406        std::string typeString() const override { return "trait"; }
407};
408
409/// instance of named type alias (typedef or variable)
410class TypeInstType final : public ReferenceToType {
411public:
412        readonly<TypeDecl> base;
413        TypeVar::Kind kind;
414
415        TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
416                std::vector<ptr<Attribute>> && as = {} )
417        : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
418        TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
419                std::vector<ptr<Attribute>> && as = {} )
420        : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
421
422        /// sets `base`, updating `kind` correctly
423        void set_base( const TypeDecl * );
424
425        bool isComplete() const override;
426
427        // not meaningful for TypeInstType
428        const AggregateDecl * aggr() const override { assert(false); }
429
430        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
431private:
432        TypeInstType * clone() const override { return new TypeInstType{ *this }; }
433        MUTATE_FRIEND
434
435        std::string typeString() const override { return "type"; }
436};
437
438/// tuple type e.g. `[int, char]`
439class TupleType final : public Type {
440public:
441        std::vector<ptr<Type>> types;
442        std::vector<ptr<Decl>> members;
443
444        TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} );
445
446        // collection simulation
447        using iterator = std::vector<ptr<Type>>::const_iterator;
448        iterator begin() const { return types.begin(); }
449        iterator end() const { return types.end(); }
450
451        unsigned size() const override { return types.size(); }
452
453        const Type * getComponent( unsigned i ) override {
454                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d",
455                        i, size() );
456                return *(begin()+i);
457        }
458
459        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
460private:
461        TupleType * clone() const override { return new TupleType{ *this }; }
462        MUTATE_FRIEND
463};
464
465/// Type of unresolved `typeof()` expression
466class TypeofType : public Type {
467public:
468        ptr<Expr> expr;
469        enum Kind { Typeof, Basetypeof } kind;
470
471        TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} )
472        : Type(q), expr(e), kind(k) {}
473
474        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
475private:
476        TypeofType * clone() const override { return new TypeofType{ *this }; }
477        MUTATE_FRIEND
478};
479
480/// GCC built-in varargs type
481class VarArgsType final : public Type {
482public:
483        VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {}
484
485        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
486private:
487        VarArgsType * clone() const override { return new VarArgsType{ *this }; }
488        MUTATE_FRIEND
489};
490
491/// Type of zero constant `0`
492class ZeroType final : public Type {
493public:
494        ZeroType( CV::Qualifiers q = {} ) : Type( q ) {}
495
496        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
497private:
498        ZeroType * clone() const override { return new ZeroType{ *this }; }
499        MUTATE_FRIEND
500};
501
502/// Type of one constant `1`
503class OneType final : public Type {
504public:
505        OneType( CV::Qualifiers q = {} ) : Type( q ) {}
506
507        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
508private:
509        OneType * clone() const override { return new OneType{ *this }; }
510        MUTATE_FRIEND
511};
512
513/// Parent type for scope-qualified types at global scope
514class GlobalScopeType final : public Type {
515public:
516        GlobalScopeType( CV::Qualifiers q = {} ) : Type( q ) {}
517
518        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
519private:
520        GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
521        MUTATE_FRIEND
522};
523
524}
525
526#undef MUTATE_FRIEND
527
528// Local Variables: //
529// tab-width: 4 //
530// mode: c++ //
531// compile-command: "make install" //
532// End: //
Note: See TracBrowser for help on using the repository browser.