clang API Documentation

RecordLayout.cpp
Go to the documentation of this file.
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 }