Home | History | Annotate | Download | only in compiler
      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