]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/dmd/sapply.c
Merge dmd upstream 6243fa6d2
[thirdparty/gcc.git] / gcc / d / dmd / sapply.c
CommitLineData
b4c522fa
IB
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/sapply.c
9 */
10
f9ab59ff 11#include "root/dsystem.h"
b4c522fa
IB
12
13#include "mars.h"
14#include "statement.h"
15#include "visitor.h"
16
17
18/**************************************
19 * A Statement tree walker that will visit each Statement s in the tree,
20 * in depth-first evaluation order, and call fp(s,param) on it.
21 * fp() signals whether the walking continues with its return value:
22 * Returns:
23 * 0 continue
24 * 1 done
25 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
26 * Creating an iterator for this would be much more complex.
27 */
28
29class PostorderStatementVisitor : public StoppableVisitor
30{
31public:
32 StoppableVisitor *v;
33 PostorderStatementVisitor(StoppableVisitor *v) : v(v) {}
34
35 bool doCond(Statement *s)
36 {
37 if (!stop && s)
38 s->accept(this);
39 return stop;
40 }
41 bool applyTo(Statement *s)
42 {
43 s->accept(v);
44 stop = v->stop;
45 return true;
46 }
47
48 void visit(Statement *s)
49 {
50 applyTo(s);
51 }
52 void visit(PeelStatement *s)
53 {
54 doCond(s->s) || applyTo(s);
55 }
56 void visit(CompoundStatement *s)
57 {
58 for (size_t i = 0; i < s->statements->dim; i++)
59 if (doCond((*s->statements)[i]))
60 return;
61 applyTo(s);
62 }
63 void visit(UnrolledLoopStatement *s)
64 {
65 for (size_t i = 0; i < s->statements->dim; i++)
66 if (doCond((*s->statements)[i]))
67 return;
68 applyTo(s);
69 }
70 void visit(ScopeStatement *s)
71 {
72 doCond(s->statement) || applyTo(s);
73 }
74 void visit(WhileStatement *s)
75 {
76 doCond(s->_body) || applyTo(s);
77 }
78 void visit(DoStatement *s)
79 {
80 doCond(s->_body) || applyTo(s);
81 }
82 void visit(ForStatement *s)
83 {
84 doCond(s->_init) || doCond(s->_body) || applyTo(s);
85 }
86 void visit(ForeachStatement *s)
87 {
88 doCond(s->_body) || applyTo(s);
89 }
90 void visit(ForeachRangeStatement *s)
91 {
92 doCond(s->_body) || applyTo(s);
93 }
94 void visit(IfStatement *s)
95 {
96 doCond(s->ifbody) || doCond(s->elsebody) || applyTo(s);
97 }
98 void visit(PragmaStatement *s)
99 {
100 doCond(s->_body) || applyTo(s);
101 }
102 void visit(SwitchStatement *s)
103 {
104 doCond(s->_body) || applyTo(s);
105 }
106 void visit(CaseStatement *s)
107 {
108 doCond(s->statement) || applyTo(s);
109 }
110 void visit(DefaultStatement *s)
111 {
112 doCond(s->statement) || applyTo(s);
113 }
114 void visit(SynchronizedStatement *s)
115 {
116 doCond(s->_body) || applyTo(s);
117 }
118 void visit(WithStatement *s)
119 {
120 doCond(s->_body) || applyTo(s);
121 }
122 void visit(TryCatchStatement *s)
123 {
124 if (doCond(s->_body))
125 return;
126
127 for (size_t i = 0; i < s->catches->dim; i++)
128 if (doCond((*s->catches)[i]->handler))
129 return;
130 applyTo(s);
131 }
132 void visit(TryFinallyStatement *s)
133 {
134 doCond(s->_body) || doCond(s->finalbody) || applyTo(s);
135 }
136 void visit(OnScopeStatement *s)
137 {
138 doCond(s->statement) || applyTo(s);
139 }
140 void visit(DebugStatement *s)
141 {
142 doCond(s->statement) || applyTo(s);
143 }
144 void visit(LabelStatement *s)
145 {
146 doCond(s->statement) || applyTo(s);
147 }
148};
149
150bool walkPostorder(Statement *s, StoppableVisitor *v)
151{
152 PostorderStatementVisitor pv(v);
153 s->accept(&pv);
154 return v->stop;
155}