diff options
author | Anders Carlsson <andersca@mac.com> | 2010-03-11 04:10:39 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-03-11 04:10:39 +0000 |
commit | 147b5ddc6c8618a9d70a83f90de409e444ae705b (patch) | |
tree | c2b12d63650ee38bbbc0b008675e4fa5d9216d29 | |
parent | 584e1dfaf6ab682cebe4fe51f55f0ae3215d303f (diff) |
Replace the class offset vectors in RecordLayoutBuilder with maps instead so we'll have faster lookup and so we can detect duplicates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98231 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/RecordLayout.h | 16 | ||||
-rw-r--r-- | lib/AST/RecordLayout.cpp | 26 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 44 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.h | 11 |
4 files changed, 47 insertions, 50 deletions
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index cd25969db0..e78476ef51 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -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() {} diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp index 68357450fb..ade2483722 100644 --- a/lib/AST/RecordLayout.cpp +++ b/lib/AST/RecordLayout.cpp @@ -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()) { diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index d9fa11d5a8..2882d64d17 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -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 * diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index ae3182a6a6..933e35025f 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -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. |