glslang: Fix over 100 warnings from MSVC warning level 4.
[platform/upstream/glslang.git] / glslang / MachineIndependent / parseConst.cpp
index 3497d8c..90621d3 100644 (file)
 //POSSIBILITY OF SUCH DAMAGE.
 //
 
-#include "ParseHelper.h"
-
 //
-// Use this class to carry along data from node to node in 
-// the traversal
+// Travarse a tree of constants to create a single folded constant.
+// It should only be used when the whole tree is known to be constant.
 //
+
+#include "ParseHelper.h"
+
+namespace glslang {
+
 class TConstTraverser : public TIntermTraverser {
 public:
-    TConstTraverser(constUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
-        constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0) {  index = 0; tOp = EOpNull;}
-    int index ;
-    constUnion *unionArray;
+    TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
+      : unionArray(cUnion), type(t),
+        constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), 
+        matrixCols(0), matrixRows(0) {  index = 0; tOp = EOpNull; }
+
+    virtual void visitConstantUnion(TIntermConstantUnion* node);
+    virtual bool visitAggregate(TVisit, TIntermAggregate* node);
+
+    int index;
+    TConstUnionArray unionArray;
     TOperator tOp;
-    TType type;
+    const TType& type;
     TOperator constructorType;
     bool singleConstantParam;
-    TInfoSink& infoSink;
-    TSymbolTable& symbolTable;
     bool error;
     int size; // size of the constructor ( 4 for vec4)
     bool isMatrix;
-    int matrixSize; // dimension of the matrix (nominal size and not the instance size)
-};
-
-//
-// The rest of the file are the traversal functions.  The last one
-// is the one that starts the traversal.
-//
-// Return true from interior nodes to have the external traversal
-// continue on to children.  If you process children yourself,
-// return false.
-//
-
-void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Symbol Node found in constant constructor", node->getLine());
-    return;
-
-}
-
-bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    
-    TQualifier qualifier = node->getType().getQualifier();
-    
-    if (qualifier != EvqConst) {
-               const int maxSize = 200;
-        char buf[maxSize];
-        sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
-        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
-        oit->error = true;
-        return false;  
-    }
-
-   oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
-    
-    return false;
-}
+    int matrixCols;
+    int matrixRows;
 
-bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-
-       const int maxSize = 200;
-    char buf[maxSize];
-    sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
-    oit->infoSink.info.message(EPrefixError, buf, node->getLine());
-    oit->error = true;
-    return false;  
-}
+protected:
+    TConstTraverser(TConstTraverser&);
+    TConstTraverser& operator=(TConstTraverser&);
+};
 
-bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
+bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
 {
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
+    if (! node->isConstructor() && node->getOp() != EOpComma) {
+        error = true;
 
-    if (!node->isConstructor() && node->getOp() != EOpComma) {
-               const int maxSize = 200;
-        char buf[maxSize];
-        sprintf_s(buf, maxSize, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
-        oit->infoSink.info.message(EPrefixError, buf, node->getLine());
-        oit->error = true;
         return false;  
     }
 
     if (node->getSequence().size() == 0) {
-        oit->error = true;
+        error = true;
+
         return false;
     }
 
     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
-    if (flag) 
-    {
-        oit->singleConstantParam = true; 
-        oit->constructorType = node->getOp();
-        oit->size = node->getType().getObjectSize();
+    if (flag) {
+        singleConstantParam = true; 
+        constructorType = node->getOp();
+        size = node->getType().computeNumComponents();
 
         if (node->getType().isMatrix()) {
-            oit->isMatrix = true;
-            oit->matrixSize = node->getType().getNominalSize();
+            isMatrix = true;
+            matrixCols = node->getType().getMatrixCols();
+            matrixRows = node->getType().getMatrixRows();
         }
     }       
 
@@ -140,130 +99,112 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
                                    p != node->getSequence().end(); p++) {
 
         if (node->getOp() == EOpComma)
-            oit->index = 0;           
+            index = 0;           
 
-        (*p)->traverse(oit);
+        (*p)->traverse(this);
     }   
     if (flag) 
     {
-        oit->singleConstantParam = false;   
-        oit->constructorType = EOpNull;
-        oit->size = 0;
-        oit->isMatrix = false;
-        oit->matrixSize = 0;
+        singleConstantParam = false;   
+        constructorType = EOpNull;
+        size = 0;
+        isMatrix = false;
+        matrixCols = 0;
+        matrixRows = 0;
     }
-    return false;
-}
 
-bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
-    oit->error = true;
     return false;
 }
 
-void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
+void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
 {
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    constUnion* leftUnionArray = oit->unionArray;
-    int instanceSize = oit->type.getObjectSize();
+    TConstUnionArray leftUnionArray(unionArray);
+    int instanceSize = type.computeNumComponents();
 
-    if (oit->index >= instanceSize)
+    if (index >= instanceSize)
         return;
 
-    if (!oit->singleConstantParam) {
-        int size = node->getType().getObjectSize();
+    if (! singleConstantParam) {
+        int rightUnionSize = node->getType().computeNumComponents();
     
-        constUnion *rightUnionArray = node->getUnionArrayPointer();
-        for (int i=0; i < size; i++) {
-            if (oit->index >= instanceSize)
+        const TConstUnionArray& rightUnionArray = node->getConstArray();
+        for (int i = 0; i < rightUnionSize; i++) {
+            if (index >= instanceSize)
                 return;
-            leftUnionArray[oit->index] = rightUnionArray[i];
+            leftUnionArray[index] = rightUnionArray[i];
 
-            (oit->index)++;
+            index++;
         }
     } else {
-        int size, totalSize, matrixSize;
-        bool isMatrix = false;
-        size = oit->size;
-        matrixSize = oit->matrixSize;
-        isMatrix = oit->isMatrix;
-        totalSize = oit->index + size ;
-        constUnion *rightUnionArray = node->getUnionArrayPointer();
-        if (!isMatrix) {
+        int endIndex = index + size;
+        const TConstUnionArray& rightUnionArray = node->getConstArray();
+        if (! isMatrix) {
             int count = 0;
-            for (int i = oit->index; i < totalSize; i++) {
+            int nodeComps = node->getType().computeNumComponents();
+            for (int i = index; i < endIndex; i++) {
                 if (i >= instanceSize)
                     return;
 
                 leftUnionArray[i] = rightUnionArray[count];
 
-                (oit->index)++;
+                (index)++;
                 
-                if (node->getType().getObjectSize() > 1)
+                if (nodeComps > 1)
                     count++;
             }
-        } else {  // for matrix constructors
-            int count = 0;
-            int index = oit->index;
-            for (int i = index; i < totalSize; i++) {
-                if (i >= instanceSize)
-                    return;
-                if (index - i == 0 || (i - index) % (matrixSize + 1) == 0 )
-                    leftUnionArray[i] = rightUnionArray[count];
-                else 
-                    leftUnionArray[i].setFConst(0.0f);
-
-                (oit->index)++;
-
-                if (node->getType().getObjectSize() > 1)
-                    count++;                
+        } else {
+            // constructing a matrix, but from what?
+            if (node->isMatrix()) {
+                // Matrix from a matrix; this has the outer matrix, node is the argument matrix.
+                // Traverse the outer, potentially bigger matrix, fill in missing pieces with the
+                // identity matrix.
+                for (int c = 0; c < matrixCols; ++c) {
+                    for (int r = 0; r < matrixRows; ++r) {
+                        int targetOffset = index + c * matrixRows + r;
+                        if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) {
+                            int srcOffset = c * node->getType().getMatrixRows() + r;
+                            leftUnionArray[targetOffset] = rightUnionArray[srcOffset];
+                        } else if (r == c)
+                            leftUnionArray[targetOffset].setDConst(1.0);
+                        else
+                            leftUnionArray[targetOffset].setDConst(0.0);
+                    }
+                }
+            } else {
+                // matrix from vector
+                int count = 0;
+                const int startIndex = index;
+                int nodeComps = node->getType().computeNumComponents();
+                for (int i = startIndex; i < endIndex; i++) {
+                    if (i >= instanceSize)
+                        return;
+                    if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
+                        leftUnionArray[i] = rightUnionArray[count];
+                    else 
+                        leftUnionArray[i].setDConst(0.0);
+
+                    index++;
+
+                    if (nodeComps > 1)
+                        count++;                
+                }
             }
         }
     }
 }
 
-bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
-    oit->error = true;
-    return false;
-}
-
-bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
-{
-    TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-    oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
-    oit->error = true;
-    return false;
-}
-
-//
-// This function is the one to call externally to start the traversal.
-// Individual functions can be initialized to 0 to skip processing of that
-// type of node.  It's children will still be processed.
-//
-bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, constUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
+bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
 {
     if (root == 0)
         return false;
 
-    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
+    TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
     
-    it.visitAggregate = ParseAggregate;
-    it.visitBinary = ParseBinary;
-    it.visitConstantUnion = ParseConstantUnion;
-    it.visitSelection = ParseSelection;
-    it.visitSymbol = ParseSymbol;
-    it.visitUnary = ParseUnary;
-    it.visitLoop = ParseLoop;
-    it.visitBranch = ParseBranch;
-
     root->traverse(&it);
     if (it.error)
         return true;
     else
         return false;
 }
+
+} // end namespace glslang