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