[clang] 01eb01c - [clang][Lex] Add back PPCallbacks::FileNotFound

Jonas Hahnfeld via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 24 00:52:50 PST 2023


Author: Jonas Hahnfeld
Date: 2023-01-24T09:52:27+01:00
New Revision: 01eb01c7fd7ad6f569ad4d7bf65b5327ac111955

URL: https://github.com/llvm/llvm-project/commit/01eb01c7fd7ad6f569ad4d7bf65b5327ac111955
DIFF: https://github.com/llvm/llvm-project/commit/01eb01c7fd7ad6f569ad4d7bf65b5327ac111955.diff

LOG: [clang][Lex] Add back PPCallbacks::FileNotFound

This callback was removed with commit 7a124f4859, but we use it
downstream in ROOT/Cling to implement handling of a special include
syntax. Add back a "safe" version of the callback that only takes
the file name and return a bool to silently skip the file.

Differential Revision: https://reviews.llvm.org/D142196

Added: 
    

Modified: 
    clang/include/clang/Lex/PPCallbacks.h
    clang/lib/Lex/PPDirectives.cpp
    clang/unittests/Lex/PPCallbacksTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h
index 2e99fd9300362..94f96cf9c5125 100644
--- a/clang/include/clang/Lex/PPCallbacks.h
+++ b/clang/include/clang/Lex/PPCallbacks.h
@@ -83,6 +83,16 @@ class PPCallbacks {
                            const Token &FilenameTok,
                            SrcMgr::CharacteristicKind FileType) {}
 
+  /// Callback invoked whenever the preprocessor cannot find a file for an
+  /// inclusion directive.
+  ///
+  /// \param FileName The name of the file being included, as written in the
+  /// source code.
+  ///
+  /// \returns true to indicate that the preprocessor should skip this file
+  /// and not issue any diagnostic.
+  virtual bool FileNotFound(StringRef FileName) { return false; }
+
   /// Callback invoked whenever an inclusion directive of
   /// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
   /// of whether the inclusion will actually result in an inclusion.
@@ -451,6 +461,14 @@ class PPChainedCallbacks : public PPCallbacks {
     Second->FileSkipped(SkippedFile, FilenameTok, FileType);
   }
 
+  bool FileNotFound(StringRef FileName) override {
+    bool Skip = First->FileNotFound(FileName);
+    // Make sure to invoke the second callback, no matter if the first already
+    // returned true to skip the file.
+    Skip |= Second->FileNotFound(FileName);
+    return Skip;
+  }
+
   void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
                           StringRef FileName, bool IsAngled,
                           CharSourceRange FilenameRange,

diff  --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index f08d5fe2747f7..6ae513dea8782 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -2000,6 +2000,10 @@ OptionalFileEntryRef Preprocessor::LookupHeaderIncludeOrImport(
   if (File)
     return File;
 
+  // Give the clients a chance to silently skip this include.
+  if (Callbacks && Callbacks->FileNotFound(Filename))
+    return std::nullopt;
+
   if (SuppressIncludeNotFoundError)
     return std::nullopt;
 

diff  --git a/clang/unittests/Lex/PPCallbacksTest.cpp b/clang/unittests/Lex/PPCallbacksTest.cpp
index ec719387fa022..b2be40ef3812e 100644
--- a/clang/unittests/Lex/PPCallbacksTest.cpp
+++ b/clang/unittests/Lex/PPCallbacksTest.cpp
@@ -444,6 +444,50 @@ TEST_F(PPCallbacksTest, TrigraphInMacro) {
   ASSERT_EQ("\"tri\?\?-graph.h\"", GetSourceString(Range));
 }
 
+TEST_F(PPCallbacksTest, FileNotFoundSkipped) {
+  const char *SourceText = "#include \"skipped.h\"\n";
+
+  std::unique_ptr<llvm::MemoryBuffer> SourceBuf =
+      llvm::MemoryBuffer::getMemBuffer(SourceText);
+  SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
+
+  HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
+                          Diags, LangOpts, Target.get());
+  TrivialModuleLoader ModLoader;
+
+  DiagnosticConsumer *DiagConsumer = new DiagnosticConsumer;
+  DiagnosticsEngine FileNotFoundDiags(DiagID, DiagOpts.get(), DiagConsumer);
+  Preprocessor PP(std::make_shared<PreprocessorOptions>(), FileNotFoundDiags,
+                  LangOpts, SourceMgr, HeaderInfo, ModLoader,
+                  /*IILookup=*/nullptr,
+                  /*OwnsHeaderSearch=*/false);
+  PP.Initialize(*Target);
+
+  class FileNotFoundCallbacks : public PPCallbacks {
+  public:
+    unsigned int NumCalls = 0;
+    bool FileNotFound(StringRef FileName) override {
+      NumCalls++;
+      return FileName == "skipped.h";
+    }
+  };
+
+  auto *Callbacks = new FileNotFoundCallbacks;
+  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
+
+  // Lex source text.
+  PP.EnterMainSourceFile();
+  while (true) {
+    Token Tok;
+    PP.Lex(Tok);
+    if (Tok.is(tok::eof))
+      break;
+  }
+
+  ASSERT_EQ(1u, Callbacks->NumCalls);
+  ASSERT_EQ(0u, DiagConsumer->getNumErrors());
+}
+
 TEST_F(PPCallbacksTest, OpenCLExtensionPragmaEnabled) {
   const char* Source =
     "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";


        


More information about the cfe-commits mailing list