Line data Source code
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 :
9 : #include "angle_gl.h"
10 : #include "common/debug.h"
11 : #include "compiler/translator/IntermNode.h"
12 : #include "compiler/translator/SymbolTable.h"
13 : #include "compiler/translator/util.h"
14 :
15 : namespace sh
16 : {
17 :
18 : namespace
19 : {
20 :
21 0 : class VariableInitializer : public TIntermTraverser
22 : {
23 : public:
24 0 : VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable)
25 0 : : TIntermTraverser(true, false, false),
26 : mVariables(vars),
27 : mSymbolTable(symbolTable),
28 0 : mCodeInserted(false)
29 : {
30 0 : ASSERT(mSymbolTable.atGlobalLevel());
31 0 : }
32 :
33 : protected:
34 0 : bool visitBinary(Visit, TIntermBinary *node) override { return false; }
35 0 : bool visitUnary(Visit, TIntermUnary *node) override { return false; }
36 0 : bool visitIfElse(Visit, TIntermIfElse *node) override { return false; }
37 0 : bool visitLoop(Visit, TIntermLoop *node) override { return false; }
38 0 : bool visitBranch(Visit, TIntermBranch *node) override { return false; }
39 0 : bool visitAggregate(Visit, TIntermAggregate *node) override { return false; }
40 :
41 : bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
42 :
43 : private:
44 : void insertInitCode(TIntermSequence *sequence);
45 :
46 : const InitVariableList &mVariables;
47 : const TSymbolTable &mSymbolTable;
48 : bool mCodeInserted;
49 : };
50 :
51 : // VariableInitializer implementation.
52 :
53 0 : bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
54 : {
55 : // Function definition.
56 0 : ASSERT(visit == PreVisit);
57 0 : if (node->getFunctionSymbolInfo()->isMain())
58 : {
59 0 : TIntermBlock *body = node->getBody();
60 0 : insertInitCode(body->getSequence());
61 0 : mCodeInserted = true;
62 : }
63 0 : return false;
64 : }
65 :
66 0 : void VariableInitializer::insertInitCode(TIntermSequence *sequence)
67 : {
68 0 : for (const auto &var : mVariables)
69 : {
70 0 : TString name = TString(var.name.c_str());
71 :
72 0 : if (var.isArray())
73 : {
74 : // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
75 : // doesn't have array assignment.
76 0 : size_t pos = name.find_last_of('[');
77 0 : if (pos != TString::npos)
78 : {
79 0 : name = name.substr(0, pos);
80 : }
81 0 : TType elementType = sh::GetShaderVariableBasicType(var);
82 0 : TType arrayType = elementType;
83 0 : arrayType.setArraySize(var.elementCount());
84 :
85 0 : for (unsigned int i = 0; i < var.arraySize; ++i)
86 : {
87 0 : TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
88 : TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
89 0 : TIntermTyped::CreateIndexNode(i));
90 :
91 0 : TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
92 0 : TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
93 :
94 0 : sequence->insert(sequence->begin(), assignment);
95 : }
96 : }
97 0 : else if (var.isStruct())
98 : {
99 0 : TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name));
100 0 : ASSERT(structInfo);
101 :
102 0 : TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType());
103 0 : TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
104 :
105 0 : TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
106 0 : sequence->insert(sequence->begin(), assign);
107 : }
108 : else
109 : {
110 0 : TType type = sh::GetShaderVariableBasicType(var);
111 0 : TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
112 0 : TIntermTyped *zero = TIntermTyped::CreateZero(type);
113 :
114 0 : TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
115 0 : sequence->insert(sequence->begin(), assign);
116 : }
117 : }
118 0 : }
119 :
120 : } // namespace anonymous
121 :
122 0 : void InitializeVariables(TIntermNode *root,
123 : const InitVariableList &vars,
124 : const TSymbolTable &symbolTable)
125 : {
126 0 : VariableInitializer initializer(vars, symbolTable);
127 0 : root->traverse(&initializer);
128 0 : }
129 :
130 : } // namespace sh
|