diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp')
-rwxr-xr-x | gfx/angle/src/compiler/translator/AddDefaultReturnStatements.cpp | 56 |
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; } |