| //===-- 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), Alignment(alignment), FieldOffsets(0), |
| 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, |
| bool hasOwnVFPtr, bool hasVFPtr, |
| bool hasOwnVBPtr, |
| CharUnits vbptroffset, |
| CharUnits datasize, |
| const uint64_t *fieldoffsets, |
| unsigned fieldcount, |
| CharUnits nonvirtualsize, |
| CharUnits nonvirtualalign, |
| CharUnits SizeOfLargestEmptySubobject, |
| const CXXRecordDecl *PrimaryBase, |
| bool IsPrimaryBaseVirtual, |
| bool AlignAfterVBases, |
| const BaseOffsetsMapTy& BaseOffsets, |
| const VBaseOffsetsMapTy& VBaseOffsets) |
| : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0), |
| 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->HasOwnVFPtr = hasOwnVFPtr; |
| CXXInfo->VBPtrOffset = vbptroffset; |
| CXXInfo->HasVFPtr = hasVFPtr; |
| CXXInfo->HasOwnVBPtr = hasOwnVBPtr; |
| CXXInfo->AlignAfterVBases = AlignAfterVBases; |
| |
| |
| #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 |
| } |