mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #18537 from jketema/elifdef
C++: Support `#elifdef`, `#elifndef`, and MSVC's `#import`
This commit is contained in:
2432
cpp/downgrades/59cb96ca699929b63941e81905f9b8de7eed59a6/old.dbscheme
Normal file
2432
cpp/downgrades/59cb96ca699929b63941e81905f9b8de7eed59a6/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -0,0 +1,3 @@
|
||||
description: Support #elifdef, #elifndef and #import
|
||||
compatibility: full
|
||||
preprocdirects.rel: run preprocdirects.qlo
|
||||
5
cpp/ql/lib/change-notes/2024-01-20-elifdef.md
Normal file
5
cpp/ql/lib/change-notes/2024-01-20-elifdef.md
Normal 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.
|
||||
@@ -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() }
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Support #elifdef, #elifndef and #import
|
||||
compatibility: partial
|
||||
15
cpp/ql/test/library-tests/preprocessor/preprocessor/pp23.cpp
Normal file
15
cpp/ql/test/library-tests/preprocessor/preprocessor/pp23.cpp
Normal 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
|
||||
@@ -0,0 +1,3 @@
|
||||
// semmle-extractor-options: --microsoft
|
||||
|
||||
#import "test.tlb"
|
||||
@@ -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 |
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#warning type library
|
||||
Reference in New Issue
Block a user