Coverage Report

Created: 2026-08-14 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glslang/glslang/MachineIndependent/IntermTraverse.cpp
Line
Count
Source
1
//
2
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3
// Copyright (C) 2013 LunarG, Inc.
4
// Copyright (c) 2002-2010 The ANGLE Project Authors.
5
//
6
// All rights reserved.
7
//
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions
10
// are met:
11
//
12
//    Redistributions of source code must retain the above copyright
13
//    notice, this list of conditions and the following disclaimer.
14
//
15
//    Redistributions in binary form must reproduce the above
16
//    copyright notice, this list of conditions and the following
17
//    disclaimer in the documentation and/or other materials provided
18
//    with the distribution.
19
//
20
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
21
//    contributors may be used to endorse or promote products derived
22
//    from this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
// POSSIBILITY OF SUCH DAMAGE.
36
//
37
38
#include "../Include/intermediate.h"
39
40
namespace glslang {
41
42
//
43
// Traverse the intermediate representation tree, and
44
// call a node type specific function for each node.
45
// Done recursively through the member function Traverse().
46
// Node types can be skipped if their function to call is 0,
47
// but their subtree will still be traversed.
48
// Nodes with children can have their whole subtree skipped
49
// if preVisit is turned on and the type specific function
50
// returns false.
51
//
52
// preVisit, postVisit, and rightToLeft control what order
53
// nodes are visited in.
54
//
55
56
//
57
// Traversal functions for terminals are straightforward....
58
//
59
void TIntermMethod::traverse(TIntermTraverser*)
60
0
{
61
    // Tree should always resolve all methods as a non-method.
62
0
}
63
64
void TIntermSymbol::traverse(TIntermTraverser *it)
65
0
{
66
0
    it->visitSymbol(this);
67
0
}
68
69
void TIntermConstantUnion::traverse(TIntermTraverser *it)
70
40
{
71
40
    it->visitConstantUnion(this);
72
40
}
73
74
0
const TString& TIntermSymbol::getAccessName() const {
75
0
    if (getBasicType() == EbtBlock)
76
0
        return getType().getTypeName();
77
0
    else
78
0
        return getName();
79
0
}
80
81
//
82
// Traverse a binary node.
83
//
84
void TIntermBinary::traverse(TIntermTraverser *it)
85
0
{
86
0
    bool visit = true;
87
88
    //
89
    // visit the node before children if pre-visiting.
90
    //
91
0
    if (it->preVisit)
92
0
        visit = it->visitBinary(EvPreVisit, this);
93
94
    //
95
    // Visit the children, in the right order.
96
    //
97
0
    if (visit) {
98
0
        it->incrementDepth(this);
99
100
0
        if (it->rightToLeft) {
101
0
            if (right)
102
0
                right->traverse(it);
103
104
0
            if (it->inVisit)
105
0
                visit = it->visitBinary(EvInVisit, this);
106
107
0
            if (visit && left)
108
0
                left->traverse(it);
109
0
        } else {
110
0
            if (left)
111
0
                left->traverse(it);
112
113
0
            if (it->inVisit)
114
0
                visit = it->visitBinary(EvInVisit, this);
115
116
0
            if (visit && right)
117
0
                right->traverse(it);
118
0
        }
119
120
0
        it->decrementDepth();
121
0
    }
122
123
    //
124
    // Visit the node after the children, if requested and the traversal
125
    // hasn't been canceled yet.
126
    //
127
0
    if (visit && it->postVisit)
128
0
        it->visitBinary(EvPostVisit, this);
129
0
}
130
131
//
132
// Traverse a unary node.  Same comments in binary node apply here.
133
//
134
void TIntermUnary::traverse(TIntermTraverser *it)
135
0
{
136
0
    bool visit = true;
137
138
0
    if (it->preVisit)
139
0
        visit = it->visitUnary(EvPreVisit, this);
140
141
0
    if (visit) {
142
0
        it->incrementDepth(this);
143
0
        operand->traverse(it);
144
0
        it->decrementDepth();
145
0
    }
146
147
0
    if (visit && it->postVisit)
148
0
        it->visitUnary(EvPostVisit, this);
149
0
}
150
151
//
152
// Traverse an aggregate node.  Same comments in binary node apply here.
153
//
154
void TIntermAggregate::traverse(TIntermTraverser *it)
155
20
{
156
20
    bool visit = true;
157
158
20
    if (it->preVisit)
159
20
        visit = it->visitAggregate(EvPreVisit, this);
160
161
20
    if (visit) {
162
0
        it->incrementDepth(this);
163
164
0
        if (it->rightToLeft) {
165
0
            for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++) {
166
0
                (*sit)->traverse(it);
167
168
0
                if (visit && it->inVisit) {
169
0
                    if (*sit != sequence.front())
170
0
                        visit = it->visitAggregate(EvInVisit, this);
171
0
                }
172
0
            }
173
0
        } else {
174
0
            for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) {
175
0
                (*sit)->traverse(it);
176
177
0
                if (visit && it->inVisit) {
178
0
                    if (*sit != sequence.back())
179
0
                        visit = it->visitAggregate(EvInVisit, this);
180
0
                }
181
0
            }
182
0
        }
183
184
0
        it->decrementDepth();
185
0
    }
186
187
20
    if (visit && it->postVisit)
188
0
        it->visitAggregate(EvPostVisit, this);
189
20
}
190
191
//
192
// Traverse a selection node.  Same comments in binary node apply here.
193
//
194
void TIntermSelection::traverse(TIntermTraverser *it)
195
0
{
196
0
    bool visit = true;
197
198
0
    if (it->preVisit)
199
0
        visit = it->visitSelection(EvPreVisit, this);
200
201
0
    if (visit) {
202
0
        it->incrementDepth(this);
203
0
        if (it->rightToLeft) {
204
0
            if (falseBlock)
205
0
                falseBlock->traverse(it);
206
0
            if (trueBlock)
207
0
                trueBlock->traverse(it);
208
0
            condition->traverse(it);
209
0
        } else {
210
0
            condition->traverse(it);
211
0
            if (trueBlock)
212
0
                trueBlock->traverse(it);
213
0
            if (falseBlock)
214
0
                falseBlock->traverse(it);
215
0
        }
216
0
        it->decrementDepth();
217
0
    }
218
219
0
    if (visit && it->postVisit)
220
0
        it->visitSelection(EvPostVisit, this);
221
0
}
222
223
//
224
// Traverse a loop node.  Same comments in binary node apply here.
225
//
226
void TIntermLoop::traverse(TIntermTraverser *it)
227
0
{
228
0
    bool visit = true;
229
230
0
    if (it->preVisit)
231
0
        visit = it->visitLoop(EvPreVisit, this);
232
233
0
    if (visit) {
234
0
        it->incrementDepth(this);
235
236
0
        if (it->rightToLeft) {
237
0
            if (terminal)
238
0
                terminal->traverse(it);
239
240
0
            if (body)
241
0
                body->traverse(it);
242
243
0
            if (test)
244
0
                test->traverse(it);
245
0
        } else {
246
0
            if (test)
247
0
                test->traverse(it);
248
249
0
            if (body)
250
0
                body->traverse(it);
251
252
0
            if (terminal)
253
0
                terminal->traverse(it);
254
0
        }
255
256
0
        it->decrementDepth();
257
0
    }
258
259
0
    if (visit && it->postVisit)
260
0
        it->visitLoop(EvPostVisit, this);
261
0
}
262
263
//
264
// Traverse a branch node.  Same comments in binary node apply here.
265
//
266
void TIntermBranch::traverse(TIntermTraverser *it)
267
0
{
268
0
    bool visit = true;
269
270
0
    if (it->preVisit)
271
0
        visit = it->visitBranch(EvPreVisit, this);
272
273
0
    if (visit && expression) {
274
0
        it->incrementDepth(this);
275
0
        expression->traverse(it);
276
0
        it->decrementDepth();
277
0
    }
278
279
0
    if (visit && it->postVisit)
280
0
        it->visitBranch(EvPostVisit, this);
281
0
}
282
283
//
284
// Traverse a switch node.
285
//
286
void TIntermSwitch::traverse(TIntermTraverser* it)
287
0
{
288
0
    bool visit = true;
289
290
0
    if (it->preVisit)
291
0
        visit = it->visitSwitch(EvPreVisit, this);
292
293
0
    if (visit) {
294
0
        it->incrementDepth(this);
295
0
        if (it->rightToLeft) {
296
0
            body->traverse(it);
297
0
            condition->traverse(it);
298
0
        } else {
299
0
            condition->traverse(it);
300
0
            body->traverse(it);
301
0
        }
302
0
        it->decrementDepth();
303
0
    }
304
305
0
    if (visit && it->postVisit)
306
0
        it->visitSwitch(EvPostVisit, this);
307
0
}
308
309
//
310
// Traverse a variable declaration.
311
//
312
void TIntermVariableDecl::traverse(TIntermTraverser *it)
313
0
{
314
0
    bool visit = true;
315
316
0
    if (it->preVisit)
317
0
        visit = it->visitVariableDecl(EvPreVisit, this);
318
319
0
    if (visit) {
320
0
        it->incrementDepth(this);
321
0
        if (it->rightToLeft) {
322
0
            if (it->includeDeclSymbol)
323
0
                declSymbol->traverse(it);
324
0
            if (initNode)
325
0
                initNode->traverse(it);
326
0
        }
327
0
        else {
328
0
            if (initNode)
329
0
                initNode->traverse(it);
330
0
            if (it->includeDeclSymbol)
331
0
                declSymbol->traverse(it);
332
0
        }
333
0
        it->decrementDepth();
334
0
    }
335
336
0
    if (visit && it->postVisit)
337
0
        it->visitVariableDecl(EvPostVisit, this);
338
0
}
339
340
} // end namespace glslang