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 "clang/AST/Decl.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/DenseSet.h" 21 #include "llvm/ADT/SmallVector.h" 22 23 namespace clang { 24 25 class Decl; 26 class Stmt; 27 class VarDecl; 28 29 namespace CodeGen { 30 31 /// The class detects jumps which bypass local variables declaration: 32 /// goto L; 33 /// int a; 34 /// L: 35 /// 36 /// This is simplified version of JumpScopeChecker. Primary differences: 37 /// * Detects only jumps into the scope local variables. 38 /// * Does not detect jumps out of the scope of local variables. 39 /// * Not limited to variables with initializers, JumpScopeChecker is limited. 40 class VarBypassDetector { 41 // Scope information. Contains a parent scope and related variable 42 // declaration. 43 llvm::SmallVector<std::pair<unsigned, const VarDecl *>, 48> Scopes; 44 // List of jumps with scopes. 45 llvm::SmallVector<std::pair<const Stmt *, unsigned>, 16> FromScopes; 46 // Lookup map to find scope for destinations. 47 llvm::DenseMap<const Stmt *, unsigned> ToScopes; 48 // Set of variables which were bypassed by some jump. 49 llvm::DenseSet<const VarDecl *> Bypasses; 50 // If true assume that all variables are being bypassed. 51 bool AlwaysBypassed = false; 52 53 public: 54 void Init(const Stmt *Body); 55 56 /// Returns true if the variable declaration was by bypassed by any goto or 57 /// switch statement. 58 bool IsBypassed(const VarDecl *D) const { 59 return AlwaysBypassed || Bypasses.find(D) != Bypasses.end(); 60 } 61 62 private: 63 bool BuildScopeInformation(const Decl *D, unsigned &ParentScope); 64 bool BuildScopeInformation(const Stmt *S, unsigned &origParentScope); 65 void Detect(); 66 void Detect(unsigned From, unsigned To); 67 }; 68 } 69 } 70 71 #endif 72