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