summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp1
-rw-r--r--clang/lib/AST/Decl.cpp3
-rw-r--r--clang/lib/AST/DeclCXX.cpp1
-rw-r--r--clang/lib/AST/Type.cpp32
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp7
-rw-r--r--clang/lib/CodeGen/CGNonTrivialStruct.cpp59
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp15
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp27
-rw-r--r--clang/lib/Sema/SemaDecl.cpp8
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp4
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp2
13 files changed, 131 insertions, 32 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index ac262e70629..6b9260d2d87 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1105,7 +1105,6 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
= FromData.HasConstexprNonCopyMoveConstructor;
ToData.HasDefaultedDefaultConstructor
= FromData.HasDefaultedDefaultConstructor;
- ToData.CanPassInRegisters = FromData.CanPassInRegisters;
ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index b640dccbd85..35364d6abcb 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3931,7 +3931,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
HasObjectMember(false), HasVolatileMember(false),
LoadedFieldsFromExternalStorage(false),
NonTrivialToPrimitiveDefaultInitialize(false),
- NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false) {
+ NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false),
+ CanPassInRegisters(true) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 487386fdb5d..271872352cd 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -93,7 +93,6 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false),
HasDefaultedDefaultConstructor(false),
- CanPassInRegisters(true),
DefaultedDefaultConstructorIsConstexpr(true),
HasConstexprDefaultConstructor(false),
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 99f5b1384ad..2985aac66b2 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2214,11 +2214,14 @@ QualType::isNonTrivialToPrimitiveDefaultInitialize() const {
if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize())
return PDIK_Struct;
- Qualifiers::ObjCLifetime Lifetime = getQualifiers().getObjCLifetime();
- if (Lifetime == Qualifiers::OCL_Strong)
+ switch (getQualifiers().getObjCLifetime()) {
+ case Qualifiers::OCL_Strong:
return PDIK_ARCStrong;
-
- return PDIK_Trivial;
+ case Qualifiers::OCL_Weak:
+ return PDIK_ARCWeak;
+ default:
+ return PDIK_Trivial;
+ }
}
QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const {
@@ -2228,10 +2231,14 @@ QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const {
return PCK_Struct;
Qualifiers Qs = getQualifiers();
- if (Qs.getObjCLifetime() == Qualifiers::OCL_Strong)
+ switch (Qs.getObjCLifetime()) {
+ case Qualifiers::OCL_Strong:
return PCK_ARCStrong;
-
- return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial;
+ case Qualifiers::OCL_Weak:
+ return PCK_ARCWeak;
+ default:
+ return Qs.hasVolatile() ? PCK_VolatileTrivial : PCK_Trivial;
+ }
}
QualType::PrimitiveCopyKind
@@ -2239,6 +2246,17 @@ QualType::isNonTrivialToPrimitiveDestructiveMove() const {
return isNonTrivialToPrimitiveCopy();
}
+bool QualType::canPassInRegisters() const {
+ if (const auto *RT =
+ getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
+ return RT->getDecl()->canPassInRegisters();
+
+ if (getQualifiers().getObjCLifetime() == Qualifiers::OCL_Weak)
+ return false;
+
+ return true;
+}
+
bool Type::isLiteralType(const ASTContext &Ctx) const {
if (isDependentType())
return false;
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 663f1d03fdc..1a6904976fb 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -1525,6 +1525,9 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
case QualType::PCK_Struct:
return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
BlockFieldFlags());
+ case QualType::PCK_ARCWeak:
+ // We need to register __weak direct captures with the runtime.
+ return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
case QualType::PCK_ARCStrong:
// We need to retain the copied value for __strong direct captures.
// If it's a block pointer, we have to copy the block and assign that to
@@ -1542,10 +1545,6 @@ computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
// Special rules for ARC captures:
Qualifiers QS = T.getQualifiers();
- // We need to register __weak direct captures with the runtime.
- if (QS.getObjCLifetime() == Qualifiers::OCL_Weak)
- return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
-
// Non-ARC captures of retainable pointers are strong and
// therefore require a call to _Block_object_assign.
if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount)
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
index 3b0b1731987..731938af867 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -77,6 +77,8 @@ struct DefaultInitializedTypeVisitor {
switch (PDIK) {
case QualType::PDIK_ARCStrong:
return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
+ case QualType::PDIK_ARCWeak:
+ return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
case QualType::PDIK_Struct:
return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
case QualType::PDIK_Trivial:
@@ -108,6 +110,8 @@ struct CopiedTypeVisitor {
switch (PCK) {
case QualType::PCK_ARCStrong:
return asDerived().visitARCStrong(FT, std::forward<Ts>(Args)...);
+ case QualType::PCK_ARCWeak:
+ return asDerived().visitARCWeak(FT, std::forward<Ts>(Args)...);
case QualType::PCK_Struct:
return asDerived().visitStruct(FT, std::forward<Ts>(Args)...);
case QualType::PCK_Trivial:
@@ -141,11 +145,6 @@ template <class Derived> struct StructVisitor {
template <class... Ts> void visitTrivial(Ts... Args) {}
- template <class... Ts> void visitARCWeak(Ts... Args) {
- // FIXME: remove this when visitARCWeak is implemented in the subclasses.
- llvm_unreachable("weak field is not expected");
- }
-
template <class... Ts> void visitCXXDestructor(Ts... Args) {
llvm_unreachable("field of a C++ struct type is not expected");
}
@@ -245,6 +244,13 @@ template <class Derived> struct GenFuncNameBase {
appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
}
+ void visitARCWeak(QualType FT, const FieldDecl *FD,
+ CharUnits CurStructOffset) {
+ appendStr("_w");
+ CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
+ appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
+ }
+
void visitStruct(QualType QT, const FieldDecl *FD,
CharUnits CurStructOffset) {
CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
@@ -615,6 +621,12 @@ struct GenDestructor : StructVisitor<GenDestructor>,
*CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
}
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 1> Addrs) {
+ CGF->destroyARCWeak(
+ *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ }
+
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 1> Addrs) {
CGF->callCStructDestructor(
@@ -636,6 +648,12 @@ struct GenDefaultInitialize
getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
}
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 1> Addrs) {
+ CGF->EmitNullInitialization(
+ getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ }
+
template <class FieldKind, size_t... Is>
void visitArray(FieldKind FK, QualType QT, const FieldDecl *FD,
CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
@@ -678,6 +696,14 @@ struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal);
CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true);
}
+
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
+ }
+
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
@@ -700,6 +726,14 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
/* isInitialization */ true);
}
+
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
+ }
+
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
@@ -720,6 +754,14 @@ struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
false);
}
+
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
+ }
+
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
CGF->callCStructCopyAssignmentOperator(
@@ -747,6 +789,13 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime);
}
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
+ }
+
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
CGF->callCStructMoveAssignmentOperator(
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index e812ef399e7..6ece1d3bd7e 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -2307,6 +2307,21 @@ void CodeGenFunction::EmitARCCopyWeak(Address dst, Address src) {
"objc_copyWeak");
}
+void CodeGenFunction::emitARCCopyAssignWeak(QualType Ty, Address DstAddr,
+ Address SrcAddr) {
+ llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr);
+ Object = EmitObjCConsumeObject(Ty, Object);
+ EmitARCStoreWeak(DstAddr, Object, false);
+}
+
+void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr,
+ Address SrcAddr) {
+ llvm::Value *Object = EmitARCLoadWeakRetained(SrcAddr);
+ Object = EmitObjCConsumeObject(Ty, Object);
+ EmitARCStoreWeak(DstAddr, Object, false);
+ EmitARCDestroyWeak(SrcAddr);
+}
+
/// Produce the code to do a objc_autoreleasepool_push.
/// call i8* \@objc_autoreleasePoolPush(void)
llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index fa65b1d699c..5852788e296 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3551,6 +3551,8 @@ public:
llvm::Value *EmitARCLoadWeak(Address addr);
llvm::Value *EmitARCLoadWeakRetained(Address addr);
llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored);
+ void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
+ void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
void EmitARCCopyWeak(Address dst, Address src);
void EmitARCMoveWeak(Address dst, Address src);
llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value);
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index aadbd3016bf..939679e7943 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -140,8 +140,11 @@ bool SwiftABIInfo::isLegalVectorTypeForSwift(CharUnits vectorSize,
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT,
CGCXXABI &CXXABI) {
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD)
+ if (!RD) {
+ if (!RT->getDecl()->canPassInRegisters())
+ return CGCXXABI::RAA_Indirect;
return CGCXXABI::RAA_Default;
+ }
return CXXABI.getRecordArgABI(RD);
}
@@ -153,6 +156,20 @@ static CGCXXABI::RecordArgABI getRecordArgABI(QualType T,
return getRecordArgABI(RT, CXXABI);
}
+static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
+ const ABIInfo &Info) {
+ QualType Ty = FI.getReturnType();
+
+ if (const auto *RT = Ty->getAs<RecordType>())
+ if (!isa<CXXRecordDecl>(RT->getDecl()) &&
+ !RT->getDecl()->canPassInRegisters()) {
+ FI.getReturnInfo() = Info.getNaturalAlignIndirect(Ty);
+ return true;
+ }
+
+ return CXXABI.classifyReturnType(FI);
+}
+
/// Pass transparent unions as if they were the type of the first element. Sema
/// should ensure that all elements of the union have the same "machine type".
static QualType useFirstFieldIfTransparentUnion(QualType Ty) {
@@ -1749,7 +1766,7 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
} else
State.FreeRegs = DefaultNumRegisterParameters;
- if (!getCXXABI().classifyReturnType(FI)) {
+ if (!::classifyReturnType(getCXXABI(), FI, *this)) {
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
} else if (FI.getReturnInfo().isIndirect()) {
// The C++ ABI is not aware of register usage, so we have to check if the
@@ -3545,7 +3562,7 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
unsigned FreeSSERegs = IsRegCall ? 16 : 8;
unsigned NeededInt, NeededSSE;
- if (!getCXXABI().classifyReturnType(FI)) {
+ if (!::classifyReturnType(getCXXABI(), FI, *this)) {
if (IsRegCall && FI.getReturnType()->getTypePtr()->isRecordType() &&
!FI.getReturnType()->getTypePtr()->isUnionType()) {
FI.getReturnInfo() =
@@ -4895,7 +4912,7 @@ private:
bool isIllegalVectorType(QualType Ty) const;
void computeInfo(CGFunctionInfo &FI) const override {
- if (!getCXXABI().classifyReturnType(FI))
+ if (!::classifyReturnType(getCXXABI(), FI, *this))
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
for (auto &it : FI.arguments())
@@ -5626,7 +5643,7 @@ void WindowsARMTargetCodeGenInfo::setTargetAttributes(
}
void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
- if (!getCXXABI().classifyReturnType(FI))
+ if (!::classifyReturnType(getCXXABI(), FI, *this))
FI.getReturnInfo() =
classifyReturnType(FI.getReturnType(), FI.isVariadic());
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ea971353039..6319e4b34ce 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15266,7 +15266,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// Get the type for the field.
const Type *FDTy = FD->getType().getTypePtr();
- Qualifiers QS = FD->getType().getQualifiers();
if (!FD->isAnonymousStructOrUnion()) {
// Remember all fields written by the user.
@@ -15407,10 +15406,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
- Record && !ObjCFieldLifetimeErrReported &&
- ((!getLangOpts().CPlusPlus &&
- QS.getObjCLifetime() == Qualifiers::OCL_Weak) ||
- Record->isUnion())) {
+ Record && !ObjCFieldLifetimeErrReported && Record->isUnion()) {
// It's an error in ARC or Weak if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
@@ -15456,6 +15452,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Record->setNonTrivialToPrimitiveCopy(true);
if (FT.isDestructedType())
Record->setNonTrivialToPrimitiveDestroy(true);
+ if (!FT.canPassInRegisters())
+ Record->setCanPassInRegisters(false);
}
if (Record && FD->getType().isVolatileQualified())
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index ab99a170799..733748c2932 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -742,6 +742,7 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) {
RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt());
RD->setNonTrivialToPrimitiveCopy(Record.readInt());
RD->setNonTrivialToPrimitiveDestroy(Record.readInt());
+ RD->setCanPassInRegisters(Record.readInt());
return Redecl;
}
@@ -1587,7 +1588,6 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasIrrelevantDestructor = Record.readInt();
Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
Data.HasDefaultedDefaultConstructor = Record.readInt();
- Data.CanPassInRegisters = Record.readInt();
Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
Data.HasConstexprDefaultConstructor = Record.readInt();
Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
@@ -1727,7 +1727,6 @@ void ASTDeclReader::MergeDefinitionData(
MATCH_FIELD(HasIrrelevantDestructor)
OR_FIELD(HasConstexprNonCopyMoveConstructor)
OR_FIELD(HasDefaultedDefaultConstructor)
- MATCH_FIELD(CanPassInRegisters)
MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
OR_FIELD(HasConstexprDefaultConstructor)
MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
@@ -4107,6 +4106,7 @@ void ASTDeclReader::UpdateDecl(Decl *D,
bool HadRealDefinition =
OldDD && (OldDD->Definition != RD ||
!Reader.PendingFakeDefinitionData.count(OldDD));
+ RD->setCanPassInRegisters(Record.readInt());
ReadCXXRecordDefinition(RD, /*Update*/true);
// Visible update is handled separately.
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index e63000c669a..a6412ed470a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5193,6 +5193,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
auto *RD = cast<CXXRecordDecl>(D);
UpdatedDeclContexts.insert(RD->getPrimaryContext());
+ Record.push_back(RD->canPassInRegisters());
Record.AddCXXDefinitionData(RD);
Record.AddOffset(WriteDeclContextLexicalBlock(
*Context, const_cast<CXXRecordDecl *>(RD)));
@@ -6020,7 +6021,6 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
Record->push_back(Data.HasIrrelevantDestructor);
Record->push_back(Data.HasConstexprNonCopyMoveConstructor);
Record->push_back(Data.HasDefaultedDefaultConstructor);
- Record->push_back(Data.CanPassInRegisters);
Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr);
Record->push_back(Data.HasConstexprDefaultConstructor);
Record->push_back(Data.HasNonLiteralTypeFieldsOrBases);
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index b3886b6555f..6a426036a26 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -468,6 +468,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
Record.push_back(D->isNonTrivialToPrimitiveCopy());
Record.push_back(D->isNonTrivialToPrimitiveDestroy());
+ Record.push_back(D->canPassInRegisters());
if (D->getDeclContext() == D->getLexicalDeclContext() &&
!D->hasAttrs() &&
@@ -1909,6 +1910,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
// isNonTrivialToPrimitiveDestroy
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // canPassInRegisters
// DC
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset
OpenPOWER on IntegriCloud