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 117