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)53bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root) 54 { 55 AddAndTrueToLoopConditionTraverser traverser; 56 root->traverse(&traverser); 57 return compiler->validateAST(root); 58 } 59 60 } // namespace sh 61