From 88cb27a160adc305783a44f922ee4b216006ebf9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 7 Apr 2008 04:56:42 +0000 Subject: [PATCH] move sorting of qualifying protocols from the parser into sema. This allows clients of the parser to have the unmolested list if desired, and guarantees that noone can create an ObjCQualifiedInterfaceType with an unsorted list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49310 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 31 ++++++++++++++++++++++++++++--- lib/Parse/ParseObjc.cpp | 16 +--------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index bb03479a01..5119cfb026 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -811,10 +811,33 @@ QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) { return QualType(Decl->TypeForDecl, 0); } +/// CmpProtocolNames - Comparison predicate for sorting protocols +/// alphabetically. +static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, + const ObjCProtocolDecl *RHS) { + return strcmp(LHS->getName(), RHS->getName()) < 0; +} + +static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols, + unsigned &NumProtocols) { + ObjCProtocolDecl **ProtocolsEnd = Protocols+NumProtocols; + + // Sort protocols, keyed by name. + std::sort(Protocols, Protocols+NumProtocols, CmpProtocolNames); + + // Remove duplicates. + ProtocolsEnd = std::unique(Protocols, ProtocolsEnd); + NumProtocols = ProtocolsEnd-Protocols; +} + + /// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for /// the given interface decl and the conforming protocol list. QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { + // Sort the protocol list alphabetically to canonicalize it. + SortAndUniqueProtocols(Protocols, NumProtocols); + llvm::FoldingSetNodeID ID; ObjCQualifiedInterfaceType::Profile(ID, Protocols, NumProtocols); @@ -831,12 +854,14 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl, return QualType(QType, 0); } -/// getObjCQualifiedIdType - Return a -/// getObjCQualifiedIdType type for the 'id' decl and -/// the conforming protocol list. +/// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl +/// and the conforming protocol list. QualType ASTContext::getObjCQualifiedIdType(QualType idType, ObjCProtocolDecl **Protocols, unsigned NumProtocols) { + // Sort the protocol list alphabetically to canonicalize it. + SortAndUniqueProtocols(Protocols, NumProtocols); + llvm::FoldingSetNodeID ID; ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols); diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index dfd00ec420..2aee03ae95 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -701,18 +701,11 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, MethodImplKind, isVariadic); } -/// CmpProtocolVals - Comparison predicate for sorting protocols. -static bool CmpProtocolVals(const IdentifierInfo* const& lhs, - const IdentifierInfo* const& rhs) { - return strcmp(lhs->getName(), rhs->getName()) < 0; -} - /// objc-protocol-refs: /// '<' identifier-list '>' /// bool Parser::ParseObjCProtocolReferences( - llvm::SmallVectorImpl &ProtocolRefs, SourceLocation &endLoc) -{ + llvm::SmallVectorImpl &ProtocolRefs, SourceLocation &endLoc){ assert(Tok.is(tok::less) && "expected <"); ConsumeToken(); // the "<" @@ -731,13 +724,6 @@ bool Parser::ParseObjCProtocolReferences( ConsumeToken(); } - // Sort protocols, keyed by name. - // Later on, we remove duplicates. - std::stable_sort(ProtocolRefs.begin(), ProtocolRefs.end(), CmpProtocolVals); - - // Make protocol names unique. - ProtocolRefs.erase(std::unique(ProtocolRefs.begin(), ProtocolRefs.end()), - ProtocolRefs.end()); // Consume the '>'. if (Tok.is(tok::greater)) { endLoc = ConsumeAnyToken();