gfx/angle/src/compiler/parseConst.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/angle/src/compiler/parseConst.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,245 @@
     1.4 +//
     1.5 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
     1.6 +// Use of this source code is governed by a BSD-style license that can be
     1.7 +// found in the LICENSE file.
     1.8 +//
     1.9 +
    1.10 +#include "compiler/ParseHelper.h"
    1.11 +
    1.12 +//
    1.13 +// Use this class to carry along data from node to node in 
    1.14 +// the traversal
    1.15 +//
    1.16 +class TConstTraverser : public TIntermTraverser {
    1.17 +public:
    1.18 +    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t)
    1.19 +        : error(false),
    1.20 +          index(0),
    1.21 +          unionArray(cUnion),
    1.22 +          type(t),
    1.23 +          constructorType(constructType),
    1.24 +          singleConstantParam(singleConstParam),
    1.25 +          infoSink(sink),
    1.26 +          symbolTable(symTable),
    1.27 +          size(0),
    1.28 +          isMatrix(false),
    1.29 +          matrixSize(0) {
    1.30 +    }
    1.31 +
    1.32 +    bool error;
    1.33 +
    1.34 +protected:
    1.35 +    void visitSymbol(TIntermSymbol*);
    1.36 +    void visitConstantUnion(TIntermConstantUnion*);
    1.37 +    bool visitBinary(Visit visit, TIntermBinary*);
    1.38 +    bool visitUnary(Visit visit, TIntermUnary*);
    1.39 +    bool visitSelection(Visit visit, TIntermSelection*);
    1.40 +    bool visitAggregate(Visit visit, TIntermAggregate*);
    1.41 +    bool visitLoop(Visit visit, TIntermLoop*);
    1.42 +    bool visitBranch(Visit visit, TIntermBranch*);
    1.43 +
    1.44 +    size_t index;
    1.45 +    ConstantUnion *unionArray;
    1.46 +    TType type;
    1.47 +    TOperator constructorType;
    1.48 +    bool singleConstantParam;
    1.49 +    TInfoSink& infoSink;
    1.50 +    TSymbolTable& symbolTable;
    1.51 +    size_t size; // size of the constructor ( 4 for vec4)
    1.52 +    bool isMatrix;
    1.53 +    size_t matrixSize; // dimension of the matrix (nominal size and not the instance size)
    1.54 +};
    1.55 +
    1.56 +//
    1.57 +// The rest of the file are the traversal functions.  The last one
    1.58 +// is the one that starts the traversal.
    1.59 +//
    1.60 +// Return true from interior nodes to have the external traversal
    1.61 +// continue on to children.  If you process children yourself,
    1.62 +// return false.
    1.63 +//
    1.64 +
    1.65 +void TConstTraverser::visitSymbol(TIntermSymbol* node)
    1.66 +{
    1.67 +    infoSink.info.message(EPrefixInternalError, node->getLine(), "Symbol Node found in constant constructor");
    1.68 +    return;
    1.69 +
    1.70 +}
    1.71 +
    1.72 +bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
    1.73 +{
    1.74 +    TQualifier qualifier = node->getType().getQualifier();
    1.75 +    
    1.76 +    if (qualifier != EvqConst) {
    1.77 +        TString buf;
    1.78 +        buf.append("'constructor' : assigning non-constant to ");
    1.79 +        buf.append(type.getCompleteString());
    1.80 +        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
    1.81 +        error = true;
    1.82 +        return false;  
    1.83 +    }
    1.84 +
    1.85 +   infoSink.info.message(EPrefixInternalError, node->getLine(), "Binary Node found in constant constructor");
    1.86 +    
    1.87 +    return false;
    1.88 +}
    1.89 +
    1.90 +bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
    1.91 +{
    1.92 +    TString buf;
    1.93 +    buf.append("'constructor' : assigning non-constant to ");
    1.94 +    buf.append(type.getCompleteString());
    1.95 +    infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
    1.96 +    error = true;
    1.97 +    return false;  
    1.98 +}
    1.99 +
   1.100 +bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
   1.101 +{
   1.102 +    if (!node->isConstructor() && node->getOp() != EOpComma) {
   1.103 +        TString buf;
   1.104 +        buf.append("'constructor' : assigning non-constant to ");
   1.105 +        buf.append(type.getCompleteString());
   1.106 +        infoSink.info.message(EPrefixError, node->getLine(), buf.c_str());
   1.107 +        error = true;
   1.108 +        return false;  
   1.109 +    }
   1.110 +
   1.111 +    if (node->getSequence().size() == 0) {
   1.112 +        error = true;
   1.113 +        return false;
   1.114 +    }
   1.115 +
   1.116 +    bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
   1.117 +    if (flag) 
   1.118 +    {
   1.119 +        singleConstantParam = true; 
   1.120 +        constructorType = node->getOp();
   1.121 +        size = node->getType().getObjectSize();
   1.122 +
   1.123 +        if (node->getType().isMatrix()) {
   1.124 +            isMatrix = true;
   1.125 +            matrixSize = node->getType().getNominalSize();
   1.126 +        }
   1.127 +    }       
   1.128 +
   1.129 +    for (TIntermSequence::iterator p = node->getSequence().begin(); 
   1.130 +                                   p != node->getSequence().end(); p++) {
   1.131 +
   1.132 +        if (node->getOp() == EOpComma)
   1.133 +            index = 0;           
   1.134 +
   1.135 +        (*p)->traverse(this);
   1.136 +    }   
   1.137 +    if (flag) 
   1.138 +    {
   1.139 +        singleConstantParam = false;   
   1.140 +        constructorType = EOpNull;
   1.141 +        size = 0;
   1.142 +        isMatrix = false;
   1.143 +        matrixSize = 0;
   1.144 +    }
   1.145 +    return false;
   1.146 +}
   1.147 +
   1.148 +bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
   1.149 +{
   1.150 +    infoSink.info.message(EPrefixInternalError, node->getLine(), "Selection Node found in constant constructor");
   1.151 +    error = true;
   1.152 +    return false;
   1.153 +}
   1.154 +
   1.155 +void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
   1.156 +{
   1.157 +    if (!node->getUnionArrayPointer())
   1.158 +    {
   1.159 +        // The constant was not initialized, this should already have been logged
   1.160 +        assert(infoSink.info.size() != 0);
   1.161 +        return;
   1.162 +    }
   1.163 +
   1.164 +    ConstantUnion* leftUnionArray = unionArray;
   1.165 +    size_t instanceSize = type.getObjectSize();
   1.166 +
   1.167 +    if (index >= instanceSize)
   1.168 +        return;
   1.169 +
   1.170 +    if (!singleConstantParam) {
   1.171 +        size_t size = node->getType().getObjectSize();
   1.172 +    
   1.173 +        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
   1.174 +        for (size_t i = 0; i < size; i++) {
   1.175 +            if (index >= instanceSize)
   1.176 +                return;
   1.177 +            leftUnionArray[index] = rightUnionArray[i];
   1.178 +
   1.179 +            (index)++;
   1.180 +        }
   1.181 +    } else {
   1.182 +        size_t totalSize = index + size;
   1.183 +        ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
   1.184 +        if (!isMatrix) {
   1.185 +            size_t count = 0;
   1.186 +            for (size_t i = index; i < totalSize; i++) {
   1.187 +                if (i >= instanceSize)
   1.188 +                    return;
   1.189 +
   1.190 +                leftUnionArray[i] = rightUnionArray[count];
   1.191 +
   1.192 +                (index)++;
   1.193 +                
   1.194 +                if (node->getType().getObjectSize() > 1)
   1.195 +                    count++;
   1.196 +            }
   1.197 +        } else {  // for matrix constructors
   1.198 +            size_t count = 0;
   1.199 +            size_t element = index;
   1.200 +            for (size_t i = index; i < totalSize; i++) {
   1.201 +                if (i >= instanceSize)
   1.202 +                    return;
   1.203 +                if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 )
   1.204 +                    leftUnionArray[i] = rightUnionArray[count];
   1.205 +                else 
   1.206 +                    leftUnionArray[i].setFConst(0.0f);
   1.207 +
   1.208 +                (index)++;
   1.209 +
   1.210 +                if (node->getType().getObjectSize() > 1)
   1.211 +                    count++;                
   1.212 +            }
   1.213 +        }
   1.214 +    }
   1.215 +}
   1.216 +
   1.217 +bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
   1.218 +{
   1.219 +    infoSink.info.message(EPrefixInternalError, node->getLine(), "Loop Node found in constant constructor");
   1.220 +    error = true;
   1.221 +    return false;
   1.222 +}
   1.223 +
   1.224 +bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
   1.225 +{
   1.226 +    infoSink.info.message(EPrefixInternalError, node->getLine(), "Branch Node found in constant constructor");
   1.227 +    error = true;
   1.228 +    return false;
   1.229 +}
   1.230 +
   1.231 +//
   1.232 +// This function is the one to call externally to start the traversal.
   1.233 +// Individual functions can be initialized to 0 to skip processing of that
   1.234 +// type of node.  It's children will still be processed.
   1.235 +//
   1.236 +bool TIntermediate::parseConstTree(const TSourceLoc& line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
   1.237 +{
   1.238 +    if (root == 0)
   1.239 +        return false;
   1.240 +
   1.241 +    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
   1.242 +
   1.243 +    root->traverse(&it);
   1.244 +    if (it.error)
   1.245 +        return true;
   1.246 +    else
   1.247 +        return false;
   1.248 +}

mercurial