aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenTBAA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenTBAA.cpp73
1 files changed, 45 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index ea66adb..2bc4b8a 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -25,16 +25,18 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
using namespace clang;
using namespace CodeGen;
-CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext,
+CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M,
const CodeGenOptions &CGO,
const LangOptions &Features, MangleContext &MContext)
- : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext),
- MDHelper(VMContext), Root(nullptr), Char(nullptr) {
-}
+ : Context(Ctx), Module(M), CodeGenOpts(CGO),
+ Features(Features), MContext(MContext), MDHelper(M.getContext()),
+ Root(nullptr), Char(nullptr)
+{}
CodeGenTBAA::~CodeGenTBAA() {
}
@@ -54,10 +56,10 @@ llvm::MDNode *CodeGenTBAA::getRoot() {
return Root;
}
-// For both scalar TBAA and struct-path aware TBAA, the scalar type has the
-// same format: name, parent node, and offset.
-llvm::MDNode *CodeGenTBAA::createTBAAScalarType(StringRef Name,
- llvm::MDNode *Parent) {
+llvm::MDNode *CodeGenTBAA::createScalarTypeNode(StringRef Name,
+ llvm::MDNode *Parent,
+ uint64_t Size) {
+ (void)Size; // TODO: Support generation of size-aware type nodes.
return MDHelper.createTBAAScalarTypeNode(Name, Parent);
}
@@ -67,7 +69,7 @@ llvm::MDNode *CodeGenTBAA::getChar() {
// these special powers only cover user-accessible memory, and doesn't
// include things like vtables.
if (!Char)
- Char = createTBAAScalarType("omnipotent char", getRoot());
+ Char = createScalarTypeNode("omnipotent char", getRoot(), /* Size= */ 1);
return Char;
}
@@ -108,6 +110,8 @@ static bool isValidBaseType(QualType QTy) {
}
llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
+ uint64_t Size = Context.getTypeSizeInChars(Ty).getQuantity();
+
// Handle builtin types.
if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
switch (BTy->getKind()) {
@@ -138,7 +142,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// treating wchar_t, char16_t, and char32_t as distinct from their
// "underlying types".
default:
- return createTBAAScalarType(BTy->getName(Features), getChar());
+ return createScalarTypeNode(BTy->getName(Features), getChar(), Size);
}
}
@@ -152,7 +156,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// TODO: Implement C++'s type "similarity" and consider dis-"similar"
// pointers distinct.
if (Ty->isPointerType() || Ty->isReferenceType())
- return createTBAAScalarType("any pointer", getChar());
+ return createScalarTypeNode("any pointer", getChar(), Size);
// Enum types are distinct types. In C++ they have "underlying types",
// however they aren't related for TBAA.
@@ -167,7 +171,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
MContext.mangleTypeName(QualType(ETy, 0), Out);
- return createTBAAScalarType(OutName, getChar());
+ return createScalarTypeNode(OutName, getChar(), Size);
}
// For now, handle any other kind of type conservatively.
@@ -204,8 +208,11 @@ llvm::MDNode *CodeGenTBAA::getTypeInfo(QualType QTy) {
return MetadataCache[Ty] = TypeNode;
}
-TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo() {
- return TBAAAccessInfo(createTBAAScalarType("vtable pointer", getRoot()));
+TBAAAccessInfo CodeGenTBAA::getVTablePtrAccessInfo(llvm::Type *VTablePtrType) {
+ llvm::DataLayout DL(&Module);
+ unsigned Size = DL.getPointerTypeSize(VTablePtrType);
+ return TBAAAccessInfo(createScalarTypeNode("vtable pointer", getRoot(), Size),
+ Size);
}
bool
@@ -245,7 +252,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
uint64_t Offset = BaseOffset;
uint64_t Size = Context.getTypeSizeInChars(QTy).getQuantity();
llvm::MDNode *TBAAType = MayAlias ? getChar() : getTypeInfo(QTy);
- llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType));
+ llvm::MDNode *TBAATag = getAccessTagInfo(TBAAAccessInfo(TBAAType, Size));
Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size, TBAATag));
return true;
}
@@ -268,19 +275,20 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
-
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- SmallVector <std::pair<llvm::MDNode*, uint64_t>, 4> Fields;
- unsigned idx = 0;
- for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i, ++idx) {
- QualType FieldQTy = i->getType();
- llvm::MDNode *FieldNode = isValidBaseType(FieldQTy) ?
+ SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
+ for (FieldDecl *Field : RD->fields()) {
+ QualType FieldQTy = Field->getType();
+ llvm::MDNode *TypeNode = isValidBaseType(FieldQTy) ?
getBaseTypeInfo(FieldQTy) : getTypeInfo(FieldQTy);
- if (!FieldNode)
+ if (!TypeNode)
return BaseTypeMetadataCache[Ty] = nullptr;
- Fields.push_back(std::make_pair(
- FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth()));
+
+ uint64_t BitOffset = Layout.getFieldOffset(Field->getFieldIndex());
+ uint64_t Offset = Context.toCharUnitsFromBits(BitOffset).getQuantity();
+ uint64_t Size = Context.getTypeSizeInChars(FieldQTy).getQuantity();
+ Fields.push_back(llvm::MDBuilder::TBAAStructField(Offset, Size,
+ TypeNode));
}
SmallString<256> OutName;
@@ -291,8 +299,15 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
} else {
OutName = RD->getName();
}
+
+ // TODO: Support size-aware type nodes and create one here for the
+ // given aggregate type.
+
// Create the struct type node with a vector of pairs (offset, type).
- return MDHelper.createTBAAStructTypeNode(OutName, Fields);
+ SmallVector<std::pair<llvm::MDNode*, uint64_t>, 4> OffsetsAndTypes;
+ for (const auto &Field : Fields)
+ OffsetsAndTypes.push_back(std::make_pair(Field.TBAA, Field.Offset));
+ return MDHelper.createTBAAStructTypeNode(OutName, OffsetsAndTypes);
}
return nullptr;
@@ -314,14 +329,16 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfo(QualType QTy) {
}
llvm::MDNode *CodeGenTBAA::getAccessTagInfo(TBAAAccessInfo Info) {
+ assert(!Info.isIncomplete() && "Access to an object of an incomplete type!");
+
if (Info.isMayAlias())
- Info = TBAAAccessInfo(getChar());
+ Info = TBAAAccessInfo(getChar(), Info.Size);
if (!Info.AccessType)
return nullptr;
if (!CodeGenOpts.StructPathTBAA)
- Info = TBAAAccessInfo(Info.AccessType);
+ Info = TBAAAccessInfo(Info.AccessType, Info.Size);
llvm::MDNode *&N = AccessTagMetadataCache[Info];
if (N)