1//===--- RecordLayoutUtils.cpp - Shared record layout queries -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/CodeGenUtils/RecordLayoutUtils.h"
10#include "clang/AST/RecordLayout.h"
11#include "clang/Basic/TargetInfo.h"
12
13namespace clang::CodeGenUtils {
14
15bool hasOwnStorage(const ASTContext &Ctx, const CXXRecordDecl *Decl,
16 const CXXRecordDecl *Query) {
17 const ASTRecordLayout &DeclLayout = Ctx.getASTRecordLayout(D: Decl);
18 if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query)
19 return false;
20 for (const auto &Base : Decl->bases())
21 if (!hasOwnStorage(Ctx, Decl: Base.getType()->getAsCXXRecordDecl(), Query))
22 return false;
23 return true;
24}
25
26bool isDiscreteBitFieldABI(const ASTContext &Ctx, const RecordDecl *RD) {
27 return Ctx.getTargetInfo().getCXXABI().isMicrosoft() || RD->isMsStruct(C: Ctx);
28}
29
30bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD) {
31 if (FD->isZeroLengthBitField())
32 return true;
33
34 if (FD->isUnnamedBitField())
35 return false;
36
37 return isEmptyRecordForLayout(Ctx, T: FD->getType());
38}
39
40bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T) {
41 const auto *RD = T->getAsRecordDecl();
42 if (!RD)
43 return false;
44
45 // If this is a C++ record, check the bases first.
46 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD)) {
47 if (CXXRD->isDynamicClass())
48 return false;
49
50 for (const auto &I : CXXRD->bases())
51 if (!isEmptyRecordForLayout(Ctx, T: I.getType()))
52 return false;
53 }
54
55 for (const auto *I : RD->fields())
56 if (!isEmptyFieldForLayout(Ctx, FD: I))
57 return false;
58
59 return true;
60}
61
62bool isOverlappingVBaseABI(const ASTContext &Ctx) {
63 return !Ctx.getTargetInfo().getCXXABI().isMicrosoft();
64}
65
66} // namespace clang::CodeGenUtils
67