diff options
Diffstat (limited to 'clang/lib/AST/RecordLayout.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayout.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/clang/lib/AST/RecordLayout.cpp b/clang/lib/AST/RecordLayout.cpp new file mode 100644 index 0000000..0114eba --- /dev/null +++ b/clang/lib/AST/RecordLayout.cpp @@ -0,0 +1,89 @@ +//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the RecordLayout interface. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" +#include "clang/Basic/TargetInfo.h" + +using namespace clang; + +void ASTRecordLayout::Destroy(ASTContext &Ctx) { + if (FieldOffsets) + Ctx.Deallocate(FieldOffsets); + if (CXXInfo) { + Ctx.Deallocate(CXXInfo); + CXXInfo->~CXXRecordLayoutInfo(); + } + this->~ASTRecordLayout(); + Ctx.Deallocate(this); +} + +ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, + CharUnits alignment, CharUnits datasize, + const uint64_t *fieldoffsets, + unsigned fieldcount) + : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), + FieldCount(fieldcount), CXXInfo(0) { + if (FieldCount > 0) { + FieldOffsets = new (Ctx) uint64_t[FieldCount]; + memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); + } +} + +// Constructor for C++ records. +ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, + CharUnits size, CharUnits alignment, + CharUnits vfptroffset, CharUnits vbptroffset, + CharUnits datasize, + const uint64_t *fieldoffsets, + unsigned fieldcount, + CharUnits nonvirtualsize, + CharUnits nonvirtualalign, + CharUnits SizeOfLargestEmptySubobject, + const CXXRecordDecl *PrimaryBase, + bool IsPrimaryBaseVirtual, + const BaseOffsetsMapTy& BaseOffsets, + const BaseOffsetsMapTy& VBaseOffsets) + : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), + FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) +{ + if (FieldCount > 0) { + FieldOffsets = new (Ctx) uint64_t[FieldCount]; + memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); + } + + CXXInfo->PrimaryBase.setPointer(PrimaryBase); + CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); + CXXInfo->NonVirtualSize = nonvirtualsize; + CXXInfo->NonVirtualAlign = nonvirtualalign; + CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; + CXXInfo->BaseOffsets = BaseOffsets; + CXXInfo->VBaseOffsets = VBaseOffsets; + CXXInfo->VFPtrOffset = vfptroffset; + CXXInfo->VBPtrOffset = vbptroffset; + +#ifndef NDEBUG + if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { + if (isPrimaryBaseVirtual()) { + // Microsoft ABI doesn't have primary virtual base + if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) { + assert(getVBaseClassOffset(PrimaryBase).isZero() && + "Primary virtual base must be at offset 0!"); + } + } else { + assert(getBaseClassOffsetInBits(PrimaryBase) == 0 && + "Primary base must be at offset 0!"); + } + } +#endif +} |