blob: a0cddaca0832acd178f3490f973218fd97235245 [file] [log] [blame]
Olli Etuaho00f6fbb2016-07-20 16:32:29 +03001//
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// IntermNodePatternMatcher is a helper class for matching node trees to given patterns.
7// It can be used whenever the same checks for certain node structures are common to multiple AST
8// traversers.
9//
10
11#include "compiler/translator/IntermNodePatternMatcher.h"
12
13#include "compiler/translator/IntermNode.h"
14
15namespace
16{
17
18bool IsNodeBlock(TIntermNode *node)
19{
20 ASSERT(node != nullptr);
21 return (node->getAsAggregate() && node->getAsAggregate()->getOp() == EOpSequence);
22}
23
24} // anonymous namespace
25
26IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask)
27{
28}
29
30bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode)
31{
32 if ((mMask & kExpressionReturningArray) != 0)
33 {
34 if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr &&
35 !IsNodeBlock(parentNode))
36 {
37 return true;
38 }
39 }
40
41 if ((mMask & kUnfoldedShortCircuitExpression) != 0)
42 {
43 if (node->getRight()->hasSideEffects() &&
44 (node->getOp() == EOpLogicalOr || node->getOp() == EOpLogicalAnd))
45 {
46 return true;
47 }
48 }
49 return false;
50}
51
52bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parentNode)
53{
54 if ((mMask & kExpressionReturningArray) != 0)
55 {
56 if (parentNode != nullptr)
57 {
58 TIntermBinary *parentBinary = parentNode->getAsBinaryNode();
59 bool parentIsAssignment =
60 (parentBinary != nullptr &&
61 (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize));
62
63 if (node->getType().isArray() && !parentIsAssignment &&
64 (node->isConstructor() || node->getOp() == EOpFunctionCall) &&
65 !IsNodeBlock(parentNode))
66 {
67 return true;
68 }
69 }
70 }
71 return false;
72}
73
74bool IntermNodePatternMatcher::match(TIntermSelection *node)
75{
76 if ((mMask & kUnfoldedShortCircuitExpression) != 0)
77 {
78 if (node->usesTernaryOperator())
79 {
80 return true;
81 }
82 }
83 return false;
84}