C++: Support #elifdef #elifndef, and MSVC's #import

This commit is contained in:
Jeroen Ketema
2025-01-16 21:05:46 +01:00
parent a0ef2888c7
commit 9fd95381dc
4 changed files with 65 additions and 16 deletions

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,

View File

@@ -1,11 +1,11 @@
| 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 | PreprocessorElif | BAR | 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 | PreprocessorElif | 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 |
@@ -49,5 +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 |