#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H
#define LLVM_CLANG_LIB_CODEGEN_CODEGENTBAA_H
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/MDBuilder.h"
namespace llvm {
class LLVMContext;
class MDNode;
}
namespace clang {
class ASTContext;
class CodeGenOptions;
class LangOptions;
class MangleContext;
class QualType;
class Type;
namespace CodeGen {
class CGRecordLayout;
struct TBAAPathTag {
TBAAPathTag(const Type *B, const llvm::MDNode *A, uint64_t O)
: BaseT(B), AccessN(A), Offset(O) {}
const Type *BaseT;
const llvm::MDNode *AccessN;
uint64_t Offset;
};
class CodeGenTBAA {
ASTContext &Context;
const CodeGenOptions &CodeGenOpts;
const LangOptions &Features;
MangleContext &MContext;
llvm::MDBuilder MDHelper;
llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
llvm::DenseMap<const Type *, llvm::MDNode *> StructTypeMetadataCache;
llvm::DenseMap<TBAAPathTag, llvm::MDNode *> StructTagMetadataCache;
llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> ScalarTagMetadataCache;
llvm::DenseMap<const Type *, llvm::MDNode *> StructMetadataCache;
llvm::MDNode *Root;
llvm::MDNode *Char;
llvm::MDNode *getRoot();
llvm::MDNode *getChar();
bool CollectFields(uint64_t BaseOffset,
QualType Ty,
SmallVectorImpl<llvm::MDBuilder::TBAAStructField> &Fields,
bool MayAlias);
llvm::MDNode *createTBAAScalarType(StringRef Name, llvm::MDNode *Parent);
public:
CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext &VMContext,
const CodeGenOptions &CGO,
const LangOptions &Features,
MangleContext &MContext);
~CodeGenTBAA();
llvm::MDNode *getTBAAInfo(QualType QTy);
llvm::MDNode *getTBAAInfoForVTablePtr();
llvm::MDNode *getTBAAStructInfo(QualType QTy);
llvm::MDNode *getTBAAStructTypeInfo(QualType QType);
llvm::MDNode *getTBAAStructTagInfo(QualType BaseQType,
llvm::MDNode *AccessNode, uint64_t Offset);
llvm::MDNode *getTBAAScalarTagInfo(llvm::MDNode *AccessNode);
};
} }
namespace llvm {
template<> struct DenseMapInfo<clang::CodeGen::TBAAPathTag> {
static clang::CodeGen::TBAAPathTag getEmptyKey() {
return clang::CodeGen::TBAAPathTag(
DenseMapInfo<const clang::Type *>::getEmptyKey(),
DenseMapInfo<const MDNode *>::getEmptyKey(),
DenseMapInfo<uint64_t>::getEmptyKey());
}
static clang::CodeGen::TBAAPathTag getTombstoneKey() {
return clang::CodeGen::TBAAPathTag(
DenseMapInfo<const clang::Type *>::getTombstoneKey(),
DenseMapInfo<const MDNode *>::getTombstoneKey(),
DenseMapInfo<uint64_t>::getTombstoneKey());
}
static unsigned getHashValue(const clang::CodeGen::TBAAPathTag &Val) {
return DenseMapInfo<const clang::Type *>::getHashValue(Val.BaseT) ^
DenseMapInfo<const MDNode *>::getHashValue(Val.AccessN) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Offset);
}
static bool isEqual(const clang::CodeGen::TBAAPathTag &LHS,
const clang::CodeGen::TBAAPathTag &RHS) {
return LHS.BaseT == RHS.BaseT &&
LHS.AccessN == RHS.AccessN &&
LHS.Offset == RHS.Offset;
}
};
}
#endif