LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - Intermediate.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 118 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2002-2014 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             : //
       8             : // Build the intermediate representation.
       9             : //
      10             : 
      11             : #include <float.h>
      12             : #include <limits.h>
      13             : #include <algorithm>
      14             : 
      15             : #include "compiler/translator/Intermediate.h"
      16             : #include "compiler/translator/SymbolTable.h"
      17             : 
      18             : namespace sh
      19             : {
      20             : 
      21             : ////////////////////////////////////////////////////////////////////////////
      22             : //
      23             : // First set of functions are to help build the intermediate representation.
      24             : // These functions are not member functions of the nodes.
      25             : // They are called from parser productions.
      26             : //
      27             : /////////////////////////////////////////////////////////////////////////////
      28             : 
      29             : //
      30             : // Add a terminal node for an identifier in an expression.
      31             : //
      32             : // Returns the added node.
      33             : //
      34           0 : TIntermSymbol *TIntermediate::addSymbol(
      35             :     int id, const TString &name, const TType &type, const TSourceLoc &line)
      36             : {
      37           0 :     TIntermSymbol *node = new TIntermSymbol(id, name, type);
      38           0 :     node->setLine(line);
      39             : 
      40           0 :     return node;
      41             : }
      42             : 
      43             : //
      44             : // Connect two nodes through an index operator, where the left node is the base
      45             : // of an array or struct, and the right node is a direct or indirect offset.
      46             : //
      47             : // Returns the added node.
      48             : // The caller should set the type of the returned node.
      49             : //
      50           0 : TIntermTyped *TIntermediate::addIndex(TOperator op,
      51             :                                       TIntermTyped *base,
      52             :                                       TIntermTyped *index,
      53             :                                       const TSourceLoc &line,
      54             :                                       TDiagnostics *diagnostics)
      55             : {
      56           0 :     TIntermBinary *node = new TIntermBinary(op, base, index);
      57           0 :     node->setLine(line);
      58             : 
      59           0 :     TIntermTyped *folded = node->fold(diagnostics);
      60           0 :     if (folded)
      61             :     {
      62           0 :         return folded;
      63             :     }
      64             : 
      65           0 :     return node;
      66             : }
      67             : 
      68             : // This is the safe way to change the operator on an aggregate, as it
      69             : // does lots of error checking and fixing.  Especially for establishing
      70             : // a function call's operation on it's set of parameters.
      71             : //
      72             : // Returns an aggregate node, which could be the one passed in if
      73             : // it was already an aggregate but no operator was set.
      74           0 : TIntermAggregate *TIntermediate::setAggregateOperator(
      75             :     TIntermNode *node, TOperator op, const TSourceLoc &line)
      76             : {
      77             :     TIntermAggregate *aggNode;
      78             : 
      79             :     //
      80             :     // Make sure we have an aggregate.  If not turn it into one.
      81             :     //
      82           0 :     if (node)
      83             :     {
      84           0 :         aggNode = node->getAsAggregate();
      85           0 :         if (aggNode == NULL || aggNode->getOp() != EOpNull)
      86             :         {
      87             :             //
      88             :             // Make an aggregate containing this node.
      89             :             //
      90           0 :             aggNode = new TIntermAggregate();
      91           0 :             aggNode->getSequence()->push_back(node);
      92             :         }
      93             :     }
      94             :     else
      95             :     {
      96           0 :         aggNode = new TIntermAggregate();
      97             :     }
      98             : 
      99             :     //
     100             :     // Set the operator.
     101             :     //
     102           0 :     aggNode->setOp(op);
     103           0 :     aggNode->setLine(line);
     104             : 
     105           0 :     return aggNode;
     106             : }
     107             : 
     108             : //
     109             : // Safe way to combine two nodes into an aggregate.  Works with null pointers,
     110             : // a node that's not a aggregate yet, etc.
     111             : //
     112             : // Returns the resulting aggregate, unless 0 was passed in for
     113             : // both existing nodes.
     114             : //
     115           0 : TIntermAggregate *TIntermediate::growAggregate(
     116             :     TIntermNode *left, TIntermNode *right, const TSourceLoc &line)
     117             : {
     118           0 :     if (left == NULL && right == NULL)
     119           0 :         return NULL;
     120             : 
     121           0 :     TIntermAggregate *aggNode = NULL;
     122           0 :     if (left)
     123           0 :         aggNode = left->getAsAggregate();
     124           0 :     if (!aggNode || aggNode->getOp() != EOpNull)
     125             :     {
     126           0 :         aggNode = new TIntermAggregate;
     127           0 :         if (left)
     128           0 :             aggNode->getSequence()->push_back(left);
     129             :     }
     130             : 
     131           0 :     if (right)
     132           0 :         aggNode->getSequence()->push_back(right);
     133             : 
     134           0 :     aggNode->setLine(line);
     135             : 
     136           0 :     return aggNode;
     137             : }
     138             : 
     139             : //
     140             : // Turn an existing node into an aggregate.
     141             : //
     142             : // Returns an aggregate, unless NULL was passed in for the existing node.
     143             : //
     144           0 : TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceLoc &line)
     145             : {
     146           0 :     if (node == nullptr)
     147           0 :         return nullptr;
     148             : 
     149           0 :     TIntermAggregate *aggNode = new TIntermAggregate;
     150           0 :     aggNode->getSequence()->push_back(node);
     151             : 
     152           0 :     aggNode->setLine(line);
     153             : 
     154           0 :     return aggNode;
     155             : }
     156             : 
     157             : // If the input node is nullptr, return nullptr.
     158             : // If the input node is a block node, return it.
     159             : // If the input node is not a block node, put it inside a block node and return that.
     160           0 : TIntermBlock *TIntermediate::EnsureBlock(TIntermNode *node)
     161             : {
     162           0 :     if (node == nullptr)
     163           0 :         return nullptr;
     164           0 :     TIntermBlock *blockNode = node->getAsBlock();
     165           0 :     if (blockNode != nullptr)
     166           0 :         return blockNode;
     167             : 
     168           0 :     blockNode = new TIntermBlock();
     169           0 :     blockNode->setLine(node->getLine());
     170           0 :     blockNode->getSequence()->push_back(node);
     171           0 :     return blockNode;
     172             : }
     173             : 
     174             : // For "if" test nodes.  There are three children; a condition,
     175             : // a true path, and a false path.  The two paths are in the
     176             : // nodePair.
     177             : //
     178             : // Returns the node created.
     179           0 : TIntermNode *TIntermediate::addIfElse(TIntermTyped *cond,
     180             :                                       TIntermNodePair nodePair,
     181             :                                       const TSourceLoc &line)
     182             : {
     183             :     // For compile time constant conditions, prune the code now.
     184             : 
     185           0 :     if (cond->getAsConstantUnion())
     186             :     {
     187           0 :         if (cond->getAsConstantUnion()->getBConst(0) == true)
     188             :         {
     189           0 :             return EnsureBlock(nodePair.node1);
     190             :         }
     191             :         else
     192             :         {
     193           0 :             return EnsureBlock(nodePair.node2);
     194             :         }
     195             :     }
     196             : 
     197             :     TIntermIfElse *node =
     198           0 :         new TIntermIfElse(cond, EnsureBlock(nodePair.node1), EnsureBlock(nodePair.node2));
     199           0 :     node->setLine(line);
     200             : 
     201           0 :     return node;
     202             : }
     203             : 
     204           0 : TIntermTyped *TIntermediate::AddComma(TIntermTyped *left,
     205             :                                       TIntermTyped *right,
     206             :                                       const TSourceLoc &line,
     207             :                                       int shaderVersion)
     208             : {
     209           0 :     TIntermTyped *commaNode = nullptr;
     210           0 :     if (!left->hasSideEffects())
     211             :     {
     212           0 :         commaNode = right;
     213             :     }
     214             :     else
     215             :     {
     216           0 :         commaNode = new TIntermBinary(EOpComma, left, right);
     217           0 :         commaNode->setLine(line);
     218             :     }
     219           0 :     TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(shaderVersion, left, right);
     220           0 :     commaNode->getTypePointer()->setQualifier(resultQualifier);
     221           0 :     return commaNode;
     222             : }
     223             : 
     224             : // For "?:" test nodes.  There are three children; a condition,
     225             : // a true path, and a false path.  The two paths are specified
     226             : // as separate parameters.
     227             : //
     228             : // Returns the ternary node created, or one of trueExpression and falseExpression if the expression
     229             : // could be folded.
     230           0 : TIntermTyped *TIntermediate::AddTernarySelection(TIntermTyped *cond,
     231             :                                                  TIntermTyped *trueExpression,
     232             :                                                  TIntermTyped *falseExpression,
     233             :                                                  const TSourceLoc &line)
     234             : {
     235             :     // Note that the node resulting from here can be a constant union without being qualified as
     236             :     // constant.
     237           0 :     if (cond->getAsConstantUnion())
     238             :     {
     239             :         TQualifier resultQualifier =
     240           0 :             TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression);
     241           0 :         if (cond->getAsConstantUnion()->getBConst(0))
     242             :         {
     243           0 :             trueExpression->getTypePointer()->setQualifier(resultQualifier);
     244           0 :             return trueExpression;
     245             :         }
     246             :         else
     247             :         {
     248           0 :             falseExpression->getTypePointer()->setQualifier(resultQualifier);
     249           0 :             return falseExpression;
     250             :         }
     251             :     }
     252             : 
     253             :     // Make a ternary node.
     254           0 :     TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
     255           0 :     node->setLine(line);
     256             : 
     257           0 :     return node;
     258             : }
     259             : 
     260           0 : TIntermSwitch *TIntermediate::addSwitch(TIntermTyped *init,
     261             :                                         TIntermBlock *statementList,
     262             :                                         const TSourceLoc &line)
     263             : {
     264           0 :     TIntermSwitch *node = new TIntermSwitch(init, statementList);
     265           0 :     node->setLine(line);
     266             : 
     267           0 :     return node;
     268             : }
     269             : 
     270           0 : TIntermCase *TIntermediate::addCase(
     271             :     TIntermTyped *condition, const TSourceLoc &line)
     272             : {
     273           0 :     TIntermCase *node = new TIntermCase(condition);
     274           0 :     node->setLine(line);
     275             : 
     276           0 :     return node;
     277             : }
     278             : 
     279             : //
     280             : // Constant terminal nodes.  Has a union that contains bool, float or int constants
     281             : //
     282             : // Returns the constant union node created.
     283             : //
     284             : 
     285           0 : TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *constantUnion,
     286             :                                                       const TType &type,
     287             :                                                       const TSourceLoc &line)
     288             : {
     289           0 :     TIntermConstantUnion *node = new TIntermConstantUnion(constantUnion, type);
     290           0 :     node->setLine(line);
     291             : 
     292           0 :     return node;
     293             : }
     294             : 
     295           0 : TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression,
     296             :                                         const TVectorFields &fields,
     297             :                                         const TSourceLoc &dotLocation)
     298             : {
     299           0 :     TVector<int> fieldsVector;
     300           0 :     for (int i = 0; i < fields.num; ++i)
     301             :     {
     302           0 :         fieldsVector.push_back(fields.offsets[i]);
     303             :     }
     304           0 :     TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldsVector);
     305           0 :     node->setLine(dotLocation);
     306             : 
     307           0 :     TIntermTyped *folded = node->fold();
     308           0 :     if (folded)
     309             :     {
     310           0 :         return folded;
     311             :     }
     312             : 
     313           0 :     return node;
     314             : }
     315             : 
     316             : //
     317             : // Create loop nodes.
     318             : //
     319           0 : TIntermNode *TIntermediate::addLoop(
     320             :     TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr,
     321             :     TIntermNode *body, const TSourceLoc &line)
     322             : {
     323           0 :     TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureBlock(body));
     324           0 :     node->setLine(line);
     325             : 
     326           0 :     return node;
     327             : }
     328             : 
     329             : //
     330             : // Add branches.
     331             : //
     332           0 : TIntermBranch* TIntermediate::addBranch(
     333             :     TOperator branchOp, const TSourceLoc &line)
     334             : {
     335           0 :     return addBranch(branchOp, 0, line);
     336             : }
     337             : 
     338           0 : TIntermBranch* TIntermediate::addBranch(
     339             :     TOperator branchOp, TIntermTyped *expression, const TSourceLoc &line)
     340             : {
     341           0 :     TIntermBranch *node = new TIntermBranch(branchOp, expression);
     342           0 :     node->setLine(line);
     343             : 
     344           0 :     return node;
     345             : }
     346             : 
     347           0 : TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate,
     348             :                                                   TDiagnostics *diagnostics)
     349             : {
     350           0 :     switch (aggregate->getOp())
     351             :     {
     352             :         case EOpAtan:
     353             :         case EOpPow:
     354             :         case EOpMod:
     355             :         case EOpMin:
     356             :         case EOpMax:
     357             :         case EOpClamp:
     358             :         case EOpMix:
     359             :         case EOpStep:
     360             :         case EOpSmoothStep:
     361             :         case EOpMul:
     362             :         case EOpOuterProduct:
     363             :         case EOpLessThan:
     364             :         case EOpLessThanEqual:
     365             :         case EOpGreaterThan:
     366             :         case EOpGreaterThanEqual:
     367             :         case EOpVectorEqual:
     368             :         case EOpVectorNotEqual:
     369             :         case EOpDistance:
     370             :         case EOpDot:
     371             :         case EOpCross:
     372             :         case EOpFaceForward:
     373             :         case EOpReflect:
     374             :         case EOpRefract:
     375           0 :             return aggregate->fold(diagnostics);
     376             :         default:
     377             :             // TODO: Add support for folding array constructors
     378           0 :             if (aggregate->isConstructor() && !aggregate->isArray())
     379             :             {
     380           0 :                 return aggregate->fold(diagnostics);
     381             :             }
     382             :             // Constant folding not supported for the built-in.
     383           0 :             return nullptr;
     384             :     }
     385             : }
     386             : 
     387             : }  // namespace sh

Generated by: LCOV version 1.13