blob: 115c561c775f1561677f199c6ec19c38aa7d87e4 [file] [log] [blame]
Zhenyao Mo4a667fe2014-02-11 12:35:01 -08001//
2// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "compiler/translator/InitializeVariables.h"
8#include "compiler/translator/compilerdebug.h"
9
10namespace
11{
12
13TIntermConstantUnion* constructFloatConstUnionNode(const TType& type)
14{
15 TType myType = type;
16 unsigned char size = myType.getNominalSize();
17 if (myType.isMatrix())
18 size *= size;
19 ConstantUnion *u = new ConstantUnion[size];
20 for (int ii = 0; ii < size; ++ii)
21 u[ii].setFConst(0.0f);
22
23 myType.clearArrayness();
24 myType.setQualifier(EvqConst);
25 TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
26 return node;
27}
28
29TIntermConstantUnion* constructIndexNode(int index)
30{
31 ConstantUnion *u = new ConstantUnion[1];
32 u[0].setIConst(index);
33
34 TType type(EbtInt, EbpUndefined, EvqConst, 1);
35 TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
36 return node;
37}
38
39} // namespace anonymous
40
41bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate* node)
42{
43 bool visitChildren = !mCodeInserted;
44 switch (node->getOp())
45 {
46 case EOpSequence:
47 break;
48 case EOpFunction:
49 {
50 // Function definition.
51 ASSERT(visit == PreVisit);
52 if (node->getName() == "main(")
53 {
54 TIntermSequence &sequence = node->getSequence();
55 ASSERT((sequence.size() == 1) || (sequence.size() == 2));
56 TIntermAggregate *body = NULL;
57 if (sequence.size() == 1)
58 {
59 body = new TIntermAggregate(EOpSequence);
60 sequence.push_back(body);
61 }
62 else
63 {
64 body = sequence[1]->getAsAggregate();
65 }
66 ASSERT(body);
67 insertInitCode(body->getSequence());
68 mCodeInserted = true;
69 }
70 break;
71 }
72 default:
73 visitChildren = false;
74 break;
75 }
76 return visitChildren;
77}
78
79void InitializeVariables::insertInitCode(TIntermSequence& sequence)
80{
81 for (size_t ii = 0; ii < mVariables.size(); ++ii)
82 {
83 const InitVariableInfo& varInfo = mVariables[ii];
84
85 if (varInfo.type.isArray())
86 {
87 for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index)
88 {
89 TIntermBinary *assign = new TIntermBinary(EOpAssign);
90 sequence.insert(sequence.begin(), assign);
91
92 TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
93 TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
94 indexDirect->setLeft(symbol);
95 TIntermConstantUnion *indexNode = constructIndexNode(index);
96 indexDirect->setRight(indexNode);
97
98 assign->setLeft(indexDirect);
99
100 TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
101 assign->setRight(zeroConst);
102 }
103 }
104 else
105 {
106 TIntermBinary *assign = new TIntermBinary(EOpAssign);
107 sequence.insert(sequence.begin(), assign);
108 TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
109 assign->setLeft(symbol);
110 TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
111 assign->setRight(zeroConst);
112 }
113
114 }
115}
116