Pass 1 at building on linux: remove compile errors from machine independent.
[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 #include "ParseHelper.h"
36
37 //
38 // Use this class to carry along data from node to node in 
39 // the traversal
40 //
41 class TConstTraverser : public TIntermTraverser {
42 public:
43     TConstTraverser(constUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
44         constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), 
45         matrixCols(0), matrixRows(0) {  index = 0; tOp = EOpNull;}
46     int index ;
47     constUnion *unionArray;
48     TOperator tOp;
49     TType type;
50     TOperator constructorType;
51     bool singleConstantParam;
52     TInfoSink& infoSink;
53     TSymbolTable& symbolTable;
54     bool error;
55     int size; // size of the constructor ( 4 for vec4)
56     bool isMatrix;
57     int matrixCols;
58     int matrixRows;
59 };
60
61 //
62 // The rest of the file are the traversal functions.  The last one
63 // is the one that starts the traversal.
64 //
65 // Return true from interior nodes to have the external traversal
66 // continue on to children.  If you process children yourself,
67 // return false.
68 //
69
70 void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
71 {
72     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
73     oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
74
75     return;
76 }
77
78 bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
79 {
80     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
81     
82     TStorageQualifier qualifier = node->getType().getQualifier().storage;
83     
84     if (qualifier != EvqConst) {
85                 const int maxSize = 200;
86         char buf[maxSize];
87         snprintf(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
88         oit->infoSink.info.message(EPrefixError, buf, node->getLine());
89         oit->error = true;
90
91         return false;  
92     }
93
94    oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
95     
96     return false;
97 }
98
99 bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
100 {
101     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
102
103         const int maxSize = 200;
104     char buf[maxSize];
105     snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
106     oit->infoSink.info.message(EPrefixError, buf, node->getLine());
107     oit->error = true;
108
109     return false;  
110 }
111
112 bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
113 {
114     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
115
116     if (!node->isConstructor() && node->getOp() != EOpComma) {
117                 const int maxSize = 200;
118         char buf[maxSize];
119         snprintf(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
120         oit->infoSink.info.message(EPrefixError, buf, node->getLine());
121         oit->error = true;
122
123         return false;  
124     }
125
126     if (node->getSequence().size() == 0) {
127         oit->error = true;
128
129         return false;
130     }
131
132     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
133     if (flag) {
134         oit->singleConstantParam = true; 
135         oit->constructorType = node->getOp();
136         oit->size = node->getType().getObjectSize();
137
138         if (node->getType().isMatrix()) {
139             oit->isMatrix = true;
140             oit->matrixCols = node->getType().getMatrixCols();
141             oit->matrixRows = node->getType().getMatrixRows();
142         }
143     }       
144
145     for (TIntermSequence::iterator p = node->getSequence().begin(); 
146                                    p != node->getSequence().end(); p++) {
147
148         if (node->getOp() == EOpComma)
149             oit->index = 0;           
150
151         (*p)->traverse(oit);
152     }   
153     if (flag) 
154     {
155         oit->singleConstantParam = false;   
156         oit->constructorType = EOpNull;
157         oit->size = 0;
158         oit->isMatrix = false;
159         oit->matrixCols = 0;
160         oit->matrixRows = 0;
161     }
162
163     return false;
164 }
165
166 bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
167 {
168     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
169     oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
170     oit->error = true;
171     return false;
172 }
173
174 void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
175 {
176     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
177     constUnion* leftUnionArray = oit->unionArray;
178     int instanceSize = oit->type.getObjectSize();
179
180     if (oit->index >= instanceSize)
181         return;
182
183     if (!oit->singleConstantParam) {
184         int size = node->getType().getObjectSize();
185     
186         constUnion *rightUnionArray = node->getUnionArrayPointer();
187         for (int i=0; i < size; i++) {
188             if (oit->index >= instanceSize)
189                 return;
190             leftUnionArray[oit->index] = rightUnionArray[i];
191
192             (oit->index)++;
193         }
194     } else {
195         int size, totalSize, matrixCols, matrixRows;
196         bool isMatrix = false;
197         size = oit->size;
198         matrixCols = oit->matrixCols;
199         matrixRows = oit->matrixRows;
200         isMatrix = oit->isMatrix;
201         totalSize = oit->index + size;
202         constUnion *rightUnionArray = node->getUnionArrayPointer();
203         if (!isMatrix) {
204             int count = 0;
205             for (int i = oit->index; i < totalSize; i++) {
206                 if (i >= instanceSize)
207                     return;
208
209                 leftUnionArray[i] = rightUnionArray[count];
210
211                 (oit->index)++;
212                 
213                 if (node->getType().getObjectSize() > 1)
214                     count++;
215             }
216         } else {  // for matrix constructors
217             int count = 0;
218             int index = oit->index;
219             for (int i = index; i < totalSize; i++) {
220                 if (i >= instanceSize)
221                     return;
222                 if (index - i == 0 || (i - index) % (matrixRows + 1) == 0 )
223                     leftUnionArray[i] = rightUnionArray[count];
224                 else 
225                     leftUnionArray[i].setFConst(0.0f);
226
227                 (oit->index)++;
228
229                 if (node->getType().getObjectSize() > 1)
230                     count++;                
231             }
232         }
233     }
234 }
235
236 bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
237 {
238     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
239     oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
240     oit->error = true;
241     
242     return false;
243 }
244
245 bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
246 {
247     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
248     oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
249     oit->error = true;
250     
251     return false;
252 }
253
254 //
255 // This function is the one to call externally to start the traversal.
256 // Individual functions can be initialized to 0 to skip processing of that
257 // type of node.  It's children will still be processed.
258 //
259 bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, constUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
260 {
261     if (root == 0)
262         return false;
263
264     TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
265     
266     it.visitAggregate = ParseAggregate;
267     it.visitBinary = ParseBinary;
268     it.visitConstantUnion = ParseConstantUnion;
269     it.visitSelection = ParseSelection;
270     it.visitSymbol = ParseSymbol;
271     it.visitUnary = ParseUnary;
272     it.visitLoop = ParseLoop;
273     it.visitBranch = ParseBranch;
274
275     root->traverse(&it);
276     if (it.error)
277         return true;
278     else
279         return false;
280 }