Skip to content

Commit 2c9af9e

Browse files
committed
C++: Add support for requires clauses and constraints on template parameters
1 parent 204afab commit 2c9af9e

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

cpp/ql/lib/semmle/code/cpp/Function.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,27 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
715715
* specification.
716716
*/
717717
predicate isNoExcept() { fun_decl_empty_noexcept(underlyingElement(this)) }
718+
719+
/**
720+
* Gets a requires clause if this declaration is a template with such a clause.
721+
*/
722+
Expr getARequiresClause() { fun_requires(underlyingElement(this), _, unresolveElement(result)) }
723+
724+
/**
725+
* Gets the requires clause that appears after the template argument list if this
726+
* declaration is a template with such a clause.
727+
*/
728+
Expr getTemplateRequiresClause() {
729+
fun_requires(underlyingElement(this), 1, unresolveElement(result))
730+
}
731+
732+
/**
733+
* Gets the requires clause that appears after the declarator if this declaration
734+
* is a template with such a clause.
735+
*/
736+
Expr getFunctionRequiresClause() {
737+
fun_requires(underlyingElement(this), 2, unresolveElement(result))
738+
}
718739
}
719740

720741
/**

cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ class TypeTemplateParameter extends UserType, TemplateParameterImpl {
5959
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }
6060

6161
override predicate involvesTemplateParameter() { any() }
62+
63+
/**
64+
* Get the type constraint of this type template parameter.
65+
*/
66+
Expr getTypeConstraint() {
67+
type_template_type_constraint(underlyingElement(this), unresolveElement(result))
68+
}
6269
}
6370

6471
/**

cpp/ql/lib/semmle/code/cpp/UserType.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,9 @@ class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
129129
* class or typedef.
130130
*/
131131
predicate isTopLevel() { type_decl_top(underlyingElement(this)) }
132+
133+
/**
134+
* Gets the requires clause if this declaration is a template with such a clause.
135+
*/
136+
Expr getRequiresClause() { type_requires(underlyingElement(this), unresolveElement(result)) }
132137
}

cpp/ql/lib/semmle/code/cpp/Variable.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
278278

279279
/** Holds if this declaration is a template specialization. */
280280
predicate isSpecialization() { var_specialized(underlyingElement(this)) }
281+
282+
/**
283+
* Gets the requires clause if this declaration is a template with such a clause.
284+
*/
285+
Expr getRequiresClause() { var_requires(underlyingElement(this), unresolveElement(result)) }
281286
}
282287

283288
/**

cpp/ql/lib/semmlecode.cpp.dbscheme

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,19 @@ fun_decl_typedef_type(
480480
int typedeftype_id: @usertype ref
481481
);
482482

483+
/*
484+
case @fun_requires.kind of
485+
1 = @template_attached
486+
| 2 = @function_attached
487+
;
488+
*/
489+
490+
fun_requires(
491+
int id: @fun_decl ref,
492+
int kind: int ref,
493+
int constraint: @expr ref
494+
);
495+
483496
param_decl_bind(
484497
unique int id: @var_decl ref,
485498
int index: int ref,
@@ -501,6 +514,10 @@ var_decl_specifiers(
501514
string name: string ref
502515
)
503516
is_structured_binding(unique int id: @variable ref);
517+
var_requires(
518+
int id: @var_decl ref,
519+
int constraint: @expr ref
520+
);
504521

505522
type_decls(
506523
unique int id: @type_decl,
@@ -511,6 +528,10 @@ type_def(unique int id: @type_decl ref);
511528
type_decl_top(
512529
unique int type_decl: @type_decl ref
513530
);
531+
type_requires(
532+
int id: @type_decl ref,
533+
int constraint: @expr ref
534+
);
514535

515536
namespace_decls(
516537
unique int id: @namespace_decl,
@@ -790,6 +811,11 @@ nontype_template_parameters(
790811
int id: @expr ref
791812
);
792813

814+
type_template_type_constraint(
815+
int id: @usertype ref,
816+
int constraint: @expr ref
817+
);
818+
793819
mangled_name(
794820
unique int id: @declaration ref,
795821
int mangled_name : @mangledname,

0 commit comments

Comments
 (0)