summaryrefslogtreecommitdiff
path: root/clang/lib/AST/RecordLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/RecordLayout.cpp')
-rw-r--r--clang/lib/AST/RecordLayout.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/clang/lib/AST/RecordLayout.cpp b/clang/lib/AST/RecordLayout.cpp
new file mode 100644
index 000000000000..e7b500e1902d
--- /dev/null
+++ b/clang/lib/AST/RecordLayout.cpp
@@ -0,0 +1,94 @@
+//===- RecordLayout.cpp - Layout information for a struct/union -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/TargetCXXABI.h"
+#include "clang/Basic/TargetInfo.h"
+#include <cassert>
+
+using namespace clang;
+
+void ASTRecordLayout::Destroy(ASTContext &Ctx) {
+ if (CXXInfo) {
+ CXXInfo->~CXXRecordLayoutInfo();
+ Ctx.Deallocate(CXXInfo);
+ }
+ this->~ASTRecordLayout();
+ Ctx.Deallocate(this);
+}
+
+ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
+ CharUnits alignment,
+ CharUnits unadjustedAlignment,
+ CharUnits requiredAlignment,
+ CharUnits datasize,
+ ArrayRef<uint64_t> fieldoffsets)
+ : Size(size), DataSize(datasize), Alignment(alignment),
+ UnadjustedAlignment(unadjustedAlignment),
+ RequiredAlignment(requiredAlignment) {
+ FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
+}
+
+// Constructor for C++ records.
+ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
+ CharUnits size, CharUnits alignment,
+ CharUnits unadjustedAlignment,
+ CharUnits requiredAlignment,
+ bool hasOwnVFPtr, bool hasExtendableVFPtr,
+ CharUnits vbptroffset,
+ CharUnits datasize,
+ ArrayRef<uint64_t> fieldoffsets,
+ CharUnits nonvirtualsize,
+ CharUnits nonvirtualalignment,
+ CharUnits SizeOfLargestEmptySubobject,
+ const CXXRecordDecl *PrimaryBase,
+ bool IsPrimaryBaseVirtual,
+ const CXXRecordDecl *BaseSharingVBPtr,
+ bool EndsWithZeroSizedObject,
+ bool LeadsWithZeroSizedBase,
+ const BaseOffsetsMapTy& BaseOffsets,
+ const VBaseOffsetsMapTy& VBaseOffsets)
+ : Size(size), DataSize(datasize), Alignment(alignment),
+ UnadjustedAlignment(unadjustedAlignment),
+ RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
+{
+ FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
+
+ CXXInfo->PrimaryBase.setPointer(PrimaryBase);
+ CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
+ CXXInfo->NonVirtualSize = nonvirtualsize;
+ CXXInfo->NonVirtualAlignment = nonvirtualalignment;
+ CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
+ CXXInfo->BaseOffsets = BaseOffsets;
+ CXXInfo->VBaseOffsets = VBaseOffsets;
+ CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
+ CXXInfo->VBPtrOffset = vbptroffset;
+ CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
+ CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
+ CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
+ CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
+
+#ifndef NDEBUG
+ if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
+ if (isPrimaryBaseVirtual()) {
+ if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
+ assert(getVBaseClassOffset(PrimaryBase).isZero() &&
+ "Primary virtual base must be at offset 0!");
+ }
+ } else {
+ assert(getBaseClassOffset(PrimaryBase).isZero() &&
+ "Primary base must be at offset 0!");
+ }
+ }
+#endif
+}