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     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                                  const uint64_t *fieldoffsets,
     36                                  unsigned fieldcount)
     37   : Size(size), DataSize(datasize), Alignment(alignment),
     38     RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
     39     FieldCount(fieldcount), CXXInfo(nullptr) {
     40   if (FieldCount > 0)  {
     41     FieldOffsets = new (Ctx) uint64_t[FieldCount];
     42     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
     43   }
     44 }
     45 
     46 // Constructor for C++ records.
     47 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
     48                                  CharUnits size, CharUnits alignment,
     49                                  CharUnits requiredAlignment,
     50                                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
     51                                  CharUnits vbptroffset,
     52                                  CharUnits datasize,
     53                                  const uint64_t *fieldoffsets,
     54                                  unsigned fieldcount,
     55                                  CharUnits nonvirtualsize,
     56                                  CharUnits nonvirtualalignment,
     57                                  CharUnits SizeOfLargestEmptySubobject,
     58                                  const CXXRecordDecl *PrimaryBase,
     59                                  bool IsPrimaryBaseVirtual,
     60                                  const CXXRecordDecl *BaseSharingVBPtr,
     61                                  bool HasZeroSizedSubObject,
     62                                  bool LeadsWithZeroSizedBase,
     63                                  const BaseOffsetsMapTy& BaseOffsets,
     64                                  const VBaseOffsetsMapTy& VBaseOffsets)
     65   : Size(size), DataSize(datasize), Alignment(alignment),
     66     RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
     67     FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
     68 {
     69   if (FieldCount > 0)  {
     70     FieldOffsets = new (Ctx) uint64_t[FieldCount];
     71     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
     72   }
     73 
     74   CXXInfo->PrimaryBase.setPointer(PrimaryBase);
     75   CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
     76   CXXInfo->NonVirtualSize = nonvirtualsize;
     77   CXXInfo->NonVirtualAlignment = nonvirtualalignment;
     78   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
     79   CXXInfo->BaseOffsets = BaseOffsets;
     80   CXXInfo->VBaseOffsets = VBaseOffsets;
     81   CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
     82   CXXInfo->VBPtrOffset = vbptroffset;
     83   CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
     84   CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
     85   CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
     86   CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
     87 
     88 
     89 #ifndef NDEBUG
     90     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
     91       if (isPrimaryBaseVirtual()) {
     92         if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
     93           assert(getVBaseClassOffset(PrimaryBase).isZero() &&
     94                  "Primary virtual base must be at offset 0!");
     95         }
     96       } else {
     97         assert(getBaseClassOffset(PrimaryBase).isZero() &&
     98                "Primary base must be at offset 0!");
     99       }
    100     }
    101 #endif
    102 }
    103