glslang: Fix over 100 warnings from MSVC warning level 4.
[platform/upstream/glslang.git] / glslang / MachineIndependent / parseConst.cpp
1 //
2 //Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 //All rights reserved.
4 //
5 //Redistribution and use in source and binary forms, with or without
6 //modification, are permitted provided that the following conditions
7 //are met:
8 //
9 //    Redistributions of source code must retain the above copyright
10 //    notice, this list of conditions and the following disclaimer.
11 //
12 //    Redistributions in binary form must reproduce the above
13 //    copyright notice, this list of conditions and the following
14 //    disclaimer in the documentation and/or other materials provided
15 //    with the distribution.
16 //
17 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18 //    contributors may be used to endorse or promote products derived
19 //    from this software without specific prior written permission.
20 //
21 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //POSSIBILITY OF SUCH DAMAGE.
33 //
34
35 //
36 // Travarse a tree of constants to create a single folded constant.
37 // It should only be used when the whole tree is known to be constant.
38 //
39
40 #include "ParseHelper.h"
41
42 namespace glslang {
43
44 class TConstTraverser : public TIntermTraverser {
45 public:
46     TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
47       : unionArray(cUnion), type(t),
48         constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), 
49         matrixCols(0), matrixRows(0) {  index = 0; tOp = EOpNull; }
50
51     virtual void visitConstantUnion(TIntermConstantUnion* node);
52     virtual bool visitAggregate(TVisit, TIntermAggregate* node);
53
54     int index;
55     TConstUnionArray unionArray;
56     TOperator tOp;
57     const TType& type;
58     TOperator constructorType;
59     bool singleConstantParam;
60     bool error;
61     int size; // size of the constructor ( 4 for vec4)
62     bool isMatrix;
63     int matrixCols;
64     int matrixRows;
65
66 protected:
67     TConstTraverser(TConstTraverser&);
68     TConstTraverser& operator=(TConstTraverser&);
69 };
70
71 bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
72 {
73     if (! node->isConstructor() && node->getOp() != EOpComma) {
74         error = true;
75
76         return false;  
77     }
78
79     if (node->getSequence().size() == 0) {
80         error = true;
81
82         return false;
83     }
84
85     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
86     if (flag) {
87         singleConstantParam = true; 
88         constructorType = node->getOp();
89         size = node->getType().computeNumComponents();
90
91         if (node->getType().isMatrix()) {
92             isMatrix = true;
93             matrixCols = node->getType().getMatrixCols();
94             matrixRows = node->getType().getMatrixRows();
95         }
96     }       
97
98     for (TIntermSequence::iterator p = node->getSequence().begin(); 
99                                    p != node->getSequence().end(); p++) {
100
101         if (node->getOp() == EOpComma)
102             index = 0;           
103
104         (*p)->traverse(this);
105     }   
106     if (flag) 
107     {
108         singleConstantParam = false;   
109         constructorType = EOpNull;
110         size = 0;
111         isMatrix = false;
112         matrixCols = 0;
113         matrixRows = 0;
114     }
115
116     return false;
117 }
118
119 void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
120 {
121     TConstUnionArray leftUnionArray(unionArray);
122     int instanceSize = type.computeNumComponents();
123
124     if (index >= instanceSize)
125         return;
126
127     if (! singleConstantParam) {
128         int rightUnionSize = node->getType().computeNumComponents();
129     
130         const TConstUnionArray& rightUnionArray = node->getConstArray();
131         for (int i = 0; i < rightUnionSize; i++) {
132             if (index >= instanceSize)
133                 return;
134             leftUnionArray[index] = rightUnionArray[i];
135
136             index++;
137         }
138     } else {
139         int endIndex = index + size;
140         const TConstUnionArray& rightUnionArray = node->getConstArray();
141         if (! isMatrix) {
142             int count = 0;
143             int nodeComps = node->getType().computeNumComponents();
144             for (int i = index; i < endIndex; i++) {
145                 if (i >= instanceSize)
146                     return;
147
148                 leftUnionArray[i] = rightUnionArray[count];
149
150                 (index)++;
151                 
152                 if (nodeComps > 1)
153                     count++;
154             }
155         } else {
156             // constructing a matrix, but from what?
157             if (node->isMatrix()) {
158                 // Matrix from a matrix; this has the outer matrix, node is the argument matrix.
159                 // Traverse the outer, potentially bigger matrix, fill in missing pieces with the
160                 // identity matrix.
161                 for (int c = 0; c < matrixCols; ++c) {
162                     for (int r = 0; r < matrixRows; ++r) {
163                         int targetOffset = index + c * matrixRows + r;
164                         if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) {
165                             int srcOffset = c * node->getType().getMatrixRows() + r;
166                             leftUnionArray[targetOffset] = rightUnionArray[srcOffset];
167                         } else if (r == c)
168                             leftUnionArray[targetOffset].setDConst(1.0);
169                         else
170                             leftUnionArray[targetOffset].setDConst(0.0);
171                     }
172                 }
173             } else {
174                 // matrix from vector
175                 int count = 0;
176                 const int startIndex = index;
177                 int nodeComps = node->getType().computeNumComponents();
178                 for (int i = startIndex; i < endIndex; i++) {
179                     if (i >= instanceSize)
180                         return;
181                     if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
182                         leftUnionArray[i] = rightUnionArray[count];
183                     else 
184                         leftUnionArray[i].setDConst(0.0);
185
186                     index++;
187
188                     if (nodeComps > 1)
189                         count++;                
190                 }
191             }
192         }
193     }
194 }
195
196 bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
197 {
198     if (root == 0)
199         return false;
200
201     TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
202     
203     root->traverse(&it);
204     if (it.error)
205         return true;
206     else
207         return false;
208 }
209
210 } // end namespace glslang