RecordLayout.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #include "clang/AST/ASTContext.h"
  14. #include "clang/AST/RecordLayout.h"
  15. #include "clang/Basic/TargetInfo.h"
  16. using namespace clang;
  17. void ASTRecordLayout::Destroy(ASTContext &Ctx) {
  18. if (FieldOffsets)
  19. Ctx.Deallocate(FieldOffsets);
  20. if (CXXInfo) {
  21. CXXInfo->~CXXRecordLayoutInfo();
  22. Ctx.Deallocate(CXXInfo);
  23. }
  24. this->~ASTRecordLayout();
  25. Ctx.Deallocate(this);
  26. }
  27. ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
  28. CharUnits alignment,
  29. CharUnits requiredAlignment,
  30. CharUnits datasize,
  31. const uint64_t *fieldoffsets,
  32. unsigned fieldcount)
  33. : Size(size), DataSize(datasize), Alignment(alignment),
  34. RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
  35. FieldCount(fieldcount), CXXInfo(nullptr) {
  36. if (FieldCount > 0) {
  37. FieldOffsets = new (Ctx) uint64_t[FieldCount];
  38. memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  39. }
  40. }
  41. // Constructor for C++ records.
  42. ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
  43. CharUnits size, CharUnits alignment,
  44. CharUnits requiredAlignment,
  45. bool hasOwnVFPtr, bool hasExtendableVFPtr,
  46. CharUnits vbptroffset,
  47. CharUnits datasize,
  48. const uint64_t *fieldoffsets,
  49. unsigned fieldcount,
  50. CharUnits nonvirtualsize,
  51. CharUnits nonvirtualalignment,
  52. CharUnits SizeOfLargestEmptySubobject,
  53. const CXXRecordDecl *PrimaryBase,
  54. bool IsPrimaryBaseVirtual,
  55. const CXXRecordDecl *BaseSharingVBPtr,
  56. bool HasZeroSizedSubObject,
  57. bool LeadsWithZeroSizedBase,
  58. const BaseOffsetsMapTy& BaseOffsets,
  59. const VBaseOffsetsMapTy& VBaseOffsets)
  60. : Size(size), DataSize(datasize), Alignment(alignment),
  61. RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
  62. FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
  63. {
  64. if (FieldCount > 0) {
  65. FieldOffsets = new (Ctx) uint64_t[FieldCount];
  66. memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  67. }
  68. CXXInfo->PrimaryBase.setPointer(PrimaryBase);
  69. CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
  70. CXXInfo->NonVirtualSize = nonvirtualsize;
  71. CXXInfo->NonVirtualAlignment = nonvirtualalignment;
  72. CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
  73. CXXInfo->BaseOffsets = BaseOffsets;
  74. CXXInfo->VBaseOffsets = VBaseOffsets;
  75. CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
  76. CXXInfo->VBPtrOffset = vbptroffset;
  77. CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
  78. CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
  79. CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
  80. CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
  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. }