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

Restore the behavior existing prior to
fe2eefc471. 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.
This commit is contained in:
Volodymyr Sapsai
2025-05-05 12:06:41 -07:00
committed by GitHub
parent b32c6d18a4
commit c296b1258c
2 changed files with 25 additions and 7 deletions

View File

@@ -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) {

View File

@@ -237,14 +237,13 @@ protected:
}
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