27class ReturnsOnAllPathsVisitor :
public ProgramVisitor {
29 bool visitExpression(
const Expression& expr)
override {
34 bool visitStatement(
const Statement& stmt)
override {
35 switch (stmt.kind()) {
38 case Statement::Kind::kReturn:
42 case Statement::Kind::kBreak:
47 fFoundContinue =
true;
50 case Statement::Kind::kIf: {
51 const IfStatement&
i = stmt.as<IfStatement>();
52 ReturnsOnAllPathsVisitor trueVisitor;
53 ReturnsOnAllPathsVisitor falseVisitor;
54 trueVisitor.visitStatement(*
i.ifTrue());
56 falseVisitor.visitStatement(*
i.ifFalse());
60 fFoundBreak = (trueVisitor.fFoundBreak || falseVisitor.fFoundBreak);
61 fFoundContinue = (trueVisitor.fFoundContinue || falseVisitor.fFoundContinue);
64 fFoundReturn = (trueVisitor.fFoundReturn && falseVisitor.fFoundReturn);
65 return fFoundBreak || fFoundContinue || fFoundReturn;
67 case Statement::Kind::kFor: {
68 const ForStatement&
f = stmt.as<ForStatement>();
72 ReturnsOnAllPathsVisitor forVisitor;
73 forVisitor.visitStatement(*
f.statement());
76 fFoundReturn = forVisitor.fFoundReturn;
79 case Statement::Kind::kDo: {
80 const DoStatement&
d = stmt.as<DoStatement>();
82 ReturnsOnAllPathsVisitor doVisitor;
83 doVisitor.visitStatement(*
d.statement());
86 fFoundReturn = doVisitor.fFoundReturn;
89 case Statement::Kind::kBlock:
92 return INHERITED::visitStatement(stmt);
94 case Statement::Kind::kSwitch: {
100 const SwitchStatement&
s = stmt.as<SwitchStatement>();
101 bool foundDefault =
false;
102 bool fellThrough =
false;
103 for (
const std::unique_ptr<Statement>& switchStmt :
s.cases()) {
106 const SwitchCase& sc = switchStmt->as<SwitchCase>();
107 if (sc.isDefault()) {
111 ReturnsOnAllPathsVisitor caseVisitor;
112 caseVisitor.visitStatement(sc);
117 if (caseVisitor.fFoundContinue) {
118 fFoundContinue =
true;
121 if (caseVisitor.fFoundBreak) {
127 fellThrough = !caseVisitor.fFoundReturn;
132 if (fellThrough || !foundDefault) {
142 case Statement::Kind::kSwitchCase:
144 return INHERITED::visitStatement(stmt);
147 case Statement::Kind::kExpression:
149 case Statement::Kind::kVarDeclaration:
157 bool fFoundReturn =
false;
158 bool fFoundBreak =
false;
159 bool fFoundContinue =
false;
171 ReturnsOnAllPathsVisitor visitor;
172 visitor.visitStatement(body);
173 return !visitor.fFoundReturn;
#define INHERITED(method,...)
Expression(Position pos, Kind kind, const Type *type)
const Type & returnType() const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
bool CanExitWithoutReturningValue(const FunctionDeclaration &funcDecl, const Statement &body)