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