OikawaKirie created this revision.
OikawaKirie added reviewers: gamesh411, balazske, martong, xazax.hun.
OikawaKirie added a project: clang.
Herald added subscribers: steakhal, ASDenysPetrov, dkrupp, donat.nagy, 
Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware.
OikawaKirie requested review of this revision.
Herald added a subscriber: cfe-commits.

During CTU, the *on-demand parsing* will read and parse the invocation list to 
know how to compile the file being imported. However, it seems that the 
invocation list will be parsed again if a previous parsing has failed. Then, 
parse again and fail again. This patch tries to overcome the problem by storing 
the error code during the first parsing, and re-create the stored error during 
the later parsings.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101763

Files:
  clang/include/clang/CrossTU/CrossTranslationUnit.h
  clang/lib/CrossTU/CrossTranslationUnit.cpp


Index: clang/lib/CrossTU/CrossTranslationUnit.cpp
===================================================================
--- clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -667,12 +667,16 @@
   /// Lazily initialize the invocation list member used for on-demand parsing.
   if (InvocationList)
     return llvm::Error::success();
+  else if (index_error_code::no_error != InvocationListParsingError)
+    return llvm::make_error<IndexError>(InvocationListParsingError);
 
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileContent =
       llvm::MemoryBuffer::getFile(InvocationListFilePath);
-  if (!FileContent)
-    return llvm::make_error<IndexError>(
-        index_error_code::invocation_list_file_not_found);
+  if (!FileContent) {
+    InvocationListParsingError =
+        index_error_code::invocation_list_file_not_found;
+    return llvm::make_error<IndexError>(InvocationListParsingError);
+  }
   std::unique_ptr<llvm::MemoryBuffer> ContentBuffer = std::move(*FileContent);
   assert(ContentBuffer && "If no error was produced after loading, the pointer 
"
                           "should not be nullptr.");
@@ -680,8 +684,13 @@
   llvm::Expected<InvocationListTy> ExpectedInvocationList =
       parseInvocationList(ContentBuffer->getBuffer(), PathStyle);
 
-  if (!ExpectedInvocationList)
-    return ExpectedInvocationList.takeError();
+  // Handle the error to store the code for next call to this function.
+  if (!ExpectedInvocationList) {
+    llvm::handleAllErrors(
+        ExpectedInvocationList.takeError(),
+        [&](IndexError &E) { InvocationListParsingError = E.getCode(); });
+    return llvm::make_error<IndexError>(InvocationListParsingError);
+  }
 
   InvocationList = *ExpectedInvocationList;
 
Index: clang/include/clang/CrossTU/CrossTranslationUnit.h
===================================================================
--- clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -38,6 +38,7 @@
 namespace cross_tu {
 
 enum class index_error_code {
+  no_error = 0,
   unspecified = 1,
   missing_index_file,
   invalid_index_format,
@@ -253,6 +254,7 @@
     /// In case of on-demand parsing, the invocations for parsing the source
     /// files is stored.
     llvm::Optional<InvocationListTy> InvocationList;
+    index_error_code InvocationListParsingError = index_error_code::no_error;
   };
 
   /// Maintain number of AST loads and check for reaching the load limit.


Index: clang/lib/CrossTU/CrossTranslationUnit.cpp
===================================================================
--- clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -667,12 +667,16 @@
   /// Lazily initialize the invocation list member used for on-demand parsing.
   if (InvocationList)
     return llvm::Error::success();
+  else if (index_error_code::no_error != InvocationListParsingError)
+    return llvm::make_error<IndexError>(InvocationListParsingError);
 
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileContent =
       llvm::MemoryBuffer::getFile(InvocationListFilePath);
-  if (!FileContent)
-    return llvm::make_error<IndexError>(
-        index_error_code::invocation_list_file_not_found);
+  if (!FileContent) {
+    InvocationListParsingError =
+        index_error_code::invocation_list_file_not_found;
+    return llvm::make_error<IndexError>(InvocationListParsingError);
+  }
   std::unique_ptr<llvm::MemoryBuffer> ContentBuffer = std::move(*FileContent);
   assert(ContentBuffer && "If no error was produced after loading, the pointer "
                           "should not be nullptr.");
@@ -680,8 +684,13 @@
   llvm::Expected<InvocationListTy> ExpectedInvocationList =
       parseInvocationList(ContentBuffer->getBuffer(), PathStyle);
 
-  if (!ExpectedInvocationList)
-    return ExpectedInvocationList.takeError();
+  // Handle the error to store the code for next call to this function.
+  if (!ExpectedInvocationList) {
+    llvm::handleAllErrors(
+        ExpectedInvocationList.takeError(),
+        [&](IndexError &E) { InvocationListParsingError = E.getCode(); });
+    return llvm::make_error<IndexError>(InvocationListParsingError);
+  }
 
   InvocationList = *ExpectedInvocationList;
 
Index: clang/include/clang/CrossTU/CrossTranslationUnit.h
===================================================================
--- clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -38,6 +38,7 @@
 namespace cross_tu {
 
 enum class index_error_code {
+  no_error = 0,
   unspecified = 1,
   missing_index_file,
   invalid_index_format,
@@ -253,6 +254,7 @@
     /// In case of on-demand parsing, the invocations for parsing the source
     /// files is stored.
     llvm::Optional<InvocationListTy> InvocationList;
+    index_error_code InvocationListParsingError = index_error_code::no_error;
   };
 
   /// Maintain number of AST loads and check for reaching the load limit.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to