Fix PR4922, where Sema would complete tentative definitions in nondeterminstic
order because it was doing so while iterating over a densemap.

There are still similar problems in other places, for example 
WeakUndeclaredIdentifiers is still written to the PCH file in a nondeterminstic
order, and we emit warnings about #pragma weak in nondeterminstic order.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81236 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index b41902c..2d72c3e 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -256,13 +256,16 @@
   // template instantiations earlier.
   PerformPendingImplicitInstantiations();
   
-  // check for #pragma weak identifiers that were never declared
+  // Check for #pragma weak identifiers that were never declared
+  // FIXME: This will cause diagnostics to be emitted in a non-determinstic
+  // order!  Iterating over a densemap like this is bad.
   for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
-        I = WeakUndeclaredIdentifiers.begin(),
-        E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
-      if (!I->second.getUsed())
-        Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
-          << I->first;
+       I = WeakUndeclaredIdentifiers.begin(),
+       E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
+    if (I->second.getUsed()) continue;
+    
+    Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
+      << I->first;
   }
 
   if (!CompleteTranslationUnit)
@@ -279,31 +282,30 @@
   //   translation unit contains a file scope declaration of that
   //   identifier, with the composite type as of the end of the
   //   translation unit, with an initializer equal to 0.
-  for (llvm::DenseMap<DeclarationName, VarDecl *>::iterator 
-         D = TentativeDefinitions.begin(),
-         DEnd = TentativeDefinitions.end();
-       D != DEnd; ++D) {
-    VarDecl *VD = D->second;
-
-    if (VD->isInvalidDecl() || !VD->isTentativeDefinition(Context))
+  for (unsigned i = 0, e = TentativeDefinitionList.size(); i != e; ++i) {
+    VarDecl *VD = TentativeDefinitions.lookup(TentativeDefinitionList[i]);
+    
+    // If the tentative definition was completed, it will be in the list, but
+    // not the map.
+    if (VD == 0 || VD->isInvalidDecl() || !VD->isTentativeDefinition(Context))
       continue;
 
     if (const IncompleteArrayType *ArrayT 
         = Context.getAsIncompleteArrayType(VD->getType())) {
       if (RequireCompleteType(VD->getLocation(), 
                               ArrayT->getElementType(),
-                              diag::err_tentative_def_incomplete_type_arr))
+                              diag::err_tentative_def_incomplete_type_arr)) {
         VD->setInvalidDecl();
-      else {
-        // Set the length of the array to 1 (C99 6.9.2p5).
-        Diag(VD->getLocation(),  diag::warn_tentative_incomplete_array);
-        llvm::APInt One(Context.getTypeSize(Context.getSizeType()), 
-                        true);
-        QualType T 
-          = Context.getConstantArrayWithoutExprType(ArrayT->getElementType(),
-                                                    One, ArrayType::Normal, 0);
-        VD->setType(T);
+        continue;
       }
+      
+      // Set the length of the array to 1 (C99 6.9.2p5).
+      Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
+      llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
+      QualType T 
+        = Context.getConstantArrayWithoutExprType(ArrayT->getElementType(),
+                                                  One, ArrayType::Normal, 0);
+      VD->setType(T);
     } else if (RequireCompleteType(VD->getLocation(), VD->getType(), 
                                    diag::err_tentative_def_incomplete_type))
       VD->setInvalidDecl();