clang API Documentation
00001 //===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the RecordLayout interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/AST/ASTContext.h" 00015 #include "clang/AST/RecordLayout.h" 00016 #include "clang/Basic/TargetInfo.h" 00017 00018 using namespace clang; 00019 00020 void ASTRecordLayout::Destroy(ASTContext &Ctx) { 00021 if (FieldOffsets) 00022 Ctx.Deallocate(FieldOffsets); 00023 if (CXXInfo) { 00024 CXXInfo->~CXXRecordLayoutInfo(); 00025 Ctx.Deallocate(CXXInfo); 00026 } 00027 this->~ASTRecordLayout(); 00028 Ctx.Deallocate(this); 00029 } 00030 00031 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size, 00032 CharUnits alignment, 00033 CharUnits requiredAlignment, 00034 CharUnits datasize, 00035 const uint64_t *fieldoffsets, 00036 unsigned fieldcount) 00037 : Size(size), DataSize(datasize), Alignment(alignment), 00038 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr), 00039 FieldCount(fieldcount), CXXInfo(nullptr) { 00040 if (FieldCount > 0) { 00041 FieldOffsets = new (Ctx) uint64_t[FieldCount]; 00042 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 00043 } 00044 } 00045 00046 // Constructor for C++ records. 00047 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, 00048 CharUnits size, CharUnits alignment, 00049 CharUnits requiredAlignment, 00050 bool hasOwnVFPtr, bool hasExtendableVFPtr, 00051 CharUnits vbptroffset, 00052 CharUnits datasize, 00053 const uint64_t *fieldoffsets, 00054 unsigned fieldcount, 00055 CharUnits nonvirtualsize, 00056 CharUnits nonvirtualalignment, 00057 CharUnits SizeOfLargestEmptySubobject, 00058 const CXXRecordDecl *PrimaryBase, 00059 bool IsPrimaryBaseVirtual, 00060 const CXXRecordDecl *BaseSharingVBPtr, 00061 bool HasZeroSizedSubObject, 00062 bool LeadsWithZeroSizedBase, 00063 const BaseOffsetsMapTy& BaseOffsets, 00064 const VBaseOffsetsMapTy& VBaseOffsets) 00065 : Size(size), DataSize(datasize), Alignment(alignment), 00066 RequiredAlignment(requiredAlignment), FieldOffsets(nullptr), 00067 FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) 00068 { 00069 if (FieldCount > 0) { 00070 FieldOffsets = new (Ctx) uint64_t[FieldCount]; 00071 memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets)); 00072 } 00073 00074 CXXInfo->PrimaryBase.setPointer(PrimaryBase); 00075 CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual); 00076 CXXInfo->NonVirtualSize = nonvirtualsize; 00077 CXXInfo->NonVirtualAlignment = nonvirtualalignment; 00078 CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject; 00079 CXXInfo->BaseOffsets = BaseOffsets; 00080 CXXInfo->VBaseOffsets = VBaseOffsets; 00081 CXXInfo->HasOwnVFPtr = hasOwnVFPtr; 00082 CXXInfo->VBPtrOffset = vbptroffset; 00083 CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr; 00084 CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr; 00085 CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject; 00086 CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase; 00087 00088 00089 #ifndef NDEBUG 00090 if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) { 00091 if (isPrimaryBaseVirtual()) { 00092 if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) { 00093 assert(getVBaseClassOffset(PrimaryBase).isZero() && 00094 "Primary virtual base must be at offset 0!"); 00095 } 00096 } else { 00097 assert(getBaseClassOffset(PrimaryBase).isZero() && 00098 "Primary base must be at offset 0!"); 00099 } 00100 } 00101 #endif 00102 }