mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 05:06:06 +00:00
Replace the class offset vectors in RecordLayoutBuilder with maps instead so we'll have faster lookup and so we can detect duplicates.
llvm-svn: 98231
This commit is contained in:
parent
f2fa75bdbb
commit
6a84889d3f
@ -112,13 +112,14 @@ private:
|
||||
/// PrimaryBase - The primary base info for this record.
|
||||
PrimaryBaseInfo PrimaryBase;
|
||||
|
||||
/// BaseOffsets - Contains a map from base classes to their offset.
|
||||
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy;
|
||||
|
||||
/// BaseOffsets - Contains a map from base classes to their offset.
|
||||
BaseOffsetsMapTy BaseOffsets;
|
||||
|
||||
/// VBaseOffsets - Contains a map from vbase classes to their offset.
|
||||
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
|
||||
llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
|
||||
BaseOffsetsMapTy VBaseOffsets;
|
||||
};
|
||||
|
||||
/// CXXInfo - If the record layout is for a C++ record, this will have
|
||||
@ -133,15 +134,14 @@ private:
|
||||
unsigned fieldcount);
|
||||
|
||||
// Constructor for C++ records.
|
||||
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
|
||||
ASTRecordLayout(ASTContext &Ctx,
|
||||
uint64_t size, unsigned alignment, uint64_t datasize,
|
||||
const uint64_t *fieldoffsets, unsigned fieldcount,
|
||||
uint64_t nonvirtualsize, unsigned nonvirtualalign,
|
||||
const PrimaryBaseInfo &PrimaryBase,
|
||||
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
|
||||
unsigned numbases,
|
||||
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
|
||||
unsigned numvbases);
|
||||
const BaseOffsetsMapTy& BaseOffsets,
|
||||
const BaseOffsetsMapTy& VBaseOffsets);
|
||||
|
||||
~ASTRecordLayout() {}
|
||||
|
||||
|
@ -38,17 +38,15 @@ ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignm
|
||||
|
||||
// Constructor for C++ records.
|
||||
ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
|
||||
uint64_t size, unsigned alignment,
|
||||
uint64_t datasize,
|
||||
const uint64_t *fieldoffsets,
|
||||
unsigned fieldcount,
|
||||
uint64_t nonvirtualsize,
|
||||
unsigned nonvirtualalign,
|
||||
const PrimaryBaseInfo &PrimaryBase,
|
||||
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
|
||||
unsigned numbases,
|
||||
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
|
||||
unsigned numvbases)
|
||||
uint64_t size, unsigned alignment,
|
||||
uint64_t datasize,
|
||||
const uint64_t *fieldoffsets,
|
||||
unsigned fieldcount,
|
||||
uint64_t nonvirtualsize,
|
||||
unsigned nonvirtualalign,
|
||||
const PrimaryBaseInfo &PrimaryBase,
|
||||
const BaseOffsetsMapTy& BaseOffsets,
|
||||
const BaseOffsetsMapTy& VBaseOffsets)
|
||||
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
|
||||
FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
|
||||
{
|
||||
@ -60,10 +58,8 @@ ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
|
||||
CXXInfo->PrimaryBase = PrimaryBase;
|
||||
CXXInfo->NonVirtualSize = nonvirtualsize;
|
||||
CXXInfo->NonVirtualAlign = nonvirtualalign;
|
||||
for (unsigned i = 0; i != numbases; ++i)
|
||||
CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
|
||||
for (unsigned i = 0; i != numvbases; ++i)
|
||||
CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
|
||||
CXXInfo->BaseOffsets = BaseOffsets;
|
||||
CXXInfo->VBaseOffsets = VBaseOffsets;
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
|
||||
|
@ -159,14 +159,14 @@ void ASTRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
|
||||
}
|
||||
|
||||
uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) {
|
||||
for (size_t i = 0; i < Bases.size(); ++i) {
|
||||
if (Bases[i].first == Base)
|
||||
return Bases[i].second;
|
||||
}
|
||||
for (size_t i = 0; i < VBases.size(); ++i) {
|
||||
if (VBases[i].first == Base)
|
||||
return VBases[i].second;
|
||||
}
|
||||
ASTRecordLayout::BaseOffsetsMapTy::iterator I = Bases.find(Base);
|
||||
if (I != Bases.end())
|
||||
return I->second;
|
||||
|
||||
I = VBases.find(Base);
|
||||
if (I != VBases.end())
|
||||
return I->second;
|
||||
|
||||
assert(0 && "missing base");
|
||||
return 0;
|
||||
}
|
||||
@ -212,13 +212,15 @@ void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
|
||||
uint64_t Offset = LayoutBase(RD);
|
||||
|
||||
// Add its base class offset.
|
||||
Bases.push_back(std::make_pair(RD, Offset));
|
||||
if (!Bases.insert(std::make_pair(RD, Offset)).second)
|
||||
assert(false && "Added same base offset more than once!");
|
||||
}
|
||||
|
||||
void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
|
||||
const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *PB,
|
||||
uint64_t Offset) {
|
||||
void
|
||||
ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
|
||||
const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *PB,
|
||||
uint64_t Offset) {
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||
e = RD->bases_end(); i != e; ++i) {
|
||||
assert(!i->getType()->isDependentType() &&
|
||||
@ -234,7 +236,11 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
|
||||
// Mark it so we don't lay it out twice.
|
||||
VisitedVirtualBases.insert(Base);
|
||||
assert (IndirectPrimaryBases.count(Base) && "IndirectPrimary was wrong");
|
||||
VBases.push_back(std::make_pair(Base, Offset));
|
||||
|
||||
if (!VBases.insert(std::make_pair(Base, Offset)).second) {
|
||||
// FIXME: Enable this assertion.
|
||||
// assert(false && "Added same vbase offset more than once!");
|
||||
}
|
||||
} else if (IndirectPrimaryBases.count(Base)) {
|
||||
// Someone else will eventually lay this out.
|
||||
;
|
||||
@ -245,7 +251,7 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
|
||||
// Mark it so we don't lay it out twice.
|
||||
VisitedVirtualBases.insert(Base);
|
||||
LayoutVirtualBase(Base);
|
||||
BaseOffset = VBases.back().second;
|
||||
BaseOffset = VBases[Base];
|
||||
}
|
||||
} else {
|
||||
if (RD == Class)
|
||||
@ -269,7 +275,8 @@ void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
|
||||
uint64_t Offset = LayoutBase(RD);
|
||||
|
||||
// Add its base class offset.
|
||||
VBases.push_back(std::make_pair(RD, Offset));
|
||||
if (!VBases.insert(std::make_pair(RD, Offset)).second)
|
||||
assert(false && "Added same vbase offset more than once!");
|
||||
}
|
||||
|
||||
uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
|
||||
@ -700,10 +707,7 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
|
||||
NonVirtualSize,
|
||||
Builder.NonVirtualAlignment,
|
||||
Builder.PrimaryBase,
|
||||
Builder.Bases.data(),
|
||||
Builder.Bases.size(),
|
||||
Builder.VBases.data(),
|
||||
Builder.VBases.size());
|
||||
Builder.Bases, Builder.VBases);
|
||||
}
|
||||
|
||||
const ASTRecordLayout *
|
||||
|
@ -60,14 +60,11 @@ class ASTRecordLayoutBuilder {
|
||||
/// we're laying out.
|
||||
ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
|
||||
|
||||
typedef llvm::SmallVector<std::pair<const CXXRecordDecl *,
|
||||
uint64_t>, 4> BaseOffsetsTy;
|
||||
/// Bases - base classes and their offsets in the record.
|
||||
ASTRecordLayout::BaseOffsetsMapTy Bases;
|
||||
|
||||
/// Bases - base classes and their offsets from the record.
|
||||
BaseOffsetsTy Bases;
|
||||
|
||||
// VBases - virtual base classes and their offsets from the record.
|
||||
BaseOffsetsTy VBases;
|
||||
// VBases - virtual base classes and their offsets in the record.
|
||||
ASTRecordLayout::BaseOffsetsMapTy VBases;
|
||||
|
||||
/// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
|
||||
/// primary base classes for some other direct or indirect base class.
|
||||
|
Loading…
x
Reference in New Issue
Block a user