1 //===- RecordLayout.cpp - Layout information for a struct/union -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the RecordLayout interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/RecordLayout.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/Basic/TargetCXXABI.h" 17 #include "clang/Basic/TargetInfo.h" 18 #include <cassert> 19 20 using namespace clang; 21 22 void ASTRecordLayout::Destroy(ASTContext &Ctx) { 23 if (CXXInfo) { 24 CXXInfo->~CXXRecordLayoutInfo(); 25 Ctx.Deallocate(CXXInfo); 26 } 27 this->~ASTRecordLayout(); 28 Ctx.Deallocate(this); 29 } 30 31 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 32 CharUnits alignment, 33 CharUnits requiredAlignment, 34 CharUnits datasize, 35 ArrayRef<uint64_t> fieldoffsets) 36 : Size(size), DataSize(datasize), Alignment(alignment), 37 RequiredAlignment(requiredAlignment) { 38 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 39 } 40 41 // Constructor for C++ records. 42 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 43 CharUnits size, CharUnits alignment, 44 CharUnits requiredAlignment, 45 bool hasOwnVFPtr, bool hasExtendableVFPtr, 46 CharUnits vbptroffset, 47 CharUnits datasize, 48 ArrayRef<uint64_t> fieldoffsets, 49 CharUnits nonvirtualsize, 50 CharUnits nonvirtualalignment, 51 CharUnits SizeOfLargestEmptySubobject, 52 const CXXRecordDecl *PrimaryBase, 53 bool IsPrimaryBaseVirtual, 54 const CXXRecordDecl *BaseSharingVBPtr, 55 bool EndsWithZeroSizedObject, 56 bool LeadsWithZeroSizedBase, 57 const BaseOffsetsMapTy& BaseOffsets, 58 const VBaseOffsetsMapTy& VBaseOffsets) 59 : Size(size), DataSize(datasize), Alignment(alignment), 60 RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 61 { 62 FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end()); 63 64 CXXInfo->PrimaryBase.setPointer(PrimaryBase); 65 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 66 CXXInfo->NonVirtualSize = nonvirtualsize; 67 CXXInfo->NonVirtualAlignment = nonvirtualalignment; 68 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 69 CXXInfo->BaseOffsets = BaseOffsets; 70 CXXInfo->VBaseOffsets = VBaseOffsets; 71 CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 72 CXXInfo->VBPtrOffset = vbptroffset; 73 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 74 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 75 CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject; 76 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; 77 78 #ifndef NDEBUG 79 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 80 if (isPrimaryBaseVirtual()) { 81 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 82 assert(getVBaseClassOffset(PrimaryBase).isZero() && 83 "Primary virtual base must be at offset 0!"); 84 } 85 } else { 86 assert(getBaseClassOffset(PrimaryBase).isZero() && 87 "Primary base must be at offset 0!"); 88 } 89 } 90 #endif 91 } 92