summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h7
-rw-r--r--clang/lib/CodeGen/CGClass.cpp5
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp8
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp10
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp29
5 files changed, 47 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index ed5771d2ca4..83426dc3a03 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -582,6 +582,13 @@ public:
/// Emit a single constructor/destructor with the given type from a C++
/// constructor Decl.
virtual void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) = 0;
+
+ /// Load a vtable from This, an object of polymorphic type RD, or from one of
+ /// its virtual bases if it does not have its own vtable. Returns the vtable
+ /// and the class from which the vtable was loaded.
+ virtual std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) = 0;
};
// Create an instance of a C++ ABI class:
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 95043ea0325..9bbdc98f1f2 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2627,8 +2627,9 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
EmitBlock(CheckBlock);
}
- llvm::Value *VTable =
- GetVTablePtr(Address(Derived, getPointerAlign()), Int8PtrTy, ClassDecl);
+ llvm::Value *VTable;
+ std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr(
+ *this, Address(Derived, getPointerAlign()), ClassDecl);
EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 3eb4bd6b901..41bb199ffde 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -368,9 +368,11 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
} else {
if (SanOpts.has(SanitizerKind::CFINVCall) &&
MD->getParent()->isDynamicClass()) {
- llvm::Value *VTable = GetVTablePtr(This, Int8PtrTy, MD->getParent());
- EmitVTablePtrCheckForCall(MD->getParent(), VTable, CFITCK_NVCall,
- CE->getLocStart());
+ llvm::Value *VTable;
+ const CXXRecordDecl *RD;
+ std::tie(VTable, RD) =
+ CGM.getCXXABI().LoadVTablePtr(*this, This, MD->getParent());
+ EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->getLocStart());
}
if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index ea5e8dd82c5..c375b82ea93 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -389,6 +389,10 @@ public:
void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
+ std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) override;
+
private:
bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {
const auto &VtableLayout =
@@ -4041,3 +4045,9 @@ ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
}
return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
}
+
+std::pair<llvm::Value *, const CXXRecordDecl *>
+ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+ return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 97a7fbab9a5..ffb3681c258 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -578,7 +578,7 @@ private:
return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
}
- std::pair<Address, llvm::Value *>
+ std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy);
@@ -745,6 +745,10 @@ public:
llvm::GlobalVariable *getThrowInfo(QualType T) override;
+ std::pair<llvm::Value *, const CXXRecordDecl *>
+ LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) override;
+
private:
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
@@ -926,7 +930,7 @@ void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
/// We need to perform a generic polymorphic operation (like a typeid
/// or a cast), which requires an object with a vfptr. Adjust the
/// address to point to an object with a vfptr.
-std::pair<Address, llvm::Value *>
+std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy) {
Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
@@ -937,7 +941,8 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
// covers non-virtual base subobjects: a class with its own virtual
// functions would be a candidate to be a primary base.
if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
- return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+ return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
+ SrcDecl);
// Okay, one of the vbases must have a vfptr, or else this isn't
// actually a polymorphic class.
@@ -956,7 +961,7 @@ MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(Value.getPointer(), Offset);
CharUnits VBaseAlign =
CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
- return std::make_pair(Address(Ptr, VBaseAlign), Offset);
+ return std::make_tuple(Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
}
bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
@@ -987,7 +992,7 @@ llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
QualType SrcRecordTy,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) {
- std::tie(ThisPtr, std::ignore) =
+ std::tie(ThisPtr, std::ignore, std::ignore) =
performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
auto Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()).getInstruction();
return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
@@ -1011,7 +1016,8 @@ llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
llvm::Value *Offset;
- std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
+ std::tie(This, Offset, std::ignore) =
+ performBaseAdjustment(CGF, This, SrcRecordTy);
llvm::Value *ThisPtr = This.getPointer();
Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
@@ -1037,7 +1043,8 @@ llvm::Value *
MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
QualType SrcRecordTy,
QualType DestTy) {
- std::tie(Value, std::ignore) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+ std::tie(Value, std::ignore, std::ignore) =
+ performBaseAdjustment(CGF, Value, SrcRecordTy);
// PVOID __RTCastToVoid(
// PVOID inptr)
@@ -4244,3 +4251,11 @@ void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
};
CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args);
}
+
+std::pair<llvm::Value *, const CXXRecordDecl *>
+MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
+ const CXXRecordDecl *RD) {
+ std::tie(This, std::ignore, RD) =
+ performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
+ return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
+}
OpenPOWER on IntegriCloud