Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / compiler / translator / InitializeVariables.cpp
1 //
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
10 namespace
11 {
12
13 TIntermConstantUnion* 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
29 TIntermConstantUnion* 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
41 bool 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
79 void 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