blob: cb76f1de02ab231880ec3d53bd4d02edb3ec7107 [file] [log] [blame]
Jamie Madilleb1a0102013-07-08 13:31:38 -04001//
2// Copyright (c) 2002-2011 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
7#ifndef COMPILER_DETECT_RECURSION_H_
8#define COMPILER_DETECT_RECURSION_H_
9
Jamie Madilleb1a0102013-07-08 13:31:38 -040010#include <limits.h>
Geoff Lang17732822013-08-29 13:46:49 -040011#include "compiler/translator/intermediate.h"
12#include "compiler/translator/VariableInfo.h"
Jamie Madilleb1a0102013-07-08 13:31:38 -040013
14class TInfoSink;
15
16// Traverses intermediate tree to detect function recursion.
17class DetectCallDepth : public TIntermTraverser {
18public:
19 enum ErrorCode {
20 kErrorMissingMain,
21 kErrorRecursion,
22 kErrorMaxDepthExceeded,
23 kErrorNone
24 };
25
26 DetectCallDepth(TInfoSink& infoSync, bool limitCallStackDepth, int maxCallStackDepth);
27 ~DetectCallDepth();
28
29 virtual bool visitAggregate(Visit, TIntermAggregate*);
30
31 bool checkExceedsMaxDepth(int depth);
32
33 ErrorCode detectCallDepth();
34
35private:
36 class FunctionNode {
37 public:
38 static const int kInfiniteCallDepth = INT_MAX;
39
40 FunctionNode(const TString& fname);
41
42 const TString& getName() const;
43
44 // If a function is already in the callee list, this becomes a no-op.
45 void addCallee(FunctionNode* callee);
46
47 // Returns kInifinityCallDepth if recursive function calls are detected.
48 int detectCallDepth(DetectCallDepth* detectCallDepth, int depth);
49
50 // Reset state.
51 void reset();
52
53 private:
54 // mangled function name is unique.
55 TString name;
56
57 // functions that are directly called by this function.
58 TVector<FunctionNode*> callees;
59
60 Visit visit;
61 };
62
63 ErrorCode detectCallDepthForFunction(FunctionNode* func);
64 FunctionNode* findFunctionByName(const TString& name);
65 void resetFunctionNodes();
66
67 TInfoSink& getInfoSink() { return infoSink; }
68
69 TVector<FunctionNode*> functions;
70 FunctionNode* currentFunction;
71 TInfoSink& infoSink;
72 int maxDepth;
73
74 DetectCallDepth(const DetectCallDepth&);
75 void operator=(const DetectCallDepth&);
76};
77
78#endif // COMPILER_DETECT_RECURSION_H_