A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/RecordLayoutBuilder_8cpp_source.html below:

clang: lib/AST/RecordLayoutBuilder.cpp Source File

20#include "llvm/Support/Format.h" 21#include "llvm/Support/MathExtras.h" 23using namespace clang

;

38struct

BaseSubobjectInfo {

50

BaseSubobjectInfo *PrimaryVirtualBaseInfo;

53 const

BaseSubobjectInfo *Derived;

59struct

ExternalLayout {

60

ExternalLayout() =

default

;

69

llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsets;

72

llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsets;

75

llvm::DenseMap<const CXXRecordDecl *, CharUnits> VirtualBaseOffsets;

80

assert(FieldOffsets.count(FD) &&

81 "Field does not have an external offset"

);

82 return

FieldOffsets[FD];

86 auto

Known = BaseOffsets.find(RD);

87 if

(Known == BaseOffsets.end())

89

BaseOffset = Known->second;

94 auto

Known = VirtualBaseOffsets.find(RD);

95 if

(Known == VirtualBaseOffsets.end())

97

BaseOffset = Known->second;

104class

EmptySubobjectMap {

112 typedef

llvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy;

113 typedef

llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy;

114

EmptyClassOffsetsMapTy EmptyClassOffsets;

122 void

ComputeEmptySubobjectSizes();

126 void

UpdateEmptyBaseSubobjects(

const

BaseSubobjectInfo *Info,

127 CharUnits

Offset,

bool

PlacingEmptyBase);

131 bool

PlacingOverlappingField);

133 bool

PlacingOverlappingField);

137 bool

AnyEmptySubobjectsBeyondOffset(

CharUnits

Offset)

const

{

138 return

Offset <= MaxEmptyClassOffset;

144

assert(FieldOffset % CharWidth == 0 &&

145 "Field offset not at char boundary!"

);

154 bool

CanPlaceBaseSubobjectAtOffset(

const

BaseSubobjectInfo *Info,

157 bool

CanPlaceFieldSubobjectAtOffset(

const CXXRecordDecl

*RD,

160 bool

CanPlaceFieldSubobjectAtOffset(

const FieldDecl

*FD,

171

ComputeEmptySubobjectSizes();

178 bool

CanPlaceBaseAtOffset(

const

BaseSubobjectInfo *Info,

186void

EmptySubobjectMap::ComputeEmptySubobjectSizes() {

195

EmptySize = Layout.

getSize

();

201 if

(EmptySize > SizeOfLargestEmptySubobject)

202

SizeOfLargestEmptySubobject = EmptySize;

219

EmptySize = Layout.

getSize

();

225 if

(EmptySize > SizeOfLargestEmptySubobject)

226

SizeOfLargestEmptySubobject = EmptySize;

231

EmptySubobjectMap::CanPlaceSubobjectAtOffset(

const CXXRecordDecl

*RD,

237

EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);

238 if

(I == EmptyClassOffsets.end())

241 const

ClassVectorTy &Classes = I->second;

242 if

(!llvm::is_contained(Classes, RD))

249void

EmptySubobjectMap::AddSubobjectAtOffset(

const CXXRecordDecl

*RD,

257

ClassVectorTy &Classes = EmptyClassOffsets[Offset];

258 if

(llvm::is_contained(Classes, RD))

261

Classes.push_back(RD);

264 if

(Offset > MaxEmptyClassOffset)

265

MaxEmptyClassOffset = Offset;

269

EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(

const

BaseSubobjectInfo *Info,

273 if

(!AnyEmptySubobjectsBeyondOffset(Offset))

276 if

(!CanPlaceSubobjectAtOffset(Info->Class, Offset))

281 for

(

const

BaseSubobjectInfo *

Base

: Info->Bases) {

282 if

(

Base

->IsVirtual)

287 if

(!CanPlaceBaseSubobjectAtOffset(

Base

, BaseOffset))

291 if

(Info->PrimaryVirtualBaseInfo) {

292

BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;

294 if

(Info == PrimaryVirtualBaseInfo->Derived) {

295 if

(!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset))

301 for

(

const FieldDecl

*Field : Info->Class->fields()) {

302 if

(

Field

->isBitField())

306 if

(!CanPlaceFieldSubobjectAtOffset(Field, FieldOffset))

313void

EmptySubobjectMap::UpdateEmptyBaseSubobjects(

const

BaseSubobjectInfo *Info,

315 bool

PlacingEmptyBase) {

316 if

(!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {

325

AddSubobjectAtOffset(Info->Class, Offset);

329 for

(

const

BaseSubobjectInfo *

Base

: Info->Bases) {

330 if

(

Base

->IsVirtual)

334

UpdateEmptyBaseSubobjects(

Base

, BaseOffset, PlacingEmptyBase);

337 if

(Info->PrimaryVirtualBaseInfo) {

338

BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;

340 if

(Info == PrimaryVirtualBaseInfo->Derived)

341

UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,

346 for

(

const FieldDecl

*Field : Info->Class->fields()) {

347 if

(

Field

->isBitField())

351

UpdateEmptyFieldSubobjects(Field, FieldOffset, PlacingEmptyBase);

355bool

EmptySubobjectMap::CanPlaceBaseAtOffset(

const

BaseSubobjectInfo *Info,

359 if

(SizeOfLargestEmptySubobject.isZero())

362 if

(!CanPlaceBaseSubobjectAtOffset(Info, Offset))

367

UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());

372

EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(

const CXXRecordDecl

*RD,

377 if

(!AnyEmptySubobjectsBeyondOffset(Offset))

380 if

(!CanPlaceSubobjectAtOffset(RD, Offset))

387 if

(

Base

.isVirtual())

393 if

(!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))

403 if

(!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))

410 if

(

Field

->isBitField())

414 if

(!CanPlaceFieldSubobjectAtOffset(Field, FieldOffset))

422

EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(

const FieldDecl

*FD,

426 if

(!AnyEmptySubobjectsBeyondOffset(Offset))

431 return

CanPlaceFieldSubobjectAtOffset(RD, RD, Offset);

445 for

(uint64_t I = 0; I != NumElements; ++I) {

448 if

(!AnyEmptySubobjectsBeyondOffset(ElementOffset))

451 if

(!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))

454

ElementOffset += Layout.

getSize

();

461bool

EmptySubobjectMap::CanPlaceFieldAtOffset(

const FieldDecl

*FD,

463 if

(!CanPlaceFieldSubobjectAtOffset(FD, Offset))

468

UpdateEmptyFieldSubobjects(FD, Offset, FD->

hasAttr

<NoUniqueAddressAttr>());

472void

EmptySubobjectMap::UpdateEmptyFieldSubobjects(

474 bool

PlacingOverlappingField) {

485 if

(!PlacingOverlappingField && Offset >= SizeOfLargestEmptySubobject)

488

AddSubobjectAtOffset(RD, Offset);

494 if

(

Base

.isVirtual())

500

UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset,

501

PlacingOverlappingField);

510

UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset,

511

PlacingOverlappingField);

517 if

(

Field

->isBitField())

521

UpdateEmptyFieldSubobjects(Field, FieldOffset, PlacingOverlappingField);

525void

EmptySubobjectMap::UpdateEmptyFieldSubobjects(

529

UpdateEmptyFieldSubobjects(RD, RD, Offset, PlacingOverlappingField);

546 for

(uint64_t I = 0; I != NumElements; ++I) {

552 if

(!PlacingOverlappingField &&

553

ElementOffset >= SizeOfLargestEmptySubobject)

556

UpdateEmptyFieldSubobjects(RD, RD, ElementOffset,

557

PlacingOverlappingField);

558

ElementOffset += Layout.

getSize

();

565class

ItaniumRecordLayoutBuilder {

572

EmptySubobjectMap *EmptySubobjects;

593

LLVM_PREFERRED_TYPE(

bool

)

594 unsigned

UseExternalLayout : 1;

598

LLVM_PREFERRED_TYPE(

bool

)

599 unsigned

InferAlignment : 1;

602

LLVM_PREFERRED_TYPE(

bool

)

605

LLVM_PREFERRED_TYPE(

bool

)

606 unsigned

IsUnion : 1;

608

LLVM_PREFERRED_TYPE(

bool

)

609 unsigned

IsMac68kAlign : 1;

611

LLVM_PREFERRED_TYPE(

bool

)

612 unsigned

IsNaturalAlign : 1;

614

LLVM_PREFERRED_TYPE(

bool

)

615 unsigned

IsMsStruct : 1;

621 unsigned char

UnfilledBitsInLastUnit;

625 unsigned char

LastBitfieldStorageUnitSize;

648 bool

PrimaryBaseIsVirtual;

661 bool

HandledFirstNonOverlappingEmptyField;

663 typedef

llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;

666

BaseOffsetsMapTy Bases;

686

ItaniumRecordLayoutBuilder(

const ASTContext

&Context,

687

EmptySubobjectMap *EmptySubobjects)

688

: Context(Context), EmptySubobjects(EmptySubobjects),

Size

(0),

691

UnadjustedAlignment(

CharUnits

::One()), UseExternalLayout(

false

),

693

IsMac68kAlign(

false

),

694

IsNaturalAlign(!Context.getTargetInfo().getTriple().isOSAIX()),

695

IsMsStruct(

false

), UnfilledBitsInLastUnit(0),

696

LastBitfieldStorageUnitSize(0), MaxFieldAlignment(

CharUnits

::

Zero

()),

699

PreferredNVAlignment(

CharUnits

::One()),

700

PaddedFieldSize(

CharUnits

::

Zero

()), PrimaryBase(nullptr),

701

PrimaryBaseIsVirtual(

false

), HasOwnVFPtr(

false

), HasPackedField(

false

),

702

HandledFirstNonOverlappingEmptyField(

false

),

703

FirstNearlyEmptyVBase(nullptr) {}

710 void

LayoutField(

const FieldDecl

*

D

,

bool

InsertExtraPadding);

711 void

LayoutWideBitField(uint64_t FieldSize, uint64_t StorageUnitSize,

720

llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator;

722 typedef

llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *>

723

BaseSubobjectInfoMapTy;

731

BaseSubobjectInfoMapTy NonVirtualBaseInfo;

739

BaseSubobjectInfo *ComputeBaseSubobjectInfo(

const CXXRecordDecl

*RD,

741

BaseSubobjectInfo *Derived);

748 void

EnsureVTablePointerAlignment(

CharUnits

UnpackedBaseAlign);

755 void

LayoutNonVirtualBase(

const

BaseSubobjectInfo *

Base

);

757 void

AddPrimaryVirtualBaseOffsets(

const

BaseSubobjectInfo *Info,

765 void

LayoutVirtualBase(

const

BaseSubobjectInfo *

Base

);

772 void

InitializeLayout(

const Decl

*

D

);

781

UpdateAlignment(NewAlignment, UnpackedNewAlignment, NewAlignment);

783 void

UpdateAlignment(

CharUnits

NewAlignment) {

784

UpdateAlignment(NewAlignment, NewAlignment, NewAlignment);

793

uint64_t ComputedOffset);

795 void

CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset,

796

uint64_t UnpackedOffset,

unsigned

UnpackedAlign,

808 void

setSize(uint64_t NewSize) {

Size

= NewSize; }

810 CharUnits

getAlignment()

const

{

return

Alignment; }

816 uint64_t

getDataSizeInBits()

const

{

return

DataSize; }

818 void

setDataSize(

CharUnits

NewSize) { DataSize = Context.

toBits

(NewSize); }

819 void

setDataSize(uint64_t NewSize) { DataSize = NewSize; }

821

ItaniumRecordLayoutBuilder(

const

ItaniumRecordLayoutBuilder &) =

delete

;

822 void

operator=(

const

ItaniumRecordLayoutBuilder &) =

delete

;

826void

ItaniumRecordLayoutBuilder::SelectPrimaryVBase(

const CXXRecordDecl

*RD) {

827 for

(

const auto

&I : RD->

bases

()) {

828

assert(!I.getType()->isDependentType() &&

829 "Cannot layout class with dependent bases."

);

837 if

(!IndirectPrimaryBases.count(

Base

)) {

839

PrimaryBaseIsVirtual =

true

;

844 if

(!FirstNearlyEmptyVBase)

845

FirstNearlyEmptyVBase =

Base

;

848

SelectPrimaryVBase(

Base

);

855void

ItaniumRecordLayoutBuilder::DeterminePrimaryBase(

const CXXRecordDecl

*RD) {

867 for

(

const auto

&I : RD->

bases

()) {

874 if

(

Base

->isDynamicClass()) {

877

PrimaryBaseIsVirtual =

false

;

887

SelectPrimaryVBase(RD);

893 if

(FirstNearlyEmptyVBase) {

894

PrimaryBase = FirstNearlyEmptyVBase;

895

PrimaryBaseIsVirtual =

true

;

899

assert(!PrimaryBase &&

"Should not get here with a primary base!"

);

902

BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(

903 const CXXRecordDecl

*RD,

bool

IsVirtual, BaseSubobjectInfo *Derived) {

904

BaseSubobjectInfo *Info;

910

assert(InfoSlot->Class == RD &&

"Wrong class for virtual base info!"

);

915

InfoSlot =

new

(BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;

918

Info =

new

(BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;

922

Info->IsVirtual = IsVirtual;

923

Info->Derived =

nullptr

;

924

Info->PrimaryVirtualBaseInfo =

nullptr

;

927

BaseSubobjectInfo *PrimaryVirtualBaseInfo =

nullptr

;

935

assert(PrimaryVirtualBase &&

"Didn't have a primary virtual base!"

);

940 if

(PrimaryVirtualBaseInfo) {

941 if

(PrimaryVirtualBaseInfo->Derived) {

945

PrimaryVirtualBase =

nullptr

;

948

Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;

949

PrimaryVirtualBaseInfo->Derived = Info;

956 for

(

const auto

&I : RD->

bases

()) {

957 bool

IsVirtual = I.isVirtual();

959 const CXXRecordDecl

*BaseDecl = I.getType()->getAsCXXRecordDecl();

961

Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));

964 if

(PrimaryVirtualBase && !PrimaryVirtualBaseInfo) {

968

assert(PrimaryVirtualBaseInfo &&

969 "Did not create a primary virtual base!"

);

972

Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;

973

PrimaryVirtualBaseInfo->Derived = Info;

979void

ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(

981 for

(

const auto

&I : RD->

bases

()) {

982 bool

IsVirtual = I.isVirtual();

984 const CXXRecordDecl

*BaseDecl = I.getType()->getAsCXXRecordDecl();

987

BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual,

993 "Did not add virtual base!"

);

996

assert(!NonVirtualBaseInfo.count(BaseDecl) &&

997 "Non-virtual base already exists!"

);

998

NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info));

1003void

ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment(

1008 if

(!MaxFieldAlignment.

isZero

()) {

1009

BaseAlign = std::min(BaseAlign, MaxFieldAlignment);

1010

UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment);

1014

setSize(getSize().alignTo(BaseAlign));

1017

UpdateAlignment(BaseAlign, UnpackedBaseAlign, BaseAlign);

1020void

ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(

1023

DeterminePrimaryBase(RD);

1026

ComputeBaseSubobjectInfo(RD);

1030 if

(PrimaryBaseIsVirtual) {

1033

BaseSubobjectInfo *PrimaryBaseInfo =

VirtualBaseInfo

.lookup(PrimaryBase);

1034

PrimaryBaseInfo->Derived =

nullptr

;

1037

IndirectPrimaryBases.insert(PrimaryBase);

1039

assert(!VisitedVirtualBases.count(PrimaryBase) &&

1040 "vbase already visited!"

);

1041

VisitedVirtualBases.insert(PrimaryBase);

1043

LayoutVirtualBase(PrimaryBaseInfo);

1045

BaseSubobjectInfo *PrimaryBaseInfo =

1046

NonVirtualBaseInfo.lookup(PrimaryBase);

1047

assert(PrimaryBaseInfo &&

1048 "Did not find base info for non-virtual primary base!"

);

1050

LayoutNonVirtualBase(PrimaryBaseInfo);

1056

assert(DataSize == 0 &&

"Vtable pointer must be at offset zero!"

);

1061

EnsureVTablePointerAlignment(PtrAlign);

1062

HasOwnVFPtr =

true

;

1064

assert(!IsUnion &&

"Unions cannot be dynamic classes."

);

1065

HandledFirstNonOverlappingEmptyField =

true

;

1067

setSize(getSize() + PtrWidth);

1068

setDataSize(getSize());

1072 for

(

const auto

&I : RD->

bases

()) {

1078 const CXXRecordDecl

*BaseDecl = I.getType()->getAsCXXRecordDecl();

1083 if

(BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual)

1087

BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.

lookup

(BaseDecl);

1088

assert(BaseInfo &&

"Did not find base info for non-virtual base!"

);

1090

LayoutNonVirtualBase(BaseInfo);

1094void

ItaniumRecordLayoutBuilder::LayoutNonVirtualBase(

1095 const

BaseSubobjectInfo *

Base

) {

1100

assert(!Bases.count(

Base

->Class) &&

"base offset already exists!"

);

1101

Bases.insert(std::make_pair(

Base

->Class, Offset));

1103

AddPrimaryVirtualBaseOffsets(

Base

, Offset);

1106void

ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(

1107 const

BaseSubobjectInfo *Info,

CharUnits

Offset) {

1109 if

(!Info->Class->getNumVBases())

1113 if

(Info->PrimaryVirtualBaseInfo) {

1114

assert(Info->PrimaryVirtualBaseInfo->IsVirtual &&

1115 "Primary virtual base is not virtual!"

);

1116 if

(Info->PrimaryVirtualBaseInfo->Derived == Info) {

1118

assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) &&

1119 "primary vbase offset already exists!"

);

1120

VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class,

1124

AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset);

1130 for

(

const

BaseSubobjectInfo *

Base

: Info->Bases) {

1131 if

(

Base

->IsVirtual)

1135

AddPrimaryVirtualBaseOffsets(

Base

, BaseOffset);

1139void

ItaniumRecordLayoutBuilder::LayoutVirtualBases(

1142 bool

PrimaryBaseIsVirtual;

1144 if

(MostDerivedClass == RD) {

1145

PrimaryBase = this->PrimaryBase;

1146

PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;

1154

assert(!

Base

.getType()->isDependentType() &&

1155 "Cannot layout class with dependent bases."

);

1159 if

(

Base

.isVirtual()) {

1160 if

(PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {

1161 bool

IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);

1164 if

(!IndirectPrimaryBase) {

1166 if

(!VisitedVirtualBases.insert(BaseDecl).second)

1169 const

BaseSubobjectInfo *BaseInfo =

VirtualBaseInfo

.lookup(BaseDecl);

1170

assert(BaseInfo &&

"Did not find virtual base info!"

);

1171

LayoutVirtualBase(BaseInfo);

1181

LayoutVirtualBases(BaseDecl, MostDerivedClass);

1185void

ItaniumRecordLayoutBuilder::LayoutVirtualBase(

1186 const

BaseSubobjectInfo *

Base

) {

1187

assert(!

Base

->Derived &&

"Trying to lay out a primary virtual base!"

);

1193

assert(!VBases.count(

Base

->Class) &&

"vbase offset already exists!"

);

1194

VBases.insert(std::make_pair(

Base

->Class,

1197

AddPrimaryVirtualBaseOffsets(

Base

, Offset);

1201

ItaniumRecordLayoutBuilder::LayoutBase(

const

BaseSubobjectInfo *

Base

) {

1202

assert(!IsUnion &&

"Unions cannot have base classes."

);

1208 bool

HasExternalLayout =

false

;

1209 if

(UseExternalLayout) {

1210 if

(

Base

->IsVirtual)

1211

HasExternalLayout =

External

.getExternalVBaseOffset(

Base

->Class, Offset);

1213

HasExternalLayout =

External

.getExternalNVBaseOffset(

Base

->Class, Offset);

1216 auto

getBaseOrPreferredBaseAlignFromUnpacked = [&](

CharUnits

UnpackedAlign) {

1219 return

(Packed && ((Context.

getLangOpts

().getClangABICompat() <=

1230

getBaseOrPreferredBaseAlignFromUnpacked(UnpackedBaseAlign);

1232

getBaseOrPreferredBaseAlignFromUnpacked(UnpackedPreferredBaseAlign);

1234 const bool

DefaultsToAIXPowerAlignment =

1236 if

(DefaultsToAIXPowerAlignment) {

1241 if

(!

Base

->Class->isEmpty() && !HandledFirstNonOverlappingEmptyField) {

1244

HandledFirstNonOverlappingEmptyField =

true

;

1245

}

else if

(!IsNaturalAlign) {

1246

UnpackedPreferredBaseAlign = UnpackedBaseAlign;

1247

PreferredBaseAlign = BaseAlign;

1251 CharUnits

UnpackedAlignTo = !DefaultsToAIXPowerAlignment

1253

: UnpackedPreferredBaseAlign;

1255 if

(

Base

->Class->isEmpty() &&

1258

setSize(std::max(getSize(), Layout.

getSize

()));

1261

UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign);

1268 if

(!MaxFieldAlignment.

isZero

()) {

1269

BaseAlign = std::min(BaseAlign, MaxFieldAlignment);

1270

PreferredBaseAlign = std::min(PreferredBaseAlign, MaxFieldAlignment);

1271

UnpackedAlignTo = std::min(UnpackedAlignTo, MaxFieldAlignment);

1275

!DefaultsToAIXPowerAlignment ? BaseAlign : PreferredBaseAlign;

1276 if

(!HasExternalLayout) {

1278

Offset = getDataSize().alignTo(AlignTo);

1281 while

(!EmptySubobjects->CanPlaceBaseAtOffset(

Base

, Offset))

1284 bool

Allowed = EmptySubobjects->CanPlaceBaseAtOffset(

Base

, Offset);

1286

assert(Allowed &&

"Base subobject externally placed at overlapping offset"

);

1288 if

(InferAlignment && Offset < getDataSize().alignTo(AlignTo)) {

1292

InferAlignment =

false

;

1296 if

(!

Base

->Class->isEmpty()) {

1300

setSize(std::max(getSize(), getDataSize()));

1302

setSize(std::max(getSize(), Offset + Layout.

getSize

()));

1305

UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign);

1310void

ItaniumRecordLayoutBuilder::InitializeLayout(

const Decl

*

D

) {

1311 if

(

const RecordDecl

*RD = dyn_cast<RecordDecl>(

D

)) {

1316

Packed =

D

->

hasAttr

<PackedAttr>();

1319 if

(

unsigned

DefaultMaxFieldAlignment = Context.

getLangOpts

().PackStruct) {

1327 if

(

D

->

hasAttr

<AlignMac68kAttr>()) {

1329

!

D

->

hasAttr

<AlignNaturalAttr>() &&

1330 "Having both mac68k and natural alignment on a decl is not allowed."

);

1331

IsMac68kAlign =

true

;

1336 if

(

D

->

hasAttr

<AlignNaturalAttr>())

1337

IsNaturalAlign =

true

;

1339 if

(

const

MaxFieldAlignmentAttr *MFAA =

D

->

getAttr

<MaxFieldAlignmentAttr>())

1346

HandledFirstNonOverlappingEmptyField =

1350 if

(

const RecordDecl

*RD = dyn_cast<RecordDecl>(

D

))

1352

UseExternalLayout = Source->layoutRecordType(

1357 if

(UseExternalLayout) {

1363

InferAlignment =

true

;

1369void

ItaniumRecordLayoutBuilder::Layout(

const RecordDecl

*

D

) {

1370

InitializeLayout(

D

);

1378void

ItaniumRecordLayoutBuilder::Layout(

const CXXRecordDecl

*RD) {

1379

InitializeLayout(RD);

1382

LayoutNonVirtualBases(RD);

1388

NonVirtualAlignment = Alignment;

1389

PreferredNVAlignment = PreferredAlignment;

1392

LayoutVirtualBases(RD, RD);

1401 if

(

Base

.isVirtual())

1406

assert(Bases.count(BaseDecl) &&

"Did not find base offset!"

);

1413

assert(VBases.count(BaseDecl) &&

"Did not find base offset!"

);

1427

setSize(getDataSize());

1430

InitializeLayout(

D

);

1432 for

(

const ObjCIvarDecl

*IVD =

D

->all_declared_ivar_begin(); IVD;

1433

IVD = IVD->getNextIvar())

1434

LayoutField(IVD,

false

);

1441void

ItaniumRecordLayoutBuilder::LayoutFields(

const RecordDecl

*

D

) {

1444 bool

InsertExtraPadding =

D

->mayInsertExtraPadding(

true

);

1445 bool

HasFlexibleArrayMember =

D

->hasFlexibleArrayMember();

1446 for

(

auto

I =

D

->field_begin(), End =

D

->field_end(); I != End; ++I) {

1447

LayoutField(*I, InsertExtraPadding &&

1448

(std::next(I) != End || !HasFlexibleArrayMember));

1457 return

llvm::alignTo(Size, CharAlignment);

1460void

ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,

1461

uint64_t StorageUnitSize,

1465 "Can only have wide bit-fields in C++!"

);

1477 for

(

const QualType

&QT : IntegralPODTypes) {

1480 if

(Size > FieldSize)

1485

assert(!

Type

.isNull() &&

"Did not find a type!"

);

1490

UnfilledBitsInLastUnit = 0;

1491

LastBitfieldStorageUnitSize = 0;

1494 uint64_t

UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;

1499

setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));

1504

FieldOffset = llvm::alignTo(getDataSizeInBits(), Context.

toBits

(TypeAlign));

1506 uint64_t

NewSizeInBits = FieldOffset + FieldSize;

1510

UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;

1514

FieldOffsets.push_back(FieldOffset);

1516

CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset,

1517

Context.

toBits

(TypeAlign), FieldPacked,

D

);

1520

setSize(std::max(getSizeInBits(), getDataSizeInBits()));

1523

UpdateAlignment(TypeAlign);

1530void

ItaniumRecordLayoutBuilder::LayoutBitField(

const FieldDecl

*

D

) {

1531 bool

FieldPacked = Packed ||

D

->

hasAttr

<PackedAttr>();

1532 uint64_t

FieldSize =

D

->getBitWidthValue();

1535 unsigned

FieldAlign = FieldInfo.

Align

;

1598

FieldAlign = StorageUnitSize;

1603 if

(LastBitfieldStorageUnitSize != StorageUnitSize ||

1604

UnfilledBitsInLastUnit < FieldSize) {

1606 if

(!LastBitfieldStorageUnitSize && !FieldSize)

1609

UnfilledBitsInLastUnit = 0;

1610

LastBitfieldStorageUnitSize = 0;

1624

StorageUnitSize = 32;

1626 if

(!AlignIsRequired)

1630 if

(FieldAlign < StorageUnitSize) {

1633

FieldAlign = StorageUnitSize;

1640 if

(FieldSize > StorageUnitSize && !

isAIXLayout

(Context)) {

1641

LayoutWideBitField(FieldSize, StorageUnitSize, FieldPacked,

D

);

1647

IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit);

1652 if

(FieldSize == 0 &&

1655 if

(!IsUnion && FieldOffset == 0 &&

1661 unsigned

ZeroLengthBitfieldBoundary =

1663

FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);

1672 unsigned

UnpackedFieldAlign = FieldAlign;

1675 if

(!IsMsStruct && FieldPacked && FieldSize != 0)

1680 if

(ExplicitFieldAlign) {

1681

FieldAlign = std::max(FieldAlign, ExplicitFieldAlign);

1682

UnpackedFieldAlign = std::max(UnpackedFieldAlign, ExplicitFieldAlign);

1687 unsigned

MaxFieldAlignmentInBits = Context.

toBits

(MaxFieldAlignment);

1688 if

(!MaxFieldAlignment.

isZero

() && FieldSize) {

1689

UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);

1691

FieldAlign = UnpackedFieldAlign;

1693

FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);

1698 if

(IsMsStruct && IsUnion) {

1699

FieldAlign = UnpackedFieldAlign = 1;

1705 uint64_t

UnpaddedFieldOffset = FieldOffset;

1706 uint64_t

UnpackedFieldOffset = FieldOffset;

1716 if

(FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) {

1717

FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);

1718

UnpackedFieldOffset =

1719

llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);

1720

UnfilledBitsInLastUnit = 0;

1725 bool

AllowPadding = MaxFieldAlignment.

isZero

();

1728 if

(FieldSize == 0 ||

1730

(FieldOffset & (FieldAlign - 1)) + FieldSize > StorageUnitSize)) {

1731

FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);

1732

}

else if

(ExplicitFieldAlign &&

1733

(MaxFieldAlignmentInBits == 0 ||

1734

ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&

1738

FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign);

1742 if

(FieldSize == 0 ||

1744

(UnpackedFieldOffset & (UnpackedFieldAlign - 1)) + FieldSize >

1746

UnpackedFieldOffset =

1747

llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);

1748 else if

(ExplicitFieldAlign &&

1749

(MaxFieldAlignmentInBits == 0 ||

1750

ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&

1752

UnpackedFieldOffset =

1753

llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign);

1758 if

(UseExternalLayout)

1759

FieldOffset = updateExternalFieldOffset(

D

, FieldOffset);

1762

FieldOffsets.push_back(FieldOffset);

1770

!

D

->getIdentifier())

1771

FieldAlign = UnpackedFieldAlign = 1;

1779 if

(!MaxFieldAlignment.

isZero

()) {

1780

UnpackedFieldAlign =

1781

std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);

1782

FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);

1787 if

(!UseExternalLayout)

1788

CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,

1789

UnpackedFieldAlign, FieldPacked,

D

);

1799

RoundedFieldSize = (FieldSize ? StorageUnitSize

1807

setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));

1811

}

else if

(IsMsStruct && FieldSize) {

1814 if

(!UnfilledBitsInLastUnit) {

1815

setDataSize(FieldOffset + StorageUnitSize);

1816

UnfilledBitsInLastUnit = StorageUnitSize;

1818

UnfilledBitsInLastUnit -= FieldSize;

1819

LastBitfieldStorageUnitSize = StorageUnitSize;

1825 uint64_t

NewSizeInBits = FieldOffset + FieldSize;

1827

setDataSize(llvm::alignTo(NewSizeInBits, CharAlignment));

1828

UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;

1833

LastBitfieldStorageUnitSize = 0;

1837

setSize(std::max(getSizeInBits(), getDataSizeInBits()));

1840

UnadjustedAlignment =

1846void

ItaniumRecordLayoutBuilder::LayoutField(

const FieldDecl

*

D

,

1847 bool

InsertExtraPadding) {

1848 auto

*FieldClass =

D

->getType()->getAsCXXRecordDecl();

1849 bool

IsOverlappingEmptyField =

1850 D

->isPotentiallyOverlapping() && FieldClass->isEmpty();

1853

(IsUnion || IsOverlappingEmptyField) ?

CharUnits::Zero

() : getDataSize();

1855 const bool

DefaultsToAIXPowerAlignment =

1857 bool

FoundFirstNonOverlappingEmptyFieldForAIX =

false

;

1858 if

(DefaultsToAIXPowerAlignment && !HandledFirstNonOverlappingEmptyField) {

1860 "The first non-overlapping empty field should have been handled."

);

1862 if

(!IsOverlappingEmptyField) {

1863

FoundFirstNonOverlappingEmptyFieldForAIX =

true

;

1870

HandledFirstNonOverlappingEmptyField = !IsUnion;

1874 if

(

D

->isBitField()) {

1875

LayoutBitField(

D

);

1879 uint64_t

UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;

1881

UnfilledBitsInLastUnit = 0;

1882

LastBitfieldStorageUnitSize = 0;

1894 auto

setDeclInfo = [&](

bool

IsIncompleteArrayType) {

1896

FieldAlign = TI.Align;

1899

EffectiveFieldSize = FieldSize =

1901

AlignRequirement = TI.AlignRequirement;

1904 if

(

D

->getType()->isIncompleteArrayType()) {

1905

setDeclInfo(

true

);

1907

setDeclInfo(

false

);

1911 if

(

D

->isPotentiallyOverlapping()) {

1913

EffectiveFieldSize =

1927 if

(!llvm::isPowerOf2_64(TypeSize.

getQuantity

())) {

1930 "Non PowerOf2 size in MSVC mode"

);

1952 if

(TypeSize > FieldAlign &&

1954

FieldAlign = TypeSize;

1959 bool

FieldPacked = (Packed && (!FieldClass || FieldClass->isPOD() ||

1960

FieldClass->hasAttr<PackedAttr>() ||

1971 auto

alignedAttrCanDecreaseAIXAlignment = [AlignRequirement, FieldPacked] {

1990 if

(DefaultsToAIXPowerAlignment && !alignedAttrCanDecreaseAIXAlignment() &&

1991

(FoundFirstNonOverlappingEmptyFieldForAIX || IsNaturalAlign)) {

1992 auto

performBuiltinTypeAlignmentUpgrade = [&](

const BuiltinType

*BTy) {

1993 if

(BTy->getKind() == BuiltinType::Double ||

1994

BTy->getKind() == BuiltinType::LongDouble) {

1996 "No need to upgrade the alignment value."

);

2001 const Type

*BaseTy =

D

->getType()->getBaseElementTypeUnsafe();

2003

performBuiltinTypeAlignmentUpgrade(

2006

performBuiltinTypeAlignmentUpgrade(BTy);

2009

assert(RD &&

"Expected non-null RecordDecl."

);

2017 CharUnits

UnpackedFieldAlign = FieldAlign;

2019 CharUnits

UnpackedFieldOffset = FieldOffset;

2020 CharUnits

OriginalFieldAlign = UnpackedFieldAlign;

2024

PackedFieldAlign = std::max(PackedFieldAlign, MaxAlignmentInChars);

2025

PreferredAlign = std::max(PreferredAlign, MaxAlignmentInChars);

2026

UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars);

2029 if

(!MaxFieldAlignment.

isZero

()) {

2030

PackedFieldAlign = std::min(PackedFieldAlign, MaxFieldAlignment);

2031

PreferredAlign = std::min(PreferredAlign, MaxFieldAlignment);

2032

UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment);

2037

FieldAlign = UnpackedFieldAlign;

2038 if

(DefaultsToAIXPowerAlignment)

2039

UnpackedFieldAlign = PreferredAlign;

2041

PreferredAlign = PackedFieldAlign;

2042

FieldAlign = PackedFieldAlign;

2046

!DefaultsToAIXPowerAlignment ? FieldAlign : PreferredAlign;

2048

FieldOffset = FieldOffset.

alignTo

(AlignTo);

2049

UnpackedFieldOffset = UnpackedFieldOffset.

alignTo

(UnpackedFieldAlign);

2051 if

(UseExternalLayout) {

2053

updateExternalFieldOffset(

D

, Context.

toBits

(FieldOffset)));

2055 if

(!IsUnion && EmptySubobjects) {

2057 bool

Allowed = EmptySubobjects->CanPlaceFieldAtOffset(

D

, FieldOffset);

2059

assert(Allowed &&

"Externally-placed field cannot be placed here"

);

2062 if

(!IsUnion && EmptySubobjects) {

2064 while

(!EmptySubobjects->CanPlaceFieldAtOffset(

D

, FieldOffset)) {

2069

FieldOffset = getDataSize().

alignTo

(AlignTo);

2071

FieldOffset += AlignTo;

2077

FieldOffsets.push_back(Context.

toBits

(FieldOffset));

2079 if

(!UseExternalLayout)

2080

CheckFieldPadding(Context.

toBits

(FieldOffset), UnpaddedFieldOffset,

2081

Context.

toBits

(UnpackedFieldOffset),

2082

Context.

toBits

(UnpackedFieldAlign), FieldPacked,

D

);

2084 if

(InsertExtraPadding) {

2086 CharUnits

ExtraSizeForAsan = ASanAlignment;

2087 if

(FieldSize % ASanAlignment)

2090

EffectiveFieldSize = FieldSize = FieldSize + ExtraSizeForAsan;

2094 if

(!IsOverlappingEmptyField) {

2095 uint64_t

EffectiveFieldSizeInBits = Context.

toBits

(EffectiveFieldSize);

2097

setDataSize(std::max(getDataSizeInBits(), EffectiveFieldSizeInBits));

2099

setDataSize(FieldOffset + EffectiveFieldSize);

2101

PaddedFieldSize = std::max(PaddedFieldSize, FieldOffset + FieldSize);

2102

setSize(std::max(getSizeInBits(), getDataSizeInBits()));

2104

setSize(std::max(getSizeInBits(),

2105

(uint64_t)Context.

toBits

(FieldOffset + FieldSize)));

2109

UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign);

2110

UpdateAlignment(FieldAlign, UnpackedFieldAlign, PreferredAlign);

2116 if

(RD->

hasAttr

<PackedAttr>() || !MaxFieldAlignment.

isZero

())

2117 if

(FieldAlign < OriginalFieldAlign)

2118 if

(

D

->getType()->isRecordType()) {

2122 if

(FieldOffset % OriginalFieldAlign != 0)

2128 if

(Packed && !FieldPacked && PackedFieldAlign < FieldAlign)

2132void

ItaniumRecordLayoutBuilder::FinishLayout(

const NamedDecl

*

D

) {

2134 if

(Context.

getLangOpts

().CPlusPlus && getSizeInBits() == 0) {

2148

setSize(std::max(getSizeInBits(), (uint64_t)Context.

toBits

(PaddedFieldSize)));

2152 uint64_t

UnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit;

2154

llvm::alignTo(getSizeInBits(), Context.

toBits

(UnpackedAlignment));

2156 uint64_t

RoundedSize = llvm::alignTo(

2160

: PreferredAlignment));

2162 if

(UseExternalLayout) {

2166 if

(InferAlignment &&

External

.Size < RoundedSize) {

2169

InferAlignment =

false

;

2176

setSize(RoundedSize);

2179 if

(

const RecordDecl

*RD = dyn_cast<RecordDecl>(

D

)) {

2181 if

(getSizeInBits() > UnpaddedSize) {

2182 unsigned

PadSize = getSizeInBits() - UnpaddedSize;

2183 bool

InBits =

true

;

2184 if

(PadSize % CharBitNum == 0) {

2185

PadSize = PadSize / CharBitNum;

2191

<< (InBits ? 1 : 0);

2194 const auto

*CXXRD = dyn_cast<CXXRecordDecl>(RD);

2202 if

(Packed && UnpackedAlignment <= Alignment &&

2203

UnpackedSizeInBits == getSizeInBits() && !HasPackedField &&

2204

(!CXXRD || CXXRD->isPOD() ||

2212void

ItaniumRecordLayoutBuilder::UpdateAlignment(

2217 if

(IsMac68kAlign || (UseExternalLayout && !InferAlignment))

2220 if

(NewAlignment > Alignment) {

2221

assert(llvm::isPowerOf2_64(NewAlignment.

getQuantity

()) &&

2222 "Alignment not a power of 2"

);

2223

Alignment = NewAlignment;

2226 if

(UnpackedNewAlignment > UnpackedAlignment) {

2227

assert(llvm::isPowerOf2_64(UnpackedNewAlignment.

getQuantity

()) &&

2228 "Alignment not a power of 2"

);

2229

UnpackedAlignment = UnpackedNewAlignment;

2232 if

(PreferredNewAlignment > PreferredAlignment) {

2233

assert(llvm::isPowerOf2_64(PreferredNewAlignment.

getQuantity

()) &&

2234 "Alignment not a power of 2"

);

2235

PreferredAlignment = PreferredNewAlignment;

2240

ItaniumRecordLayoutBuilder::updateExternalFieldOffset(

const FieldDecl

*Field,

2241

uint64_t ComputedOffset) {

2244 if

(InferAlignment && ExternalFieldOffset < ComputedOffset) {

2249

InferAlignment =

false

;

2253 return

ExternalFieldOffset;

2269 default

: llvm_unreachable(

"Invalid tag kind for field padding diagnostic!"

);

2273void

ItaniumRecordLayoutBuilder::CheckFieldPadding(

2274

uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,

2275 unsigned

UnpackedAlign,

bool

isPacked,

const FieldDecl

*

D

) {

2278 if

(isa<ObjCIvarDecl>(

D

))

2289 if

(!IsUnion && Offset > UnpaddedOffset) {

2290 unsigned

PadSize = Offset - UnpaddedOffset;

2291 bool

InBits =

true

;

2292 if

(PadSize % CharBitNum == 0) {

2293

PadSize = PadSize / CharBitNum;

2296 if

(

D

->getIdentifier()) {

2297 auto Diagnostic

=

D

->isBitField() ? diag::warn_padded_struct_bitfield

2298

: diag::warn_padded_struct_field;

2303

<<

D

->getIdentifier();

2305 auto Diagnostic

=

D

->isBitField() ? diag::warn_padded_struct_anon_bitfield

2306

: diag::warn_padded_struct_anon_field;

2310

<< (InBits ? 1 : 0);

2313 if

(isPacked && Offset != UnpackedOffset) {

2314

HasPackedField =

true

;

2338 bool

allowInlineFunctions =

2342 if

(!MD->isVirtual())

2345 if

(MD->isPureVirtual())

2350 if

(MD->isImplicit())

2353 if

(MD->isInlineSpecified() || MD->isConstexpr())

2356 if

(MD->hasInlineBody())

2360 if

(!MD->isUserProvided())

2364 if

(!allowInlineFunctions) {

2376 if

(!MD->hasAttr<CUDADeviceAttr>())

2380 if

(!MD->hasAttr<CUDAHostAttr>() && MD->hasAttr<CUDADeviceAttr>())

2388 if

(MD->hasAttr<DLLImportAttr>() && !RD->

hasAttr

<DLLImportAttr>() &&

2431 return

RD->

isPOD

();

2443

llvm_unreachable(

"bad tail-padding use kind"

);

2546struct

MicrosoftRecordLayoutBuilder {

2547 struct

ElementInfo {

2551 typedef

llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;

2552

MicrosoftRecordLayoutBuilder(

const ASTContext

&Context,

2553

EmptySubobjectMap *EmptySubobjects)

2554

: Context(Context), EmptySubobjects(EmptySubobjects) {}

2557

MicrosoftRecordLayoutBuilder(

const

MicrosoftRecordLayoutBuilder &) =

delete

;

2558 void

operator=(

const

MicrosoftRecordLayoutBuilder &) =

delete

;

2563 void

initializeLayout(

const RecordDecl

*RD);

2579 void

layoutBitField(

const FieldDecl

*FD);

2582 void

layoutZeroWidthBitField(

const FieldDecl

*FD);

2591

ElementInfo getAdjustedElementInfo(

const FieldDecl

*FD);

2593 void

placeFieldAtOffset(

CharUnits

FieldOffset) {

2594

FieldOffsets.push_back(Context.

toBits

(FieldOffset));

2597 void

placeFieldAtBitOffset(uint64_t FieldOffset) {

2598

FieldOffsets.push_back(FieldOffset);

2601 void

computeVtorDispSet(

2602

llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet,

2605

EmptySubobjectMap *EmptySubobjects;

2629

ElementInfo PointerInfo;

2637

BaseOffsetsMapTy Bases;

2643 unsigned

RemainingBitsInField;

2647 bool

LastFieldIsNonZeroWidthBitfield : 1;

2649 bool

HasOwnVFPtr : 1;

2655 bool

EndsWithZeroSizedObject : 1;

2658 bool

LeadsWithZeroSizedBase : 1;

2661 bool

UseExternalLayout : 1;

2669

MicrosoftRecordLayoutBuilder::ElementInfo

2670

MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(

2675 if

(!MaxFieldAlignment.

isZero

())

2676

Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);

2682

Alignment = std::max(Alignment, Info.Alignment);

2689

MicrosoftRecordLayoutBuilder::ElementInfo

2690

MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(

2696

ElementInfo Info{TInfo.

Width

, TInfo.Align};

2702

FieldRequiredAlignment = std::max(

2708

Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);

2714

FieldRequiredAlignment = std::max(FieldRequiredAlignment,

2718

RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment);

2721 if

(!MaxFieldAlignment.

isZero

())

2722

Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);

2723 if

(FD->

hasAttr

<PackedAttr>())

2725

Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);

2729void

MicrosoftRecordLayoutBuilder::layout(

const RecordDecl

*RD) {

2732

initializeLayout(RD);

2734

DataSize =

Size

=

Size

.alignTo(Alignment);

2735

RequiredAlignment = std::max(

2740void

MicrosoftRecordLayoutBuilder::cxxLayout(

const CXXRecordDecl

*RD) {

2743

initializeLayout(RD);

2744

initializeCXXLayout(RD);

2745

layoutNonVirtualBases(RD);

2749 if

(HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))

2750

Alignment = std::max(Alignment, PointerInfo.Alignment);

2751 auto

RoundingAlignment = Alignment;

2752 if

(!MaxFieldAlignment.

isZero

())

2753

RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);

2754 if

(!UseExternalLayout)

2755 Size

=

Size

.alignTo(RoundingAlignment);

2756

NonVirtualSize =

Size

;

2757

RequiredAlignment = std::max(

2759

layoutVirtualBases(RD);

2763void

MicrosoftRecordLayoutBuilder::initializeLayout(

const RecordDecl

*RD) {

2776 if

(

unsigned

DefaultMaxFieldAlignment = Context.

getLangOpts

().PackStruct)

2780 if

(

const

MaxFieldAlignmentAttr *MFAA = RD->

getAttr

<MaxFieldAlignmentAttr>()){

2781 unsigned

PackedAlignment = MFAA->getAlignment();

2782 if

(PackedAlignment <=

2787 if

(RD->

hasAttr

<PackedAttr>())

2791

UseExternalLayout =

false

;

2793

UseExternalLayout = Source->layoutRecordType(

2799

MicrosoftRecordLayoutBuilder::initializeCXXLayout(

const CXXRecordDecl

*RD) {

2800

EndsWithZeroSizedObject =

false

;

2801

LeadsWithZeroSizedBase =

false

;

2802

HasOwnVFPtr =

false

;

2804

PrimaryBase =

nullptr

;

2805

SharedVBPtrBase =

nullptr

;

2813 if

(!MaxFieldAlignment.

isZero

())

2814

PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment);

2818

MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(

const CXXRecordDecl

*RD) {

2826 bool

HasPolymorphicBaseClass =

false

;

2833 if

(

Base

.isVirtual()) {

2838 if

(!SharedVBPtrBase && BaseLayout.

hasVBPtr

()) {

2839

SharedVBPtrBase = BaseDecl;

2847

PrimaryBase = BaseDecl;

2851

layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);

2855 if

(!HasPolymorphicBaseClass)

2858

HasOwnVFPtr =

true

;

2859 else if

(!PrimaryBase) {

2863 if

(MicrosoftVTableContext::hasVtableSlot(M) &&

2864

M->size_overridden_methods() == 0) {

2865

HasOwnVFPtr =

true

;

2873 bool

CheckLeadingLayout = !PrimaryBase;

2876 if

(

Base

.isVirtual())

2887 if

(CheckLeadingLayout) {

2888

CheckLeadingLayout =

false

;

2892

layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);

2898 else if

(SharedVBPtrBase) {

2900

VBPtrOffset = Bases[SharedVBPtrBase] + Layout.

getVBPtrOffset

();

2905 if

(!isa<CXXRecordDecl>(RD))

2907 if

(RD->

hasAttr

<EmptyBasesAttr>())

2909 if

(

auto

*LVA = RD->

getAttr

<LayoutVersionAttr>())

2911 if

(LVA->getVersion() <= LangOptions::MSVC2015)

2919void

MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(

2930

ElementInfo Info = getAdjustedElementInfo(BaseLayout);

2934 bool

FoundBase =

false

;

2935 if

(UseExternalLayout) {

2936

FoundBase =

External

.getExternalNVBaseOffset(BaseDecl, BaseOffset);

2937 if

(BaseOffset > Size) {

2943 if

(MDCUsesEBO && BaseDecl->

isEmpty

() &&

2948

BaseOffset =

Size

=

Size

.alignTo(Info.Alignment);

2951

Bases.insert(std::make_pair(BaseDecl, BaseOffset));

2954

PreviousBaseLayout = &BaseLayout;

2957void

MicrosoftRecordLayoutBuilder::layoutFields(

const RecordDecl

*RD) {

2958

LastFieldIsNonZeroWidthBitfield =

false

;

2963void

MicrosoftRecordLayoutBuilder::layoutField(

const FieldDecl

*FD) {

2968

LastFieldIsNonZeroWidthBitfield =

false

;

2969

ElementInfo Info = getAdjustedElementInfo(FD);

2970

Alignment = std::max(Alignment, Info.Alignment);

2975

FieldClass->

fields

().empty();

2978 if

(UseExternalLayout) {

2981

}

else if

(IsUnion) {

2983

}

else if

(EmptySubobjects) {

2984 if

(!IsOverlappingEmptyField)

2985

FieldOffset = DataSize.

alignTo

(Info.Alignment);

2987 while

(!EmptySubobjects->CanPlaceFieldAtOffset(FD, FieldOffset)) {

2989 bool

HasBases = ParentClass && (!ParentClass->

bases

().empty() ||

2990

!ParentClass->

vbases

().empty());

2995

FieldOffset = DataSize.

alignTo

(Info.Alignment);

2997

FieldOffset += Info.Alignment;

3001

FieldOffset =

Size

.alignTo(Info.Alignment);

3003

placeFieldAtOffset(FieldOffset);

3005 if

(!IsOverlappingEmptyField)

3006

DataSize = std::max(DataSize, FieldOffset + Info.Size);

3008 Size

= std::max(Size, FieldOffset + Info.Size);

3011void

MicrosoftRecordLayoutBuilder::layoutBitField(

const FieldDecl

*FD) {

3014

layoutZeroWidthBitField(FD);

3017

ElementInfo Info = getAdjustedElementInfo(FD);

3020 if

(Width > Context.

toBits

(Info.Size))

3021

Width = Context.

toBits

(Info.Size);

3025 if

(!UseExternalLayout && !IsUnion && LastFieldIsNonZeroWidthBitfield &&

3026

CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) {

3027

placeFieldAtBitOffset(Context.

toBits

(Size) - RemainingBitsInField);

3028

RemainingBitsInField -= Width;

3031

LastFieldIsNonZeroWidthBitfield =

true

;

3032

CurrentBitfieldSize = Info.Size;

3033 if

(UseExternalLayout) {

3034 auto

FieldBitOffset =

External

.getExternalFieldOffset(FD);

3035

placeFieldAtBitOffset(FieldBitOffset);

3037

llvm::alignDown(FieldBitOffset, Context.

toBits

(Info.Alignment)) +

3038

Context.

toBits

(Info.Size));

3039 Size

= std::max(Size, NewSize);

3040

Alignment = std::max(Alignment, Info.Alignment);

3041

}

else if

(IsUnion) {

3043 Size

= std::max(Size, Info.Size);

3048

placeFieldAtOffset(FieldOffset);

3049 Size

= FieldOffset + Info.Size;

3050

Alignment = std::max(Alignment, Info.Alignment);

3051

RemainingBitsInField = Context.

toBits

(Info.Size) - Width;

3057

MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(

const FieldDecl

*FD) {

3060 if

(!LastFieldIsNonZeroWidthBitfield) {

3066

LastFieldIsNonZeroWidthBitfield =

false

;

3067

ElementInfo Info = getAdjustedElementInfo(FD);

3070 Size

= std::max(Size, Info.Size);

3075

placeFieldAtOffset(FieldOffset);

3077

Alignment = std::max(Alignment, Info.Alignment);

3082void

MicrosoftRecordLayoutBuilder::injectVBPtr(

const CXXRecordDecl

*RD) {

3083 if

(!HasVBPtr || SharedVBPtrBase)

3088

VBPtrOffset = VBPtrOffset.

alignTo

(PointerInfo.Alignment);

3090 CharUnits

FieldStart = VBPtrOffset + PointerInfo.Size;

3093 if

(UseExternalLayout) {

3096 if

(Size < FieldStart)

3102 CharUnits

Offset = (FieldStart - InjectionSite)

3103

.alignTo(std::max(RequiredAlignment, Alignment));

3105 for

(uint64_t &FieldOffset : FieldOffsets)

3106

FieldOffset += Context.

toBits

(Offset);

3107 for

(BaseOffsetsMapTy::value_type &

Base

: Bases)

3108 if

(

Base

.second >= InjectionSite)

3109 Base

.second += Offset;

3112void

MicrosoftRecordLayoutBuilder::injectVFPtr(

const CXXRecordDecl

*RD) {

3118

PointerInfo.Size.alignTo(std::max(RequiredAlignment, Alignment));

3122

VBPtrOffset += Offset;

3124 if

(UseExternalLayout) {

3127 if

(

Size

.isZero())

3136 for

(uint64_t &FieldOffset : FieldOffsets)

3137

FieldOffset += Context.

toBits

(Offset);

3138 for

(BaseOffsetsMapTy::value_type &

Base

: Bases)

3139 Base

.second += Offset;

3142void

MicrosoftRecordLayoutBuilder::layoutVirtualBases(

const CXXRecordDecl

*RD) {

3147 CharUnits

VtorDispAlignment = VtorDispSize;

3149 if

(!MaxFieldAlignment.

isZero

())

3150

VtorDispAlignment = std::min(VtorDispAlignment, MaxFieldAlignment);

3155 const CXXRecordDecl

*BaseDecl = VBase.getType()->getAsCXXRecordDecl();

3160

VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment);

3163

computeVtorDispSet(HasVtorDispSet, RD);

3167 const CXXRecordDecl

*BaseDecl = VBase.getType()->getAsCXXRecordDecl();

3169 bool

HasVtordisp = HasVtorDispSet.contains(BaseDecl);

3178 Size

=

Size

.alignTo(VtorDispAlignment) + VtorDispSize;

3179

Alignment = std::max(VtorDispAlignment, Alignment);

3182

ElementInfo Info = getAdjustedElementInfo(BaseLayout);

3186 if

(UseExternalLayout) {

3187 if

(!

External

.getExternalVBaseOffset(BaseDecl, BaseOffset))

3190

BaseOffset =

Size

.alignTo(Info.Alignment);

3192

assert(BaseOffset >= Size &&

"base offset already allocated"

);

3194

VBases.insert(std::make_pair(BaseDecl,

3197

PreviousBaseLayout = &BaseLayout;

3201void

MicrosoftRecordLayoutBuilder::finalizeLayout(

const RecordDecl

*RD) {

3205 if

(!RequiredAlignment.isZero()) {

3206

Alignment = std::max(Alignment, RequiredAlignment);

3207 auto

RoundingAlignment = Alignment;

3208 if

(!MaxFieldAlignment.

isZero

())

3209

RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);

3210

RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment);

3211 Size

=

Size

.alignTo(RoundingAlignment);

3213 if

(

Size

.isZero()) {

3214 if

(!

recordUsesEBO

(RD) || !cast<CXXRecordDecl>(RD)->isEmpty()) {

3215

EndsWithZeroSizedObject =

true

;

3216

LeadsWithZeroSizedBase =

true

;

3220 if

(RequiredAlignment >= MinEmptyStructSize)

3223 Size

= MinEmptyStructSize;

3226 if

(UseExternalLayout) {

3237

BasesWithOverriddenMethods,

3239 if

(BasesWithOverriddenMethods.count(RD))

3244 if

(!

Base

.isVirtual() &&

3246 Base

.getType()->getAsCXXRecordDecl()))

3251void

MicrosoftRecordLayoutBuilder::computeVtorDispSet(

3252

llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtordispSet,

3261

HasVtordispSet.insert(BaseDecl);

3272 if

(bi.second.hasVtorDisp())

3273

HasVtordispSet.insert(bi.first);

3293 if

(MicrosoftVTableContext::hasVtableSlot(MD) &&

3294

!isa<CXXDestructorDecl>(MD) && !MD->isPureVirtual())

3296 while

(!Work.empty()) {

3300 if

(MethodRange.begin() == MethodRange.end())

3301

BasesWithOverriddenMethods.insert(MD->

getParent

());

3303

Work.insert(MethodRange.begin(), MethodRange.end());

3311 if

(!HasVtordispSet.count(BaseDecl) &&

3313

HasVtordispSet.insert(BaseDecl);

3327 if

(

D

->hasExternalLexicalStorage() && !

D

->getDefinition())

3332 D

=

D

->getDefinition();

3333

assert(

D

&&

"Cannot get layout of forward declarations!"

);

3334

assert(!

D

->

isInvalidDecl

() &&

"Cannot get layout of invalid decl!"

);

3335

assert(

D

->isCompleteDefinition() &&

"Cannot layout type before complete!"

);

3341 if

(Entry)

return

*Entry;

3346 if

(

const auto

*RD = dyn_cast<CXXRecordDecl>(

D

)) {

3347

EmptySubobjectMap EmptySubobjects(*

this

, RD);

3348

MicrosoftRecordLayoutBuilder Builder(*

this

, &EmptySubobjects);

3349

Builder.cxxLayout(RD);

3351

*

this

, Builder.Size, Builder.Alignment, Builder.Alignment,

3352

Builder.Alignment, Builder.RequiredAlignment, Builder.HasOwnVFPtr,

3353

Builder.HasOwnVFPtr || Builder.PrimaryBase, Builder.VBPtrOffset,

3354

Builder.DataSize, Builder.FieldOffsets, Builder.NonVirtualSize,

3356

Builder.PrimaryBase,

false

, Builder.SharedVBPtrBase,

3357

Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,

3358

Builder.Bases, Builder.VBases);

3360

MicrosoftRecordLayoutBuilder Builder(*

this

,

nullptr

);

3361

Builder.layout(

D

);

3363

*

this

, Builder.Size, Builder.Alignment, Builder.Alignment,

3364

Builder.Alignment, Builder.RequiredAlignment, Builder.Size,

3365

Builder.FieldOffsets);

3368 if

(

const auto

*RD = dyn_cast<CXXRecordDecl>(

D

)) {

3369

EmptySubobjectMap EmptySubobjects(*

this

, RD);

3370

ItaniumRecordLayoutBuilder Builder(*

this

, &EmptySubobjects);

3376 bool

skipTailPadding =

3381

skipTailPadding ? Builder.getSize() : Builder.getDataSize();

3383

skipTailPadding ? DataSize : Builder.NonVirtualSize;

3385

*

this

, Builder.getSize(), Builder.Alignment,

3386

Builder.PreferredAlignment, Builder.UnadjustedAlignment,

3390

NonVirtualSize, Builder.NonVirtualAlignment,

3391

Builder.PreferredNVAlignment,

3392

EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,

3393

Builder.PrimaryBaseIsVirtual,

nullptr

,

false

,

false

, Builder.Bases,

3396

ItaniumRecordLayoutBuilder Builder(*

this

,

nullptr

);

3397

Builder.Layout(

D

);

3400

*

this

, Builder.getSize(), Builder.Alignment,

3401

Builder.PreferredAlignment, Builder.UnadjustedAlignment,

3403

Builder.Alignment, Builder.getSize(), Builder.FieldOffsets);

3407

ASTRecordLayouts[

D

] = NewEntry;

3410

llvm::outs() <<

"\n*** Dumping AST Record Layout\n"

;

3421

assert(RD->

getDefinition

() &&

"Cannot get key function for forward decl!"

);

3435

KeyFunctions[RD] =

const_cast<Decl

*

>

(

Result

);

3437 return

cast_or_null<CXXMethodDecl>(

Result

);

3442 "not working with method declaration from class definition"

);

3447 const auto

&Map = KeyFunctions;

3448 auto

I = Map.find(Method->

getParent

());

3451 if

(I == Map.end())

return

;

3459

KeyFunctions.erase(Method->

getParent

());

3469

uint64_t OffsetInBits;

3470 if

(

const FieldDecl

*FD = dyn_cast<FieldDecl>(VD)) {

3480 return

OffsetInBits;

3508 for

(

const ObjCIvarDecl

*IVD = Container->all_declared_ivar_begin();

3509

IVD; IVD = IVD->getNextIvar()) {

3514

assert(Index < RL->getFieldCount() &&

"Ivar is not inside record layout!"

);

3528 if

(

D

->hasExternalLexicalStorage() && !

D

->getDefinition())

3530 D

=

D

->getDefinition();

3531

assert(

D

&& !

D

->

isInvalidDecl

() &&

D

->isThisDeclarationADefinition() &&

3532 "Invalid interface decl!"

);

3547 if

(SynthCount == 0)

3548 return

getObjCLayout(

D

,

nullptr

);

3551

ItaniumRecordLayoutBuilder Builder(*

this

,

nullptr

);

3552

Builder.Layout(

D

);

3555

*

this

, Builder.getSize(), Builder.Alignment, Builder.PreferredAlignment,

3556

Builder.UnadjustedAlignment,

3558

Builder.Alignment, Builder.getDataSize(), Builder.FieldOffsets);

3560

ObjCLayouts[Key] = NewEntry;

3566 CharUnits

Offset,

unsigned

IndentLevel) {

3567

OS << llvm::format(

"%10"

PRId64

" | "

, (int64_t)Offset.getQuantity());

3568

OS.indent(IndentLevel * 2);

3572 unsigned Begin

,

unsigned

Width,

3573 unsigned

IndentLevel) {

3576

llvm::raw_svector_ostream BufferOS(Buffer);

3577

BufferOS << Offset.getQuantity() <<

':'

;

3581

BufferOS <<

Begin

<<

'-'

<< (

Begin

+ Width - 1);

3585

OS << llvm::right_justify(Buffer, 10) <<

" | "

;

3586

OS.indent(IndentLevel * 2);

3591

OS.indent(IndentLevel * 2);

3597 unsigned

IndentLevel,

3598 const char

* Description,

3600 bool

IncludeVirtualBases) {

3602 auto

CXXRD = dyn_cast<CXXRecordDecl>(RD);

3605

OS <<

C

.getTypeDeclType(

const_cast<RecordDecl

*

>

(RD));

3607

OS <<

' '

<< Description;

3608 if

(CXXRD && CXXRD->isEmpty())

3621 if

(CXXRD->isDynamicClass() && !PrimaryBase && !

isMsLayout

(

C

)) {

3623

OS <<

'('

<< *RD <<

" vtable pointer)\n"

;

3624

}

else if

(HasOwnVFPtr) {

3627

OS <<

'('

<< *RD <<

" vftable pointer)\n"

;

3633

assert(!

Base

.getType()->isDependentType() &&

3634 "Cannot layout class with dependent bases."

);

3635 if

(!

Base

.isVirtual())

3636

Bases.push_back(

Base

.getType()->getAsCXXRecordDecl());

3649 Base

== PrimaryBase ?

"(primary base)"

:

"(base)"

,

3657

OS <<

'('

<< *RD <<

" vbtable pointer)\n"

;

3663

uint64_t LocalFieldOffsetInBits =

3666

Offset +

C

.toCharUnitsFromBits(LocalFieldOffsetInBits);

3669 if

(

auto

RT = Field->getType()->getAs<

RecordType

>()) {

3671

Field->getName().data(),

3677 if

(Field->isBitField()) {

3678

uint64_t LocalFieldByteOffsetInBits =

C

.toBits(FieldOffset - Offset);

3679 unsigned Begin

= LocalFieldOffsetInBits - LocalFieldByteOffsetInBits;

3680 unsigned

Width = Field->getBitWidthValue();

3685 const QualType

&FieldType =

C

.getLangOpts().DumpRecordLayoutsCanonical

3686

? Field->getType().getCanonicalType()

3688

OS << FieldType <<

' '

<< *Field <<

'\n'

;

3692 if

(CXXRD && IncludeVirtualBases) {

3697

assert(

Base

.isVirtual() &&

"Found non-virtual class!"

);

3702 if

(VtorDisps.find(VBase)->second.hasVtorDisp()) {

3704

OS <<

"(vtordisp for vbase "

<< *VBase <<

")\n"

;

3709 "(primary virtual base)"

:

"(virtual base)"

,

3715 if

(!PrintSizeInfo)

return

;

3722 if

(

C

.getTargetInfo().defaultsToAIXPowerAlignment())

3730 if

(

C

.getTargetInfo().defaultsToAIXPowerAlignment())

3731

OS <<

", preferrednvalign=" 3738 bool

Simple)

const

{

3755

OS <<

"\nLayout: "

;

3756

OS <<

"<ASTRecordLayout\n"

;

3761 if

(

Target

->defaultsToAIXPowerAlignment())

3764 if

(

const CXXRecordDecl

*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {

3765

OS <<

" BaseOffsets: ["

;

3767 for

(

auto

I : CXXRD->bases()) {

3772 Base

= I.getType()->getAsCXXRecordDecl();

3773

OS << Info.CXXInfo->BaseOffsets[

Base

].getQuantity();

3776

OS <<

" VBaseOffsets: ["

;

3778 for

(

auto

I : CXXRD->vbases()) {

3781

VBase = I.getType()->getAsCXXRecordDecl();

3782

OS << Info.CXXInfo->VBaseOffsets[VBase].VBaseOffset.getQuantity();

3786

OS <<

" FieldOffsets: ["

;

3787 for

(

unsigned

i = 0, e = Info.

getFieldCount

(); i != e; ++i) {

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)

llvm::MachO::Target Target

static const CXXMethodDecl * computeKeyFunction(ASTContext &Context, const CXXRecordDecl *RD)

static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD)

Does the target C++ ABI require us to skip over the tail-padding of the given class (considering it a...

static bool isAIXLayout(const ASTContext &Context)

static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel)

static uint64_t roundUpSizeToCharAlignment(uint64_t Size, const ASTContext &Context)

static void PrintOffset(raw_ostream &OS, CharUnits Offset, unsigned IndentLevel)

static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag)

Get diagnostic select index for tag kind for field padding diagnostic message.

static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, const ASTContext &C, CharUnits Offset, unsigned IndentLevel, const char *Description, bool PrintSizeInfo, bool IncludeVirtualBases)

static bool isMsLayout(const ASTContext &Context)

static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)

static bool RequiresVtordisp(const llvm::SmallPtrSetImpl< const CXXRecordDecl * > &BasesWithOverriddenMethods, const CXXRecordDecl *RD)

static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset, unsigned Begin, unsigned Width, unsigned IndentLevel)

static bool recordUsesEBO(const RecordDecl *RD)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const ConstantArrayType * getAsConstantArrayType(QualType T) const

CharUnits getTypeAlignInChars(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in characters.

uint64_t getFieldOffset(const ValueDecl *FD) const

Get the offset of a FieldDecl or IndirectFieldDecl, in bits.

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple=false) const

const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)

Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...

const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const

Get or compute information about the layout of the specified Objective-C implementation.

QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const

Return the unique reference to the type for the specified type declaration.

const LangOptions & getLangOpts() const

const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const

Get or compute information about the layout of the specified Objective-C interface.

QualType getBaseElementType(const ArrayType *VAT) const

Return the innermost element type of an array type.

unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const

bool isNearlyEmpty(const CXXRecordDecl *RD) const

const TargetInfo * getAuxTargetInfo() const

CanQualType UnsignedLongTy

TypeInfo getTypeInfo(const Type *T) const

Get the size and alignment of the specified complete type in bits.

bool isAlignmentRequired(const Type *T) const

Determine if the alignment the type has was required using an alignment attribute.

void setNonKeyFunction(const CXXMethodDecl *method)

Observe that the given method cannot be a key function.

TypeInfoChars getTypeInfoInChars(const Type *T) const

int64_t toBits(CharUnits CharSize) const

Convert a size in characters to a size in bits.

uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) const

Get the offset of an ObjCIvarDecl in bits.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

CanQualType UnsignedCharTy

CanQualType UnsignedIntTy

CanQualType UnsignedLongLongTy

CanQualType UnsignedShortTy

DiagnosticsEngine & getDiagnostics() const

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

ExternalASTSource * getExternalSource() const

Retrieve a pointer to the external AST source associated with this AST context, if any.

uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const

Return number of constant array elements.

uint64_t getCharWidth() const

Return the size of the character type, in bits.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

bool endsWithZeroSizedObject() const

bool hasOwnVFPtr() const

hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...

CharUnits getAlignment() const

getAlignment - Get the record alignment in characters.

CharUnits getPreferredAlignment() const

getPreferredFieldAlignment - Get the record preferred alignment in characters.

bool hasOwnVBPtr() const

hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...

llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy

CharUnits getSize() const

getSize - Get the record size in characters.

unsigned getFieldCount() const

getFieldCount - Get the number of fields in the layout.

bool hasVBPtr() const

hasVBPtr - Does this class have a virtual function table pointer.

bool leadsWithZeroSizedBase() const

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getNonVirtualAlignment() const

getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...

CharUnits getVBPtrOffset() const

getVBPtrOffset - Get the offset for virtual base table pointer.

CharUnits getDataSize() const

getDataSize() - Get the record data size, which is the record size without tail padding,...

CharUnits getRequiredAlignment() const

CharUnits getSizeOfLargestEmptySubobject() const

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

CharUnits getPreferredNVAlignment() const

getPreferredNVAlignment - Get the preferred non-virtual alignment (in chars) of an object,...

CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const

getVBaseClassOffset - Get the offset, in chars, for the given base class.

const VBaseOffsetsMapTy & getVBaseOffsetsMap() const

const CXXRecordDecl * getPrimaryBase() const

getPrimaryBase - Get the primary base for this record.

bool hasExtendableVFPtr() const

hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...

bool isPrimaryBaseVirtual() const

isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.

CharUnits getNonVirtualSize() const

getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...

This class is used for builtin types like 'int'.

Represents a base class of a C++ class.

A set of all the primary bases for a class.

Represents a static or instance method of a struct/union/class.

overridden_method_range overridden_methods() const

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

Represents a C++ struct/union/class.

void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet &Bases) const

Get the indirect primary bases for this class.

bool hasUserDeclaredDestructor() const

Determine whether this class has a user-declared destructor.

method_range methods() const

CXXRecordDecl * getDefinition() const

bool isPolymorphic() const

Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...

TemplateSpecializationKind getTemplateSpecializationKind() const

Determine whether this particular class is a specialization or instantiation of a class template or m...

base_class_range vbases()

bool isDynamicClass() const

bool isCXX11StandardLayout() const

Determine whether this class was standard-layout per C++11 [class]p7, specifically using the C++11 ru...

bool hasUserDeclaredConstructor() const

Determine whether this class has any user-declared constructors.

bool isPOD() const

Whether this class is a POD-type (C++ [class]p4)

MSVtorDispMode getMSVtorDispMode() const

Controls when vtordisps will be emitted if this record is used as a virtual base.

bool isEmpty() const

Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).

bool isTrivial() const

Determine whether this class is considered trivial.

unsigned getNumVBases() const

Retrieves the number of virtual base classes of this class.

CharUnits - This is an opaque type for sizes expressed in character units.

bool isZero() const

isZero - Test whether the quantity equals zero.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits One()

One - Construct a CharUnits quantity of one.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

CharUnits alignTo(const CharUnits &Align) const

alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

Complex values, per C99 6.2.5p11.

Represents the canonical version of C arrays with a specified constant size.

lookup_result lookup(DeclarationName Name) const

lookup - Find the declarations (if any) with the given Name in this context.

Decl - This represents one declaration (or definition), e.g.

Decl * getMostRecentDecl()

Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...

unsigned getMaxAlignment() const

getMaxAlignment - return the maximum alignment specified by attributes on this decl,...

bool isInvalidDecl() const

SourceLocation getLocation() const

A little helper class used to produce diagnostics.

A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

Abstract interface for external sources of AST nodes.

virtual void CompleteType(TagDecl *Tag)

Gives the external AST source an opportunity to complete an incomplete type.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getBitWidthValue() const

Computes the bit width of this field, if this is a bit field.

unsigned getFieldIndex() const

Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

bool isPotentiallyOverlapping() const

Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...

Represents a function declaration or definition.

bool isInlineSpecified() const

Determine whether the "inline" keyword was specified for this function.

Represents a field injected from an anonymous union/struct into the parent scope.

ArrayRef< NamedDecl * > chain() const

@ Ver6

Attempt to be ABI-compatible with code generated by Clang 6.0.x (SVN r321711).

@ Ver15

Attempt to be ABI-compatible with code generated by Clang 15.0.x.

This represents a decl that may have a name.

bool isExternallyVisible() const

ObjCContainerDecl - Represents a container for method declarations.

ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...

Represents an ObjC class declaration.

ObjCIvarDecl - Represents an ObjC instance variable.

ObjCInterfaceDecl * getContainingInterface()

Return the class interface that this ivar is logically contained in; this is either the interface whe...

ObjCIvarDecl * getCanonicalDecl() override

Retrieves the canonical declaration of this field.

A (possibly-)qualified type.

Represents a struct/union/class.

bool isMsStruct(const ASTContext &C) const

Get whether or not this is an ms_struct which can be turned on with an attribute, pragma,...

field_range fields() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

decl_type * getFirstDecl()

Return the first declaration of this declaration or itself if this is the only declaration.

Encodes a location in the source.

The basic abstraction for the target C++ ABI.

TailPaddingUseRules getTailPaddingUseRules() const

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

bool canKeyFunctionBeInline() const

Can an out-of-line inline function serve as a key function?

@ AlwaysUseTailPadding

The tail-padding of a base class is always theoretically available, even if it's POD.

@ UseTailPaddingUnlessPOD11

Only allocate objects in the tail padding of a base class if the base class is not POD according to t...

@ UseTailPaddingUnlessPOD03

Only allocate objects in the tail padding of a base class if the base class is not POD according to t...

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

bool useLeadingZeroLengthBitfield() const

Check whether zero length bitfield alignment is respected if they are leading members.

uint64_t getPointerWidth(LangAS AddrSpace) const

Return the width of pointers on this target, for the specified address space.

virtual bool hasPS4DLLImportExport() const

virtual bool defaultsToAIXPowerAlignment() const

Whether target defaults to the power alignment rules of AIX.

unsigned getCharAlign() const

unsigned getZeroLengthBitfieldBoundary() const

Get the fixed alignment value in bits for a member that follows a zero length bitfield.

bool useExplicitBitFieldAlignment() const

Check whether explicit bitfield alignment attributes should be.

uint64_t getPointerAlign(LangAS AddrSpace) const

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

unsigned getCharWidth() const

bool useZeroLengthBitfieldAlignment() const

Check whether zero length bitfields should force alignment of the next member.

bool useBitFieldTypeAlignment() const

Check whether the alignment of bit-field types is respected when laying out structures.

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

const Type * getBaseElementTypeUnsafe() const

Get the base element type of this type, potentially discarding type qualifiers.

const T * getAs() const

Member-template getAs<specific type>'.

const Type * getUnqualifiedDesugaredType() const

Return the specified type with any "sugar" removed from the type, removing any typedefs,...

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Defines the clang::TargetInfo interface.

bool Zero(InterpState &S, CodePtr OpPC)

The JSON file list parser is used to communicate input to InstallAPI.

@ External

External linkage, which indicates that the entity can be referred to from other translation units.

@ Result

The result type of a method or function.

TagTypeKind

The kind of a tag type.

@ Interface

The "__interface" keyword.

@ Struct

The "struct" keyword.

@ Class

The "class" keyword.

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

TemplateSpecializationKind

Describes the kind of template specialization that a particular template specialization declaration r...

@ TSK_ExplicitInstantiationDefinition

This template specialization was instantiated from a template due to an explicit instantiation defini...

@ TSK_ExplicitInstantiationDeclaration

This template specialization was instantiated from a template due to an explicit instantiation declar...

@ TSK_ImplicitInstantiation

This template specialization was implicitly instantiated from a template.

@ None

The alignment was not explicit in code.

@ RequiredByTypedef

The alignment comes from an alignment attribute on a typedef.

@ RequiredByRecord

The alignment comes from an alignment attribute on a record type.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

bool isValid() const

Whether this pointer is non-NULL.

bool isOffset() const

Whether this pointer is currently stored as an offset.

T * get(ExternalASTSource *Source) const

Retrieve the pointer to the AST node that this lazy pointer points to.

All virtual base related information about a given record decl.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4