1 //===--- VarBypassDetector.cpp - Bypass jumps detector ------------*- C++ -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains VarBypassDetector class, which is used to detect 11 // local variable declarations which can be bypassed by jumps. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 16 #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 17 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/DenseSet.h" 20 #include "llvm/ADT/SmallVector.h" 21 22 namespace clang { 23 24 class Decl; 25 class Stmt; 26 class VarDecl; 27 28 namespace CodeGen { 29 30 /// The class detects jumps which bypass local variables declaration: 31 /// goto L; 32 /// int a; 33 /// L: 34 /// 35 /// This is simplified version of JumpScopeChecker. Primary differences: 36 /// * Detects only jumps into the scope local variables. 37 /// * Does not detect jumps out of the scope of local variables. 38 /// * Not limited to variables with initializers, JumpScopeChecker is limited. 39 class VarBypassDetector { 40 // Scope information. Contains a parent scope and related variable 41 // declaration. 42 llvm::SmallVector<std::pair<unsigned, const VarDecl *>, 48> Scopes; 43 // List of jumps with scopes. 44 llvm::SmallVector<std::pair<const Stmt *, unsigned>, 16> FromScopes; 45 // Lookup map to find scope for destinations. 46 llvm::DenseMap<const Stmt *, unsigned> ToScopes; 47 // Set of variables which were bypassed by some jump. 48 llvm::DenseSet<const VarDecl *> Bypasses; 49 // If true assume that all variables are being bypassed. 50 bool AlwaysBypassed = false; 51 52 public: 53 void Init(const Stmt *Body); 54 55 /// Returns true if the variable declaration was by bypassed by any goto or 56 /// switch statement. 57 bool IsBypassed(const VarDecl *D) const { 58 return AlwaysBypassed || Bypasses.find(D) != Bypasses.end(); 59 } 60 61 private: 62 bool BuildScopeInformation(const Decl *D, unsigned &ParentScope); 63 bool BuildScopeInformation(const Stmt *S, unsigned &origParentScope); 64 void Detect(); 65 void Detect(unsigned From, unsigned To); 66 }; 67 } 68 } 69 70 #endif 71