[Modules] Make "#pragma weak" undeclared identifiers be tracked

deterministically.

This fixes a latent issue where even Clang's Sema (and diagnostics) were
non-deterministic in the face of this pragma. The fix is super simple --
just use a MapVector so we track the order in which these are parsed (or
imported). Especially considering how rare they are, this seems like the
perfect tradeoff. I've also simplified the client code with judicious
use of auto and range based for loops.

I've added some pretty hilarious code to my stress test which now
survives the binary diff without issue.

llvm-svn: 233261
This commit is contained in:
Chandler Carruth
2015-03-26 08:32:49 +00:00
parent 23536d92c7
commit f85d98285e
7 changed files with 49 additions and 28 deletions

View File

@@ -524,14 +524,8 @@ void Sema::LoadExternalWeakUndeclaredIdentifiers() {
SmallVector<std::pair<IdentifierInfo *, WeakInfo>, 4> WeakIDs;
ExternalSource->ReadWeakUndeclaredIdentifiers(WeakIDs);
for (unsigned I = 0, N = WeakIDs.size(); I != N; ++I) {
llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator Pos
= WeakUndeclaredIdentifiers.find(WeakIDs[I].first);
if (Pos != WeakUndeclaredIdentifiers.end())
continue;
WeakUndeclaredIdentifiers.insert(WeakIDs[I]);
}
for (auto &WeakID : WeakIDs)
WeakUndeclaredIdentifiers.insert(WeakID);
}
@@ -694,16 +688,13 @@ void Sema::ActOnEndOfTranslationUnit() {
}
// 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.
LoadExternalWeakUndeclaredIdentifiers();
for (llvm::DenseMap<IdentifierInfo*,WeakInfo>::iterator
I = WeakUndeclaredIdentifiers.begin(),
E = WeakUndeclaredIdentifiers.end(); I != E; ++I) {
if (I->second.getUsed()) continue;
for (auto WeakID : WeakUndeclaredIdentifiers) {
if (WeakID.second.getUsed())
continue;
Diag(I->second.getLocation(), diag::warn_weak_identifier_undeclared)
<< I->first;
Diag(WeakID.second.getLocation(), diag::warn_weak_identifier_undeclared)
<< WeakID.first;
}
if (LangOpts.CPlusPlus11 &&