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