summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenTBAA.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-14 18:50:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-07-14 18:50:02 +0000
commit1f917f69ff07f09b6dbb670971f57f8efe718b84 (patch)
tree99293cbc1411737cd995dac10a99b2c40ef0944c /clang/lib/CodeGen/CodeGenTBAA.cpp
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
Vendor import of llvm-project main llvmorg-15-init-16436-g18a6ab5b8d1f.vendor/llvm-project/llvmorg-15-init-16436-g18a6ab5b8d1f
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTBAA.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenTBAA.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 95763d8e18b7..0cb63fbbe9e5 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -335,7 +335,42 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
const RecordDecl *RD = TTy->getDecl()->getDefinition();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- SmallVector<llvm::MDBuilder::TBAAStructField, 4> Fields;
+ using TBAAStructField = llvm::MDBuilder::TBAAStructField;
+ SmallVector<TBAAStructField, 4> Fields;
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ // Handle C++ base classes. Non-virtual bases can treated a a kind of
+ // field. Virtual bases are more complex and omitted, but avoid an
+ // incomplete view for NewStructPathTBAA.
+ if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
+ return BaseTypeMetadataCache[Ty] = nullptr;
+ for (const CXXBaseSpecifier &B : CXXRD->bases()) {
+ if (B.isVirtual())
+ continue;
+ QualType BaseQTy = B.getType();
+ const CXXRecordDecl *BaseRD = BaseQTy->getAsCXXRecordDecl();
+ if (BaseRD->isEmpty())
+ continue;
+ llvm::MDNode *TypeNode = isValidBaseType(BaseQTy)
+ ? getBaseTypeInfo(BaseQTy)
+ : getTypeInfo(BaseQTy);
+ if (!TypeNode)
+ return BaseTypeMetadataCache[Ty] = nullptr;
+ uint64_t Offset = Layout.getBaseClassOffset(BaseRD).getQuantity();
+ uint64_t Size =
+ Context.getASTRecordLayout(BaseRD).getDataSize().getQuantity();
+ Fields.push_back(
+ llvm::MDBuilder::TBAAStructField(Offset, Size, TypeNode));
+ }
+ // The order in which base class subobjects are allocated is unspecified,
+ // so may differ from declaration order. In particular, Itanium ABI will
+ // allocate a primary base first.
+ // Since we exclude empty subobjects, the objects are not overlapping and
+ // their offsets are unique.
+ llvm::sort(Fields,
+ [](const TBAAStructField &A, const TBAAStructField &B) {
+ return A.Offset < B.Offset;
+ });
+ }
for (FieldDecl *Field : RD->fields()) {
if (Field->isZeroSize(Context) || Field->isUnnamedBitfield())
continue;