clang/Modules: Split loop in ReadAST between failable and not
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 10 Nov 2019 18:50:12 +0000 (10:50 -0800)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Mon, 11 Nov 2019 23:53:48 +0000 (15:53 -0800)
Split a loop in ReadAST that visits the just-loaded module chain,
between an initial loop that reads further from the ASTs (and can fail)
and a second loop that does some preloading (and cannot fail).  This
makes it less likely for a reading failure to affect the AST.

This is not fixing a known bug and the behaviour change may not be
observable, it's just part of an audit to look at all of the error
handling in the ASTReader.

https://reviews.llvm.org/D70056

clang/lib/Serialization/ASTReader.cpp

index 412bc78..a5cd9e9 100644 (file)
@@ -4202,7 +4202,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
 
   // Here comes stuff that we only do once the entire chain is loaded.
 
-  // Load the AST blocks of all of the modules that we loaded.
+  // Load the AST blocks of all of the modules that we loaded.  We can still
+  // hit errors parsing the ASTs at this point.
   for (ImportedModule &M : Loaded) {
     ModuleFile &F = *M.Mod;
 
@@ -4221,6 +4222,11 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName,
     F.GlobalBitOffset = TotalModulesSizeInBits;
     TotalModulesSizeInBits += F.SizeInBits;
     GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F));
+  }
+
+  // Preload source locations and interesting indentifiers.
+  for (ImportedModule &M : Loaded) {
+    ModuleFile &F = *M.Mod;
 
     // Preload SLocEntries.
     for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I) {