1 //
2 // Copyright (c) 2016 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 // AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a
7 //                                 return.
8 //
9 
10 #include "compiler/translator/AddDefaultReturnStatements.h"
11 
12 #include "compiler/translator/IntermNode.h"
13 #include "compiler/translator/IntermNode_util.h"
14 #include "compiler/translator/util.h"
15 
16 namespace sh
17 {
18 
19 namespace
20 {
21 
NeedsReturnStatement(TIntermFunctionDefinition * node,TType * returnType)22 bool NeedsReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
23 {
24     *returnType = node->getFunctionPrototype()->getType();
25     if (returnType->getBasicType() == EbtVoid)
26     {
27         return false;
28     }
29 
30     TIntermBlock *bodyNode    = node->getBody();
31     TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
32     if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
33     {
34         return false;
35     }
36 
37     return true;
38 }
39 
40 }  // anonymous namespace
41 
AddDefaultReturnStatements(TIntermBlock * root)42 void AddDefaultReturnStatements(TIntermBlock *root)
43 {
44     TType returnType;
45     for (TIntermNode *node : *root->getSequence())
46     {
47         TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
48         if (definition != nullptr && NeedsReturnStatement(definition, &returnType))
49         {
50             TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType));
51 
52             TIntermBlock *bodyNode = definition->getBody();
53             bodyNode->getSequence()->push_back(branch);
54         }
55     }
56 }
57 
58 }  // namespace sh
59