Switch the standard DeclarationName comparator to be a tri-valued comparator.

Use that while fixing a nasty misuse of qsort in vtable codegen which, somehow,
has not actually caused a crash.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96062 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2010-02-13 01:04:05 +00:00
Родитель c1ddcabef0
Коммит 7fe0b9ea2c
3 изменённых файлов: 42 добавлений и 26 удалений

Просмотреть файл

@ -274,30 +274,34 @@ public:
static DeclarationName getTombstoneMarker() {
return DeclarationName(uintptr_t(-2));
}
static int compare(DeclarationName LHS, DeclarationName RHS);
void dump() const;
};
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
bool operator<(DeclarationName LHS, DeclarationName RHS);
inline bool operator<(DeclarationName LHS, DeclarationName RHS) {
return DeclarationName::compare(LHS, RHS) < 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
return RHS < LHS;
return DeclarationName::compare(LHS, RHS) > 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
return !(RHS < LHS);
return DeclarationName::compare(LHS, RHS) <= 0;
}
/// Ordering on two declaration names. If both names are identifiers,
/// this provides a lexicographical ordering.
inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
return !(LHS < RHS);
return DeclarationName::compare(LHS, RHS) >= 0;
}
/// DeclarationNameTable - Used to store and retrieve DeclarationName

Просмотреть файл

@ -66,27 +66,33 @@ public:
}
};
bool operator<(DeclarationName LHS, DeclarationName RHS) {
static int compareInt(unsigned A, unsigned B) {
return (A < B ? -1 : (A > B ? 1 : 0));
}
int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
if (LHS.getNameKind() != RHS.getNameKind())
return LHS.getNameKind() < RHS.getNameKind();
return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
switch (LHS.getNameKind()) {
case DeclarationName::Identifier:
return LHS.getAsIdentifierInfo()->getName() <
RHS.getAsIdentifierInfo()->getName();
case DeclarationName::Identifier: {
IdentifierInfo *LII = LHS.getAsIdentifierInfo();
IdentifierInfo *RII = RHS.getAsIdentifierInfo();
if (!LII) return RII ? -1 : 0;
if (!RII) return 1;
return LII->getName().compare(RII->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) {
unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
for (unsigned I = 0, N = std::min(LN, RN); 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;
@ -94,27 +100,32 @@ bool operator<(DeclarationName LHS, DeclarationName RHS) {
default: break;
}
}
return LHSSelector.getNumArgs() < RHSSelector.getNumArgs();
return compareInt(LN, RN);
}
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName:
return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType());
if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
return -1;
if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
return 1;
return 0;
case DeclarationName::CXXOperatorName:
return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
return compareInt(LHS.getCXXOverloadedOperator(),
RHS.getCXXOverloadedOperator());
case DeclarationName::CXXLiteralOperatorName:
return LHS.getCXXLiteralIdentifier()->getName() <
RHS.getCXXLiteralIdentifier()->getName();
return LHS.getCXXLiteralIdentifier()->getName().compare(
RHS.getCXXLiteralIdentifier()->getName());
case DeclarationName::CXXUsingDirective:
return false;
return 0;
}
return false;
return 0;
}
} // end namespace clang

Просмотреть файл

@ -1109,9 +1109,10 @@ private:
}
static int DclCmp(const void *p1, const void *p2) {
const CXXMethodDecl *MD1 = (const CXXMethodDecl *)p1;
const CXXMethodDecl *MD2 = (const CXXMethodDecl *)p2;
return (MD1->getIdentifier() - MD2->getIdentifier());
const CXXMethodDecl *MD1 = *(const CXXMethodDecl *const *)p1;
const CXXMethodDecl *MD2 = *(const CXXMethodDecl *const *)p2;
return (DeclarationName::compare(MD1->getDeclName(), MD2->getDeclName()));
}
void MergeForwarding() {
@ -1127,7 +1128,7 @@ private:
for (A_t::iterator I = A.begin(),
E = A.end(); I != E; ++I) {
A_t::iterator J = I;
while (++J != E && DclCmp(*I, *J) == 0)
while (++J != E && DclCmp(I, J) == 0)
if (DclIsSame(*I, *J)) {
if (0) printf("connecting %s\n", (*I)->getNameAsCString());
ForwardUnique[*J] = *I;