source: src/AST/Type.hpp @ 361bf01

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 361bf01 was 361bf01, checked in by Fangren Yu <f37yu@…>, 3 years ago

remove ParameterizedType? and put content into FunctionType?

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