| // |
| // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| #include "compiler/translator/InitializeVariables.h" |
| #include "compiler/translator/compilerdebug.h" |
| |
| namespace |
| { |
| |
| TIntermConstantUnion* constructFloatConstUnionNode(const TType& type) |
| { |
| TType myType = type; |
| unsigned char size = myType.getNominalSize(); |
| if (myType.isMatrix()) |
| size *= size; |
| ConstantUnion *u = new ConstantUnion[size]; |
| for (int ii = 0; ii < size; ++ii) |
| u[ii].setFConst(0.0f); |
| |
| myType.clearArrayness(); |
| myType.setQualifier(EvqConst); |
| TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); |
| return node; |
| } |
| |
| TIntermConstantUnion* constructIndexNode(int index) |
| { |
| ConstantUnion *u = new ConstantUnion[1]; |
| u[0].setIConst(index); |
| |
| TType type(EbtInt, EbpUndefined, EvqConst, 1); |
| TIntermConstantUnion *node = new TIntermConstantUnion(u, type); |
| return node; |
| } |
| |
| } // namespace anonymous |
| |
| bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate* node) |
| { |
| bool visitChildren = !mCodeInserted; |
| switch (node->getOp()) |
| { |
| case EOpSequence: |
| break; |
| case EOpFunction: |
| { |
| // Function definition. |
| ASSERT(visit == PreVisit); |
| if (node->getName() == "main(") |
| { |
| TIntermSequence &sequence = node->getSequence(); |
| ASSERT((sequence.size() == 1) || (sequence.size() == 2)); |
| TIntermAggregate *body = NULL; |
| if (sequence.size() == 1) |
| { |
| body = new TIntermAggregate(EOpSequence); |
| sequence.push_back(body); |
| } |
| else |
| { |
| body = sequence[1]->getAsAggregate(); |
| } |
| ASSERT(body); |
| insertInitCode(body->getSequence()); |
| mCodeInserted = true; |
| } |
| break; |
| } |
| default: |
| visitChildren = false; |
| break; |
| } |
| return visitChildren; |
| } |
| |
| void InitializeVariables::insertInitCode(TIntermSequence& sequence) |
| { |
| for (size_t ii = 0; ii < mVariables.size(); ++ii) |
| { |
| const InitVariableInfo& varInfo = mVariables[ii]; |
| |
| if (varInfo.type.isArray()) |
| { |
| for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index) |
| { |
| TIntermBinary *assign = new TIntermBinary(EOpAssign); |
| sequence.insert(sequence.begin(), assign); |
| |
| TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); |
| TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); |
| indexDirect->setLeft(symbol); |
| TIntermConstantUnion *indexNode = constructIndexNode(index); |
| indexDirect->setRight(indexNode); |
| |
| assign->setLeft(indexDirect); |
| |
| TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); |
| assign->setRight(zeroConst); |
| } |
| } |
| else |
| { |
| TIntermBinary *assign = new TIntermBinary(EOpAssign); |
| sequence.insert(sequence.begin(), assign); |
| TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); |
| assign->setLeft(symbol); |
| TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); |
| assign->setRight(zeroConst); |
| } |
| |
| } |
| } |
| |