1 //===--- VarBypassDetector.cpp - Bypass jumps detector ------------*- C++ -*-=// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains VarBypassDetector class, which is used to detect 10 // local variable declarations which can be bypassed by jumps. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 15 #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 16 17 #include "clang/AST/Decl.h" 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