]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/apply.c
Add D front-end, libphobos library, and D2 testsuite.
[thirdparty/gcc.git] / gcc / d / dmd / apply.c
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
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/D-Programming-Language/dmd/blob/master/src/apply.c
9 */
10
11 #include <stdio.h>
12 #include <assert.h>
13
14 #include "mars.h"
15 #include "expression.h"
16 #include "template.h"
17 #include "visitor.h"
18
19
20 /**************************************
21 * An Expression tree walker that will visit each Expression e in the tree,
22 * in depth-first evaluation order, and call fp(e,param) on it.
23 * fp() signals whether the walking continues with its return value:
24 * Returns:
25 * 0 continue
26 * 1 done
27 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
28 * Creating an iterator for this would be much more complex.
29 */
30
31 class PostorderExpressionVisitor : public StoppableVisitor
32 {
33 public:
34 StoppableVisitor *v;
35 PostorderExpressionVisitor(StoppableVisitor *v) : v(v) {}
36
37 bool doCond(Expression *e)
38 {
39 if (!stop && e)
40 e->accept(this);
41 return stop;
42 }
43 bool doCond(Expressions *e)
44 {
45 if (!e)
46 return false;
47 for (size_t i = 0; i < e->dim && !stop; i++)
48 doCond((*e)[i]);
49 return stop;
50 }
51 bool applyTo(Expression *e)
52 {
53 e->accept(v);
54 stop = v->stop;
55 return true;
56 }
57
58 void visit(Expression *e)
59 {
60 applyTo(e);
61 }
62
63 void visit(NewExp *e)
64 {
65 //printf("NewExp::apply(): %s\n", toChars());
66
67 doCond(e->thisexp) || doCond(e->newargs) || doCond(e->arguments) || applyTo(e);
68 }
69
70 void visit(NewAnonClassExp *e)
71 {
72 //printf("NewAnonClassExp::apply(): %s\n", toChars());
73
74 doCond(e->thisexp) || doCond(e->newargs) || doCond(e->arguments) || applyTo(e);
75 }
76
77 void visit(TypeidExp *e)
78 {
79 doCond(isExpression(e->obj)) || applyTo(e);
80 }
81
82 void visit(UnaExp *e)
83 {
84 doCond(e->e1) || applyTo(e);
85 }
86
87 void visit(BinExp *e)
88 {
89 doCond(e->e1) || doCond(e->e2) || applyTo(e);
90 }
91
92 void visit(AssertExp *e)
93 {
94 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
95 doCond(e->e1) || doCond(e->msg) || applyTo(e);
96 }
97
98 void visit(CallExp *e)
99 {
100 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
101 doCond(e->e1) || doCond(e->arguments) || applyTo(e);
102 }
103
104 void visit(ArrayExp *e)
105 {
106 //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
107 doCond(e->e1) || doCond(e->arguments) || applyTo(e);
108 }
109
110 void visit(SliceExp *e)
111 {
112 doCond(e->e1) || doCond(e->lwr) || doCond(e->upr) || applyTo(e);
113 }
114
115 void visit(ArrayLiteralExp *e)
116 {
117 doCond(e->basis) || doCond(e->elements) || applyTo(e);
118 }
119
120 void visit(AssocArrayLiteralExp *e)
121 {
122 doCond(e->keys) || doCond(e->values) || applyTo(e);
123 }
124
125 void visit(StructLiteralExp *e)
126 {
127 if (e->stageflags & stageApply) return;
128 int old = e->stageflags;
129 e->stageflags |= stageApply;
130 doCond(e->elements) || applyTo(e);
131 e->stageflags = old;
132 }
133
134 void visit(TupleExp *e)
135 {
136 doCond(e->e0) || doCond(e->exps) || applyTo(e);
137 }
138
139 void visit(CondExp *e)
140 {
141 doCond(e->econd) || doCond(e->e1) || doCond(e->e2) || applyTo(e);
142 }
143 };
144
145 bool walkPostorder(Expression *e, StoppableVisitor *v)
146 {
147 PostorderExpressionVisitor pv(v);
148 e->accept(&pv);
149 return v->stop;
150 }