]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/AST/RecordLayout.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / AST / RecordLayout.cpp
1 //===- RecordLayout.cpp - Layout information for a struct/union -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file defines the RecordLayout interface.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/AST/RecordLayout.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/Basic/TargetCXXABI.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include <cassert>
18
19 using namespace clang;
20
21 void ASTRecordLayout::Destroy(ASTContext &Ctx) {
22   if (CXXInfo) {
23     CXXInfo->~CXXRecordLayoutInfo();
24     Ctx.Deallocate(CXXInfo);
25   }
26   this->~ASTRecordLayout();
27   Ctx.Deallocate(this);
28 }
29
30 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
31                                  CharUnits alignment,
32                                  CharUnits unadjustedAlignment,
33                                  CharUnits requiredAlignment,
34                                  CharUnits datasize,
35                                  ArrayRef<uint64_t> fieldoffsets)
36     : Size(size), DataSize(datasize), Alignment(alignment),
37       UnadjustedAlignment(unadjustedAlignment),
38       RequiredAlignment(requiredAlignment) {
39   FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
40 }
41
42 // Constructor for C++ records.
43 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
44                                  CharUnits size, CharUnits alignment,
45                                  CharUnits unadjustedAlignment,
46                                  CharUnits requiredAlignment,
47                                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
48                                  CharUnits vbptroffset,
49                                  CharUnits datasize,
50                                  ArrayRef<uint64_t> fieldoffsets,
51                                  CharUnits nonvirtualsize,
52                                  CharUnits nonvirtualalignment,
53                                  CharUnits SizeOfLargestEmptySubobject,
54                                  const CXXRecordDecl *PrimaryBase,
55                                  bool IsPrimaryBaseVirtual,
56                                  const CXXRecordDecl *BaseSharingVBPtr,
57                                  bool EndsWithZeroSizedObject,
58                                  bool LeadsWithZeroSizedBase,
59                                  const BaseOffsetsMapTy& BaseOffsets,
60                                  const VBaseOffsetsMapTy& VBaseOffsets)
61   : Size(size), DataSize(datasize), Alignment(alignment),
62     UnadjustedAlignment(unadjustedAlignment),
63     RequiredAlignment(requiredAlignment), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
64 {
65   FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
66
67   CXXInfo->PrimaryBase.setPointer(PrimaryBase);
68   CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
69   CXXInfo->NonVirtualSize = nonvirtualsize;
70   CXXInfo->NonVirtualAlignment = nonvirtualalignment;
71   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
72   CXXInfo->BaseOffsets = BaseOffsets;
73   CXXInfo->VBaseOffsets = VBaseOffsets;
74   CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
75   CXXInfo->VBPtrOffset = vbptroffset;
76   CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
77   CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
78   CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
79   CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
80
81 #ifndef NDEBUG
82     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
83       if (isPrimaryBaseVirtual()) {
84         if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
85           assert(getVBaseClassOffset(PrimaryBase).isZero() &&
86                  "Primary virtual base must be at offset 0!");
87         }
88       } else {
89         assert(getBaseClassOffset(PrimaryBase).isZero() &&
90                "Primary base must be at offset 0!");
91       }
92     }
93 #endif
94 }