Skip to content

Commit 9fd9538

Browse files
committed
C++: Support #elifdef #elifndef, and MSVC's #import
1 parent a0ef288 commit 9fd9538

File tree

4 files changed

+65
-16
lines changed

4 files changed

+65
-16
lines changed

cpp/ql/lib/semmle/code/cpp/Include.qll

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,24 @@ class IncludeNext extends Include, @ppd_include_next {
5757
}
5858

5959
/**
60-
* A `#import` preprocessor directive (used heavily in Objective C, and
61-
* supported by GCC as an extension in C). For example the following code
62-
* contains one `Import` directive:
60+
* An Objective C `#import` preprocessor directive (supported by GCC as
61+
* an extension in C). For example the following code contains one `Import`
62+
* directive:
6363
* ```
6464
* #import <header3.h>
6565
* ```
6666
*/
6767
class Import extends Include, @ppd_objc_import {
6868
override string toString() { result = "#import " + this.getIncludeText() }
6969
}
70+
71+
/**
72+
* A Microsoft `#import` preprocessor directive for importing a type library.
73+
* For example the following code contains one `TypeLibraryImport` directive:
74+
* ```
75+
* #import "library.tlb"
76+
* ```
77+
*/
78+
class TypeLibraryImport extends Include, @ppd_ms_import {
79+
override string toString() { result = "#import " + this.getIncludeText() }
80+
}

cpp/ql/lib/semmle/code/cpp/Preprocessor.qll

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private class TPreprocessorBranchDirective = @ppd_branch or @ppd_else or @ppd_en
4242

4343
/**
4444
* A C/C++ preprocessor branch related directive: `#if`, `#ifdef`,
45-
* `#ifndef`, `#elif`, `#else` or `#endif`.
45+
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif`.
4646
*/
4747
class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBranchDirective {
4848
/**
@@ -74,8 +74,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
7474
}
7575

7676
/**
77-
* Gets the next `#elif`, `#else` or `#endif` matching this branching
78-
* directive.
77+
* Gets the next `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif` matching
78+
* this branching directive.
7979
*
8080
* For example `somePreprocessorBranchDirective.getIf().getNext()` gets
8181
* the second directive in the same construct as
@@ -88,8 +88,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
8888
}
8989

9090
/**
91-
* Gets the index of this branching directive within the matching #if,
92-
* #ifdef or #ifndef.
91+
* Gets the index of this branching directive within the matching `#if`,
92+
* `#ifdef` or `#ifndef`.
9393
*/
9494
private int getIndexInBranch(PreprocessorBranch branch) {
9595
this =
@@ -102,8 +102,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
102102
}
103103

104104
/**
105-
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`, or
106-
* `#elif`.
105+
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`,
106+
* `#elif`, `#elifdef`, or `#elifndef`.
107107
*
108108
* A branching directive has a condition and that condition may be evaluated
109109
* at compile-time. As a result, the preprocessor will either take the
@@ -151,8 +151,8 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
151151
* #endif
152152
* ```
153153
* For the related notion of a directive which causes branching (which
154-
* includes `#if`, plus also `#ifdef`, `#ifndef`, and `#elif`), see
155-
* `PreprocessorBranch`.
154+
* includes `#if`, plus also `#ifdef`, `#ifndef`, `#elif`, `#elifdef`,
155+
* and `#elifndef`), see `PreprocessorBranch`.
156156
*/
157157
class PreprocessorIf extends PreprocessorBranch, @ppd_if {
158158
override string toString() { result = "#if " + this.getHead() }
@@ -222,6 +222,40 @@ class PreprocessorElif extends PreprocessorBranch, @ppd_elif {
222222
override string toString() { result = "#elif " + this.getHead() }
223223
}
224224

225+
/**
226+
* A C/C++ preprocessor `#elifdef` directive. For example there is a
227+
* `PreprocessorElifdef` on the third line of the following code:
228+
* ```
229+
* #ifdef MYDEFINE1
230+
* // ...
231+
* #elifdef MYDEFINE2
232+
* // ...
233+
* #else
234+
* // ...
235+
* #endif
236+
* ```
237+
*/
238+
class PreprocessorElifdef extends PreprocessorBranch, @ppd_elifdef {
239+
override string toString() { result = "#elifdef " + this.getHead() }
240+
}
241+
242+
/**
243+
* A C/C++ preprocessor `#elifndef` directive. For example there is a
244+
* `PreprocessorElifndef` on the third line of the following code:
245+
* ```
246+
* #ifdef MYDEFINE1
247+
* // ...
248+
* #elifndef MYDEFINE2
249+
* // ...
250+
* #else
251+
* // ...
252+
* #endif
253+
* ```
254+
*/
255+
class PreprocessorElifndef extends PreprocessorBranch, @ppd_elifndef {
256+
override string toString() { result = "#elifndef " + this.getHead() }
257+
}
258+
225259
/**
226260
* A C/C++ preprocessor `#endif` directive. For example there is a
227261
* `PreprocessorEndif` on the third line of the following code:

cpp/ql/lib/semmlecode.cpp.dbscheme

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2318,12 +2318,15 @@ case @preprocdirect.kind of
23182318
| 11 = @ppd_pragma
23192319
| 12 = @ppd_objc_import
23202320
| 13 = @ppd_include_next
2321+
| 14 = @ppd_ms_import
2322+
| 15 = @ppd_elifdef
2323+
| 16 = @ppd_elifndef
23212324
| 18 = @ppd_warning
23222325
;
23232326

2324-
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
2327+
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
23252328

2326-
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
2329+
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
23272330

23282331
preprocpair(
23292332
int begin : @ppd_branch ref,

cpp/ql/test/library-tests/preprocessor/preprocessor/preproc.expected

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
| a.h:0:0:0:0 | a.h | 1 | 1 | 1 | 19 | IncludeNext | "a.h" | N/A |
22
| pp23.cpp:0:0:0:0 | pp23.cpp | 3 | 1 | 3 | 11 | Macro | BAR | |
33
| pp23.cpp:0:0:0:0 | pp23.cpp | 5 | 1 | 5 | 10 | PreprocessorIfdef | FOO | N/A |
4-
| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | PreprocessorElif | BAR | N/A |
4+
| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | PreprocessorElifdef | BAR | N/A |
55
| pp23.cpp:0:0:0:0 | pp23.cpp | 8 | 1 | 8 | 16 | PreprocessorWarning | C++23 2 | N/A |
66
| pp23.cpp:0:0:0:0 | pp23.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A |
77
| pp23.cpp:0:0:0:0 | pp23.cpp | 11 | 1 | 11 | 10 | PreprocessorIfdef | FOO | N/A |
8-
| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | PreprocessorElif | FOO | N/A |
8+
| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | PreprocessorElifndef | FOO | N/A |
99
| pp23.cpp:0:0:0:0 | pp23.cpp | 14 | 1 | 14 | 16 | PreprocessorWarning | C++23 3 | N/A |
1010
| pp23.cpp:0:0:0:0 | pp23.cpp | 15 | 1 | 15 | 6 | PreprocessorEndif | N/A | N/A |
1111
| pp.cpp:0:0:0:0 | pp.cpp | 1 | 1 | 1 | 16 | PreprocessorIf | defined(FOO) | N/A |
@@ -49,5 +49,6 @@
4949
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |
5050
| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | PreprocessorUndef | MULTILINE | N/A |
5151
| pp.h:0:0:0:0 | pp.h | 16 | 1 | 17 | 8 | Include | "pp.h" | N/A |
52+
| ppms.cpp:0:0:0:0 | ppms.cpp | 3 | 1 | 3 | 18 | TypeLibraryImport | "test.tlb" | N/A |
5253
| test.tlh:0:0:0:0 | test.tlh | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
5354
| test.tlh:0:0:0:0 | test.tlh | 3 | 1 | 3 | 21 | PreprocessorWarning | type library | N/A |

0 commit comments

Comments
 (0)