source: src/AST/Expr.hpp @ 3d8d7a7

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 3d8d7a7 was 89c2f7c9, checked in by Aaron Moss <a3moss@…>, 5 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 12.7 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// Expr.hpp --
8//
9// Author           : Aaron B. Moss
10// Created On       : Fri May 10 10:30:00 2019
11// Last Modified By : Aaron B. Moss
12// Created On       : Fri May 10 10:30:00 2019
13// Update Count     : 1
14//
15
16#pragma once
17
18#include <cassert>
19#include <map>
20#include <utility>        // for move
21#include <vector>
22
23#include "Fwd.hpp"        // for UniqueId
24#include "ParseNode.hpp"
25#include "Visitor.hpp"
26
27namespace ast {
28
29/// Contains the ID of a declaration and a type that is derived from that declaration,
30/// but subject to decay-to-pointer and type parameter renaming
31struct ParamEntry {
32        UniqueId decl;
33        ptr<Type> actualType;
34        ptr<Type> formalType;
35        ptr<Expr> expr;
36
37        ParamEntry() : decl( 0 ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
38        ParamEntry( UniqueId id, Type* actual, Type* formal, Expr* e )
39        : decl( id ), actualType( actual ), formalType( formal ), expr( e ) {}
40};
41
42/// Pre-resolution list of parameters to infer
43using ResnSlots = std::vector<UniqueId>;
44/// Post-resolution map of inferred parameters
45using InferredParams = std::map< UniqueId, ParamEntry >;
46
47/// Base node for expressions
48class Expr : public ParseNode {
49public:
50        /// Saves space (~16 bytes) by combining ResnSlots and InferredParams
51        struct InferUnion {
52                enum { Empty, Slots, Params } mode;
53                union data_t {
54                        char def;
55                        ResnSlots resnSlots;
56                        InferredParams inferParams;
57
58                        data_t() : def('\0') {}
59                        ~data_t() {}
60                } data;
61
62                /// initializes from other InferUnion
63                void init_from( const InferUnion& o ) {
64                        switch ( o.mode ) {
65                        case Empty:  return;
66                        case Slots:  new(&data.resnSlots) ResnSlots{ o.data.resnSlots }; return;
67                        case Params: new(&data.inferParams) InferredParams{ o.data.inferParams }; return;
68                        }
69                }
70
71                /// initializes from other InferUnion (move semantics)
72                void init_from( InferUnion&& o ) {
73                        switch ( o.mode ) {
74                        case Empty:  return;
75                        case Slots:  new(&data.resnSlots) ResnSlots{ std::move(o.data.resnSlots) }; return;
76                        case Params:
77                                new(&data.inferParams) InferredParams{ std::move(o.data.inferParams) }; return;
78                        }
79                }
80
81                /// clears variant fields
82                void reset() {
83                        switch( mode ) {
84                        case Empty:  return;
85                        case Slots:  data.resnSlots.~ResnSlots(); return;
86                        case Params: data.inferParams.~InferredParams(); return;
87                        }
88                }
89
90                InferUnion() : mode(Empty), data() {}
91                InferUnion( const InferUnion& o ) : mode( o.mode ), data() { init_from( o ); }
92                InferUnion( InferUnion&& o ) : mode( o.mode ), data() { init_from( std::move(o) ); }
93                InferUnion& operator= ( const InferUnion& ) = delete;
94                InferUnion& operator= ( InferUnion&& ) = delete;
95                ~InferUnion() { reset(); }
96
97                ResnSlots& resnSlots() {
98                        switch (mode) {
99                        case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; // fallthrough
100                        case Slots: return data.resnSlots;
101                        case Params: assert(!"Cannot return to resnSlots from Params");
102                        }
103                }
104
105                InferredParams& inferParams() {
106                        switch (mode) {
107                        case Slots: data.resnSlots.~ResnSlots(); // fallthrough
108                        case Empty: new(&data.inferParams) InferredParams{}; mode = Params; // fallthrough
109                        case Params: return data.inferParams;
110                        }
111                }
112        };
113
114        ptr<Type> result;
115        ptr<TypeSubstitution> env;
116        InferUnion inferred;
117        bool extension = false;
118
119        Expr(const CodeLocation & loc ) : ParseNode( loc ), result(), env(), inferred() {}
120
121        Expr * set_extension( bool ex ) { extension = ex; return this; }
122
123        virtual const Expr * accept( Visitor & v ) const override = 0;
124private:
125        Expr * clone() const override = 0;
126};
127
128/// A type used as an expression (e.g. a type generator parameter)
129class TypeExpr final : public Expr {
130public:
131        ptr<Type> type;
132
133        TypeExpr( const CodeLocation & loc, const Type * t ) : Expr(loc), type(t) {}
134
135        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
136private:
137        TypeExpr * clone() const override { return new TypeExpr{ *this }; }
138};
139
140
141//=================================================================================================
142/// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency
143/// remove only if there is a better solution
144/// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with
145/// forward declarations
146inline void increment( const class Expr * node, Node::ref_type ref ) { node->increment(ref); }
147inline void decrement( const class Expr * node, Node::ref_type ref ) { node->decrement(ref); }
148// inline void increment( const class ApplicationExpr * node, Node::ref_type ref ) { node->increment(ref); }
149// inline void decrement( const class ApplicationExpr * node, Node::ref_type ref ) { node->decrement(ref); }
150// inline void increment( const class UntypedExpr * node, Node::ref_type ref ) { node->increment(ref); }
151// inline void decrement( const class UntypedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
152// inline void increment( const class NameExpr * node, Node::ref_type ref ) { node->increment(ref); }
153// inline void decrement( const class NameExpr * node, Node::ref_type ref ) { node->decrement(ref); }
154// inline void increment( const class AddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
155// inline void decrement( const class AddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
156// inline void increment( const class LabelAddressExpr * node, Node::ref_type ref ) { node->increment(ref); }
157// inline void decrement( const class LabelAddressExpr * node, Node::ref_type ref ) { node->decrement(ref); }
158// inline void increment( const class CastExpr * node, Node::ref_type ref ) { node->increment(ref); }
159// inline void decrement( const class CastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
160// inline void increment( const class KeywordCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
161// inline void decrement( const class KeywordCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
162// inline void increment( const class VirtualCastExpr * node, Node::ref_type ref ) { node->increment(ref); }
163// inline void decrement( const class VirtualCastExpr * node, Node::ref_type ref ) { node->decrement(ref); }
164// inline void increment( const class MemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
165// inline void decrement( const class MemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
166// inline void increment( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->increment(ref); }
167// inline void decrement( const class UntypedMemberExpr * node, Node::ref_type ref ) { node->decrement(ref); }
168// inline void increment( const class VariableExpr * node, Node::ref_type ref ) { node->increment(ref); }
169// inline void decrement( const class VariableExpr * node, Node::ref_type ref ) { node->decrement(ref); }
170// inline void increment( const class ConstantExpr * node, Node::ref_type ref ) { node->increment(ref); }
171// inline void decrement( const class ConstantExpr * node, Node::ref_type ref ) { node->decrement(ref); }
172// inline void increment( const class SizeofExpr * node, Node::ref_type ref ) { node->increment(ref); }
173// inline void decrement( const class SizeofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
174// inline void increment( const class AlignofExpr * node, Node::ref_type ref ) { node->increment(ref); }
175// inline void decrement( const class AlignofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
176// inline void increment( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
177// inline void decrement( const class UntypedOffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
178// inline void increment( const class OffsetofExpr * node, Node::ref_type ref ) { node->increment(ref); }
179// inline void decrement( const class OffsetofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
180// inline void increment( const class OffsetPackExpr * node, Node::ref_type ref ) { node->increment(ref); }
181// inline void decrement( const class OffsetPackExpr * node, Node::ref_type ref ) { node->decrement(ref); }
182// inline void increment( const class AttrExpr * node, Node::ref_type ref ) { node->increment(ref); }
183// inline void decrement( const class AttrExpr * node, Node::ref_type ref ) { node->decrement(ref); }
184// inline void increment( const class LogicalExpr * node, Node::ref_type ref ) { node->increment(ref); }
185// inline void decrement( const class LogicalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
186// inline void increment( const class ConditionalExpr * node, Node::ref_type ref ) { node->increment(ref); }
187// inline void decrement( const class ConditionalExpr * node, Node::ref_type ref ) { node->decrement(ref); }
188// inline void increment( const class CommaExpr * node, Node::ref_type ref ) { node->increment(ref); }
189// inline void decrement( const class CommaExpr * node, Node::ref_type ref ) { node->decrement(ref); }
190// inline void increment( const class TypeExpr * node, Node::ref_type ref ) { node->increment(ref); }
191// inline void decrement( const class TypeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
192// inline void increment( const class AsmExpr * node, Node::ref_type ref ) { node->increment(ref); }
193// inline void decrement( const class AsmExpr * node, Node::ref_type ref ) { node->decrement(ref); }
194// inline void increment( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->increment(ref); }
195// inline void decrement( const class ImplicitCopyCtorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
196// inline void increment( const class ConstructorExpr * node, Node::ref_type ref ) { node->increment(ref); }
197// inline void decrement( const class ConstructorExpr * node, Node::ref_type ref ) { node->decrement(ref); }
198// inline void increment( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->increment(ref); }
199// inline void decrement( const class CompoundLiteralExpr * node, Node::ref_type ref ) { node->decrement(ref); }
200// inline void increment( const class UntypedValofExpr * node, Node::ref_type ref ) { node->increment(ref); }
201// inline void decrement( const class UntypedValofExpr * node, Node::ref_type ref ) { node->decrement(ref); }
202// inline void increment( const class RangeExpr * node, Node::ref_type ref ) { node->increment(ref); }
203// inline void decrement( const class RangeExpr * node, Node::ref_type ref ) { node->decrement(ref); }
204// inline void increment( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
205// inline void decrement( const class UntypedTupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
206// inline void increment( const class TupleExpr * node, Node::ref_type ref ) { node->increment(ref); }
207// inline void decrement( const class TupleExpr * node, Node::ref_type ref ) { node->decrement(ref); }
208// inline void increment( const class TupleIndexExpr * node, Node::ref_type ref ) { node->increment(ref); }
209// inline void decrement( const class TupleIndexExpr * node, Node::ref_type ref ) { node->decrement(ref); }
210// inline void increment( const class TupleAssignExpr * node, Node::ref_type ref ) { node->increment(ref); }
211// inline void decrement( const class TupleAssignExpr * node, Node::ref_type ref ) { node->decrement(ref); }
212// inline void increment( const class StmtExpr * node, Node::ref_type ref ) { node->increment(ref); }
213// inline void decrement( const class StmtExpr * node, Node::ref_type ref ) { node->decrement(ref); }
214// inline void increment( const class UniqueExpr * node, Node::ref_type ref ) { node->increment(ref); }
215// inline void decrement( const class UniqueExpr * node, Node::ref_type ref ) { node->decrement(ref); }
216// inline void increment( const class UntypedInitExpr * node, Node::ref_type ref ) { node->increment(ref); }
217// inline void decrement( const class UntypedInitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
218// inline void increment( const class InitExpr * node, Node::ref_type ref ) { node->increment(ref); }
219// inline void decrement( const class InitExpr * node, Node::ref_type ref ) { node->decrement(ref); }
220// inline void increment( const class DeletedExpr * node, Node::ref_type ref ) { node->increment(ref); }
221// inline void decrement( const class DeletedExpr * node, Node::ref_type ref ) { node->decrement(ref); }
222// inline void increment( const class DefaultArgExpr * node, Node::ref_type ref ) { node->increment(ref); }
223// inline void decrement( const class DefaultArgExpr * node, Node::ref_type ref ) { node->decrement(ref); }
224// inline void increment( const class GenericExpr * node, Node::ref_type ref ) { node->increment(ref); }
225// inline void decrement( const class GenericExpr * node, Node::ref_type ref ) { node->decrement(ref); }
226}
227
228// Local Variables: //
229// tab-width: 4 //
230// mode: c++ //
231// compile-command: "make install" //
232// End: //
Note: See TracBrowser for help on using the repository browser.