blob: 30713c6fa79cfcd80852361a31bdbc492634eec0 [file] [log] [blame]
Olli Etuahofc0e2bc2015-04-16 13:39:56 +03001//
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//
Olli Etuahoa6f22092015-05-08 18:31:10 +03006// The SeparateDeclarations function processes declarations, so that in the end each declaration
7// contains only one declarator.
Jamie Madilld7b1ab52016-12-12 14:42:19 -05008// This is useful as an intermediate step when initialization needs to be separated from
9// declaration, or when things need to be unfolded out of the initializer.
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030010// 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
Olli Etuahoc26214d2018-03-16 10:43:11 +020018#include "compiler/translator/tree_util/IntermTraverse.h"
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030019
Jamie Madill45bcc782016-11-07 13:58:48 -050020namespace sh
21{
22
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030023namespace
24{
25
Olli Etuahoa6f22092015-05-08 18:31:10 +030026class SeparateDeclarationsTraverser : private TIntermTraverser
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030027{
28 public:
29 static void apply(TIntermNode *root);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050030
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030031 private:
Olli Etuahoa6f22092015-05-08 18:31:10 +030032 SeparateDeclarationsTraverser();
Olli Etuaho13389b62016-10-16 11:48:18 +010033 bool visitDeclaration(Visit, TIntermDeclaration *node) override;
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030034};
35
Olli Etuahoa6f22092015-05-08 18:31:10 +030036void SeparateDeclarationsTraverser::apply(TIntermNode *root)
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030037{
Olli Etuahoa6f22092015-05-08 18:31:10 +030038 SeparateDeclarationsTraverser separateDecl;
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030039 root->traverse(&separateDecl);
40 separateDecl.updateTree();
41}
42
Olli Etuahoa6f22092015-05-08 18:31:10 +030043SeparateDeclarationsTraverser::SeparateDeclarationsTraverser()
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030044 : TIntermTraverser(true, false, false)
45{
46}
47
Olli Etuaho13389b62016-10-16 11:48:18 +010048bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030049{
Olli Etuaho13389b62016-10-16 11:48:18 +010050 TIntermSequence *sequence = node->getSequence();
51 if (sequence->size() > 1)
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030052 {
Olli Etuaho13389b62016-10-16 11:48:18 +010053 TIntermBlock *parentBlock = getParentNode()->getAsBlock();
54 ASSERT(parentBlock != nullptr);
55
56 TIntermSequence replacementDeclarations;
57 for (size_t ii = 0; ii < sequence->size(); ++ii)
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030058 {
Olli Etuaho13389b62016-10-16 11:48:18 +010059 TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030060
Olli Etuaho13389b62016-10-16 11:48:18 +010061 replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped());
62 replacementDeclaration->setLine(sequence->at(ii)->getLine());
63 replacementDeclarations.push_back(replacementDeclaration);
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030064 }
Olli Etuaho13389b62016-10-16 11:48:18 +010065
66 mMultiReplacements.push_back(
67 NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations));
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030068 }
Olli Etuaho13389b62016-10-16 11:48:18 +010069 return false;
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030070}
71
Jamie Madilld7b1ab52016-12-12 14:42:19 -050072} // namespace
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030073
Olli Etuahoa6f22092015-05-08 18:31:10 +030074void SeparateDeclarations(TIntermNode *root)
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030075{
Olli Etuahoa6f22092015-05-08 18:31:10 +030076 SeparateDeclarationsTraverser::apply(root);
Olli Etuahofc0e2bc2015-04-16 13:39:56 +030077}
Jamie Madill45bcc782016-11-07 13:58:48 -050078
79} // namespace sh