blob: 68e2b53b87103ad2f2ede141b87a6fe36b35d301 [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"
Olli Etuahod57e0db2015-04-24 15:05:08 +03008
9#include "common/debug.h"
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080010
11namespace
12{
13
Zhenyao Moe40d1e92014-07-16 17:40:36 -070014TIntermConstantUnion *constructFloatConstUnionNode(const TType &type)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080015{
16 TType myType = type;
Minmin Gong794e0002015-04-07 18:31:54 -070017 unsigned char size = static_cast<unsigned char>(myType.getNominalSize());
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080018 if (myType.isMatrix())
19 size *= size;
20 ConstantUnion *u = new ConstantUnion[size];
21 for (int ii = 0; ii < size; ++ii)
22 u[ii].setFConst(0.0f);
23
24 myType.clearArrayness();
25 myType.setQualifier(EvqConst);
26 TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
27 return node;
28}
29
Zhenyao Moe40d1e92014-07-16 17:40:36 -070030TIntermConstantUnion *constructIndexNode(int index)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080031{
32 ConstantUnion *u = new ConstantUnion[1];
33 u[0].setIConst(index);
34
35 TType type(EbtInt, EbpUndefined, EvqConst, 1);
36 TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
37 return node;
38}
39
40} // namespace anonymous
41
Zhenyao Moe40d1e92014-07-16 17:40:36 -070042bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080043{
44 bool visitChildren = !mCodeInserted;
45 switch (node->getOp())
46 {
47 case EOpSequence:
48 break;
49 case EOpFunction:
50 {
51 // Function definition.
52 ASSERT(visit == PreVisit);
53 if (node->getName() == "main(")
54 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070055 TIntermSequence *sequence = node->getSequence();
56 ASSERT((sequence->size() == 1) || (sequence->size() == 2));
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080057 TIntermAggregate *body = NULL;
Zhenyao Moe40d1e92014-07-16 17:40:36 -070058 if (sequence->size() == 1)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080059 {
60 body = new TIntermAggregate(EOpSequence);
Zhenyao Moe40d1e92014-07-16 17:40:36 -070061 sequence->push_back(body);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080062 }
63 else
64 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070065 body = (*sequence)[1]->getAsAggregate();
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080066 }
67 ASSERT(body);
68 insertInitCode(body->getSequence());
69 mCodeInserted = true;
70 }
71 break;
72 }
73 default:
74 visitChildren = false;
75 break;
76 }
77 return visitChildren;
78}
79
Zhenyao Moe40d1e92014-07-16 17:40:36 -070080void InitializeVariables::insertInitCode(TIntermSequence *sequence)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080081{
82 for (size_t ii = 0; ii < mVariables.size(); ++ii)
83 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070084 const InitVariableInfo &varInfo = mVariables[ii];
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080085
86 if (varInfo.type.isArray())
87 {
88 for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index)
89 {
90 TIntermBinary *assign = new TIntermBinary(EOpAssign);
Zhenyao Moe40d1e92014-07-16 17:40:36 -070091 sequence->insert(sequence->begin(), assign);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080092
93 TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
94 TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
95 indexDirect->setLeft(symbol);
96 TIntermConstantUnion *indexNode = constructIndexNode(index);
97 indexDirect->setRight(indexNode);
98
99 assign->setLeft(indexDirect);
100
101 TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
102 assign->setRight(zeroConst);
103 }
104 }
105 else
106 {
107 TIntermBinary *assign = new TIntermBinary(EOpAssign);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700108 sequence->insert(sequence->begin(), assign);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -0800109 TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
110 assign->setLeft(symbol);
111 TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
112 assign->setRight(zeroConst);
113 }
114
115 }
116}
117