[clang-tools-extra] [compiler-rt] 78842 support for the .yml file extension (PR #79900)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 29 13:15:17 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: None (harbandana)

<details>
<summary>Changes</summary>



---

Patch is 109.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/79900.diff


3 Files Affected:

- (modified) clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp (+275-271) 
- (modified) compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake (+100-97) 
- (modified) compiler-rt/lib/hwasan/hwasan_report.cpp (+1096-1100) 


``````````diff
diff --git a/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
index 87ed1b8797cb05e..20bafef7240438f 100644
--- a/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
+++ b/clang-tools-extra/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp
@@ -1,271 +1,275 @@
-//===-- ApplyReplacements.cpp - Apply and deduplicate replacements --------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file provides the implementation for deduplicating, detecting
-/// conflicts in, and applying collections of Replacements.
-///
-/// FIXME: Use Diagnostics for output instead of llvm::errs().
-///
-//===----------------------------------------------------------------------===//
-#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Format/Format.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Tooling/Core/Diagnostic.h"
-#include "clang/Tooling/DiagnosticsYaml.h"
-#include "clang/Tooling/ReplacementsYaml.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include <optional>
-
-using namespace llvm;
-using namespace clang;
-
-static void eatDiagnostics(const SMDiagnostic &, void *) {}
-
-namespace clang {
-namespace replace {
-
-namespace detail {
-template <typename TranslationUnits>
-static std::error_code collectReplacementsFromDirectory(
-    const llvm::StringRef Directory, TranslationUnits &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<std::unique_ptr<MemoryBuffer>> 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);
-    typename TranslationUnits::value_type 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 ErrorCode;
-}
-} // namespace detail
-
-template <>
-std::error_code collectReplacementsFromDirectory(
-    const llvm::StringRef Directory, TUReplacements &TUs,
-    TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) {
-  return detail::collectReplacementsFromDirectory(Directory, TUs, TUFiles,
-                                                  Diagnostics);
-}
-
-template <>
-std::error_code collectReplacementsFromDirectory(
-    const llvm::StringRef Directory, TUDiagnostics &TUs,
-    TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) {
-  return detail::collectReplacementsFromDirectory(Directory, TUs, TUFiles,
-                                                  Diagnostics);
-}
-
-/// Extract replacements from collected TranslationUnitReplacements and
-/// TranslationUnitDiagnostics and group them per file. Identical replacements
-/// from diagnostics are deduplicated.
-///
-/// \param[in] TUs Collection of all found and deserialized
-/// TranslationUnitReplacements.
-/// \param[in] TUDs Collection of all found and deserialized
-/// TranslationUnitDiagnostics.
-/// \param[in] SM Used to deduplicate paths.
-///
-/// \returns A map mapping FileEntry to a set of Replacement targeting that
-/// file.
-static llvm::DenseMap<FileEntryRef, std::vector<tooling::Replacement>>
-groupReplacements(const TUReplacements &TUs, const TUDiagnostics &TUDs,
-                  const clang::SourceManager &SM) {
-  llvm::StringSet<> Warned;
-  llvm::DenseMap<FileEntryRef, std::vector<tooling::Replacement>>
-      GroupedReplacements;
-
-  // Deduplicate identical replacements in diagnostics unless they are from the
-  // same TU.
-  // FIXME: Find an efficient way to deduplicate on diagnostics level.
-  llvm::DenseMap<const FileEntry *,
-                 std::map<tooling::Replacement,
-                          const tooling::TranslationUnitDiagnostics *>>
-      DiagReplacements;
-
-  auto AddToGroup = [&](const tooling::Replacement &R,
-                        const tooling::TranslationUnitDiagnostics *SourceTU,
-                        const std::optional<std::string> BuildDir) {
-    // Use the file manager to deduplicate paths. FileEntries are
-    // automatically canonicalized. Since relative paths can come from different
-    // build directories, make them absolute immediately.
-    SmallString<128> Path = R.getFilePath();
-    if (BuildDir)
-      llvm::sys::fs::make_absolute(*BuildDir, Path);
-    else
-      SM.getFileManager().makeAbsolutePath(Path);
-
-    if (auto Entry = SM.getFileManager().getOptionalFileRef(Path)) {
-      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.
-          return;
-      }
-      GroupedReplacements[*Entry].push_back(R);
-    } else if (Warned.insert(Path).second) {
-      errs() << "Described file '" << R.getFilePath()
-             << "' doesn't exist. Ignoring...\n";
-    }
-  };
-
-  for (const auto &TU : TUs)
-    for (const tooling::Replacement &R : TU.Replacements)
-      AddToGroup(R, nullptr, {});
-
-  for (const auto &TU : TUDs)
-    for (const auto &D : TU.Diagnostics)
-      if (const auto *ChoosenFix = tooling::selectFirstFix(D)) {
-        for (const auto &Fix : *ChoosenFix)
-          for (const tooling::Replacement &R : Fix.second)
-            AddToGroup(R, &TU, D.BuildDirectory);
-      }
-
-  // Sort replacements per file to keep consistent behavior when
-  // clang-apply-replacements run on differents machine.
-  for (auto &FileAndReplacements : GroupedReplacements) {
-    llvm::sort(FileAndReplacements.second);
-  }
-
-  return GroupedReplacements;
-}
-
-bool mergeAndDeduplicate(const TUReplacements &TUs, const TUDiagnostics &TUDs,
-                         FileToChangesMap &FileChanges,
-                         clang::SourceManager &SM, bool IgnoreInsertConflict) {
-  auto GroupedReplacements = groupReplacements(TUs, TUDs, SM);
-  bool ConflictDetected = false;
-
-  // To report conflicting replacements on corresponding file, all replacements
-  // are stored into 1 big AtomicChange.
-  for (const auto &FileAndReplacements : GroupedReplacements) {
-    FileEntryRef Entry = FileAndReplacements.first;
-    const SourceLocation BeginLoc =
-        SM.getLocForStartOfFile(SM.getOrCreateFileID(Entry, SrcMgr::C_User));
-    tooling::AtomicChange FileChange(Entry.getName(), Entry.getName());
-    for (const auto &R : FileAndReplacements.second) {
-      llvm::Error Err =
-          FileChange.replace(SM, BeginLoc.getLocWithOffset(R.getOffset()),
-                             R.getLength(), R.getReplacementText());
-      if (Err) {
-        // FIXME: This will report conflicts by pair using a file+offset format
-        // which is not so much human readable.
-        // A first improvement could be to translate offset to line+col. For
-        // this and without loosing error message some modifications around
-        // `tooling::ReplacementError` are need (access to
-        // `getReplacementErrString`).
-        // A better strategy could be to add a pretty printer methods for
-        // conflict reporting. Methods that could be parameterized to report a
-        // conflict in different format, file+offset, file+line+col, or even
-        // more human readable using VCS conflict markers.
-        // For now, printing directly the error reported by `AtomicChange` is
-        // the easiest solution.
-        errs() << llvm::toString(std::move(Err)) << "\n";
-        if (IgnoreInsertConflict) {
-          tooling::Replacements &Replacements = FileChange.getReplacements();
-          unsigned NewOffset =
-              Replacements.getShiftedCodePosition(R.getOffset());
-          unsigned NewLength = Replacements.getShiftedCodePosition(
-                                   R.getOffset() + R.getLength()) -
-                               NewOffset;
-          if (NewLength == R.getLength()) {
-            tooling::Replacement RR = tooling::Replacement(
-                R.getFilePath(), NewOffset, NewLength, R.getReplacementText());
-            Replacements = Replacements.merge(tooling::Replacements(RR));
-          } else {
-            llvm::errs()
-                << "Can't resolve conflict, skipping the replacement.\n";
-            ConflictDetected = true;
-          }
-        } else
-          ConflictDetected = true;
-      }
-    }
-    FileChanges.try_emplace(Entry,
-                            std::vector<tooling::AtomicChange>{FileChange});
-  }
-
-  return !ConflictDetected;
-}
-
-llvm::Expected<std::string>
-applyChanges(StringRef File, const std::vector<tooling::AtomicChange> &Changes,
-             const tooling::ApplyChangesSpec &Spec,
-             DiagnosticsEngine &Diagnostics) {
-  FileManager Files((FileSystemOptions()));
-  SourceManager SM(Diagnostics, Files);
-
-  llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
-      SM.getFileManager().getBufferForFile(File);
-  if (!Buffer)
-    return errorCodeToError(Buffer.getError());
-  return tooling::applyAtomicChanges(File, Buffer.get()->getBuffer(), Changes,
-                                     Spec);
-}
-
-bool deleteReplacementFiles(const TUReplacementFiles &Files,
-                            clang::DiagnosticsEngine &Diagnostics) {
-  bool Success = true;
-  for (const auto &Filename : Files) {
-    std::error_code Error = llvm::sys::fs::remove(Filename);
-    if (Error) {
-      Success = false;
-      // FIXME: Use Diagnostics for outputting errors.
-      errs() << "Error deleting file: " << Filename << "\n";
-      errs() << Error.message() << "\n";
-      errs() << "Please delete the file manually\n";
-    }
-  }
-  return Success;
-}
-
-} // end namespace replace
-} // end namespace clang
+//===-- ApplyReplacements.cpp - Apply and deduplicate replacements --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file provides the implementation for deduplicating, detecting
+/// conflicts in, and applying collections of Replacements.
+///
+/// FIXME: Use Diagnostics for output instead of llvm::errs().
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang-apply-replacements/Tooling/ApplyReplacements.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/DiagnosticsYaml.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <optional>
+
+using namespace llvm;
+using namespace clang;
+
+static void eatDiagnostics(const SMDiagnostic &, void *) {}
+
+namespace clang {
+namespace replace {
+
+namespace detail {
+
+static constexpr std::array<StringRef, 3> AllowedExtensions = {".yaml", ".yml", ""};
+
+template <typename TranslationUnits>
+static std::error_code collectReplacementsFromDirectory(
+    const llvm::StringRef Directory, TranslationUnits &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 (!is_contained(AllowedExtensions, extension(I->path())))
+      continue;
+    
+    TUFiles.push_back(I->path());
+
+    ErrorOr<std::unique_ptr<MemoryBuffer>> 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);
+    typename TranslationUnits::value_type 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 ErrorCode;
+}
+} // namespace detail
+
+template <>
+std::error_code collectReplacementsFromDirectory(
+    const llvm::StringRef Directory, TUReplacements &TUs,
+    TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) {
+  return detail::collectReplacementsFromDirectory(Directory, TUs, TUFiles,
+                                                  Diagnostics);
+}
+
+template <>
+std::error_code collectReplacementsFromDirectory(
+    const llvm::StringRef Directory, TUDiagnostics &TUs,
+    TUReplacementFiles &TUFiles, clang::DiagnosticsEngine &Diagnostics) {
+  return detail::collectReplacementsFromDirectory(Directory, TUs, TUFiles,
+                                                  Diagnostics);
+}
+
+/// Extract replacements from collected TranslationUnitReplacements and
+/// TranslationUnitDiagnostics and group them per file. Identical replacements
+/// from diagnostics are deduplicated.
+///
+/// \param[in] TUs Collection of all found and deserialized
+/// TranslationUnitReplacements.
+/// \param[in] TUDs Collection of all found and deserialized
+/// TranslationUnitDiagnostics.
+/// \param[in] SM Used to deduplicate paths.
+///
+/// \returns A map mapping FileEntry to a set of Replacement targeting that
+/// file.
+static llvm::DenseMap<FileEntryRef, std::vector<tooling::Replacement>>
+groupReplacements(const TUReplacements &TUs, const TUDiagnostics &TUDs,
+                  const clang::SourceManager &SM) {
+  llvm::StringSet<> Warned;
+  llvm::DenseMap<FileEntryRef, std::vector<tooling::Replacement>>
+      GroupedReplacements;
+
+  // Deduplicate identical replacements in diagnostics unless they are from the
+  // same TU.
+  // FIXME: Find an efficient way to deduplicate on diagnostics level.
+  llvm::DenseMap<const FileEntry *,
+                 std::map<tooling::Replacement,
+                          const tooling::TranslationUnitDiagnostics *>>
+      DiagReplacements;
+
+  auto AddToGroup = [&](const tooling::Replacement &R,
+                        const tooling::TranslationUnitDiagnostics *SourceTU,
+                        const std::optional<std::string> BuildDir) {
+    // Use the file manager to deduplicate paths. FileEntries are
+    // automatically canonicalized. Since relative paths can come from different
+    // build directories, make them absolute immediately.
+    SmallString<128> Path = R.getFilePath();
+    if (BuildDir)
+      llvm::sys::fs::make_absolute(*BuildDir, Path);
+    else
+      SM.getFileManager().makeAbsolutePath(Path);
+
+    if (auto Entry = SM.getFileManager().getOptionalFileRef(Path)) {
+      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.
+          return;
+      }
+      GroupedReplacements[*Entry].push_back(R);
+    } else if (Warned.insert(Path).second) {
+      errs() << "Described file '" << R.getFilePath()
+             << "' doesn't exist. Ignoring...\n";
+    }
+  };
+
+  for (const auto &TU : TUs)
+    for (const tooling::Replacement &R : TU.Replacements)
+      AddToGroup(R, nullptr, {});
+
+  for (const auto &TU : TUDs)
+    for (const auto &D : TU.Diagnostics)
+      if (const auto *ChoosenFix = tooling::selectFirstFix(D)) {
+        for (const auto &Fix : *ChoosenFix)
+          for (const tooling::Replacement &R : Fix.second)
+            AddToGroup(R, &TU, D.BuildDirectory);
+      }
+
+  // Sort replacements per file to keep consistent behavior when
+  // clang-apply-replacements run on differents machine.
+  for (auto &FileAndReplacements : GroupedReplacements) {
+    llvm::sort(FileAndReplacements.second);
+  }
+
+  return GroupedReplacements;
+}
+
+bool mergeAndDeduplicate(const TUReplacements &TUs, const TUDiagnostics &TUDs,
+                         FileToChangesMap &FileChanges,
+                         clang::SourceManager &SM, bool IgnoreInsertConflict) {
+  auto GroupedReplacements = groupReplacements(TUs, TUDs, SM);
+  bool ConflictDetected = false;
+
+  // To report conflicting replacements on corresponding file, all replacements
+  // are stored into 1 big AtomicChange.
+  for (const auto &FileAndReplacements : GroupedReplacements) {
+    FileEntryRef Entry = FileAndReplacements.first;
+    const SourceLocation BeginLoc =
+        SM.getLocForStartOfFile(SM.getOrCreateFileID(Entry, SrcMgr::C_User));
+    tooling::AtomicChange FileChange(Entry.getName(), Entry.getName());
+    for (const auto &R : FileAndReplacements.second) {
+      llvm::Error Err =
+          FileChange.replace(SM, BeginLoc.getLocWithOffset(R.getOffset()),
+                             R.getLength(), R.getReplacementText());
+      if (Err) {
+        // FIXME: This will report conflicts by pair using a file+offset format
+        // which is not so much human readable.
+        // A first improvement could be to translate offset to line+col. For
+        // this and without loosing error message some modifications around
+        // `tooling::ReplacementError` are need (access to
+        // `getReplacementErrString`).
+        // A better strategy could be to add a pretty printer methods for
+        // conflict reporting. Methods that could be parameterized to report a
+        // conflict in different format, file+offset, file+line+col, or even
+        // more human readable using VCS conflict markers.
+        // For now, printing directly the error reported by `AtomicChange` is
+        // the easiest solution.
+        errs() << llvm::toString(std::move(Err)) << "\n";
+        if (IgnoreInsertConflict) {
+          tooling::Replacements &Replacements = FileChange.getReplacements();
+          unsigned NewOffset =
+              Replacements.getShiftedCodePosition(R.getOffset());
+          unsigned NewLength = Replacements.getShiftedCodePosition(
+                                   R.getOffset() + R.getLength()) -
+                               NewOffset;
+          if (NewLength == R.getLength()) {
+            tooling::...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/79900


More information about the cfe-commits mailing list