opnsense-src/include/clang/Analysis/AnalysisContext.h

261 lines
7.6 KiB
C
Raw Normal View History

2009-10-14 14:03:49 -04:00
//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines AnalysisContext, a class that manages the analysis context
// data for path sensitive analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
2009-12-15 13:49:47 -05:00
#include "clang/AST/Decl.h"
2009-10-14 14:03:49 -04:00
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
2009-12-15 13:49:47 -05:00
#include "llvm/ADT/PointerUnion.h"
2009-10-14 14:03:49 -04:00
#include "llvm/ADT/DenseMap.h"
2009-12-01 06:08:04 -05:00
#include "llvm/Support/Allocator.h"
2009-10-14 14:03:49 -04:00
namespace clang {
class Decl;
class Stmt;
class CFG;
2010-01-01 05:34:51 -05:00
class CFGBlock;
2009-10-14 14:03:49 -04:00
class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
2009-12-15 13:49:47 -05:00
class LocationContextManager;
class StackFrameContext;
2009-10-14 14:03:49 -04:00
/// AnalysisContext contains the context data for the function or method under
/// analysis.
class AnalysisContext {
const Decl *D;
// AnalysisContext owns the following data.
CFG *cfg;
LiveVariables *liveness;
ParentMap *PM;
2009-12-01 06:08:04 -05:00
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
llvm::BumpPtrAllocator A;
2010-01-23 06:10:26 -05:00
bool AddEHEdges;
2009-10-14 14:03:49 -04:00
public:
2010-01-23 06:10:26 -05:00
AnalysisContext(const Decl *d, bool addehedges = false)
: D(d), cfg(0), liveness(0), PM(0), ReferencedBlockVars(0),
AddEHEdges(addehedges) {}
2009-12-01 06:08:04 -05:00
2009-10-14 14:03:49 -04:00
~AnalysisContext();
2009-12-01 06:08:04 -05:00
ASTContext &getASTContext() { return D->getASTContext(); }
2009-10-14 14:03:49 -04:00
const Decl *getDecl() { return D; }
2010-01-23 06:10:26 -05:00
/// getAddEHEdges - Return true iff we are adding exceptional edges from
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must
/// cope with that.
bool getAddEHEdges() const { return AddEHEdges; }
2009-10-14 14:03:49 -04:00
Stmt *getBody();
CFG *getCFG();
ParentMap &getParentMap();
LiveVariables *getLiveVariables();
2009-12-01 06:08:04 -05:00
typedef const VarDecl * const * referenced_decls_iterator;
std::pair<referenced_decls_iterator, referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl *BD);
2009-10-14 14:03:49 -04:00
/// Return the ImplicitParamDecl* associated with 'self' if this
/// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
const ImplicitParamDecl *getSelfDecl() const;
};
class AnalysisContextManager {
typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
ContextMap Contexts;
public:
~AnalysisContextManager();
AnalysisContext *getContext(const Decl *D);
2009-10-23 10:22:18 -04:00
// Discard all previously created AnalysisContexts.
void clear();
2009-10-14 14:03:49 -04:00
};
class LocationContext : public llvm::FoldingSetNode {
public:
2009-12-15 13:49:47 -05:00
enum ContextKind { StackFrame, Scope, Block };
2009-10-14 14:03:49 -04:00
private:
ContextKind Kind;
AnalysisContext *Ctx;
const LocationContext *Parent;
protected:
LocationContext(ContextKind k, AnalysisContext *ctx,
const LocationContext *parent)
: Kind(k), Ctx(ctx), Parent(parent) {}
public:
2009-12-15 13:49:47 -05:00
virtual ~LocationContext();
2009-11-04 10:04:32 -05:00
2009-10-14 14:03:49 -04:00
ContextKind getKind() const { return Kind; }
AnalysisContext *getAnalysisContext() const { return Ctx; }
const LocationContext *getParent() const { return Parent; }
const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
LiveVariables *getLiveVariables() const {
return getAnalysisContext()->getLiveVariables();
}
ParentMap &getParentMap() const {
return getAnalysisContext()->getParentMap();
}
const ImplicitParamDecl *getSelfDecl() const {
return Ctx->getSelfDecl();
}
2009-12-15 13:49:47 -05:00
const StackFrameContext *getCurrentStackFrame() const;
const StackFrameContext *
getStackFrameForDeclContext(const DeclContext *DC) const;
2009-10-14 14:03:49 -04:00
2009-12-15 13:49:47 -05:00
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
2009-10-14 14:03:49 -04:00
static bool classof(const LocationContext*) { return true; }
2009-12-15 13:49:47 -05:00
public:
static void ProfileCommon(llvm::FoldingSetNodeID &ID,
ContextKind ck,
AnalysisContext *ctx,
const LocationContext *parent,
const void* data);
2009-10-14 14:03:49 -04:00
};
class StackFrameContext : public LocationContext {
2010-01-01 05:34:51 -05:00
// The callsite where this stack frame is established.
2009-10-14 14:03:49 -04:00
const Stmt *CallSite;
2010-01-01 05:34:51 -05:00
// The parent block of the callsite.
const CFGBlock *Block;
// The index of the callsite in the CFGBlock.
unsigned Index;
2009-12-15 13:49:47 -05:00
friend class LocationContextManager;
2009-10-14 14:03:49 -04:00
StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
2010-01-01 05:34:51 -05:00
const Stmt *s, const CFGBlock *blk, unsigned idx)
: LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
Index(idx) {}
2009-11-04 10:04:32 -05:00
2009-12-15 13:49:47 -05:00
public:
~StackFrameContext() {}
2009-10-14 14:03:49 -04:00
2009-12-15 13:49:47 -05:00
const Stmt *getCallSite() const { return CallSite; }
2009-10-14 14:03:49 -04:00
2010-01-01 05:34:51 -05:00
const CFGBlock *getCallSiteBlock() const { return Block; }
unsigned getIndex() const { return Index; }
2009-12-15 13:49:47 -05:00
void Profile(llvm::FoldingSetNodeID &ID);
2009-10-14 14:03:49 -04:00
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
2010-01-01 05:34:51 -05:00
const LocationContext *parent, const Stmt *s,
const CFGBlock *blk, unsigned idx) {
2009-12-15 13:49:47 -05:00
ProfileCommon(ID, StackFrame, ctx, parent, s);
2010-01-01 05:34:51 -05:00
ID.AddPointer(blk);
ID.AddInteger(idx);
2009-12-15 13:49:47 -05:00
}
2009-10-14 14:03:49 -04:00
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == StackFrame;
}
};
class ScopeContext : public LocationContext {
const Stmt *Enter;
2009-12-15 13:49:47 -05:00
friend class LocationContextManager;
2009-10-14 14:03:49 -04:00
ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
: LocationContext(Scope, ctx, parent), Enter(s) {}
2009-12-15 13:49:47 -05:00
public:
~ScopeContext() {}
void Profile(llvm::FoldingSetNodeID &ID);
2009-10-14 14:03:49 -04:00
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
2009-12-15 13:49:47 -05:00
const LocationContext *parent, const Stmt *s) {
ProfileCommon(ID, Scope, ctx, parent, s);
}
2009-10-14 14:03:49 -04:00
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == Scope;
}
};
2009-12-15 13:49:47 -05:00
class BlockInvocationContext : public LocationContext {
2010-02-16 04:31:36 -05:00
// FIXME: Add back context-sensivity (we don't want libAnalysis to know
// about MemRegion).
const BlockDecl *BD;
2009-12-15 13:49:47 -05:00
friend class LocationContextManager;
BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
const BlockDecl *bd)
2010-02-16 04:31:36 -05:00
: LocationContext(Block, ctx, parent), BD(bd) {}
2009-12-15 13:49:47 -05:00
public:
~BlockInvocationContext() {}
2010-02-16 04:31:36 -05:00
const BlockDecl *getBlockDecl() const { return BD; }
2009-12-15 13:49:47 -05:00
void Profile(llvm::FoldingSetNodeID &ID);
2010-02-16 04:31:36 -05:00
2009-12-15 13:49:47 -05:00
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
const LocationContext *parent, const BlockDecl *bd) {
ProfileCommon(ID, Block, ctx, parent, bd);
}
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == Block;
}
};
2009-10-14 14:03:49 -04:00
class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
public:
2009-10-23 10:22:18 -04:00
~LocationContextManager();
2009-12-15 13:49:47 -05:00
const StackFrameContext *getStackFrame(AnalysisContext *ctx,
const LocationContext *parent,
2010-01-01 05:34:51 -05:00
const Stmt *s, const CFGBlock *blk,
unsigned idx);
2009-10-14 14:03:49 -04:00
2009-12-15 13:49:47 -05:00
const ScopeContext *getScope(AnalysisContext *ctx,
const LocationContext *parent,
const Stmt *s);
2009-10-23 10:22:18 -04:00
/// Discard all previously created LocationContext objects.
void clear();
2009-12-15 13:49:47 -05:00
private:
template <typename LOC, typename DATA>
const LOC *getLocationContext(AnalysisContext *ctx,
const LocationContext *parent,
const DATA *d);
2009-10-14 14:03:49 -04:00
};
} // end clang namespace
#endif