Skip to content

Commit fe2eefc

Browse files
authored
[clang][index] Handle undefined function-like macros in single file parse mode (#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.)
1 parent 5709506 commit fe2eefc

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

clang/lib/Lex/PPExpressions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "clang/Lex/MacroInfo.h"
2727
#include "clang/Lex/PPCallbacks.h"
2828
#include "clang/Lex/Preprocessor.h"
29+
#include "clang/Lex/PreprocessorOptions.h"
2930
#include "clang/Lex/Token.h"
3031
#include "llvm/ADT/APSInt.h"
3132
#include "llvm/ADT/STLExtras.h"
@@ -592,6 +593,15 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
592593
Token &PeekTok, bool ValueLive,
593594
bool &IncludedUndefinedIds,
594595
Preprocessor &PP) {
596+
if (PP.getPreprocessorOpts().SingleFileParseMode && IncludedUndefinedIds) {
597+
// The single-file parse mode behavior kicks in as soon as single identifier
598+
// is undefined. If we've already seen one, there's no point in continuing
599+
// with the rest of the expression. Besides saving work, this also prevents
600+
// calling undefined function-like macros.
601+
PP.DiscardUntilEndOfDirective(PeekTok);
602+
return true;
603+
}
604+
595605
unsigned PeekPrec = getPrecedence(PeekTok.getKind());
596606
// If this token isn't valid, report the error.
597607
if (PeekPrec == ~0U) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: split-file %s %t
2+
// RUN: c-index-test -single-file-parse %t/tu.c 2>&1 | FileCheck %t/tu.c
3+
4+
//--- header.h
5+
#define FUNCTION_LIKE_MACRO() 1
6+
//--- tu.c
7+
#include "header.h"
8+
// CHECK-NOT: tu.c:[[@LINE+1]]:5: error: function-like macro 'FUNCTION_LIKE_MACRO' is not defined
9+
#if FUNCTION_LIKE_MACRO()
10+
// CHECK: tu.c:[[@LINE+1]]:5: FunctionDecl=then_fn
11+
int then_fn();
12+
#else
13+
// CHECK: tu.c:[[@LINE+1]]:5: FunctionDecl=else_fn
14+
int else_fn();
15+
#endif

0 commit comments

Comments
 (0)