]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/dmd/ctfe.h
Merge dmd upstream 6d5b853d3
[thirdparty/gcc.git] / gcc / d / dmd / ctfe.h
CommitLineData
b4c522fa
IB
1
2/* Compiler implementation of the D programming language
f3ed896c 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
b4c522fa
IB
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/ctfe.h
9 */
10
11#pragma once
12
13#include "arraytypes.h"
14#include "tokens.h"
15#include "expression.h"
16
17/**
18 Global status of the CTFE engine. Mostly used for performance diagnostics
19 */
20struct CtfeStatus
21{
22 static int callDepth; // current number of recursive calls
23 /* When printing a stack trace,
24 * suppress this number of calls
25 */
26 static int stackTraceCallsToSuppress;
27 static int maxCallDepth; // highest number of recursive calls
28 static int numArrayAllocs; // Number of allocated arrays
29 static int numAssignments; // total number of assignments executed
30};
31
32/**
33 A reference to a class, or an interface. We need this when we
34 point to a base class (we must record what the type is).
35 */
36class ClassReferenceExp : public Expression
37{
38public:
39 StructLiteralExp *value;
40 ClassReferenceExp(Loc loc, StructLiteralExp *lit, Type *type);
41 ClassDeclaration *originalClass();
42
43 /// Return index of the field, or -1 if not found
44 int getFieldIndex(Type *fieldtype, unsigned fieldoffset);
45 /// Return index of the field, or -1 if not found
46 /// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
47 int findFieldIndexByName(VarDeclaration *v);
48 void accept(Visitor *v) { v->visit(this); }
49};
50
51// The various functions are used only to detect compiler CTFE bugs
52Expression *getValue(VarDeclaration *vd);
53bool hasValue(VarDeclaration *vd);
54void setValueNull(VarDeclaration *vd);
55void setValueWithoutChecking(VarDeclaration *vd, Expression *newval);
56void setValue(VarDeclaration *vd, Expression *newval);
57
58/// Return index of the field, or -1 if not found
59/// Same as getFieldIndex, but checks for a direct match with the VarDeclaration
60int findFieldIndexByName(StructDeclaration *sd, VarDeclaration *v);
61
62
63/** An uninitialized value
64 */
65class VoidInitExp : public Expression
66{
67public:
68 VarDeclaration *var;
69
70 VoidInitExp(VarDeclaration *var, Type *type);
71 const char *toChars();
72 void accept(Visitor *v) { v->visit(this); }
73};
74
75// Create an appropriate void initializer
76UnionExp voidInitLiteral(Type *t, VarDeclaration *var);
77
78/** Fake class which holds the thrown exception.
79 Used for implementing exception handling.
80*/
81class ThrownExceptionExp : public Expression
82{
83public:
84 ClassReferenceExp *thrown; // the thing being tossed
85 ThrownExceptionExp(Loc loc, ClassReferenceExp *victim);
86 const char *toChars();
87 /// Generate an error message when this exception is not caught
88 void generateUncaughtError();
89 void accept(Visitor *v) { v->visit(this); }
90};
91
92/****************************************************************/
93
94// This type is only used by the interpreter.
95
96class CTFEExp : public Expression
97{
98public:
99 CTFEExp(TOK tok);
100
101 const char *toChars();
102
103 // Handy instances to share
104 static CTFEExp *cantexp;
105 static CTFEExp *voidexp;
106 static CTFEExp *breakexp;
107 static CTFEExp *continueexp;
108 static CTFEExp *gotoexp;
109
110 static bool isCantExp(Expression *e) { return e && e->op == TOKcantexp; }
111 static bool isGotoExp(Expression *e) { return e && e->op == TOKgoto; }
112};
113
114/****************************************************************/
115
116
117/// True if 'e' is TOKcantexp, or an exception
118bool exceptionOrCantInterpret(Expression *e);
119
120// Used for debugging only
121void showCtfeExpr(Expression *e, int level = 0);
122
123/// Return true if this is a valid CTFE expression
124bool isCtfeValueValid(Expression *newval);
125bool isCtfeReferenceValid(Expression *newval);
126
127/// Given expr, which evaluates to an array/AA/string literal,
128/// return true if it needs to be copied
129bool needToCopyLiteral(Expression *expr);
130
131/// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
132/// This value will be used for in-place modification.
133UnionExp copyLiteral(Expression *e);
134
135/// Set this literal to the given type, copying it if necessary
136Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
137UnionExp paintTypeOntoLiteralCopy(Type *type, Expression *lit);
138
139/// Convert from a CTFE-internal slice, into a normal Expression
140Expression *resolveSlice(Expression *e, UnionExp *pue = NULL);
141
142/// Determine the array length, without interpreting the expression.
143uinteger_t resolveArrayLength(Expression *e);
144
145/// Create an array literal consisting of 'elem' duplicated 'dim' times.
146ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
147 Expression *elem, size_t dim);
148
149/// Create a string literal consisting of 'value' duplicated 'dim' times.
150StringExp *createBlockDuplicatedStringLiteral(Loc loc, Type *type,
151 unsigned value, size_t dim, unsigned char sz);
152
153
154/* Set dest = src, where both dest and src are container value literals
155 * (ie, struct literals, or static arrays (can be an array literal or a string)
156 * Assignment is recursively in-place.
157 * Purpose: any reference to a member of 'dest' will remain valid after the
158 * assignment.
159 */
160void assignInPlace(Expression *dest, Expression *src);
161
162/// Duplicate the elements array, then set field 'indexToChange' = newelem.
163Expressions *changeOneElement(Expressions *oldelems, size_t indexToChange, Expression *newelem);
164
165/// Given an AA literal aae, set arr[index] = newval and return the new array.
166Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae,
167 Expression *index, Expression *newval);
168
169/// Given array literal oldval of type ArrayLiteralExp or StringExp, of length
170/// oldlen, change its length to newlen. If the newlen is longer than oldlen,
171/// all new elements will be set to the default initializer for the element type.
172UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
173 Expression *oldval, size_t oldlen, size_t newlen);
174
175
176
177/// Return true if t is a pointer (not a function pointer)
178bool isPointer(Type *t);
179
180// For CTFE only. Returns true if 'e' is TRUE or a non-null pointer.
181bool isTrueBool(Expression *e);
182
183/// Is it safe to convert from srcPointee* to destPointee* ?
184/// srcPointee is the genuine type (never void).
185/// destPointee may be void.
186bool isSafePointerCast(Type *srcPointee, Type *destPointee);
187
188/// Given pointer e, return the memory block expression it points to,
189/// and set ofs to the offset within that memory block.
190Expression *getAggregateFromPointer(Expression *e, dinteger_t *ofs);
191
192/// Return true if agg1 and agg2 are pointers to the same memory block
193bool pointToSameMemoryBlock(Expression *agg1, Expression *agg2);
194
195// return e1 - e2 as an integer, or error if not possible
196UnionExp pointerDifference(Loc loc, Type *type, Expression *e1, Expression *e2);
197
198/// Return 1 if true, 0 if false
199/// -1 if comparison is illegal because they point to non-comparable memory blocks
200int comparePointers(TOK op, Expression *agg1, dinteger_t ofs1, Expression *agg2, dinteger_t ofs2);
201
202// Return eptr op e2, where eptr is a pointer, e2 is an integer,
203// and op is TOKadd or TOKmin
204UnionExp pointerArithmetic(Loc loc, TOK op, Type *type,
205 Expression *eptr, Expression *e2);
206
207// True if conversion from type 'from' to 'to' involves a reinterpret_cast
208// floating point -> integer or integer -> floating point
209bool isFloatIntPaint(Type *to, Type *from);
210
211// Reinterpret float/int value 'fromVal' as a float/integer of type 'to'.
212Expression *paintFloatInt(Expression *fromVal, Type *to);
213
214/// Return true if t is an AA
215bool isAssocArray(Type *t);
216
217/// Given a template AA type, extract the corresponding built-in AA type
218TypeAArray *toBuiltinAAType(Type *t);
219
220/* Given an AA literal 'ae', and a key 'e2':
221 * Return ae[e2] if present, or NULL if not found.
222 * Return TOKcantexp on error.
223 */
224Expression *findKeyInAA(Loc loc, AssocArrayLiteralExp *ae, Expression *e2);
225
226/// True if type is TypeInfo_Class
227bool isTypeInfo_Class(Type *type);
228
229
230/***********************************************
231 COW const-folding operations
232***********************************************/
233
234/// Return true if non-pointer expression e can be compared
235/// with >,is, ==, etc, using ctfeCmp, ctfeEquals, ctfeIdentity
236bool isCtfeComparable(Expression *e);
237
238/// Evaluate ==, !=. Resolves slices before comparing. Returns 0 or 1
239int ctfeEqual(Loc loc, TOK op, Expression *e1, Expression *e2);
240
241/// Evaluate is, !is. Resolves slices before comparing. Returns 0 or 1
242int ctfeIdentity(Loc loc, TOK op, Expression *e1, Expression *e2);
243
244/// Returns rawCmp OP 0; where OP is ==, !=, <, >=, etc. Result is 0 or 1
245int specificCmp(TOK op, int rawCmp);
246
247/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
248int intUnsignedCmp(TOK op, dinteger_t n1, dinteger_t n2);
249
250/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
251int intSignedCmp(TOK op, sinteger_t n1, sinteger_t n2);
252
253/// Returns e1 OP e2; where OP is ==, !=, <, >=, etc. Result is 0 or 1
254int realCmp(TOK op, real_t r1, real_t r2);
255
256/// Evaluate >,<=, etc. Resolves slices before comparing. Returns 0 or 1
257int ctfeCmp(Loc loc, TOK op, Expression *e1, Expression *e2);
258
259/// Returns e1 ~ e2. Resolves slices before concatenation.
260UnionExp ctfeCat(Loc loc, Type *type, Expression *e1, Expression *e2);
261
262/// Same as for constfold.Index, except that it only works for static arrays,
263/// dynamic arrays, and strings.
264Expression *ctfeIndex(Loc loc, Type *type, Expression *e1, uinteger_t indx);
265
266/// Cast 'e' of type 'type' to type 'to'.
267Expression *ctfeCast(Loc loc, Type *type, Type *to, Expression *e);