diff options
-rw-r--r-- | lib/AST/ASTContext.cpp | 31 | ||||
-rw-r--r-- | 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<IdentifierInfo*> &ProtocolRefs, SourceLocation &endLoc) -{ + llvm::SmallVectorImpl<IdentifierInfo*> &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(); |