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 (CXXInfo) {
     22     CXXInfo->~CXXRecordLayoutInfo();
     23     Ctx.Deallocate(CXXInfo);
     24   }
     25   this->~ASTRecordLayout();
     26   Ctx.Deallocate(this);
     27 }
     28 
     29 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
     30                                  CharUnits alignment,
     31                                  CharUnits requiredAlignment,
     32                                  CharUnits datasize,
     33                                  ArrayRef<uint64_t> fieldoffsets)
     34     : Size(size), DataSize(datasize), Alignment(alignment),
     35       RequiredAlignment(requiredAlignment), CXXInfo(nullptr) {
     36   FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
     37 }
     38 
     39 // Constructor for C++ records.
     40 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
     41                                  CharUnits size, CharUnits alignment,
     42                                  CharUnits requiredAlignment,
     43                                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
     44                                  CharUnits vbptroffset,
     45                                  CharUnits datasize,
     46                                  ArrayRef<uint64_t> fieldoffsets,
     47                                  CharUnits nonvirtualsize,
     48                                  CharUnits nonvirtualalignment,
     49                                  CharUnits SizeOfLargestEmptySubobject,
     50                                  const CXXRecordDecl *PrimaryBase,
     51                                  bool IsPrimaryBaseVirtual,
     52                                  const CXXRecordDecl *BaseSharingVBPtr,
     53                                  bool EndsWithZeroSizedObject,
     54                                  bool LeadsWithZeroSizedBase,
     55                                  const BaseOffsetsMapTy& BaseOffsets,
     56                                  const VBaseOffsetsMapTy& VBaseOffsets)
     57   : Size(size), DataSize(datasize), Alignment(alignment),
     58     RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
     59 {
     60   FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
     61 
     62   CXXInfo->PrimaryBase.setPointer(PrimaryBase);
     63   CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
     64   CXXInfo->NonVirtualSize = nonvirtualsize;
     65   CXXInfo->NonVirtualAlignment = nonvirtualalignment;
     66   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
     67   CXXInfo->BaseOffsets = BaseOffsets;
     68   CXXInfo->VBaseOffsets = VBaseOffsets;
     69   CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
     70   CXXInfo->VBPtrOffset = vbptroffset;
     71   CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
     72   CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
     73   CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
     74   CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
     75 
     76 
     77 #ifndef NDEBUG
     78     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
     79       if (isPrimaryBaseVirtual()) {
     80         if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
     81           assert(getVBaseClassOffset(PrimaryBase).isZero() &&
     82                  "Primary virtual base must be at offset 0!");
     83         }
     84       } else {
     85         assert(getBaseClassOffset(PrimaryBase).isZero() &&
     86                "Primary base must be at offset 0!");
     87       }
     88     }
     89 #endif
     90 }
     91