xref: /llvm-project/clang/lib/CodeGen/VarBypassDetector.h (revision 972d4133e9685558d0a1740d306af70c57e8e67a)
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