source: src/AST/Type.hpp @ 21184e3

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 21184e3 was 0f6a7752, checked in by Aaron Moss <a3moss@…>, 5 years ago

Put in temporary patch to finish new resolver port

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