Merge pull request #18368 from github/jketema/template-parameters-7

C++: Handle requires clauses and type template type constraints
This commit is contained in:
Jeroen Ketema
2025-01-10 15:02:41 +01:00
committed by GitHub
13 changed files with 10237 additions and 309 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,6 @@
description: Support requires clauses and type constraints
compatibility: full
fun_requires.rel: delete
var_requires.rel: delete
type_requires.rel: delete
type_template_type_constraint.rel: delete

View File

@@ -0,0 +1,7 @@
---
category: feature
---
* New predicates `getARequiresClause`, `getTemplateRequiresClause` and `getFunctionRequiresClause` were added to the `FunctionDeclarationEntry` class, which yield the requires clauses when the entry represents a function template declaration with requires clauses.
* A new predicate `getRequiresClause` was added to the `TypeDeclarationEntry` class, which yields the requires clause when the entry represents a class template declaration with a requires clause.
* A new predicate `getRequiresClause` was added to the `VariableDeclarationEntry` class, which yields the requires clause when the entry represents a variable template declaration with a requires clause.
* A new predicate `getTypeConstraint` was added to the `TypeTemplateParameter` class, which yields the type constraint of the parameter if it exists.

View File

@@ -715,6 +715,27 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* specification.
*/
predicate isNoExcept() { fun_decl_empty_noexcept(underlyingElement(this)) }
/**
* Gets a requires clause if this declaration is a template with such a clause.
*/
Expr getARequiresClause() { fun_requires(underlyingElement(this), _, unresolveElement(result)) }
/**
* Gets the requires clause that appears after the template argument list if this
* declaration is a template with such a clause.
*/
Expr getTemplateRequiresClause() {
fun_requires(underlyingElement(this), 1, unresolveElement(result))
}
/**
* Gets the requires clause that appears after the declarator if this declaration
* is a template with such a clause.
*/
Expr getFunctionRequiresClause() {
fun_requires(underlyingElement(this), 2, unresolveElement(result))
}
}
/**

View File

@@ -59,6 +59,13 @@ class TypeTemplateParameter extends UserType, TemplateParameterImpl {
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
override predicate involvesTemplateParameter() { any() }
/**
* Get the type constraint of this type template parameter.
*/
Expr getTypeConstraint() {
type_template_type_constraint(underlyingElement(this), unresolveElement(result))
}
}
/**

View File

@@ -129,4 +129,9 @@ class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
* class or typedef.
*/
predicate isTopLevel() { type_decl_top(underlyingElement(this)) }
/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { type_requires(underlyingElement(this), unresolveElement(result)) }
}

View File

@@ -278,6 +278,11 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { var_specialized(underlyingElement(this)) }
/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { var_requires(underlyingElement(this), unresolveElement(result)) }
}
/**

View File

@@ -480,6 +480,19 @@ fun_decl_typedef_type(
int typedeftype_id: @usertype ref
);
/*
case @fun_requires.kind of
1 = @template_attached
| 2 = @function_attached
;
*/
fun_requires(
int id: @fun_decl ref,
int kind: int ref,
int constraint: @expr ref
);
param_decl_bind(
unique int id: @var_decl ref,
int index: int ref,
@@ -501,6 +514,10 @@ var_decl_specifiers(
string name: string ref
)
is_structured_binding(unique int id: @variable ref);
var_requires(
int id: @var_decl ref,
int constraint: @expr ref
);
type_decls(
unique int id: @type_decl,
@@ -511,6 +528,10 @@ type_def(unique int id: @type_decl ref);
type_decl_top(
unique int type_decl: @type_decl ref
);
type_requires(
int id: @type_decl ref,
int constraint: @expr ref
);
namespace_decls(
unique int id: @namespace_decl,
@@ -790,6 +811,11 @@ nontype_template_parameters(
int id: @expr ref
);
type_template_type_constraint(
int id: @usertype ref,
int constraint: @expr ref
);
mangled_name(
unique int id: @declaration ref,
int mangled_name : @mangledname,

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 requires clauses and type constraints
compatibility: partial