aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /clang/lib/CodeGen/MicrosoftCXXABI.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
downloadsrc-706b4fc47bbc608932d3b491ae19a3b9cde9497b.tar.gz
src-706b4fc47bbc608932d3b491ae19a3b9cde9497b.zip
Vendor import of llvm-project master e26a78e70, the last commit beforevendor/llvm-project/llvmorg-10-init-17466-ge26a78e7085
the llvmorg-11-init tag, from which release/10.x was branched.
Notes
Notes: svn path=/vendor/llvm-project/master/; revision=356843 svn path=/vendor/llvm-project/llvmorg-10-init-17466-ge26a78e7085/; revision=356844; tag=vendor/llvm-project/llvmorg-10-init-17466-ge26a78e7085
Diffstat (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp119
1 files changed, 72 insertions, 47 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 2d8b538bc2ee..aff46135705a 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -19,11 +19,13 @@
#include "CodeGenModule.h"
#include "CodeGenTypes.h"
#include "TargetInfo.h"
-#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/VTableBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/Intrinsics.h"
@@ -619,6 +621,9 @@ private:
llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
const MethodVFTableLocation &ML);
+ llvm::Constant *EmitMemberDataPointer(const CXXRecordDecl *RD,
+ CharUnits offset);
+
public:
llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
@@ -1339,6 +1344,13 @@ void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
// The TU defining a dtor is only guaranteed to emit a base destructor. All
// other destructor variants are delegating thunks.
CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
+
+ // If the class is dllexported, emit the complete (vbase) destructor wherever
+ // the base dtor is emitted.
+ // FIXME: To match MSVC, this should only be done when the class is exported
+ // with -fdllexport-inlines enabled.
+ if (D->getParent()->getNumVBases() > 0 && D->hasAttr<DLLExportAttr>())
+ CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
}
CharUnits
@@ -2601,27 +2613,27 @@ bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
// we can't zero initialize. The field offset is sometimes also -1 if 0 is a
// valid field offset.
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
- return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+ return (!inheritanceModelHasVBTableOffsetField(Inheritance) &&
RD->nullFieldOffsetIsZero());
}
llvm::Type *
MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
llvm::SmallVector<llvm::Type *, 4> fields;
if (MPT->isMemberFunctionPointer())
fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk
else
fields.push_back(CGM.IntTy); // FieldOffset
- if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
- Inheritance))
+ if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
+ Inheritance))
fields.push_back(CGM.IntTy);
- if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ if (inheritanceModelHasVBPtrOffsetField(Inheritance))
fields.push_back(CGM.IntTy);
- if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ if (inheritanceModelHasVBTableOffsetField(Inheritance))
fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset
if (fields.size() == 1)
@@ -2634,7 +2646,7 @@ GetNullMemberPointerFields(const MemberPointerType *MPT,
llvm::SmallVectorImpl<llvm::Constant *> &fields) {
assert(fields.empty());
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
if (MPT->isMemberFunctionPointer()) {
// FunctionPointerOrVirtualThunk
fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
@@ -2645,12 +2657,12 @@ GetNullMemberPointerFields(const MemberPointerType *MPT,
fields.push_back(getAllOnesInt()); // FieldOffset
}
- if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
- Inheritance))
+ if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
+ Inheritance))
fields.push_back(getZeroInt());
- if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ if (inheritanceModelHasVBPtrOffsetField(Inheritance))
fields.push_back(getZeroInt());
- if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ if (inheritanceModelHasVBTableOffsetField(Inheritance))
fields.push_back(getAllOnesInt());
}
@@ -2671,21 +2683,21 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
const CXXRecordDecl *RD,
CharUnits NonVirtualBaseAdjustment,
unsigned VBTableIndex) {
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Single inheritance class member pointer are represented as scalars instead
// of aggregates.
- if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
+ if (inheritanceModelHasOnlyOneField(IsMemberFunction, Inheritance))
return FirstField;
llvm::SmallVector<llvm::Constant *, 4> fields;
fields.push_back(FirstField);
- if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
+ if (inheritanceModelHasNVOffsetField(IsMemberFunction, Inheritance))
fields.push_back(llvm::ConstantInt::get(
CGM.IntTy, NonVirtualBaseAdjustment.getQuantity()));
- if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
+ if (inheritanceModelHasVBPtrOffsetField(Inheritance)) {
CharUnits Offs = CharUnits::Zero();
if (VBTableIndex)
Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
@@ -2693,7 +2705,7 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
}
// The rest of the fields are adjusted by conversions to a more derived class.
- if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ if (inheritanceModelHasVBTableOffsetField(Inheritance))
fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBTableIndex));
return llvm::ConstantStruct::getAnon(fields);
@@ -2702,9 +2714,13 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
llvm::Constant *
MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
CharUnits offset) {
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ return EmitMemberDataPointer(MPT->getMostRecentCXXRecordDecl(), offset);
+}
+
+llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD,
+ CharUnits offset) {
if (RD->getMSInheritanceModel() ==
- MSInheritanceAttr::Keyword_virtual_inheritance)
+ MSInheritanceModel::Virtual)
offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
llvm::Constant *FirstField =
llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity());
@@ -2726,8 +2742,17 @@ llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
C = EmitMemberFunctionPointer(MD);
} else {
+ // For a pointer to data member, start off with the offset of the field in
+ // the class in which it was declared, and convert from there if necessary.
+ // For indirect field decls, get the outermost anonymous field and use the
+ // parent class.
CharUnits FieldOffset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(MPD));
- C = EmitMemberDataPointer(DstTy, FieldOffset);
+ const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
+ if (!FD)
+ FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getParent());
+ RD = RD->getMostRecentNonInjectedDecl();
+ C = EmitMemberDataPointer(RD, FieldOffset);
}
if (!MemberPointerPath.empty()) {
@@ -2801,7 +2826,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
if (VBTableIndex == 0 &&
RD->getMSInheritanceModel() ==
- MSInheritanceAttr::Keyword_virtual_inheritance)
+ MSInheritanceModel::Virtual)
NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
// The rest of the fields are common with data member pointers.
@@ -2837,9 +2862,9 @@ MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
// If this is a single field member pointer (single inheritance), this is a
// single icmp.
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
- if (MSInheritanceAttr::hasOnlyOneField(MPT->isMemberFunctionPointer(),
- Inheritance))
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+ if (inheritanceModelHasOnlyOneField(MPT->isMemberFunctionPointer(),
+ Inheritance))
return Builder.CreateICmp(Eq, L, R);
// Compare the first field.
@@ -3039,7 +3064,7 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
CGBuilderTy &Builder = CGF.Builder;
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Extract the fields we need, regardless of model. We'll apply them if we
// have them.
@@ -3050,9 +3075,9 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
// We need to extract values.
unsigned I = 0;
FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
- if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ if (inheritanceModelHasVBPtrOffsetField(Inheritance))
VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
- if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ if (inheritanceModelHasVBTableOffsetField(Inheritance))
VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
}
@@ -3147,8 +3172,8 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
CGBuilderTy &Builder) {
const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
- MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel();
- MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel();
+ MSInheritanceModel SrcInheritance = SrcRD->getMSInheritanceModel();
+ MSInheritanceModel DstInheritance = DstRD->getMSInheritanceModel();
bool IsFunc = SrcTy->isMemberFunctionPointer();
bool IsConstant = isa<llvm::Constant>(Src);
@@ -3157,15 +3182,15 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
llvm::Value *VBPtrOffset = getZeroInt();
- if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
+ if (!inheritanceModelHasOnlyOneField(IsFunc, SrcInheritance)) {
// We need to extract values.
unsigned I = 0;
FirstField = Builder.CreateExtractValue(Src, I++);
- if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
+ if (inheritanceModelHasNVOffsetField(IsFunc, SrcInheritance))
NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
- if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
+ if (inheritanceModelHasVBPtrOffsetField(SrcInheritance))
VBPtrOffset = Builder.CreateExtractValue(Src, I++);
- if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
+ if (inheritanceModelHasVBTableOffsetField(SrcInheritance))
VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
}
@@ -3184,7 +3209,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
// adjustment to normalize the member pointer.
llvm::Value *SrcVBIndexEqZero =
Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
- if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
+ if (SrcInheritance == MSInheritanceModel::Virtual) {
if (int64_t SrcOffsetToFirstVBase =
getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
@@ -3218,8 +3243,8 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
// Update the vbindex to an appropriate value in the destination because
// SrcRD's vbtable might not be a strict prefix of the one in DstRD.
llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
- if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
- MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
+ if (inheritanceModelHasVBTableOffsetField(DstInheritance) &&
+ inheritanceModelHasVBTableOffsetField(SrcInheritance)) {
if (llvm::GlobalVariable *VDispMap =
getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
llvm::Value *VBIndex = Builder.CreateExactUDiv(
@@ -3242,7 +3267,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
// Set the VBPtrOffset to zero if the vbindex is zero. Otherwise, initialize
// it to the offset of the vbptr.
- if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
+ if (inheritanceModelHasVBPtrOffsetField(DstInheritance)) {
llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
CGM.IntTy,
getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
@@ -3253,7 +3278,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
// Likewise, apply a similar adjustment so that dereferencing the member
// pointer correctly accounts for the distance between the start of the first
// virtual base and the top of the MDC.
- if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
+ if (DstInheritance == MSInheritanceModel::Virtual) {
if (int64_t DstOffsetToFirstVBase =
getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
llvm::Value *DoDstAdjustment = Builder.CreateSelect(
@@ -3266,17 +3291,17 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
// Recompose dst from the null struct and the adjusted fields from src.
llvm::Value *Dst;
- if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
+ if (inheritanceModelHasOnlyOneField(IsFunc, DstInheritance)) {
Dst = FirstField;
} else {
Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
unsigned Idx = 0;
Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
- if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
+ if (inheritanceModelHasNVOffsetField(IsFunc, DstInheritance))
Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
- if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
+ if (inheritanceModelHasVBPtrOffsetField(DstInheritance))
Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
- if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
+ if (inheritanceModelHasVBTableOffsetField(DstInheritance))
Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
}
return Dst;
@@ -3332,7 +3357,7 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
CGBuilderTy &Builder = CGF.Builder;
- MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
// Extract the fields we need, regardless of model. We'll apply them if we
// have them.
@@ -3344,11 +3369,11 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
// We need to extract values.
unsigned I = 0;
FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
- if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
+ if (inheritanceModelHasNVOffsetField(MPT, Inheritance))
NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
- if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+ if (inheritanceModelHasVBPtrOffsetField(Inheritance))
VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
- if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+ if (inheritanceModelHasVBTableOffsetField(Inheritance))
VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
}