Skip to content

Commit ccbd5f9

Browse files
committed
cppparser: Support #elifdef, #elifndef, #warning directives (C++23)
1 parent f1786eb commit ccbd5f9

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

src/cppparser/cppPreprocessor.cxx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ process_directive(int c) {
16621662
handle_ifndef_directive(args, loc);
16631663
} else if (command == "if") {
16641664
handle_if_directive(args, loc);
1665-
} else if (command == "else" || command == "elif") {
1665+
} else if (command == "else" || command == "elif" || command == "elifdef" || command == "elifndef") {
16661666
// Presumably this follows some #if or #ifdef. We don't bother to check
16671667
// this, however.
16681668
skip_false_if_block(false);
@@ -1677,6 +1677,8 @@ process_directive(int c) {
16771677
// Quietly ignore idents.
16781678
} else if (command == "error") {
16791679
handle_error_directive(args, loc);
1680+
} else if (command == "warning") {
1681+
handle_warning_directive(args, loc);
16801682
} else {
16811683
loc.first_line = begin_line;
16821684
loc.first_column = begin_column;
@@ -1979,6 +1981,14 @@ handle_error_directive(const string &args, const YYLTYPE &loc) {
19791981
error(args, loc);
19801982
}
19811983

1984+
/**
1985+
*
1986+
*/
1987+
void CPPPreprocessor::
1988+
handle_warning_directive(const string &args, const YYLTYPE &loc) {
1989+
warning(args, loc);
1990+
}
1991+
19821992
/**
19831993
* We come here when we fail an #if or an #ifdef test, or when we reach the
19841994
* #else clause to something we didn't fail. This function skips all text up
@@ -2021,6 +2031,18 @@ skip_false_if_block(bool consider_elifs) {
20212031
handle_if_directive(args, loc);
20222032
return;
20232033
}
2034+
} else if (command == "elifdef") {
2035+
if (level == 0 && consider_elifs) {
2036+
_save_comments = true;
2037+
handle_ifdef_directive(args, loc);
2038+
return;
2039+
}
2040+
} else if (command == "elifndef") {
2041+
if (level == 0 && consider_elifs) {
2042+
_save_comments = true;
2043+
handle_ifndef_directive(args, loc);
2044+
return;
2045+
}
20242046
} else if (command == "endif") {
20252047
// Skip any args.
20262048
if (level == 0) {

src/cppparser/cppPreprocessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class CPPPreprocessor {
146146
void handle_include_directive(const std::string &args, const YYLTYPE &loc);
147147
void handle_pragma_directive(const std::string &args, const YYLTYPE &loc);
148148
void handle_error_directive(const std::string &args, const YYLTYPE &loc);
149+
void handle_warning_directive(const std::string &args, const YYLTYPE &loc);
149150

150151
void skip_false_if_block(bool consider_elifs);
151152
bool is_manifest_defined(const std::string &manifest_name) const;

tests/cppparser/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ function(parse_test file)
77
add_test(NAME ${name} COMMAND parse_file -T ${extra_args} "-S${PROJECT_SOURCE_DIR}/parser-inc" "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
88
endfunction()
99

10+
parse_test(conditional.c)
1011
parse_test(literals.c)
1112
parse_test(recursive_macros.c)
1213
parse_test(stat.c)

tests/cppparser/conditional.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#define TRUE 1
2+
3+
#ifdef TRUE
4+
#else
5+
#error Should not reach
6+
#endif
7+
8+
#if TRUE
9+
#else
10+
#error Should not reach
11+
#endif
12+
13+
#if TRUE
14+
#elif FALSE
15+
#error Should not reach
16+
#endif
17+
18+
#if TRUE
19+
#elifdef FALSE
20+
#error Should not reach
21+
#endif
22+
23+
#if TRUE
24+
#elifndef FALSE
25+
#error Should not reach
26+
#endif
27+
28+
#if TRUE
29+
#elif TRUE
30+
#error Should not reach
31+
#endif
32+
33+
#if TRUE
34+
#elifdef TRUE
35+
#error Should not reach
36+
#endif
37+
38+
#ifndef TRUE
39+
#error Should not reach
40+
#else
41+
#endif
42+
43+
#ifndef TRUE
44+
#error Should not reach
45+
#elif TRUE
46+
#else
47+
#error Should not reach
48+
#endif
49+
50+
#ifndef TRUE
51+
#error Should not reach
52+
#elifdef TRUE
53+
#else
54+
#error Should not reach
55+
#endif
56+
57+
#ifndef TRUE
58+
#error Should not reach
59+
#elif FALSE
60+
#error Should not reach
61+
#else
62+
#endif
63+
64+
#ifdef FALSE
65+
#error Should not reach
66+
#elifdef FALSE
67+
#error Should not reach
68+
#elifndef TRUE
69+
#error Should not reach
70+
#endif
71+

0 commit comments

Comments
 (0)