Home | History | Annotate | Download | only in AST
      1 //===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
      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/ASTContext.h"
     15 #include "clang/AST/RecordLayout.h"
     16 #include "clang/Basic/TargetInfo.h"
     17 
     18 using namespace clang;
     19 
     20 void ASTRecordLayout::Destroy(ASTContext &Ctx) {
     21   if (FieldOffsets)
     22     Ctx.Deallocate(FieldOffsets);
     23   if (CXXInfo) {
     24     Ctx.Deallocate(CXXInfo);
     25     CXXInfo->~CXXRecordLayoutInfo();
     26   }
     27   this->~ASTRecordLayout();
     28   Ctx.Deallocate(this);
     29 }
     30 
     31 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
     32                                  CharUnits alignment, CharUnits datasize,
     33                                  const uint64_t *fieldoffsets,
     34                                  unsigned fieldcount)
     35   : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
     36     FieldCount(fieldcount), CXXInfo(0) {
     37   if (FieldCount > 0)  {
     38     FieldOffsets = new (Ctx) uint64_t[FieldCount];
     39     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
     40   }
     41 }
     42 
     43 // Constructor for C++ records.
     44 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
     45                                  CharUnits size, CharUnits alignment,
     46                                  bool hasOwnVFPtr, CharUnits vbptroffset,
     47                                  CharUnits datasize,
     48                                  const uint64_t *fieldoffsets,
     49                                  unsigned fieldcount,
     50                                  CharUnits nonvirtualsize,
     51                                  CharUnits nonvirtualalign,
     52                                  CharUnits SizeOfLargestEmptySubobject,
     53                                  const CXXRecordDecl *PrimaryBase,
     54                                  bool IsPrimaryBaseVirtual,
     55                                  const BaseOffsetsMapTy& BaseOffsets,
     56                                  const VBaseOffsetsMapTy& VBaseOffsets)
     57   : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
     58     FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
     59 {
     60   if (FieldCount > 0)  {
     61     FieldOffsets = new (Ctx) uint64_t[FieldCount];
     62     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
     63   }
     64 
     65   CXXInfo->PrimaryBase.setPointer(PrimaryBase);
     66   CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
     67   CXXInfo->NonVirtualSize = nonvirtualsize;
     68   CXXInfo->NonVirtualAlign = nonvirtualalign;
     69   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
     70   CXXInfo->BaseOffsets = BaseOffsets;
     71   CXXInfo->VBaseOffsets = VBaseOffsets;
     72   CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
     73   CXXInfo->VBPtrOffset = vbptroffset;
     74 
     75 #ifndef NDEBUG
     76     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
     77       if (isPrimaryBaseVirtual()) {
     78         if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
     79           assert(getVBaseClassOffset(PrimaryBase).isZero() &&
     80                  "Primary virtual base must be at offset 0!");
     81         }
     82       } else {
     83         assert(getBaseClassOffset(PrimaryBase).isZero() &&
     84                "Primary base must be at offset 0!");
     85       }
     86     }
     87 #endif
     88 }
     89