1//
2// Copyright (c) 2016 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/tree_ops/AddAndTrueToLoopCondition.h"
8
9#include "compiler/translator/tree_util/IntermNode_util.h"
10#include "compiler/translator/tree_util/IntermTraverse.h"
11
12namespace sh
13{
14
15namespace
16{
17
18// An AST traverser that rewrites for and while loops by replacing "condition" with
19// "condition && true" to work around condition bug on Intel Mac.
20class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
21{
22 public:
23 AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {}
24
25 bool visitLoop(Visit, TIntermLoop *loop) override
26 {
27 // do-while loop doesn't have this bug.
28 if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile)
29 {
30 return true;
31 }
32
33 // For loop may not have a condition.
34 if (loop->getCondition() == nullptr)
35 {
36 return true;
37 }
38
39 // Constant true.
40 TIntermTyped *trueValue = CreateBoolNode(true);
41
42 // CONDITION && true.
43 TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
44 loop->setCondition(andOp);
45
46 return true;
47 }
48};
49
50} // anonymous namespace
51
52void AddAndTrueToLoopCondition(TIntermNode *root)
53{
54 AddAndTrueToLoopConditionTraverser traverser;
55 root->traverse(&traverser);
56}
57
58} // namespace sh
59