19a887f65SVitaly Buka //===--- VarBypassDetector.h - Bypass jumps detector --------------*- C++ -*-=// 264c80b4eSVitaly Buka // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664c80b4eSVitaly Buka // 764c80b4eSVitaly Buka //===----------------------------------------------------------------------===// 864c80b4eSVitaly Buka // 964c80b4eSVitaly Buka // This file contains VarBypassDetector class, which is used to detect 1064c80b4eSVitaly Buka // local variable declarations which can be bypassed by jumps. 1164c80b4eSVitaly Buka // 1264c80b4eSVitaly Buka //===----------------------------------------------------------------------===// 1364c80b4eSVitaly Buka 1464c80b4eSVitaly Buka #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 1564c80b4eSVitaly Buka #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 1664c80b4eSVitaly Buka 17f8b8b39cSRichard Trieu #include "clang/AST/Decl.h" 1864c80b4eSVitaly Buka #include "llvm/ADT/DenseMap.h" 1964c80b4eSVitaly Buka #include "llvm/ADT/DenseSet.h" 2064c80b4eSVitaly Buka #include "llvm/ADT/SmallVector.h" 2164c80b4eSVitaly Buka 2264c80b4eSVitaly Buka namespace clang { 2364c80b4eSVitaly Buka 2464c80b4eSVitaly Buka class Decl; 2564c80b4eSVitaly Buka class Stmt; 2664c80b4eSVitaly Buka class VarDecl; 2764c80b4eSVitaly Buka 2864c80b4eSVitaly Buka namespace CodeGen { 2964c80b4eSVitaly Buka 3064c80b4eSVitaly Buka /// The class detects jumps which bypass local variables declaration: 3164c80b4eSVitaly Buka /// goto L; 3264c80b4eSVitaly Buka /// int a; 3364c80b4eSVitaly Buka /// L: 3464c80b4eSVitaly Buka /// 3564c80b4eSVitaly Buka /// This is simplified version of JumpScopeChecker. Primary differences: 3664c80b4eSVitaly Buka /// * Detects only jumps into the scope local variables. 3764c80b4eSVitaly Buka /// * Does not detect jumps out of the scope of local variables. 3864c80b4eSVitaly Buka /// * Not limited to variables with initializers, JumpScopeChecker is limited. 3964c80b4eSVitaly Buka class VarBypassDetector { 4064c80b4eSVitaly Buka // Scope information. Contains a parent scope and related variable 4164c80b4eSVitaly Buka // declaration. 4264c80b4eSVitaly Buka llvm::SmallVector<std::pair<unsigned, const VarDecl *>, 48> Scopes; 4364c80b4eSVitaly Buka // List of jumps with scopes. 4464c80b4eSVitaly Buka llvm::SmallVector<std::pair<const Stmt *, unsigned>, 16> FromScopes; 4564c80b4eSVitaly Buka // Lookup map to find scope for destinations. 4664c80b4eSVitaly Buka llvm::DenseMap<const Stmt *, unsigned> ToScopes; 4764c80b4eSVitaly Buka // Set of variables which were bypassed by some jump. 4864c80b4eSVitaly Buka llvm::DenseSet<const VarDecl *> Bypasses; 4964c80b4eSVitaly Buka // If true assume that all variables are being bypassed. 5064c80b4eSVitaly Buka bool AlwaysBypassed = false; 5164c80b4eSVitaly Buka 5264c80b4eSVitaly Buka public: 5364c80b4eSVitaly Buka void Init(const Stmt *Body); 5464c80b4eSVitaly Buka 5564c80b4eSVitaly Buka /// Returns true if the variable declaration was by bypassed by any goto or 5664c80b4eSVitaly Buka /// switch statement. IsBypassed(const VarDecl * D)5764c80b4eSVitaly Buka bool IsBypassed(const VarDecl *D) const { 58*972d4133SKazu Hirata return AlwaysBypassed || Bypasses.contains(D); 5964c80b4eSVitaly Buka } 6064c80b4eSVitaly Buka 6164c80b4eSVitaly Buka private: 6264c80b4eSVitaly Buka bool BuildScopeInformation(const Decl *D, unsigned &ParentScope); 6364c80b4eSVitaly Buka bool BuildScopeInformation(const Stmt *S, unsigned &origParentScope); 6464c80b4eSVitaly Buka void Detect(); 6564c80b4eSVitaly Buka void Detect(unsigned From, unsigned To); 6664c80b4eSVitaly Buka }; 6764c80b4eSVitaly Buka } 6864c80b4eSVitaly Buka } 6964c80b4eSVitaly Buka 7064c80b4eSVitaly Buka #endif 71