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 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