This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG99b5ec1fd1a7: [include-cleaner] Merge 2 parseIWYUPragma 
impls in libToolingInclusions (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138780/new/

https://reviews.llvm.org/D138780

Files:
  clang-tools-extra/clangd/Headers.cpp
  clang-tools-extra/clangd/Headers.h
  clang-tools-extra/clangd/unittests/HeadersTests.cpp
  clang-tools-extra/include-cleaner/lib/Record.cpp
  clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
  clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp
  clang/unittests/Tooling/HeaderAnalysisTest.cpp

Index: clang/unittests/Tooling/HeaderAnalysisTest.cpp
===================================================================
--- clang/unittests/Tooling/HeaderAnalysisTest.cpp
+++ clang/unittests/Tooling/HeaderAnalysisTest.cpp
@@ -9,11 +9,14 @@
 #include "clang/Tooling/Inclusions/HeaderAnalysis.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Testing/TestAST.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gtest/gtest.h"
 
 namespace clang {
 namespace tooling {
 namespace {
+using llvm::ValueIs;
+using testing::Eq;
 
 TEST(HeaderAnalysisTest, IsSelfContained) {
   TestInputs Inputs;
@@ -58,6 +61,19 @@
   EXPECT_FALSE(isSelfContainedHeader(FM.getFile("bad.h").get(), SM, HI));
 }
 
+TEST(HeaderAnalysisTest, ParseIWYUPragma) {
+  EXPECT_THAT(parseIWYUPragma("// IWYU pragma: keep"), ValueIs(Eq("keep")));
+  EXPECT_THAT(parseIWYUPragma("// IWYU pragma:   keep  me\netc"),
+              ValueIs(Eq("keep  me")));
+  EXPECT_THAT(parseIWYUPragma("/* IWYU pragma: keep */"), ValueIs(Eq("keep")));
+  EXPECT_EQ(parseIWYUPragma("//  IWYU pragma: keep"), llvm::None)
+      << "Prefix is sensitive to whitespace";
+  EXPECT_EQ(parseIWYUPragma("// IWYU pragma:keep"), llvm::None)
+      << "Prefix is sensitive to whitespace";
+  EXPECT_EQ(parseIWYUPragma("/\n* IWYU pragma: keep */"), llvm::None)
+      << "Must start with /* or //";
+}
+
 } // namespace
 } // namespace tooling
 } // namespace clang
Index: clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp
===================================================================
--- clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp
+++ clang/lib/Tooling/Inclusions/HeaderAnalysis.cpp
@@ -64,4 +64,28 @@
       const_cast<SourceManager &>(SM).getMemoryBufferForFileOrNone(FE).value_or(
           llvm::MemoryBufferRef()));
 }
+
+llvm::Optional<StringRef> parseIWYUPragma(const char *Text) {
+  // Skip the comment start, // or /*.
+  if (Text[0] != '/' || (Text[1] != '/' && Text[1] != '*'))
+    return llvm::None;
+  bool BlockComment = Text[1] == '*';
+  Text += 2;
+
+  // Per spec, direcitves are whitespace- and case-sensitive.
+  constexpr llvm::StringLiteral IWYUPragma = " IWYU pragma: ";
+  if (strncmp(Text, IWYUPragma.data(), IWYUPragma.size()))
+    return llvm::None;
+  Text += IWYUPragma.size();
+  const char *End = Text;
+  while (*End != 0 && *End != '\n')
+    ++End;
+  StringRef Rest(Text, End - Text);
+  // Strip off whitespace and comment markers to avoid confusion. This isn't
+  // fully-compatible with IWYU, which splits into whitespace-delimited tokens.
+  if (BlockComment)
+    Rest.consume_back("*/");
+  return Rest.trim();
+}
+
 } // namespace clang::tooling
Index: clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
===================================================================
--- clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
+++ clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADER_ANALYSIS_H
 #define LLVM_CLANG_TOOLING_INCLUSIONS_HEADER_ANALYSIS_H
 
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
 namespace clang {
 class FileEntry;
 class SourceManager;
@@ -27,6 +29,13 @@
 bool isSelfContainedHeader(const FileEntry *FE, const SourceManager &SM,
                            HeaderSearch &HeaderInfo);
 
+/// If Text begins an Include-What-You-Use directive, returns it.
+/// Given "// IWYU pragma: keep", returns "keep".
+/// Input is a null-terminated char* as provided by SM.getCharacterData().
+/// (This should not be StringRef as we do *not* want to scan for its length).
+/// For multi-line comments, we return only the first line.
+llvm::Optional<llvm::StringRef> parseIWYUPragma(const char *Text);
+
 } // namespace tooling
 } // namespace clang
 
Index: clang-tools-extra/include-cleaner/lib/Record.cpp
===================================================================
--- clang-tools-extra/include-cleaner/lib/Record.cpp
+++ clang-tools-extra/include-cleaner/lib/Record.cpp
@@ -141,21 +141,6 @@
 
 } // namespace
 
-// FIXME: this is a mirror of clang::clangd::parseIWYUPragma, move to libTooling
-// to share the code?
-static llvm::Optional<StringRef> parseIWYUPragma(const char *Text) {
-  assert(strncmp(Text, "//", 2) || strncmp(Text, "/*", 2));
-  constexpr llvm::StringLiteral IWYUPragma = " IWYU pragma: ";
-  Text += 2; // Skip the comment start, // or /*.
-  if (strncmp(Text, IWYUPragma.data(), IWYUPragma.size()))
-    return llvm::None;
-  Text += IWYUPragma.size();
-  const char *End = Text;
-  while (*End != 0 && *End != '\n')
-    ++End;
-  return StringRef(Text, End - Text);
-}
-
 class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
 public:
   RecordPragma(const CompilerInstance &CI, PragmaIncludes *Out)
@@ -229,7 +214,8 @@
 
   bool HandleComment(Preprocessor &PP, SourceRange Range) override {
     auto &SM = PP.getSourceManager();
-    auto Pragma = parseIWYUPragma(SM.getCharacterData(Range.getBegin()));
+    auto Pragma =
+        tooling::parseIWYUPragma(SM.getCharacterData(Range.getBegin()));
     if (!Pragma)
       return false;
 
Index: clang-tools-extra/clangd/unittests/HeadersTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HeadersTests.cpp
+++ clang-tools-extra/clangd/unittests/HeadersTests.cpp
@@ -447,18 +447,6 @@
   EXPECT_FALSE(Includes.hasIWYUExport(getID("none.h", Includes)));
 }
 
-TEST(Headers, ParseIWYUPragma) {
-  EXPECT_THAT(parseIWYUPragma("// IWYU pragma: keep"), HasValue(Eq("keep")));
-  EXPECT_THAT(parseIWYUPragma("// IWYU pragma: keep\netc"),
-              HasValue(Eq("keep")));
-  EXPECT_EQ(parseIWYUPragma("/* IWYU pragma: keep"), llvm::None)
-      << "Only // comments supported!";
-  EXPECT_EQ(parseIWYUPragma("//  IWYU pragma: keep"), llvm::None)
-      << "Sensitive to whitespace";
-  EXPECT_EQ(parseIWYUPragma("// IWYU pragma:keep"), llvm::None)
-      << "Sensitive to whitespace";
-}
-
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/Headers.h
===================================================================
--- clang-tools-extra/clangd/Headers.h
+++ clang-tools-extra/clangd/Headers.h
@@ -35,12 +35,6 @@
 /// Returns true if \p Include is literal include like "path" or <path>.
 bool isLiteralInclude(llvm::StringRef Include);
 
-/// If Text begins an Include-What-You-Use directive, returns it.
-/// Given "// IWYU pragma: keep", returns "keep".
-/// Input is a null-terminated char* as provided by SM.getCharacterData().
-/// (This should not be StringRef as we do *not* want to scan for its length).
-llvm::Optional<StringRef> parseIWYUPragma(const char *Text);
-
 /// Represents a header file to be #include'd.
 struct HeaderFile {
   std::string File;
Index: clang-tools-extra/clangd/Headers.cpp
===================================================================
--- clang-tools-extra/clangd/Headers.cpp
+++ clang-tools-extra/clangd/Headers.cpp
@@ -23,18 +23,6 @@
 namespace clang {
 namespace clangd {
 
-llvm::Optional<StringRef> parseIWYUPragma(const char *Text) {
-  // This gets called for every comment seen in the preamble, so it's quite hot.
-  constexpr llvm::StringLiteral IWYUPragma = "// IWYU pragma: ";
-  if (strncmp(Text, IWYUPragma.data(), IWYUPragma.size()))
-    return llvm::None;
-  Text += IWYUPragma.size();
-  const char *End = Text;
-  while (*End != 0 && *End != '\n')
-    ++End;
-  return StringRef(Text, End - Text);
-}
-
 class IncludeStructure::RecordHeaders : public PPCallbacks,
                                         public CommentHandler {
 public:
@@ -136,7 +124,8 @@
   }
 
   bool HandleComment(Preprocessor &PP, SourceRange Range) override {
-    auto Pragma = parseIWYUPragma(SM.getCharacterData(Range.getBegin()));
+    auto Pragma =
+        tooling::parseIWYUPragma(SM.getCharacterData(Range.getBegin()));
     if (!Pragma)
       return false;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to