C++: Expose explicit and explicit(bool) function specifiers

This commit is contained in:
Jeroen Ketema
2024-08-01 17:42:55 +02:00
parent 12261e6d08
commit 9744c06933
12 changed files with 10890 additions and 1577 deletions

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,3 @@
description: description: Support explicit(bool) specifiers
compatibility: full
explicit_specifier_exprs.rel: delete

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* An `isExplicit` predicate was added to the `Function` class that determines whether the function was declared as explicit.
* A `getExplicitExpr` predicate was added to the `Function` class that yields the constant boolean expression (if any) that conditionally determines whether the function is explicit.

View File

@@ -158,6 +158,26 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/ */
predicate isConsteval() { this.hasSpecifier("is_consteval") } predicate isConsteval() { this.hasSpecifier("is_consteval") }
/**
* Holds if this function is declared to be `explicit`.
*/
predicate isExplicit() { this.hasSpecifier("explicit") }
/**
* Gets the constant expression that determines whether the function is explicit.
*
* For example, for the following code the result is is the expression `sizeof(T) == 1`:
* ```
* template<typename T> struct C {
* explicit(sizeof(T) == 1)
* C(const T);
* };
* ```
*/
Expr getExplicitExpr() {
explicit_specifier_exprs(underlyingElement(this), unresolveElement(result))
}
/** /**
* Holds if this function is declared with `__attribute__((naked))` or * Holds if this function is declared with `__attribute__((naked))` or
* `__declspec(naked)`. * `__declspec(naked)`.

View File

@@ -921,6 +921,11 @@ varspecifiers(
int spec_id: @specifier ref int spec_id: @specifier ref
); );
explicit_specifier_exprs(
unique int func_id: @function ref,
int constant: @expr ref
)
attributes( attributes(
unique int id: @attribute, unique int id: @attribute,
int kind: int ref, int kind: int 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 explicit(bool) specifiers
compatibility: partial

View File

@@ -0,0 +1,12 @@
| cpp20.cpp:17:5:17:5 | (unnamed deduction guide) | | cpp20.cpp:16:14:16:27 | ... == ... | |
| cpp20.cpp:17:5:17:20 | TestExplicitBool | | cpp20.cpp:16:14:16:27 | ... == ... | |
| cpp20.cpp:17:5:17:20 | TestExplicitBool | | cpp20.cpp:16:14:16:27 | ... == ... | 0 |
| cpp20.cpp:17:5:17:20 | TestExplicitBool | explicit | cpp20.cpp:16:14:16:27 | ... == ... | 1 |
| cpp20.cpp:40:1:40:39 | TestExplicitBool2 | | cpp20.cpp:35:14:35:27 | ... == ... | |
| cpp20.cpp:40:23:40:23 | TestExplicitBool2 | | cpp20.cpp:35:14:35:27 | ... == ... | |
| cpp20.cpp:40:23:40:23 | TestExplicitBool2 | | cpp20.cpp:35:14:35:27 | ... == ... | 0 |
| cpp20.cpp:40:23:40:23 | TestExplicitBool2 | explicit | cpp20.cpp:35:14:35:27 | ... == ... | 1 |
| cpp20.cpp:51:5:51:21 | TestExplicitBool3 | | cpp20.cpp:50:14:50:27 | ... == ... | 0 |
| cpp20.cpp:51:5:51:21 | TestExplicitBool3 | explicit | cpp20.cpp:50:14:50:27 | ... == ... | 1 |
| cpp20.cpp:55:1:55:39 | TestExplicitBool3 | | cpp20.cpp:50:14:50:27 | ... == ... | |
| cpp20.cpp:64:5:64:21 | TestExplicitBool4 | explicit | cpp20.cpp:63:14:63:30 | ... == ... | 1 |

View File

@@ -0,0 +1,8 @@
import cpp
from Function f, string explicit, Expr e, string value
where
(if f.isExplicit() then explicit = "explicit" else explicit = "") and
e = f.getExplicitExpr() and
if exists(e.getValue()) then value = e.getValue() else value = ""
select f, explicit, e, value