[clang] [clang-tools-extra] Clang/Preprocessor: Not add headers of __has_include into DepColloctor (PR #120673)

YunQiang Su via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 7 00:17:21 PST 2025


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/120673

>From ef5e52370d202431c1e6970fc57a7a04b9e83b89 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 20 Dec 2024 02:55:49 +0000
Subject: [PATCH 1/2] Clang/Preprocessor: Not add headers of __has_include into
 DepColloctor

When we preprocess the bellow code with
    clang -E -MD -MF

  #if __has_include(<limits.h>)
    // DO NOTHING
  #endif
  #if 0 && __has_include(<limits.h>)
    #include <limits.h>
  #endif

It will list limits.h in the dependencies.

The same case with #__has_include_next
---
 clang/include/clang/Lex/PPCallbacks.h         |  6 +++--
 clang/lib/Frontend/DependencyFile.cpp         | 12 ++++++----
 clang/lib/Lex/PPCallbacks.cpp                 | 11 +++++----
 clang/lib/Lex/PPMacroExpansion.cpp            |  3 ++-
 .../ClangScanDeps/has_include_if_elif.cpp     |  8 +++----
 .../Frontend/dependency-gen-has-include.c     |  6 ++---
 .../dependencies-on-has-include.c             | 23 +++++++++++++++++++
 .../DependencyScannerTest.cpp                 |  8 ++-----
 8 files changed, 52 insertions(+), 25 deletions(-)
 create mode 100644 clang/test/Preprocessor/dependencies-on-has-include.c

diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
index 46cc564086f1c5..8e03c2b9a76dbb 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -370,7 +370,8 @@ class PPCallbacks {
   /// read.
   virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
                           OptionalFileEntryRef File,
-                          SrcMgr::CharacteristicKind FileType);
+                          SrcMgr::CharacteristicKind FileType,
+                          bool AddToDepCollector = true);
 
   /// Hook called when a source range is skipped.
   /// \param Range The SourceRange that was skipped. The range begins at the
@@ -621,7 +622,8 @@ class PPChainedCallbacks : public PPCallbacks {
 
   void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
                   OptionalFileEntryRef File,
-                  SrcMgr::CharacteristicKind FileType) override;
+                  SrcMgr::CharacteristicKind FileType,
+                  bool AddToDepCollector = true) override;
 
   void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
                              SourceLocation StateLoc, unsigned State) override {
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index 528eae2c5283ea..931e29cd352211 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -104,15 +104,17 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
 
   void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled,
                   OptionalFileEntryRef File,
-                  SrcMgr::CharacteristicKind FileType) override {
+                  SrcMgr::CharacteristicKind FileType,
+                  bool AddToDepCollector = true) override {
     if (!File)
       return;
     StringRef Filename =
         llvm::sys::path::remove_leading_dotslash(File->getName());
-    DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
-                                    /*IsSystem=*/isSystem(FileType),
-                                    /*IsModuleFile=*/false,
-                                    /*IsMissing=*/false);
+    if (AddToDepCollector)
+      DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
+                                      /*IsSystem=*/isSystem(FileType),
+                                      /*IsModuleFile=*/false,
+                                      /*IsMissing=*/false);
   }
 
   void EndOfMainFile() override {
diff --git a/clang/lib/Lex/PPCallbacks.cpp b/clang/lib/Lex/PPCallbacks.cpp
index cf473aa4df6564..79bb64892f6de6 100644
--- a/clang/lib/Lex/PPCallbacks.cpp
+++ b/clang/lib/Lex/PPCallbacks.cpp
@@ -15,14 +15,17 @@ PPCallbacks::~PPCallbacks() = default;
 
 void PPCallbacks::HasInclude(SourceLocation Loc, StringRef FileName,
                              bool IsAngled, OptionalFileEntryRef File,
-                             SrcMgr::CharacteristicKind FileType) {}
+                             SrcMgr::CharacteristicKind FileType,
+                             bool AddToDepCollector) {}
 
 // Out of line key method.
 PPChainedCallbacks::~PPChainedCallbacks() = default;
 
 void PPChainedCallbacks::HasInclude(SourceLocation Loc, StringRef FileName,
                                     bool IsAngled, OptionalFileEntryRef File,
-                                    SrcMgr::CharacteristicKind FileType) {
-  First->HasInclude(Loc, FileName, IsAngled, File, FileType);
-  Second->HasInclude(Loc, FileName, IsAngled, File, FileType);
+                                    SrcMgr::CharacteristicKind FileType,
+                                    bool AddToDepCollector) {
+  First->HasInclude(Loc, FileName, IsAngled, File, FileType, AddToDepCollector);
+  Second->HasInclude(Loc, FileName, IsAngled, File, FileType,
+                     AddToDepCollector);
 }
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 347c13da0ad215..3429f08f45a2a5 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1256,7 +1256,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II,
     SrcMgr::CharacteristicKind FileType = SrcMgr::C_User;
     if (File)
       FileType = PP.getHeaderSearchInfo().getFileDirFlavor(*File);
-    Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType);
+    Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType,
+                          false);
   }
 
   // Get the result value.  A result of true means the file exists.
diff --git a/clang/test/ClangScanDeps/has_include_if_elif.cpp b/clang/test/ClangScanDeps/has_include_if_elif.cpp
index b8b5bb8b6bf09f..fc22e862991fd0 100644
--- a/clang/test/ClangScanDeps/has_include_if_elif.cpp
+++ b/clang/test/ClangScanDeps/has_include_if_elif.cpp
@@ -33,7 +33,7 @@
 // RUN: clang-scan-deps -compilation-database %t/cdb.json -mode preprocess | FileCheck %s
 
 // CHECK: tu.c
-// CHECK-NEXT: header1.h
-// CHECK-NEXT: header2.h
-// CHECK-NEXT: header3.h
-// CHECK-NEXT: header4.h
+// CHECK-NOT: header1.h
+// CHECK-NOT: header2.h
+// CHECK-NOT: header3.h
+// CHECK-NOT: header4.h
diff --git a/clang/test/Frontend/dependency-gen-has-include.c b/clang/test/Frontend/dependency-gen-has-include.c
index 51de72a5a0fb1c..d2da47b4523596 100644
--- a/clang/test/Frontend/dependency-gen-has-include.c
+++ b/clang/test/Frontend/dependency-gen-has-include.c
@@ -17,11 +17,11 @@
 // RUN: FileCheck -input-file=%t.dir/file.deps %s
 // CHECK: dependency-gen-has-include.o
 // CHECK: dependency-gen-has-include.c
-// CHECK: a{{[/\\]}}header.h
+// CHECK-NOT: a{{[/\\]}}header.h
 // CHECK-NOT: missing{{[/\\]}}file.h
-// CHECK: system{{[/\\]}}system-header.h
+// CHECK-NOT: system{{[/\\]}}system-header.h
 // CHECK: next-a{{[/\\]}}next-header.h
-// CHECK: next-b{{[/\\]}}next-header.h
+// CHECK-NOT: next-b{{[/\\]}}next-header.h
 
 // Verify that we ignore system headers in user-only headers mode.
 // RUN: %clang -MMD -MF %t.dir/user-headers.deps %s -fsyntax-only -I %t.dir -isystem %t.dir/system -I %t.dir/next-a -I %t.dir/next-b
diff --git a/clang/test/Preprocessor/dependencies-on-has-include.c b/clang/test/Preprocessor/dependencies-on-has-include.c
new file mode 100644
index 00000000000000..b6efbb22e18477
--- /dev/null
+++ b/clang/test/Preprocessor/dependencies-on-has-include.c
@@ -0,0 +1,23 @@
+// Test -MF and -E flags with has_include
+
+#ifdef TEST_HAS_INCLUDE_NEXT
+#if __has_include_next(<limits.h>)
+// DO NOTHING
+#endif
+#endif
+
+#ifdef TEST_HAS_INCLUDE
+#if __has_include(<limits.h>)
+// DO NOTHING
+#endif
+#endif
+
+// RUN: %clang -DTEST_HAS_INCLUDE -E -MD -MF - %s \
+// RUN:    | FileCheck -check-prefix=TEST-HAS %s
+// TEST-HAS: dependencies-on-has-include.o:
+// TEST-HAS-NOT: limits.h
+
+// RUN: %clang -Wno-include-next-outside-header -DTEST_HAS_INCLUDE_NEXT -E -MD -MF - %s \
+// RUN:    | FileCheck -check-prefix=TEST-HAS-N %s
+// TEST-HAS-N: dependencies-on-has-include.o:
+// TEST-HAS-N-NOT: limits.h
diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp b/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp
index e1c47708059920..c2fbf3e0c7b929 100644
--- a/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp
+++ b/clang/unittests/Tooling/DependencyScanning/DependencyScannerTest.cpp
@@ -198,13 +198,9 @@ TEST(DependencyScanner, ScanDepsReuseFilemanagerHasInclude) {
   TestDependencyScanningAction Action(Deps);
   Tool.run(&Action);
   using llvm::sys::path::convert_to_slash;
-  ASSERT_EQ(Deps.size(), 6u);
+  ASSERT_EQ(Deps.size(), 2u);
   EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
-  EXPECT_EQ(convert_to_slash(Deps[1]), "/root/header.h");
-  EXPECT_EQ(convert_to_slash(Deps[2]), "/root/symlink.h");
-  EXPECT_EQ(convert_to_slash(Deps[3]), "/root/test.cpp");
-  EXPECT_EQ(convert_to_slash(Deps[4]), "/root/header.h");
-  EXPECT_EQ(convert_to_slash(Deps[5]), "/root/symlink.h");
+  EXPECT_EQ(convert_to_slash(Deps[1]), "/root/test.cpp");
 }
 
 TEST(DependencyScanner, ScanDepsWithFS) {

>From 4705d4e747f9022dbb074d1a583bfbf1e57840ce Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 20 Dec 2024 14:42:41 +0800
Subject: [PATCH 2/2] fix build clang-tidy

---
 .../clang-tidy/ExpandModularHeadersPPCallbacks.cpp             | 3 ++-
 clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
index 4c34f9ea122d9e..94bb616bef09d2 100644
--- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
+++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp
@@ -228,7 +228,8 @@ void ExpandModularHeadersPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
 }
 void ExpandModularHeadersPPCallbacks::HasInclude(SourceLocation Loc, StringRef,
                                                  bool, OptionalFileEntryRef,
-                                                 SrcMgr::CharacteristicKind) {
+                                                 SrcMgr::CharacteristicKind,
+                                                 bool AddToDepCollector) {
   parseToLocation(Loc);
 }
 void ExpandModularHeadersPPCallbacks::PragmaOpenCLExtension(
diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
index 0742c21bc43720..8402fd3b2d8c66 100644
--- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
+++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h
@@ -90,7 +90,8 @@ class ExpandModularHeadersPPCallbacks : public PPCallbacks {
   void PragmaDiagnostic(SourceLocation Loc, StringRef, diag::Severity,
                         StringRef) override;
   void HasInclude(SourceLocation Loc, StringRef, bool, OptionalFileEntryRef,
-                  SrcMgr::CharacteristicKind) override;
+                  SrcMgr::CharacteristicKind,
+                  bool AddToDepCollector = true) override;
   void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *,
                              SourceLocation StateLoc, unsigned) override;
   void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier,



More information about the cfe-commits mailing list