1a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
2a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Use of this source code is governed by a BSD-style license that can be
4a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// found in the LICENSE file.
5a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
6a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
7a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "compiler/ParseHelper.h"
8a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
9a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
10a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Use this class to carry along data from node to node in
11a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// the traversal
12a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
13a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockclass TConstTraverser : public TIntermTraverser {
14a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockpublic:
155abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t)
165abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick        : error(false),
175abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          index(0),
185abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          unionArray(cUnion),
195abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          type(t),
205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          constructorType(constructType),
215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          singleConstantParam(singleConstParam),
225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          infoSink(sink),
235abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          symbolTable(symTable),
245abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          size(0),
255abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          isMatrix(false),
265abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick          matrixSize(0) {
275abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    }
28a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool error;
30a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
31a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockprotected:
325abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    void visitSymbol(TIntermSymbol*);
335abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    void visitConstantUnion(TIntermConstantUnion*);
345abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitBinary(Visit visit, TIntermBinary*);
355abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitUnary(Visit visit, TIntermUnary*);
365abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitSelection(Visit visit, TIntermSelection*);
375abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitAggregate(Visit visit, TIntermAggregate*);
385abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitLoop(Visit visit, TIntermLoop*);
395abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    bool visitBranch(Visit visit, TIntermBranch*);
40a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
41a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    int index;
42a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    ConstantUnion *unionArray;
43a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TType type;
44a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TOperator constructorType;
45a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    bool singleConstantParam;
46a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TInfoSink& infoSink;
47a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TSymbolTable& symbolTable;
48a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    int size; // size of the constructor ( 4 for vec4)
49a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    bool isMatrix;
50a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    int matrixSize; // dimension of the matrix (nominal size and not the instance size)
51a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block};
52a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
53a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
54a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// The rest of the file are the traversal functions.  The last one
55a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// is the one that starts the traversal.
56a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
57a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Return true from interior nodes to have the external traversal
58a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// continue on to children.  If you process children yourself,
59a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// return false.
60a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
61a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
62a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TConstTraverser::visitSymbol(TIntermSymbol* node)
63a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
64a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
65a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return;
66a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
67a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
68a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
69a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
70a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
71a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TQualifier qualifier = node->getType().getQualifier();
72a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
73a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (qualifier != EvqConst) {
74a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        TString buf;
75a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        buf.append("'constructor' : assigning non-constant to ");
76a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        buf.append(type.getCompleteString());
77a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
78a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        error = true;
79a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return false;
80a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
81a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
82a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block   infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
83a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
84a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
85a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
86a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
87a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
88a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
89a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TString buf;
90a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    buf.append("'constructor' : assigning non-constant to ");
91a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    buf.append(type.getCompleteString());
92a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
93a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    error = true;
94a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
95a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
96a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
97a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
98a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
99a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (!node->isConstructor() && node->getOp() != EOpComma) {
100a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        TString buf;
101a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        buf.append("'constructor' : assigning non-constant to ");
102a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        buf.append(type.getCompleteString());
103a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        infoSink.info.message(EPrefixError, buf.c_str(), node->getLine());
104a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        error = true;
105a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return false;
106a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
107a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
108a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (node->getSequence().size() == 0) {
109a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        error = true;
110a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return false;
111a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
112a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
113a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
114a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (flag)
115a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    {
116a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        singleConstantParam = true;
117a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        constructorType = node->getOp();
118a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        size = node->getType().getObjectSize();
119a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
120a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        if (node->getType().isMatrix()) {
121a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            isMatrix = true;
122a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            matrixSize = node->getType().getNominalSize();
123a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        }
124a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
125a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
126a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    for (TIntermSequence::iterator p = node->getSequence().begin();
127a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                                   p != node->getSequence().end(); p++) {
128a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
129a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        if (node->getOp() == EOpComma)
130a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            index = 0;
131a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
132a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        (*p)->traverse(this);
133a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
134a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (flag)
135a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    {
136a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        singleConstantParam = false;
137a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        constructorType = EOpNull;
138a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        size = 0;
139a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        isMatrix = false;
140a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        matrixSize = 0;
141a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
142a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
143a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
144a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
145a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
146a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
147a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
148a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    error = true;
149a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
150a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
151a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
152a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
153a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
154a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    ConstantUnion* leftUnionArray = unionArray;
155a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    int instanceSize = type.getObjectSize();
156a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
157a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (index >= instanceSize)
158a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return;
159a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
160a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (!singleConstantParam) {
161a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        int size = node->getType().getObjectSize();
162a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
163a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
164a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        for (int i=0; i < size; i++) {
165a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            if (index >= instanceSize)
166a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                return;
167a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            leftUnionArray[index] = rightUnionArray[i];
168a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
169a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            (index)++;
170a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        }
171a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    } else {
172a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        int totalSize = index + size;
173a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
174a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        if (!isMatrix) {
175a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            int count = 0;
176a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            for (int i = index; i < totalSize; i++) {
177a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                if (i >= instanceSize)
178a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    return;
179a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
180a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                leftUnionArray[i] = rightUnionArray[count];
181a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
182a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                (index)++;
183a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
184a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                if (node->getType().getObjectSize() > 1)
185a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    count++;
186a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            }
187a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        } else {  // for matrix constructors
188a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            int count = 0;
189a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            int element = index;
190a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            for (int i = index; i < totalSize; i++) {
191a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                if (i >= instanceSize)
192a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    return;
193a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 )
194a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    leftUnionArray[i] = rightUnionArray[count];
195a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                else
196a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    leftUnionArray[i].setFConst(0.0f);
197a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
198a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                (index)++;
199a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
200a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                if (node->getType().getObjectSize() > 1)
201a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block                    count++;
202a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block            }
203a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        }
204a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    }
205a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
206a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
207a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
208a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
209a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
210a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    error = true;
211a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
212a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
213a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
214a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
215a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
216a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
217a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    error = true;
218a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    return false;
219a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
220a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
221a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
222a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// This function is the one to call externally to start the traversal.
223a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Individual functions can be initialized to 0 to skip processing of that
224a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// type of node.  It's children will still be processed.
225a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block//
226a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
227a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{
228a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (root == 0)
229a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return false;
230a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
231a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
232a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block
233a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    root->traverse(&it);
234a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    if (it.error)
235a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return true;
236a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block    else
237a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block        return false;
238a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block}
239