~gabriel1984sibiu/minitube/qt5.6

« back to all changes in this revision

Viewing changes to src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.cpp

  • Committer: Grevutiu Gabriel
  • Date: 2017-06-13 08:43:17 UTC
  • Revision ID: gabriel1984sibiu@gmail.com-20170613084317-ek0zqe0u9g3ocvi8
OriginalĀ upstreamĀ code

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright (c) 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
// RewriteElseBlocks.cpp: Implementation for tree transform to change
 
7
//   all if-else blocks to if-if blocks.
 
8
//
 
9
 
 
10
#include "compiler/translator/RewriteElseBlocks.h"
 
11
#include "compiler/translator/NodeSearch.h"
 
12
#include "compiler/translator/SymbolTable.h"
 
13
 
 
14
namespace sh
 
15
{
 
16
 
 
17
namespace
 
18
{
 
19
 
 
20
class ElseBlockRewriter : public TIntermTraverser
 
21
{
 
22
  public:
 
23
    ElseBlockRewriter();
 
24
 
 
25
  protected:
 
26
    bool visitAggregate(Visit visit, TIntermAggregate *aggregate) override;
 
27
 
 
28
  private:
 
29
    const TType *mFunctionType;
 
30
 
 
31
    TIntermNode *rewriteSelection(TIntermSelection *selection);
 
32
};
 
33
 
 
34
TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
 
35
{
 
36
    TIntermUnary *unary = new TIntermUnary(op, operand->getType());
 
37
    unary->setOperand(operand);
 
38
    return unary;
 
39
}
 
40
 
 
41
ElseBlockRewriter::ElseBlockRewriter()
 
42
    : TIntermTraverser(true, false, true),
 
43
      mFunctionType(NULL)
 
44
{}
 
45
 
 
46
bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
 
47
{
 
48
    switch (node->getOp())
 
49
    {
 
50
      case EOpSequence:
 
51
        if (visit == PostVisit)
 
52
        {
 
53
            for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++)
 
54
            {
 
55
                TIntermNode *statement = (*node->getSequence())[statementIndex];
 
56
                TIntermSelection *selection = statement->getAsSelectionNode();
 
57
                if (selection && selection->getFalseBlock() != nullptr)
 
58
                {
 
59
                    // Check for if / else if
 
60
                    TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode();
 
61
                    if (elseIfBranch)
 
62
                    {
 
63
                        selection->replaceChildNode(elseIfBranch, rewriteSelection(elseIfBranch));
 
64
                        delete elseIfBranch;
 
65
                    }
 
66
 
 
67
                    (*node->getSequence())[statementIndex] = rewriteSelection(selection);
 
68
                    delete selection;
 
69
                }
 
70
            }
 
71
        }
 
72
        break;
 
73
 
 
74
      case EOpFunction:
 
75
        // Store the current function context (see comment below)
 
76
        mFunctionType = ((visit == PreVisit) ? &node->getType() : NULL);
 
77
        break;
 
78
 
 
79
      default: break;
 
80
    }
 
81
 
 
82
    return true;
 
83
}
 
84
 
 
85
TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
 
86
{
 
87
    ASSERT(selection != nullptr);
 
88
 
 
89
    nextTemporaryIndex();
 
90
 
 
91
    TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
 
92
    TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition);
 
93
 
 
94
    TIntermSelection *falseBlock = nullptr;
 
95
 
 
96
    TType boolType(EbtBool, EbpUndefined, EvqTemporary);
 
97
 
 
98
    if (selection->getFalseBlock())
 
99
    {
 
100
        TIntermAggregate *negatedElse = nullptr;
 
101
        // crbug.com/346463
 
102
        // D3D generates error messages claiming a function has no return value, when rewriting
 
103
        // an if-else clause that returns something non-void in a function. By appending dummy
 
104
        // returns (that are unreachable) we can silence this compile error.
 
105
        if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
 
106
        {
 
107
            TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() :
 
108
                mFunctionType->getBasicString();
 
109
            TString rawText = "return (" + typeString + ")0";
 
110
            TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText);
 
111
            negatedElse = new TIntermAggregate(EOpSequence);
 
112
            negatedElse->getSequence()->push_back(returnNode);
 
113
        }
 
114
 
 
115
        TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
 
116
        TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse);
 
117
        falseBlock = new TIntermSelection(negatedCondition,
 
118
                                          selection->getFalseBlock(), negatedElse);
 
119
    }
 
120
 
 
121
    TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
 
122
    TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock);
 
123
 
 
124
    TIntermAggregate *block = new TIntermAggregate(EOpSequence);
 
125
    block->getSequence()->push_back(storeCondition);
 
126
    block->getSequence()->push_back(newSelection);
 
127
 
 
128
    return block;
 
129
}
 
130
 
 
131
}
 
132
 
 
133
void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex)
 
134
{
 
135
    ElseBlockRewriter rewriter;
 
136
    rewriter.useTemporaryIndex(temporaryIndex);
 
137
    node->traverse(&rewriter);
 
138
}
 
139
 
 
140
}