diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-05 17:18:09 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-11-05 17:18:09 +0000 |
commit | 8f57cb0305232cb53fff00ef151ca716766f3437 (patch) | |
tree | 8b316eca843681b024034db1125707173b9adb4a /lib/AST | |
parent | 51fb8b013e7734b795139f49d3b1f77c539be20a (diff) |
Notes
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 5 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 50 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 69 | ||||
-rw-r--r-- | lib/AST/RecordLayoutBuilder.h | 9 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 6 |
5 files changed, 92 insertions, 47 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index aef3d29894150..8562249479ca4 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1374,7 +1374,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) { // If the pointee or class type isn't canonical, this won't be a canonical // type either, so fill in the canonical type field. QualType Canonical; - if (!T.isCanonical()) { + if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) { Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); // Get the new insert position for the node we care about. @@ -1395,7 +1395,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, const llvm::APInt &ArySizeIn, ArrayType::ArraySizeModifier ASM, unsigned EltTypeQuals) { - assert((EltTy->isDependentType() || EltTy->isConstantSizeType()) && + assert((EltTy->isDependentType() || + EltTy->isIncompleteType() || EltTy->isConstantSizeType()) && "Constant array of VLAs is illegal!"); // Convert the array size into a canonical width matching the pointer size for diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 56a597570dd09..8664c508615fe 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeOrdering.h" #include "clang/AST/Decl.h" #include "clang/Basic/IdentifierTable.h" #include "llvm/ADT/DenseMap.h" @@ -49,11 +50,50 @@ public: }; bool operator<(DeclarationName LHS, DeclarationName RHS) { - if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) - if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) - return LhsId->getName() < RhsId->getName(); - - return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger(); + if (LHS.getNameKind() != RHS.getNameKind()) + return LHS.getNameKind() < RHS.getNameKind(); + + switch (LHS.getNameKind()) { + case DeclarationName::Identifier: + return LHS.getAsIdentifierInfo()->getName() < + RHS.getAsIdentifierInfo()->getName(); + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: { + Selector LHSSelector = LHS.getObjCSelector(); + Selector RHSSelector = RHS.getObjCSelector(); + for (unsigned I = 0, + N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs()); + I != N; ++I) { + IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I); + IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I); + if (!LHSId || !RHSId) + return LHSId && !RHSId; + + switch (LHSId->getName().compare(RHSId->getName())) { + case -1: return true; + case 1: return false; + default: break; + } + } + + return LHSSelector.getNumArgs() < RHSSelector.getNumArgs(); + } + + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()); + + case DeclarationName::CXXOperatorName: + return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator(); + + case DeclarationName::CXXUsingDirective: + return false; + } + + return false; } } // end namespace clang diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 0b159c3a7bd86..021c53e9514f6 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -174,9 +174,24 @@ void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { LayoutBaseNonVirtually(RD, true); } -void ASTRecordLayoutBuilder::LayoutVirtualBases(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; + } + assert(0 && "missing base"); + return 0; +} + + +void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class, + const CXXRecordDecl *RD, const CXXRecordDecl *PB, - int64_t Offset, + uint64_t Offset, llvm::SmallSet<const CXXRecordDecl*, 32> &mark, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), @@ -185,20 +200,7 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, "Cannot layout class with dependent bases."); const CXXRecordDecl *Base = cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); -#if 0 - const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base); - const CXXRecordDecl *PB = L.getPrimaryBase(); - if (PB && L.getPrimaryBaseWasVirtual() - && IndirectPrimary.count(PB)) { - int64_t BaseOffset; - // FIXME: calculate this. - BaseOffset = (1<<63) | (1<<31); - VBases.push_back(PB); - VBaseOffsets.push_back(BaseOffset); - } -#endif - int64_t BaseOffset = Offset;; - // FIXME: Calculate BaseOffset. + uint64_t BaseOffset = Offset; if (i->isVirtual()) { if (Base == PB) { // Only lay things out once. @@ -220,11 +222,20 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, LayoutVirtualBase(Base); BaseOffset = VBases.back().second; } + } else { + if (RD == Class) + BaseOffset = getBaseOffset(Base); + else { + const ASTRecordLayout &Layout + = Ctx.getASTRecordLayout(RD); + BaseOffset = Offset + Layout.getBaseClassOffset(Base); + } } + if (Base->getNumVBases()) { const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base); const CXXRecordDecl *PB = L.getPrimaryBase(); - LayoutVirtualBases(Base, PB, BaseOffset, mark, IndirectPrimary); + LayoutVirtualBases(Class, Base, PB, BaseOffset, mark, IndirectPrimary); } } } @@ -295,7 +306,7 @@ bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD, const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); uint64_t NumElements = Ctx.getConstantArrayElementCount(AT); - unsigned ElementOffset = Offset; + uint64_t ElementOffset = Offset; for (uint64_t I = 0; I != NumElements; ++I) { if (!canPlaceRecordAtOffset(RD, ElementOffset)) return false; @@ -366,7 +377,7 @@ ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD, const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); uint64_t NumElements = Ctx.getConstantArrayElementCount(AT); - unsigned ElementOffset = Offset; + uint64_t ElementOffset = Offset; for (uint64_t I = 0; I != NumElements; ++I) { UpdateEmptyClassOffsets(RD, ElementOffset); @@ -419,29 +430,13 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVirtualBase) { // Layout the base. - unsigned Offset = LayoutBase(RD); + uint64_t Offset = LayoutBase(RD); // Add base class offsets. if (IsVirtualBase) VBases.push_back(std::make_pair(RD, Offset)); else Bases.push_back(std::make_pair(RD, Offset)); - -#if 0 - // And now add offsets for all our primary virtual bases as well, so - // they all have offsets. - const ASTRecordLayout *L = &BaseInfo; - const CXXRecordDecl *PB = L->getPrimaryBase(); - while (PB) { - if (L->getPrimaryBaseWasVirtual()) { - VBases.push_back(PB); - VBaseOffsets.push_back(Size); - } - PB = L->getPrimaryBase(); - if (PB) - L = &Ctx.getASTRecordLayout(PB); - } -#endif } void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { @@ -476,7 +471,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { if (RD) { llvm::SmallSet<const CXXRecordDecl*, 32> mark; - LayoutVirtualBases(RD, PrimaryBase, 0, mark, IndirectPrimaryBases); + LayoutVirtualBases(RD, RD, PrimaryBase, 0, mark, IndirectPrimaryBases); } // Finally, round the size of the total struct up to the alignment of the diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index b57b37d0df4d5..077072343b1bd 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -99,9 +99,9 @@ class ASTRecordLayoutBuilder { void LayoutNonVirtualBases(const CXXRecordDecl *RD); void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase); void LayoutVirtualBase(const CXXRecordDecl *RD); - void LayoutVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *PB, - int64_t Offset, - llvm::SmallSet<const CXXRecordDecl*, 32> &mark, + void LayoutVirtualBases(const CXXRecordDecl *Class, const CXXRecordDecl *RD, + const CXXRecordDecl *PB, uint64_t Offset, + llvm::SmallSet<const CXXRecordDecl*, 32> &mark, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary); /// canPlaceRecordAtOffset - Return whether a record (either a base class @@ -124,6 +124,9 @@ class ASTRecordLayoutBuilder { /// given offset. void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset); + /// getBaseOffset - Get the offset of a direct base class. + uint64_t getBaseOffset(const CXXRecordDecl *Base); + /// FinishLayout - Finalize record layout. Adjust record size based on the /// alignment. void FinishLayout(); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 3608d34c691d3..779f6808b6c18 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -550,6 +550,12 @@ bool Type::isIncompleteType() const { // A tagged type (struct/union/enum/class) is incomplete if the decl is a // forward declaration, but not a full definition (C99 6.2.5p22). return !cast<TagType>(CanonicalType)->getDecl()->isDefinition(); + case ConstantArray: + // An array is incomplete if its element type is incomplete + // (C++ [dcl.array]p1). + // We don't handle variable arrays (they're not allowed in C++) or + // dependent-sized arrays (dependent types are never treated as incomplete). + return cast<ArrayType>(CanonicalType)->getElementType()->isIncompleteType(); case IncompleteArray: // An array of unknown size is an incomplete type (C99 6.2.5p22). return true; |