@@ -15181,3 +15181,97 @@ bool ASTContext::useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
15181
15181
ThunksToBeAbbreviated[VirtualMethodDecl] = std::move(SimplifiedThunkNames);
15182
15182
return Result;
15183
15183
}
15184
+
15185
+ bool ASTContext::arePFPFieldsTriviallyRelocatable(const RecordDecl *RD) const {
15186
+ if (getLangOpts().getPointerFieldProtection() ==
15187
+ LangOptions::PointerFieldProtectionKind::Tagged)
15188
+ return !isa<CXXRecordDecl>(RD) ||
15189
+ cast<CXXRecordDecl>(RD)->hasTrivialDestructor();
15190
+ return true;
15191
+ }
15192
+
15193
+ bool ASTContext::isPFPStruct(const RecordDecl *rec) const {
15194
+ if (getLangOpts().getPointerFieldProtection() !=
15195
+ LangOptions::PointerFieldProtectionKind::None)
15196
+ if (auto *cxxRec = dyn_cast<CXXRecordDecl>(rec))
15197
+ return !cxxRec->isStandardLayout();
15198
+ return false;
15199
+ }
15200
+
15201
+ void ASTContext::findPFPFields(QualType Ty, CharUnits Offset,
15202
+ std::vector<PFPField> &Fields,
15203
+ bool IncludeVBases) const {
15204
+ if (auto *AT = getAsConstantArrayType(Ty)) {
15205
+ if (auto *ElemDecl = AT->getElementType()->getAsCXXRecordDecl()) {
15206
+ const ASTRecordLayout &ElemRL = getASTRecordLayout(ElemDecl);
15207
+ for (unsigned i = 0; i != AT->getSize(); ++i) {
15208
+ findPFPFields(AT->getElementType(), Offset + i * ElemRL.getSize(),
15209
+ Fields, true);
15210
+ }
15211
+ }
15212
+ }
15213
+ auto *Decl = Ty->getAsCXXRecordDecl();
15214
+ if (!Decl)
15215
+ return;
15216
+ const ASTRecordLayout &RL = getASTRecordLayout(Decl);
15217
+ for (FieldDecl *field : Decl->fields()) {
15218
+ CharUnits fieldOffset =
15219
+ Offset + toCharUnitsFromBits(RL.getFieldOffset(field->getFieldIndex()));
15220
+ if (isPFPField(field))
15221
+ Fields.push_back({fieldOffset, field});
15222
+ findPFPFields(field->getType(), fieldOffset, Fields, true);
15223
+ }
15224
+ for (auto &Base : Decl->bases()) {
15225
+ if (Base.isVirtual())
15226
+ continue;
15227
+ CharUnits BaseOffset =
15228
+ Offset + RL.getBaseClassOffset(Base.getType()->getAsCXXRecordDecl());
15229
+ findPFPFields(Base.getType(), BaseOffset, Fields, false);
15230
+ }
15231
+ if (IncludeVBases) {
15232
+ for (auto &Base : Decl->vbases()) {
15233
+ CharUnits BaseOffset =
15234
+ Offset + RL.getVBaseClassOffset(Base.getType()->getAsCXXRecordDecl());
15235
+ findPFPFields(Base.getType(), BaseOffset, Fields, false);
15236
+ }
15237
+ }
15238
+ }
15239
+
15240
+ bool ASTContext::hasPFPFields(QualType ty) const {
15241
+ std::vector<PFPField> pfpFields;
15242
+ findPFPFields(ty, CharUnits::Zero(), pfpFields, true);
15243
+ return !pfpFields.empty();
15244
+ }
15245
+
15246
+ bool ASTContext::isPFPField(const FieldDecl *field) const {
15247
+ if (!isPFPStruct(field->getParent()))
15248
+ return false;
15249
+ return field->getType()->isPointerType() &&
15250
+ !field->hasAttr<NoPointerFieldProtectionAttr>();
15251
+ }
15252
+
15253
+ void ASTContext::recordMemberDataPointerEvaluation(const ValueDecl *VD) {
15254
+ if (getLangOpts().getPointerFieldProtection() ==
15255
+ LangOptions::PointerFieldProtectionKind::None)
15256
+ return;
15257
+ auto *FD = dyn_cast<FieldDecl>(VD);
15258
+ if (!FD)
15259
+ FD = cast<FieldDecl>(cast<IndirectFieldDecl>(VD)->chain().back());
15260
+ if (!isPFPField(FD))
15261
+ return;
15262
+ PFPFieldsWithEvaluatedOffset.insert(FD);
15263
+ }
15264
+
15265
+ void ASTContext::recordOffsetOfEvaluation(const OffsetOfExpr *E) {
15266
+ if (getLangOpts().getPointerFieldProtection() ==
15267
+ LangOptions::PointerFieldProtectionKind::None ||
15268
+ E->getNumComponents() == 0)
15269
+ return;
15270
+ OffsetOfNode Comp = E->getComponent(E->getNumComponents() - 1);
15271
+ if (Comp.getKind() != OffsetOfNode::Field)
15272
+ return;
15273
+ FieldDecl *FD = Comp.getField();
15274
+ if (!isPFPField(FD))
15275
+ return;
15276
+ PFPFieldsWithEvaluatedOffset.insert(FD);
15277
+ }
0 commit comments