15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//  This file defines the RecordLayout interface.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "clang/AST/ASTContext.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/AST/RecordLayout.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/Basic/TargetInfo.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using namespace clang;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ASTRecordLayout::Destroy(ASTContext &Ctx) {
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (FieldOffsets)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Ctx.Deallocate(FieldOffsets);
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (CXXInfo) {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CXXInfo->~CXXRecordLayoutInfo();
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Ctx.Deallocate(CXXInfo);
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  this->~ASTRecordLayout();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Ctx.Deallocate(this);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 CharUnits alignment,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CharUnits requiredAlignment,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CharUnits datasize,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const uint64_t *fieldoffsets,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 unsigned fieldcount)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  : Size(size), DataSize(datasize), Alignment(alignment),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FieldCount(fieldcount), CXXInfo(nullptr) {
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (FieldCount > 0)  {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FieldOffsets = new (Ctx) uint64_t[FieldCount];
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Constructor for C++ records.
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                 CharUnits size, CharUnits alignment,
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 CharUnits requiredAlignment,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool hasOwnVFPtr, bool hasExtendableVFPtr,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CharUnits vbptroffset,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CharUnits datasize,
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 const uint64_t *fieldoffsets,
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 unsigned fieldcount,
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 CharUnits nonvirtualsize,
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 CharUnits nonvirtualalignment,
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 CharUnits SizeOfLargestEmptySubobject,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const CXXRecordDecl *PrimaryBase,
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 bool IsPrimaryBaseVirtual,
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const CXXRecordDecl *BaseSharingVBPtr,
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 bool HasZeroSizedSubObject,
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 bool LeadsWithZeroSizedBase,
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 const BaseOffsetsMapTy& BaseOffsets,
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 const VBaseOffsetsMapTy& VBaseOffsets)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  : Size(size), DataSize(datasize), Alignment(alignment),
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (FieldCount > 0)  {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FieldOffsets = new (Ctx) uint64_t[FieldCount];
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CXXInfo->NonVirtualSize = nonvirtualsize;
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CXXInfo->NonVirtualAlignment = nonvirtualalignment;
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  CXXInfo->BaseOffsets = BaseOffsets;
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CXXInfo->VBaseOffsets = VBaseOffsets;
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CXXInfo->VBPtrOffset = vbptroffset;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (isPrimaryBaseVirtual()) {
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 "Primary virtual base must be at offset 0!");
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        assert(getBaseClassOffset(PrimaryBase).isZero() &&
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "Primary base must be at offset 0!");
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)