]> granicus.if.org Git - clang/commitdiff
move sorting of qualifying protocols from the parser into
authorChris Lattner <sabre@nondot.org>
Mon, 7 Apr 2008 04:56:42 +0000 (04:56 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 7 Apr 2008 04:56:42 +0000 (04:56 +0000)
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
lib/Parse/ParseObjc.cpp

index bb03479a012483ba2a6ecde7df94f01e99239ed1..5119cfb026cc90aea9312e2837e14d358f5d372b 100644 (file)
@@ -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);
   
index dfd00ec420979554d5aa1d7bd9f98ddf99ab9955..2aee03ae95b608bd3c6a242b9d2724c721849dc9 100644 (file)
@@ -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();