Home | History | Annotate | Download | only in translator
      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 <limits.h>
     11 #include "compiler/translator/intermediate.h"
     12 #include "compiler/translator/VariableInfo.h"
     13 
     14 class TInfoSink;
     15 
     16 // Traverses intermediate tree to detect function recursion.
     17 class DetectCallDepth : public TIntermTraverser {
     18 public:
     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 
     35 private:
     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_
     79