diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index dc8d7bf5064e..a984220ccbfd 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -186,32 +186,33 @@ namespace clang { return import(*From); } - template - Expected> - importSeq(const T &From) { - Expected ToOrErr = import(From); - if (!ToOrErr) - return ToOrErr.takeError(); - return std::make_tuple(std::move(*ToOrErr)); + // Helper for error management in importSeq. + template T checkImport(Error &Err, const T &From) { + // Don't attempt to import nodes if we hit an error earlier. + if (Err) + return T{}; + Expected MaybeVal = import(From); + if (!MaybeVal) { + Err = MaybeVal.takeError(); + return T{}; + } + return *MaybeVal; } // Import multiple objects with a single function call. // This should work for every type for which a variant of `import` exists. // The arguments are processed from left to right and import is stopped on // first error. - template - Expected> - importSeq(const THead &FromHead, const TTail &...FromTail) { - Expected> ToHeadOrErr = importSeq(FromHead); - if (!ToHeadOrErr) - return ToHeadOrErr.takeError(); - Expected> ToTailOrErr = importSeq(FromTail...); - if (!ToTailOrErr) - return ToTailOrErr.takeError(); - return std::tuple_cat(*ToHeadOrErr, *ToTailOrErr); + template + Expected> importSeq(const Args &... args) { + Error E = Error::success(); + std::tuple Res{checkImport(E, args)...}; + if (E) + return std::move(E); + return std::move(Res); } -// Wrapper for an overload set. + // Wrapper for an overload set. template struct CallOverloadedCreateFun { template auto operator()(Args &&... args)