Home | History | Annotate | Download | only in translator
      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