Hash :
fc0e2bc0
Author :
Date :
2015-04-16T13:39:56
Put each array declarator into a separate declaration in HLSL output Since HLSL doesn't support arrays as l-values, HLSL output needs to split declarators that initialize arrays to variable declaration and assignment implemented via a function call. To prepare for this, it is necessary that each declarator has its own declaration. BUG=angleproject:941 TEST=angle_end2end_tests, WebGL conformance tests Change-Id: I43dee487578561c01dbde90c2f55a93dda2f057a Reviewed-on: https://chromium-review.googlesource.com/266001 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org> Tested-by: Olli Etuaho <oetuaho@nvidia.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
//
// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The SeparateArrayDeclarations function processes declarations that contain array declarators. Each declarator in
// such declarations gets its own declaration.
// This is useful as an intermediate step when initialization needs to be separated from declaration.
// Example:
// int a[1] = int[1](1), b[1] = int[1](2);
// gets transformed when run through this class into the AST equivalent of:
// int a[1] = int[1](1);
// int b[1] = int[1](2);
#include "compiler/translator/SeparateDeclarations.h"
#include "compiler/translator/IntermNode.h"
namespace
{
class SeparateDeclarations : private TIntermTraverser
{
public:
static void apply(TIntermNode *root);
private:
SeparateDeclarations();
bool visitAggregate(Visit, TIntermAggregate *node) override;
};
void SeparateDeclarations::apply(TIntermNode *root)
{
SeparateDeclarations separateDecl;
root->traverse(&separateDecl);
separateDecl.updateTree();
}
SeparateDeclarations::SeparateDeclarations()
: TIntermTraverser(true, false, false)
{
}
bool SeparateDeclarations::visitAggregate(Visit, TIntermAggregate *node)
{
if (node->getOp() == EOpDeclaration)
{
TIntermSequence *sequence = node->getSequence();
bool sequenceContainsArrays = false;
for (size_t ii = 0; ii < sequence->size(); ++ii)
{
TIntermTyped *typed = sequence->at(ii)->getAsTyped();
if (typed != nullptr && typed->isArray())
{
sequenceContainsArrays = true;
break;
}
}
if (sequence->size() > 1 && sequenceContainsArrays)
{
TIntermAggregate *parentAgg = getParentNode()->getAsAggregate();
ASSERT(parentAgg != nullptr);
TIntermSequence replacementDeclarations;
for (size_t ii = 0; ii < sequence->size(); ++ii)
{
TIntermAggregate *replacementDeclaration = new TIntermAggregate;
replacementDeclaration->setOp(EOpDeclaration);
replacementDeclaration->getSequence()->push_back(sequence->at(ii));
replacementDeclaration->setLine(sequence->at(ii)->getLine());
replacementDeclarations.push_back(replacementDeclaration);
}
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacementDeclarations));
}
return false;
}
return true;
}
} // namespace
void SeparateArrayDeclarations(TIntermNode *root)
{
SeparateDeclarations::apply(root);
}