Refactor the C++ ABI code a little bit to take advantage of
what I'm going to treat as basically universal properties of
array-cookie code. Implement MS array cookies on top of that.
Based on a patch by Timur Iskhodzhanov!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155886 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index befebbe..8561ae3 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -145,6 +145,13 @@
}
CharUnits CGCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
+ if (!requiresArrayCookie(expr))
+ return CharUnits::Zero();
+ return getArrayCookieSizeImpl(expr->getAllocatedType());
+}
+
+CharUnits CGCXXABI::getArrayCookieSizeImpl(QualType elementType) {
+ // BOGUS
return CharUnits::Zero();
}
@@ -158,16 +165,53 @@
return 0;
}
-void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
- const CXXDeleteExpr *expr, QualType ElementType,
- llvm::Value *&NumElements,
- llvm::Value *&AllocPtr, CharUnits &CookieSize) {
- ErrorUnsupportedABI(CGF, "array cookie reading");
+bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
+ QualType elementType) {
+ // If the class's usual deallocation function takes two arguments,
+ // it needs a cookie.
+ if (expr->doesUsualArrayDeleteWantSize())
+ return true;
- // This should be enough to avoid assertions.
- NumElements = 0;
- AllocPtr = llvm::Constant::getNullValue(CGF.Builder.getInt8PtrTy());
- CookieSize = CharUnits::Zero();
+ return elementType.isDestructedType();
+}
+
+bool CGCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
+ // If the class's usual deallocation function takes two arguments,
+ // it needs a cookie.
+ if (expr->doesUsualArrayDeleteWantSize())
+ return true;
+
+ return expr->getAllocatedType().isDestructedType();
+}
+
+void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *ptr,
+ const CXXDeleteExpr *expr, QualType eltTy,
+ llvm::Value *&numElements,
+ llvm::Value *&allocPtr, CharUnits &cookieSize) {
+ // Derive a char* in the same address space as the pointer.
+ unsigned AS = cast<llvm::PointerType>(ptr->getType())->getAddressSpace();
+ llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
+ ptr = CGF.Builder.CreateBitCast(ptr, charPtrTy);
+
+ // If we don't need an array cookie, bail out early.
+ if (!requiresArrayCookie(expr, eltTy)) {
+ allocPtr = ptr;
+ numElements = 0;
+ cookieSize = CharUnits::Zero();
+ return;
+ }
+
+ cookieSize = getArrayCookieSizeImpl(eltTy);
+ allocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(ptr,
+ -cookieSize.getQuantity());
+ numElements = readArrayCookieImpl(CGF, allocPtr, cookieSize);
+}
+
+llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
+ llvm::Value *ptr,
+ CharUnits cookieSize) {
+ ErrorUnsupportedABI(CGF, "reading a new[] cookie");
+ return llvm::ConstantInt::get(CGF.SizeTy, 0);
}
void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,