r233348 - [Modules] When walking the lookup results in a namespace, sort them by

Chandler Carruth chandlerc at gmail.com
Thu Mar 26 18:48:11 PDT 2015


Author: chandlerc
Date: Thu Mar 26 20:48:11 2015
New Revision: 233348

URL: http://llvm.org/viewvc/llvm-project?rev=233348&view=rev
Log:
[Modules] When walking the lookup results in a namespace, sort them by
declaration name so that we mark declarations for emission in
a deterministic order (and in turn give them deterministic IDs).

This is the last for loop or data structure I can find by inspection of
the AST writer which doesn't use a deterministic order.

Found by inspection, no test case.

Modified:
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=233348&r1=233347&r2=233348&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Thu Mar 26 20:48:11 2015
@@ -980,15 +980,29 @@ void ASTDeclWriter::VisitNamespaceDecl(N
     NamespaceDecl *NS = D->getOriginalNamespace();
     Writer.UpdatedDeclContexts.insert(NS);
 
-    // Make sure all visible decls are written. They will be recorded later.
-    if (StoredDeclsMap *Map = NS->buildLookup()) {
-      for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
-           D != DEnd; ++D) {
-        DeclContext::lookup_result R = D->second.getLookupResult();
-        for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
-             ++I)
-          Writer.GetDeclRef(*I);
-      }
+    // Make sure all visible decls are written. They will be recorded later. We
+    // do this using a side data structure so we can sort the names into
+    // a deterministic order.
+    StoredDeclsMap *Map = NS->buildLookup();
+    SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16>
+        LookupResults;
+    LookupResults.reserve(Map->size());
+    for (auto &Entry : *Map)
+      LookupResults.push_back(
+          std::make_pair(Entry.first, Entry.second.getLookupResult()));
+
+    std::sort(LookupResults.begin(), LookupResults.end(), llvm::less_first());
+    for (auto &NameAndResult : LookupResults) {
+      DeclarationName Name = NameAndResult.first;
+      (void)Name;
+      assert(Name.getNameKind() != DeclarationName::CXXConstructorName &&
+             "Cannot have a constructor name in a namespace!");
+      assert(Name.getNameKind() != DeclarationName::CXXConversionFunctionName &&
+             "Cannot have a conversion function name in a namespace!");
+
+      DeclContext::lookup_result Result = NameAndResult.second;
+      for (NamedDecl *ND : Result)
+        Writer.GetDeclRef(ND);
     }
   }
 





More information about the cfe-commits mailing list