summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp')
-rwxr-xr-xgfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp56
1 files changed, 48 insertions, 8 deletions
diff --git a/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp b/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
index 5767aea2b..97111d1a1 100755
--- a/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
+++ b/gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp
@@ -31,16 +31,21 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
private:
AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {}
- static bool IsFunctionWithoutReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
+ static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType)
{
*returnType = node->getType();
- if (node->getType().getBasicType() == EbtVoid)
+ if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid)
{
return false;
}
- TIntermBlock *bodyNode = node->getBody();
- TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
+ TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
+ if (lastNode == nullptr)
+ {
+ return true;
+ }
+
+ TIntermBranch *returnNode = lastNode->getSequence()->front()->getAsBranchNode();
if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
{
return false;
@@ -49,16 +54,51 @@ class AddDefaultReturnStatementsTraverser : private TIntermTraverser
return true;
}
- bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *node) override
+ static TIntermTyped *GenerateTypeConstructor(const TType &returnType)
+ {
+ // Base case, constructing a single element
+ if (!returnType.isArray())
+ {
+ size_t objectSize = returnType.getObjectSize();
+ TConstantUnion *constantUnion = new TConstantUnion[objectSize];
+ for (size_t constantIdx = 0; constantIdx < objectSize; constantIdx++)
+ {
+ constantUnion[constantIdx].setFConst(0.0f);
+ }
+
+ TIntermConstantUnion *intermConstantUnion =
+ new TIntermConstantUnion(constantUnion, returnType);
+ return intermConstantUnion;
+ }
+
+ // Recursive case, construct an array of single elements
+ TIntermAggregate *constructorAggrigate =
+ new TIntermAggregate(TypeToConstructorOperator(returnType));
+ constructorAggrigate->setType(returnType);
+
+ size_t arraySize = returnType.getArraySize();
+ for (size_t arrayIdx = 0; arrayIdx < arraySize; arrayIdx++)
+ {
+ TType arrayElementType(returnType);
+ arrayElementType.clearArrayness();
+
+ constructorAggrigate->getSequence()->push_back(
+ GenerateTypeConstructor(arrayElementType));
+ }
+
+ return constructorAggrigate;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *node) override
{
TType returnType;
if (IsFunctionWithoutReturnStatement(node, &returnType))
{
TIntermBranch *branch =
- new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType));
+ new TIntermBranch(EOpReturn, GenerateTypeConstructor(returnType));
- TIntermBlock *bodyNode = node->getBody();
- bodyNode->getSequence()->push_back(branch);
+ TIntermAggregate *lastNode = node->getSequence()->back()->getAsAggregate();
+ lastNode->getSequence()->push_back(branch);
return false;
}