summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp5
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp20
2 files changed, 23 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 5a4b1188b7114..b6c2567bd5785 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2540,6 +2540,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// Spill the constant value to a global.
Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
getContext().getDeclAlign(VD));
+ llvm::Type *VarTy = getTypes().ConvertTypeForMem(VD->getType());
+ auto *PTy = llvm::PointerType::get(
+ VarTy, getContext().getTargetAddressSpace(VD->getType()));
+ if (PTy != Addr.getType())
+ Addr = Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, PTy);
} else {
// Should we be using the alignment of the constant pointer we emitted?
CharUnits Alignment =
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index ca06ad3f042bb..e02c9ae0b8f2b 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -617,6 +617,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;
@@ -2700,7 +2703,11 @@ 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)
offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
@@ -2724,8 +2731,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()) {