blob: 2114dc60333696f7b3c7a0f65684395bd81fe7fd [file] [log] [blame]
//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This files defines SymbolManager, a class that manages symbolic values
// created for use by GRExprEngine and related classes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
#define LLVM_CLANG_ANALYSIS_SYMMGR_H
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
namespace clang {
class SymbolID {
unsigned Data;
public:
SymbolID() : Data(~0) {}
SymbolID(unsigned x) : Data(x) {}
bool isInitialized() const { return Data != (unsigned) ~0; }
operator unsigned() const { assert (isInitialized()); return Data; }
void Profile(llvm::FoldingSetNodeID& ID) const {
assert (isInitialized());
ID.AddInteger(Data);
}
static inline void Profile(llvm::FoldingSetNodeID& ID, SymbolID X) {
X.Profile(ID);
}
};
// SymbolData: Used to record meta data about symbols.
class SymbolData {
public:
enum Kind { UninitKind, ParmKind, ContentsOfKind };
private:
uintptr_t Data;
Kind K;
protected:
SymbolData(uintptr_t D, Kind k) : Data(D), K(k) {}
SymbolData(void* D, Kind k) : Data(reinterpret_cast<uintptr_t>(D)), K(k) {}
void* getPtr() const {
assert (K != UninitKind);
return reinterpret_cast<void*>(Data);
}
uintptr_t getInt() const {
assert (K != UninitKind);
return Data;
}
public:
SymbolData() : Data(0), K(UninitKind) {}
Kind getKind() const { return K; }
inline bool operator==(const SymbolData& R) const {
return K == R.K && Data == R.Data;
}
QualType getType() const;
// Implement isa<T> support.
static inline bool classof(const SymbolData*) { return true; }
};
class SymbolDataParmVar : public SymbolData {
public:
SymbolDataParmVar(ParmVarDecl* VD) : SymbolData(VD, ParmKind) {}
ParmVarDecl* getDecl() const { return (ParmVarDecl*) getPtr(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ParmKind;
}
};
class SymbolDataContentsOf : public SymbolData {
public:
SymbolDataContentsOf(SymbolID ID) : SymbolData(ID, ContentsOfKind) {}
SymbolID getSymbol() const { return (SymbolID) getInt(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ContentsOfKind;
}
};
// Constraints on symbols. Usually wrapped by RValues.
class SymIntConstraint : public llvm::FoldingSetNode {
SymbolID Symbol;
BinaryOperator::Opcode Op;
const llvm::APSInt& Val;
public:
SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op,
const llvm::APSInt& V)
: Symbol(sym),
Op(op), Val(V) {}
BinaryOperator::Opcode getOpcode() const { return Op; }
const SymbolID& getSymbol() const { return Symbol; }
const llvm::APSInt& getInt() const { return Val; }
static inline void Profile(llvm::FoldingSetNodeID& ID,
const SymbolID& Symbol,
BinaryOperator::Opcode Op,
const llvm::APSInt& Val) {
Symbol.Profile(ID);
ID.AddInteger(Op);
ID.AddPointer(&Val);
}
void Profile(llvm::FoldingSetNodeID& ID) {
Profile(ID, Symbol, Op, Val);
}
};
class SymbolManager {
std::vector<SymbolData> SymbolToData;
typedef llvm::DenseMap<void*,SymbolID> MapTy;
MapTy DataToSymbol;
void* getKey(void* P) const {
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(P) | 0x1);
}
void* getKey(SymbolID sym) const {
return reinterpret_cast<void*>((uintptr_t) (sym << 1));
}
public:
SymbolManager();
~SymbolManager();
SymbolID getSymbol(ParmVarDecl* D);
SymbolID getContentsOfSymbol(SymbolID sym);
inline const SymbolData& getSymbolData(SymbolID ID) const {
assert (ID < SymbolToData.size());
return SymbolToData[ID];
}
inline QualType getType(SymbolID ID) const {
return getSymbolData(ID).getType();
}
};
} // end clang namespace
#endif