diff --git a/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp --- a/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp +++ b/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp @@ -37,9 +37,11 @@ namespace clang { namespace replace { -std::error_code collectReplacementsFromDirectory( - const llvm::StringRef Directory, TUReplacements &TUs, - TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) { +template +std::error_code +collectReplacementsFromDirectoryImpl(const llvm::StringRef Directory, T &TUs, + TUReplacementFiles &TUFiles, + clang::DiagnosticsEngine &Diagnostics) { using namespace llvm::sys::fs; using namespace llvm::sys::path; @@ -67,7 +69,7 @@ } yaml::Input YIn(Out.get()->getBuffer(), nullptr, &eatDiagnostics); - tooling::TranslationUnitReplacements TU; + typename T::value_type TU; YIn >> TU; if (YIn.error()) { // File doesn't appear to be a header change description. Ignore it. @@ -82,47 +84,17 @@ } std::error_code collectReplacementsFromDirectory( - const llvm::StringRef Directory, TUDiagnostics &TUs, + const llvm::StringRef Directory, TUReplacements &TUs, TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) { - using namespace llvm::sys::fs; - using namespace llvm::sys::path; - - std::error_code ErrorCode; - - for (recursive_directory_iterator I(Directory, ErrorCode), E; - I != E && !ErrorCode; I.increment(ErrorCode)) { - if (filename(I->path())[0] == '.') { - // Indicate not to descend into directories beginning with '.' - I.no_push(); - continue; - } - - if (extension(I->path()) != ".yaml") - continue; - - TUFiles.push_back(I->path()); - - ErrorOr> Out = - MemoryBuffer::getFile(I->path()); - if (std::error_code BufferError = Out.getError()) { - errs() << "Error reading " << I->path() << ": " << BufferError.message() - << "\n"; - continue; - } - - yaml::Input YIn(Out.get()->getBuffer(), nullptr, &eatDiagnostics); - tooling::TranslationUnitDiagnostics TU; - YIn >> TU; - if (YIn.error()) { - // File doesn't appear to be a header change description. Ignore it. - continue; - } - - // Only keep files that properly parse. - TUs.push_back(TU); - } + return collectReplacementsFromDirectoryImpl(Directory, TUs, TUFiles, + Diagnostics); +} - return ErrorCode; +std::error_code collectReplacementsFromDirectory( + const llvm::StringRef Directory, TUDiagnostics &TUs, + TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) { + return collectReplacementsFromDirectoryImpl(Directory, TUs, TUFiles, + Diagnostics); } /// Extract replacements from collected TranslationUnitReplacements and @@ -163,11 +135,9 @@ if (auto Entry = SM.getFileManager().getFile(R.getFilePath())) { if (SourceTU) { auto &Replaces = DiagReplacements[*Entry]; - auto It = Replaces.find(R); - if (It == Replaces.end()) - Replaces.emplace(R, SourceTU); - else if (It->second != SourceTU) - // This replacement is a duplicate of one suggested by another TU. + auto InsertPos = Replaces.try_emplace(R, SourceTU); + // This replacement is a duplicate of one suggested by another TU. + if (!InsertPos.second && InsertPos.first->second != SourceTU) return; } GroupedReplacements[*Entry].push_back(R); diff --git a/llvm/include/llvm/ADT/Twine.h b/llvm/include/llvm/ADT/Twine.h --- a/llvm/include/llvm/ADT/Twine.h +++ b/llvm/include/llvm/ADT/Twine.h @@ -291,9 +291,9 @@ /// Construct from an std::string_view by converting it to a pointer and /// length. This handles string_views on a pure API basis, and avoids /// storing one (or a pointer to one) inside a Twine, which avoids problems - /// when mixing code compiled under various C++ standards. - /*implicit*/ Twine(const std::string_view &Str) - : LHSKind(PtrAndLengthKind) { + /// when mixing code compiled under various C++ standards. Pass string_view + /// by value is preferred. + /*implicit*/ Twine(std::string_view Str) : LHSKind(PtrAndLengthKind) { LHS.ptrAndLength.ptr = Str.data(); LHS.ptrAndLength.length = Str.length(); assert(isValid() && "Invalid twine!");