source: src/AST/Type.hpp @ 67467a3

Last change on this file since 67467a3 was 0522ebe, checked in by JiadaL <j82liang@…>, 7 months ago

Add EnumPosType? to type system

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