https://github.com/jansvoboda11 created https://github.com/llvm/llvm-project/pull/135054
The single file parse mode is supposed to enter both branches of an `#if` directive whenever the condition contains undefined identifiers. This patch adds support for undefined function-like macros, where we would previously emit an error that doesn't make sense from end-user perspective. (I discovered this while working on a very similar feature that parses single module only and doesn't enter either `#if` branch when the condition contains undefined identifiers.) >From 0de77a2d87f1968f0efdb57694df65b74c3fc844 Mon Sep 17 00:00:00 2001 From: Jan Svoboda <jan_svob...@apple.com> Date: Wed, 9 Apr 2025 10:09:01 -0700 Subject: [PATCH] [clang][index] Handle undefined function-like macros in single file parse mode --- clang/lib/Lex/PPExpressions.cpp | 10 ++++++++++ ...gle-file-parse-undefined-function-like-macro.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 clang/test/Index/single-file-parse-undefined-function-like-macro.c diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 48835121b40e9..a202af774256a 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -26,6 +26,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" #include "clang/Lex/Token.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/STLExtras.h" @@ -592,6 +593,15 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, bool &IncludedUndefinedIds, Preprocessor &PP) { + if (PP.getPreprocessorOpts().SingleFileParseMode && IncludedUndefinedIds) { + // The single-file parse mode behavior kicks in as soon as single identifier + // is undefined. If we've already seen one, there's no point in continuing + // with the rest of the expression. Besides saving work, this also prevents + // calling undefined function-like macros. + PP.DiscardUntilEndOfDirective(PeekTok); + return true; + } + unsigned PeekPrec = getPrecedence(PeekTok.getKind()); // If this token isn't valid, report the error. if (PeekPrec == ~0U) { diff --git a/clang/test/Index/single-file-parse-undefined-function-like-macro.c b/clang/test/Index/single-file-parse-undefined-function-like-macro.c new file mode 100644 index 0000000000000..4d2da1382fcd9 --- /dev/null +++ b/clang/test/Index/single-file-parse-undefined-function-like-macro.c @@ -0,0 +1,15 @@ +// RUN: split-file %s %t +// RUN: c-index-test -single-file-parse %t/tu.c 2>&1 | FileCheck %t/tu.c + +//--- header.h +#define FUNCTION_LIKE_MACRO() 1 +//--- tu.c +#include "header.h" +// CHECK-NOT: tu.c:[[@LINE+1]]:5: error: function-like macro 'FUNCTION_LIKE_MACRO' is not defined +#if FUNCTION_LIKE_MACRO() +// CHECK: tu.c:[[@LINE+1]]:5: FunctionDecl=then_fn +int then_fn(); +#else +// CHECK: tu.c:[[@LINE+1]]:5: FunctionDecl=else_fn +int else_fn(); +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits