Line data Source code
1 : //
2 : // Copyright (c) 2002-2015 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 : // The SeparateDeclarations function processes declarations, so that in the end each declaration
7 : // contains only one declarator.
8 : // This is useful as an intermediate step when initialization needs to be separated from declaration,
9 : // or when things need to be unfolded out of the initializer.
10 : // Example:
11 : // int a[1] = int[1](1), b[1] = int[1](2);
12 : // gets transformed when run through this class into the AST equivalent of:
13 : // int a[1] = int[1](1);
14 : // int b[1] = int[1](2);
15 :
16 : #include "compiler/translator/SeparateDeclarations.h"
17 :
18 : #include "compiler/translator/IntermNode.h"
19 :
20 : namespace sh
21 : {
22 :
23 : namespace
24 : {
25 :
26 0 : class SeparateDeclarationsTraverser : private TIntermTraverser
27 : {
28 : public:
29 : static void apply(TIntermNode *root);
30 : private:
31 : SeparateDeclarationsTraverser();
32 : bool visitDeclaration(Visit, TIntermDeclaration *node) override;
33 : };
34 :
35 0 : void SeparateDeclarationsTraverser::apply(TIntermNode *root)
36 : {
37 0 : SeparateDeclarationsTraverser separateDecl;
38 0 : root->traverse(&separateDecl);
39 0 : separateDecl.updateTree();
40 0 : }
41 :
42 0 : SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
43 0 : : TIntermTraverser(true, false, false)
44 : {
45 0 : }
46 :
47 0 : bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
48 : {
49 0 : TIntermSequence *sequence = node->getSequence();
50 0 : if (sequence->size() > 1)
51 : {
52 0 : TIntermBlock *parentBlock = getParentNode()->getAsBlock();
53 0 : ASSERT(parentBlock != nullptr);
54 :
55 0 : TIntermSequence replacementDeclarations;
56 0 : for (size_t ii = 0; ii < sequence->size(); ++ii)
57 : {
58 0 : TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
59 :
60 0 : replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
61 0 : replacementDeclaration->setLine(sequence->at(ii)->getLine());
62 0 : replacementDeclarations.push_back(replacementDeclaration);
63 : }
64 :
65 0 : mMultiReplacements.push_back(
66 0 : NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
67 : }
68 0 : return false;
69 : }
70 :
71 : } // namespace
72 :
73 0 : void SeparateDeclarations(TIntermNode *root)
74 : {
75 0 : SeparateDeclarationsTraverser::apply(root);
76 0 : }
77 :
78 : } // namespace sh
|