[clang] First PR to llvm, adding feature for issue (PR #123543)

via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 19 19:07:56 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-format

Author: None (Shakil582)

<details>
<summary>Changes</summary>

resolves #<!-- -->43831 

I'll test it a bit more tomorrow. I think I saw something weird with the --offset functionality when testing, but my additions  worked for the test cases I gave it.


---
Full diff: https://github.com/llvm/llvm-project/pull/123543.diff


1 Files Affected:

- (modified) clang/tools/clang-format/ClangFormat.cpp (+84) 


``````````diff
diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp
index 28610052b9b74a..64af04ef4c007c 100644
--- a/clang/tools/clang-format/ClangFormat.cpp
+++ b/clang/tools/clang-format/ClangFormat.cpp
@@ -26,6 +26,12 @@
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/Process.h"
 #include <fstream>
+#include <iostream>
+#include <llvm/ADT/STLExtras.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/Frontend/OpenMP/OMPConstants.h>
+#include <llvm/MC/MCAsmMacro.h>
+#include <sys/stat.h>
 
 using namespace llvm;
 using clang::tooling::Replacements;
@@ -214,6 +220,9 @@ static cl::opt<bool> ListIgnored("list-ignored",
                                  cl::desc("List ignored files."),
                                  cl::cat(ClangFormatCategory), cl::Hidden);
 
+static SmallVector<std::string> OnWords;
+static SmallVector<std::string> OffWords;
+
 namespace clang {
 namespace format {
 
@@ -307,6 +316,72 @@ static bool fillRanges(MemoryBuffer *Code,
     unsigned Length = Sources.getFileOffset(End) - Offset;
     Ranges.push_back(tooling::Range(Offset, Length));
   }
+
+  if (!OnWords.empty() && !OffWords.empty()) {
+    StringRef CodeRef = Code->getBuffer();
+    std::set<size_t> OnSet;
+    if (Ranges.empty())
+      OnSet.insert(0);
+    else
+      OnSet.insert(Ranges[0].getOffset());
+    std::set<size_t> OffSet;
+    if (Ranges.size() == 1 && Ranges[0].getOffset() == 0 &&
+        Ranges[0].getLength() == CodeRef.size()) {
+      Ranges.pop_back();
+    }
+
+    for (const auto &Word : OffWords) {
+      size_t TempOffset = CodeRef.find(Word);
+      while (TempOffset != StringRef::npos) {
+        if (TempOffset > *OnSet.begin())
+          OffSet.insert(TempOffset);
+        TempOffset = CodeRef.find(Word, TempOffset + 1);
+      }
+    }
+
+    for (const auto &Word : OnWords) {
+      size_t TempOffset = CodeRef.find(Word);
+      while (TempOffset != StringRef::npos) {
+        OnSet.insert(TempOffset);
+        TempOffset = CodeRef.find(Word, TempOffset + 1);
+      }
+    }
+
+    while (!OnSet.empty()) {
+      size_t Offset = OnSet.extract(OnSet.begin()).value();
+      size_t Length;
+      if (!OffSet.empty())
+        Length = OffSet.extract(OffSet.begin()).value() - Offset;
+      else
+        Length = CodeRef.size() - Offset;
+
+      // Could result in loss of data
+      tooling::Range NewRange = {static_cast<unsigned>(Offset),
+                                 static_cast<unsigned>(Length)};
+
+      Ranges.push_back(NewRange);
+    }
+  }
+
+  std::sort(Ranges.begin(), Ranges.end(),
+            [](const tooling::Range &a, const tooling::Range &b) {
+              return a.getOffset() + a.getLength() <
+                     b.getOffset() + b.getLength();
+            });
+
+  auto start = Ranges.begin();
+  for (auto i = Ranges.begin() + 1; i != Ranges.end(); ++i) {
+    if (start->getOffset() + start->getLength() >= i->getOffset()) {
+      tooling::Range Temp(std::min(start->getOffset(), i->getOffset()),
+                          std::max(start->getLength(), i->getLength()));
+      Ranges.erase(start, i + 1);
+      start = Ranges.insert(start, Temp);
+      i = start;
+    } else {
+      ++start;
+    }
+  }
+
   return false;
 }
 
@@ -646,6 +721,15 @@ static bool isIgnored(StringRef FilePath) {
 
   const auto Pathname{convert_to_slash(AbsPath)};
   for (const auto &Pat : Patterns) {
+
+    if (Pat.slice(0, 3).equals_insensitive("on:")) {
+      OnWords.push_back(Pat.slice(3, Pat.size()).trim().str());
+      continue;
+    }
+    if (Pat.slice(0, 4).equals_insensitive("off:")) {
+      OffWords.push_back(Pat.slice(4, Pat.size()).trim().str());
+      continue;
+    }
     const bool IsNegated = Pat[0] == '!';
     StringRef Pattern{Pat};
     if (IsNegated)

``````````

</details>


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


More information about the cfe-commits mailing list