summaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-11-05 17:18:09 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-11-05 17:18:09 +0000
commit8f57cb0305232cb53fff00ef151ca716766f3437 (patch)
tree8b316eca843681b024034db1125707173b9adb4a /lib/AST
parent51fb8b013e7734b795139f49d3b1f77c539be20a (diff)
Notes
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp5
-rw-r--r--lib/AST/DeclarationName.cpp50
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp69
-rw-r--r--lib/AST/RecordLayoutBuilder.h9
-rw-r--r--lib/AST/Type.cpp6
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;