summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp')
-rw-r--r--chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp
new file mode 100644
index 00000000000..115c561c775
--- /dev/null
+++ b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp
@@ -0,0 +1,116 @@
+//
+// 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);
+ }
+
+ }
+}
+