1//
2// Copyright (c) 2013 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/FlagStd140Structs.h"
8
9namespace sh
10{
11
12bool FlagStd140Structs::visitBinary(Visit visit, TIntermBinary *binaryNode)
13{
14    if (binaryNode->getRight()->getBasicType() == EbtStruct)
15    {
16        switch (binaryNode->getOp())
17        {
18          case EOpIndexDirectInterfaceBlock:
19          case EOpIndexDirectStruct:
20            if (isInStd140InterfaceBlock(binaryNode->getLeft()))
21            {
22                mFlaggedNodes.push_back(binaryNode);
23            }
24            break;
25
26          default: break;
27        }
28        return false;
29    }
30
31    if (binaryNode->getOp() == EOpIndexDirectStruct)
32    {
33        return false;
34    }
35
36    return visit == PreVisit;
37}
38
39void FlagStd140Structs::visitSymbol(TIntermSymbol *symbol)
40{
41    if (isInStd140InterfaceBlock(symbol) && symbol->getBasicType() == EbtStruct)
42    {
43        mFlaggedNodes.push_back(symbol);
44    }
45}
46
47bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const
48{
49    TIntermBinary *binaryNode = node->getAsBinaryNode();
50
51    if (binaryNode)
52    {
53        return isInStd140InterfaceBlock(binaryNode->getLeft());
54    }
55
56    const TType &type = node->getType();
57
58    // determine if we are in the standard layout
59    const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
60    if (interfaceBlock)
61    {
62        return (interfaceBlock->blockStorage() == EbsStd140);
63    }
64
65    return false;
66}
67
68std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node)
69{
70    FlagStd140Structs flaggingTraversal;
71
72    node->traverse(&flaggingTraversal);
73
74    return flaggingTraversal.getFlaggedNodes();
75}
76
77}
78