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

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") }
/**
* 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
* `__declspec(naked)`.

View File

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