diff options
Diffstat (limited to 'clang/lib/AST/RecordLayout.cpp')
| -rw-r--r-- | clang/lib/AST/RecordLayout.cpp | 94 |
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 +} |
