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