RecordLayout.cpp 4.0 KB

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