1fe6060f1SDimitry Andric //===--- VarBypassDetector.h - Bypass jumps detector --------------*- C++ -*-=// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains VarBypassDetector class, which is used to detect 100b57cec5SDimitry Andric // local variable declarations which can be bypassed by jumps. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 150b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "clang/AST/Decl.h" 180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 190b57cec5SDimitry Andric #include "llvm/ADT/DenseSet.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace clang { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric class Decl; 250b57cec5SDimitry Andric class Stmt; 260b57cec5SDimitry Andric class VarDecl; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace CodeGen { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric /// The class detects jumps which bypass local variables declaration: 310b57cec5SDimitry Andric /// goto L; 320b57cec5SDimitry Andric /// int a; 330b57cec5SDimitry Andric /// L: 340b57cec5SDimitry Andric /// 350b57cec5SDimitry Andric /// This is simplified version of JumpScopeChecker. Primary differences: 360b57cec5SDimitry Andric /// * Detects only jumps into the scope local variables. 370b57cec5SDimitry Andric /// * Does not detect jumps out of the scope of local variables. 380b57cec5SDimitry Andric /// * Not limited to variables with initializers, JumpScopeChecker is limited. 390b57cec5SDimitry Andric class VarBypassDetector { 400b57cec5SDimitry Andric // Scope information. Contains a parent scope and related variable 410b57cec5SDimitry Andric // declaration. 420b57cec5SDimitry Andric llvm::SmallVector<std::pair<unsigned, const VarDecl *>, 48> Scopes; 430b57cec5SDimitry Andric // List of jumps with scopes. 440b57cec5SDimitry Andric llvm::SmallVector<std::pair<const Stmt *, unsigned>, 16> FromScopes; 450b57cec5SDimitry Andric // Lookup map to find scope for destinations. 460b57cec5SDimitry Andric llvm::DenseMap<const Stmt *, unsigned> ToScopes; 470b57cec5SDimitry Andric // Set of variables which were bypassed by some jump. 480b57cec5SDimitry Andric llvm::DenseSet<const VarDecl *> Bypasses; 490b57cec5SDimitry Andric // If true assume that all variables are being bypassed. 500b57cec5SDimitry Andric bool AlwaysBypassed = false; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric public: 530b57cec5SDimitry Andric void Init(const Stmt *Body); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// Returns true if the variable declaration was by bypassed by any goto or 560b57cec5SDimitry Andric /// switch statement. IsBypassed(const VarDecl * D)570b57cec5SDimitry Andric bool IsBypassed(const VarDecl *D) const { 58*349cc55cSDimitry Andric return AlwaysBypassed || Bypasses.contains(D); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric private: 620b57cec5SDimitry Andric bool BuildScopeInformation(const Decl *D, unsigned &ParentScope); 630b57cec5SDimitry Andric bool BuildScopeInformation(const Stmt *S, unsigned &origParentScope); 640b57cec5SDimitry Andric void Detect(); 650b57cec5SDimitry Andric void Detect(unsigned From, unsigned To); 660b57cec5SDimitry Andric }; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric #endif 71