[clang] [clang] Provide to `PPCallbacks` full expression range even in single file parse mode. (PR #138358)

Volodymyr Sapsai via cfe-commits cfe-commits at lists.llvm.org
Fri May 2 16:13:39 PDT 2025


https://github.com/vsapsai created https://github.com/llvm/llvm-project/pull/138358

Restore the behavior existing prior to fe2eefc4718f57e1753f7bd51c158fc03d70b34f. Make reporting of unevaluated directive source range more consistent and with fewer assumptions. In case of a failed evaluation don't assume any specific token and don't assume correct `PPValue` range tracking.

>From 04d38f3d889e161ed9ecb356a6c01de743886bf6 Mon Sep 17 00:00:00 2001
From: Volodymyr Sapsai <vsapsai at apple.com>
Date: Fri, 2 May 2025 16:09:26 -0700
Subject: [PATCH] [clang] Provide to `PPCallbacks` full expression range even
 in single file parse mode.

Restore the behavior existing prior to fe2eefc4718f57e1753f7bd51c158fc03d70b34f.
Make reporting of unevaluated directive source range more consistent and
with fewer assumptions. In case of a failed evaluation don't assume any
specific token and don't assume correct `PPValue` range tracking.
---
 clang/lib/Lex/PPExpressions.cpp         | 11 ++++++-----
 clang/unittests/Lex/PPCallbacksTest.cpp | 21 +++++++++++++++++++--
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index a202af774256a..cf7e32bee2e71 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -903,9 +903,8 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
   SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());
   if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
     // Parse error, skip the rest of the macro line.
-    SourceRange ConditionRange = ExprStartLoc;
     if (Tok.isNot(tok::eod))
-      ConditionRange = DiscardUntilEndOfDirective(Tok);
+      DiscardUntilEndOfDirective(Tok);
 
     // Restore 'DisableMacroExpansion'.
     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
@@ -916,7 +915,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
     return {std::nullopt,
             false,
             DT.IncludedUndefinedIds,
-            {ExprStartLoc, ConditionRange.getEnd()}};
+            {ExprStartLoc, Tok.getLocation()}};
   }
 
   EvaluatedDefined = DT.State != DefinedTracker::Unknown;
@@ -948,8 +947,10 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
 
     // Restore 'DisableMacroExpansion'.
     DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
-    SourceRange ValRange = ResVal.getRange();
-    return {std::nullopt, false, DT.IncludedUndefinedIds, ValRange};
+    return {std::nullopt,
+            false,
+            DT.IncludedUndefinedIds,
+            {ExprStartLoc, Tok.getLocation()}};
   }
 
   if (CheckForEoD) {
diff --git a/clang/unittests/Lex/PPCallbacksTest.cpp b/clang/unittests/Lex/PPCallbacksTest.cpp
index 15385c13879d3..c2a84d974dd39 100644
--- a/clang/unittests/Lex/PPCallbacksTest.cpp
+++ b/clang/unittests/Lex/PPCallbacksTest.cpp
@@ -237,14 +237,13 @@ class PPCallbacksTest : public ::testing::Test {
   }
 
   std::vector<CondDirectiveCallbacks::Result>
-  DirectiveExprRange(StringRef SourceText) {
+  DirectiveExprRange(StringRef SourceText, PreprocessorOptions PPOpts = {}) {
     HeaderSearchOptions HSOpts;
     TrivialModuleLoader ModLoader;
     std::unique_ptr<llvm::MemoryBuffer> Buf =
         llvm::MemoryBuffer::getMemBuffer(SourceText);
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
     HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts, Target.get());
-    PreprocessorOptions PPOpts;
     Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
                     /*IILookup=*/nullptr, /*OwnsHeaderSearch=*/false);
     PP.Initialize(*Target);
@@ -569,6 +568,24 @@ TEST_F(PPCallbacksTest, DirectiveExprRanges) {
       Lexer::getSourceText(CharSourceRange(Results8[0].ConditionRange, false),
                            SourceMgr, LangOpts),
       "__FILE__ > FLOOFY");
+
+  const char *MultiExprIf = "#if defined(FLOOFY) || defined(FLUZZY)\n#endif\n";
+  const auto &Results9 = DirectiveExprRange(MultiExprIf);
+  EXPECT_EQ(Results9.size(), 1U);
+  EXPECT_EQ(
+      Lexer::getSourceText(CharSourceRange(Results9[0].ConditionRange, false),
+                           SourceMgr, LangOpts),
+      "defined(FLOOFY) || defined(FLUZZY)");
+
+  PreprocessorOptions PPOptsSingleFileParse;
+  PPOptsSingleFileParse.SingleFileParseMode = true;
+  const auto &Results10 =
+      DirectiveExprRange(MultiExprIf, PPOptsSingleFileParse);
+  EXPECT_EQ(Results10.size(), 1U);
+  EXPECT_EQ(
+      Lexer::getSourceText(CharSourceRange(Results10[0].ConditionRange, false),
+                           SourceMgr, LangOpts),
+      "defined(FLOOFY) || defined(FLUZZY)");
 }
 
 } // namespace



More information about the cfe-commits mailing list