|
79 | 79 | #include "llvm/ADT/StringRef.h"
|
80 | 80 | #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
|
81 | 81 | #include "llvm/Support/Capacity.h"
|
| 82 | +#include "llvm/Support/CommandLine.h" |
82 | 83 | #include "llvm/Support/Compiler.h"
|
83 | 84 | #include "llvm/Support/ErrorHandling.h"
|
84 | 85 | #include "llvm/Support/MD5.h"
|
@@ -14948,3 +14949,97 @@ bool ASTContext::useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
|
14948 | 14949 | ThunksToBeAbbreviated[VirtualMethodDecl] = std::move(SimplifiedThunkNames);
|
14949 | 14950 | return Result;
|
14950 | 14951 | }
|
| 14952 | + |
| 14953 | +bool ASTContext::arePFPFieldsTriviallyRelocatable(const RecordDecl *RD) const { |
| 14954 | + if (getLangOpts().getPointerFieldProtection() == |
| 14955 | + LangOptions::PointerFieldProtectionKind::Tagged) |
| 14956 | + return !isa<CXXRecordDecl>(RD) || |
| 14957 | + cast<CXXRecordDecl>(RD)->hasTrivialDestructor(); |
| 14958 | + return true; |
| 14959 | +} |
| 14960 | + |
| 14961 | +bool ASTContext::isPFPStruct(const RecordDecl *rec) const { |
| 14962 | + if (getLangOpts().getPointerFieldProtection() != |
| 14963 | + LangOptions::PointerFieldProtectionKind::None) |
| 14964 | + if (auto *cxxRec = dyn_cast<CXXRecordDecl>(rec)) |
| 14965 | + return !cxxRec->isStandardLayout(); |
| 14966 | + return false; |
| 14967 | +} |
| 14968 | + |
| 14969 | +void ASTContext::findPFPFields(QualType Ty, CharUnits Offset, |
| 14970 | + std::vector<PFPField> &Fields, |
| 14971 | + bool IncludeVBases) const { |
| 14972 | + if (auto *AT = getAsConstantArrayType(Ty)) { |
| 14973 | + if (auto *ElemDecl = AT->getElementType()->getAsCXXRecordDecl()) { |
| 14974 | + const ASTRecordLayout &ElemRL = getASTRecordLayout(ElemDecl); |
| 14975 | + for (unsigned i = 0; i != AT->getSize(); ++i) { |
| 14976 | + findPFPFields(AT->getElementType(), Offset + i * ElemRL.getSize(), |
| 14977 | + Fields, true); |
| 14978 | + } |
| 14979 | + } |
| 14980 | + } |
| 14981 | + auto *Decl = Ty->getAsCXXRecordDecl(); |
| 14982 | + if (!Decl) |
| 14983 | + return; |
| 14984 | + const ASTRecordLayout &RL = getASTRecordLayout(Decl); |
| 14985 | + for (FieldDecl *field : Decl->fields()) { |
| 14986 | + CharUnits fieldOffset = |
| 14987 | + Offset + toCharUnitsFromBits(RL.getFieldOffset(field->getFieldIndex())); |
| 14988 | + if (isPFPField(field)) |
| 14989 | + Fields.push_back({Offset, fieldOffset, field}); |
| 14990 | + findPFPFields(field->getType(), fieldOffset, Fields, true); |
| 14991 | + } |
| 14992 | + for (auto &Base : Decl->bases()) { |
| 14993 | + if (Base.isVirtual()) |
| 14994 | + continue; |
| 14995 | + CharUnits BaseOffset = |
| 14996 | + Offset + RL.getBaseClassOffset(Base.getType()->getAsCXXRecordDecl()); |
| 14997 | + findPFPFields(Base.getType(), BaseOffset, Fields, false); |
| 14998 | + } |
| 14999 | + if (IncludeVBases) { |
| 15000 | + for (auto &Base : Decl->vbases()) { |
| 15001 | + CharUnits BaseOffset = |
| 15002 | + Offset + RL.getVBaseClassOffset(Base.getType()->getAsCXXRecordDecl()); |
| 15003 | + findPFPFields(Base.getType(), BaseOffset, Fields, false); |
| 15004 | + } |
| 15005 | + } |
| 15006 | +} |
| 15007 | + |
| 15008 | +bool ASTContext::hasPFPFields(QualType ty) const { |
| 15009 | + std::vector<PFPField> pfpFields; |
| 15010 | + findPFPFields(ty, CharUnits::Zero(), pfpFields, true); |
| 15011 | + return !pfpFields.empty(); |
| 15012 | +} |
| 15013 | + |
| 15014 | +bool ASTContext::isPFPField(const FieldDecl *field) const { |
| 15015 | + if (!isPFPStruct(field->getParent())) |
| 15016 | + return false; |
| 15017 | + return field->getType()->isPointerType() && |
| 15018 | + !field->hasAttr<NoPointerFieldProtectionAttr>(); |
| 15019 | +} |
| 15020 | + |
| 15021 | +void ASTContext::recordMemberDataPointerEvaluation(const ValueDecl *VD) { |
| 15022 | + if (getLangOpts().getPointerFieldProtection() == |
| 15023 | + LangOptions::PointerFieldProtectionKind::None) |
| 15024 | + return; |
| 15025 | + auto *FD = dyn_cast<FieldDecl>(VD); |
| 15026 | + if (!FD) |
| 15027 | + FD = cast<FieldDecl>(cast<IndirectFieldDecl>(VD)->chain().back()); |
| 15028 | + if (!isPFPField(FD)) |
| 15029 | + return; |
| 15030 | + PFPFieldsWithEvaluatedOffset.insert(FD); |
| 15031 | +} |
| 15032 | + |
| 15033 | +void ASTContext::recordOffsetOfEvaluation(const OffsetOfExpr *E) { |
| 15034 | + if (getLangOpts().getPointerFieldProtection() == |
| 15035 | + LangOptions::PointerFieldProtectionKind::None || |
| 15036 | + E->getNumComponents() == 0) |
| 15037 | + return; |
| 15038 | + OffsetOfNode Comp = E->getComponent(E->getNumComponents() - 1); |
| 15039 | + if (Comp.getKind() != OffsetOfNode::Field) |
| 15040 | + return; |
| 15041 | + FieldDecl *FD = Comp.getField(); |
| 15042 | + if (!isPFPField(FD)) |
| 15043 | + return; |
| 15044 | + PFPFieldsWithEvaluatedOffset.insert(FD); |
| 15045 | +} |
0 commit comments