Merge pull request #18537 from jketema/elifdef

C++: Support `#elifdef`, `#elifndef`, and MSVC's `#import`
This commit is contained in:
Jeroen Ketema
2025-01-21 16:44:27 +01:00
committed by GitHub
16 changed files with 10188 additions and 332 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
class PreprocessorDirective extends @preprocdirect {
string toString() { none() }
}
class Location extends @location_default {
string toString() { none() }
}
bindingset[kind]
int getKind(int kind) {
if kind = 14
then result = 6 // Represent MSFT #import as #include
else
if kind = 15 or kind = 6
then result = 3 // Represent #elifdef and #elifndef as #elif
else result = kind
}
from PreprocessorDirective ppd, int kind, Location l
where preprocdirects(ppd, kind, l)
select ppd, getKind(kind), l

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Support #elifdef, #elifndef and #import
compatibility: full
preprocdirects.rel: run preprocdirects.qlo

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* New classes `PreprocessorElifdef` and `PreprocessorElifndef` were introduced, which represents the C23/C++23 `#elifdef` and `#elifndef` preprocessor directives.
* A new class `TypeLibraryImport` was introduced, which represents the `#import` preprocessor directive as used by the Microsoft Visual C++ for importing type libraries.

View File

@@ -57,9 +57,9 @@ class IncludeNext extends Include, @ppd_include_next {
}
/**
* A `#import` preprocessor directive (used heavily in Objective C, and
* supported by GCC as an extension in C). For example the following code
* contains one `Import` directive:
* An Objective C `#import` preprocessor directive (supported by GCC as
* an extension in C). For example the following code contains one `Import`
* directive:
* ```
* #import <header3.h>
* ```
@@ -67,3 +67,14 @@ class IncludeNext extends Include, @ppd_include_next {
class Import extends Include, @ppd_objc_import {
override string toString() { result = "#import " + this.getIncludeText() }
}
/**
* A Microsoft `#import` preprocessor directive for importing a type library.
* For example the following code contains one `TypeLibraryImport` directive:
* ```
* #import "library.tlb"
* ```
*/
class TypeLibraryImport extends Include, @ppd_ms_import {
override string toString() { result = "#import " + this.getIncludeText() }
}

View File

@@ -42,7 +42,7 @@ private class TPreprocessorBranchDirective = @ppd_branch or @ppd_else or @ppd_en
/**
* A C/C++ preprocessor branch related directive: `#if`, `#ifdef`,
* `#ifndef`, `#elif`, `#else` or `#endif`.
* `#ifndef`, `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif`.
*/
class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBranchDirective {
/**
@@ -74,8 +74,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the next `#elif`, `#else` or `#endif` matching this branching
* directive.
* Gets the next `#elif`, `#elifdef`, `#elifndef`, `#else` or `#endif` matching
* this branching directive.
*
* For example `somePreprocessorBranchDirective.getIf().getNext()` gets
* the second directive in the same construct as
@@ -88,8 +88,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* Gets the index of this branching directive within the matching #if,
* #ifdef or #ifndef.
* Gets the index of this branching directive within the matching `#if`,
* `#ifdef` or `#ifndef`.
*/
private int getIndexInBranch(PreprocessorBranch branch) {
this =
@@ -102,8 +102,8 @@ class PreprocessorBranchDirective extends PreprocessorDirective, TPreprocessorBr
}
/**
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`, or
* `#elif`.
* A C/C++ preprocessor branching directive: `#if`, `#ifdef`, `#ifndef`,
* `#elif`, `#elifdef`, or `#elifndef`.
*
* A branching directive has a condition and that condition may be evaluated
* at compile-time. As a result, the preprocessor will either take the
@@ -151,8 +151,8 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* #endif
* ```
* For the related notion of a directive which causes branching (which
* includes `#if`, plus also `#ifdef`, `#ifndef`, and `#elif`), see
* `PreprocessorBranch`.
* includes `#if`, plus also `#ifdef`, `#ifndef`, `#elif`, `#elifdef`,
* and `#elifndef`), see `PreprocessorBranch`.
*/
class PreprocessorIf extends PreprocessorBranch, @ppd_if {
override string toString() { result = "#if " + this.getHead() }
@@ -222,6 +222,40 @@ class PreprocessorElif extends PreprocessorBranch, @ppd_elif {
override string toString() { result = "#elif " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifdef` directive. For example there is a
* `PreprocessorElifdef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifdef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifdef extends PreprocessorBranch, @ppd_elifdef {
override string toString() { result = "#elifdef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#elifndef` directive. For example there is a
* `PreprocessorElifndef` on the third line of the following code:
* ```
* #ifdef MYDEFINE1
* // ...
* #elifndef MYDEFINE2
* // ...
* #else
* // ...
* #endif
* ```
*/
class PreprocessorElifndef extends PreprocessorBranch, @ppd_elifndef {
override string toString() { result = "#elifndef " + this.getHead() }
}
/**
* A C/C++ preprocessor `#endif` directive. For example there is a
* `PreprocessorEndif` on the third line of the following code:

View File

@@ -2318,12 +2318,15 @@ case @preprocdirect.kind of
| 11 = @ppd_pragma
| 12 = @ppd_objc_import
| 13 = @ppd_include_next
| 14 = @ppd_ms_import
| 15 = @ppd_elifdef
| 16 = @ppd_elifndef
| 18 = @ppd_warning
;
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next;
@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next | @ppd_ms_import;
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif;
@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif | @ppd_elifdef | @ppd_elifndef;
preprocpair(
int begin : @ppd_branch ref,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Support #elifdef, #elifndef and #import
compatibility: partial

View File

@@ -0,0 +1,15 @@
// semmle-extractor-options: -std=c++23
#define BAR
#ifdef FOO
#warning C++23 1
#elifdef BAR
#warning C++23 2
#endif
#ifdef FOO
#warning C++23 3
#elifndef FOO
#warning C++23 3
#endif

View File

@@ -0,0 +1,3 @@
// semmle-extractor-options: --microsoft
#import "test.tlb"

View File

@@ -1,4 +1,13 @@
| a.h:0:0:0:0 | a.h | 1 | 1 | 1 | 19 | IncludeNext | "a.h" | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 3 | 1 | 3 | 11 | Macro | BAR | |
| pp23.cpp:0:0:0:0 | pp23.cpp | 5 | 1 | 5 | 10 | PreprocessorIfdef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 7 | 1 | 7 | 12 | PreprocessorElifdef | BAR | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 8 | 1 | 8 | 16 | PreprocessorWarning | C++23 2 | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 9 | 1 | 9 | 6 | PreprocessorEndif | N/A | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 11 | 1 | 11 | 10 | PreprocessorIfdef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 13 | 1 | 13 | 13 | PreprocessorElifndef | FOO | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 14 | 1 | 14 | 16 | PreprocessorWarning | C++23 3 | N/A |
| pp23.cpp:0:0:0:0 | pp23.cpp | 15 | 1 | 15 | 6 | PreprocessorEndif | N/A | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 1 | 1 | 1 | 16 | PreprocessorIf | defined(FOO) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 3 | 1 | 3 | 19 | PreprocessorElif | !defined(BAR) | N/A |
| pp.cpp:0:0:0:0 | pp.cpp | 4 | 1 | 4 | 11 | Macro | BAR | |
@@ -40,3 +49,6 @@
| pp.h:0:0:0:0 | pp.h | 7 | 1 | 11 | 8 | Macro | MULTILINE | world a long |
| pp.h:0:0:0:0 | pp.h | 13 | 1 | 14 | 11 | PreprocessorUndef | MULTILINE | N/A |
| pp.h:0:0:0:0 | pp.h | 16 | 1 | 17 | 8 | Include | "pp.h" | N/A |
| ppms.cpp:0:0:0:0 | ppms.cpp | 3 | 1 | 3 | 18 | TypeLibraryImport | "test.tlb" | N/A |
| test.tlh:0:0:0:0 | test.tlh | 1 | 1 | 1 | 12 | PreprocessorPragma | once | N/A |
| test.tlh:0:0:0:0 | test.tlh | 3 | 1 | 3 | 21 | PreprocessorWarning | type library | N/A |

View File

@@ -0,0 +1,3 @@
#pragma once
#warning type library