@@ -437,6 +437,168 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if {
437437 }
438438}
439439
440+ /**
441+ * A C/C++ '(not) consteval if'. For example, the `if consteval` statement
442+ * in the following code:
443+ * ```cpp
444+ * if consteval {
445+ * ...
446+ * }
447+ * ```
448+ */
449+ class ConstevalOrNotConstevalIfStmt extends Stmt , @stmt_consteval_or_not_consteval_if {
450+ /**
451+ * Gets the 'then' statement of this '(not) consteval if' statement.
452+ *
453+ * For example, for
454+ * ```cpp
455+ * if consteval { return true; }
456+ * ```
457+ * the result is the `BlockStmt` `{ return true; }`.
458+ */
459+ Stmt getThen ( ) { consteval_if_then ( underlyingElement ( this ) , unresolveElement ( result ) ) }
460+
461+ /**
462+ * Gets the 'else' statement of this '(not) constexpr if' statement, if any.
463+ *
464+ * For example, for
465+ * ```cpp
466+ * if consteval { return true; } else { return false; }
467+ * ```
468+ * the result is the `BlockStmt` `{ return false; }`, and for
469+ * ```cpp
470+ * if consteval { return true; }
471+ * ```
472+ * there is no result.
473+ */
474+ Stmt getElse ( ) { consteval_if_else ( underlyingElement ( this ) , unresolveElement ( result ) ) }
475+
476+ /**
477+ * Holds if this '(not) constexpr if' statement has an 'else' statement.
478+ *
479+ * For example, this holds for
480+ * ```cpp
481+ * if consteval { return true; } else { return false; }
482+ * ```
483+ * but not for
484+ * ```cpp
485+ * if consteval { return true; }
486+ * ```
487+ */
488+ predicate hasElse ( ) { exists ( this .getElse ( ) ) }
489+
490+ override predicate mayBeImpure ( ) {
491+ this .getThen ( ) .mayBeImpure ( ) or
492+ this .getElse ( ) .mayBeImpure ( )
493+ }
494+
495+ override predicate mayBeGloballyImpure ( ) {
496+ this .getThen ( ) .mayBeGloballyImpure ( ) or
497+ this .getElse ( ) .mayBeGloballyImpure ( )
498+ }
499+
500+ override MacroInvocation getGeneratingMacro ( ) {
501+ this .getThen ( ) .getGeneratingMacro ( ) = result and
502+ ( this .hasElse ( ) implies this .getElse ( ) .getGeneratingMacro ( ) = result )
503+ }
504+
505+ /**
506+ * Gets the statement of this '(not) consteval if' statement evaluated during compile time, if any.
507+ *
508+ * For example, for
509+ * ```cpp
510+ * if ! consteval { return true; } else { return false; }
511+ * ```
512+ * the result is the `BlockStmt` `{ return false; }`, and for
513+ * ```cpp
514+ * if ! consteval { return true; }
515+ * ```
516+ * there is no result.
517+ */
518+ Stmt getCompileTimeEvaluatedBranch ( ) { none ( ) }
519+
520+ /**
521+ * Holds if this '(not) constexpr if' statement has a compile time evaluated statement.
522+ *
523+ * For example, this holds for
524+ * ```cpp
525+ * if ! consteval { return true; } else { return false; }
526+ * ```
527+ * but not for
528+ * ```cpp
529+ * if ! consteval { return true; }
530+ * ```
531+ */
532+ predicate hasCompileTimeEvaluatedBranch ( ) { exists ( this .getCompileTimeEvaluatedBranch ( ) ) }
533+
534+ /**
535+ * Gets the statement of this '(not) consteval if' statement evaluated during runtime, if any.
536+ *
537+ * For example, for
538+ * ```cpp
539+ * if consteval { return true; } else { return false; }
540+ * ```
541+ * the result is the `BlockStmt` `{ return false; }`, and for
542+ * ```cpp
543+ * if consteval { return true; }
544+ * ```
545+ * there is no result.
546+ */
547+ Stmt getRuntimeEvaluatedBranch ( ) { none ( ) }
548+
549+ /**
550+ * Holds if this '(not) constexpr if' statement has a runtime evaluated statement.
551+ *
552+ * For example, this holds for
553+ * ```cpp
554+ * if consteval { return true; } else { return false; }
555+ * ```
556+ * but not for
557+ * ```cpp
558+ * if consteval { return true; }
559+ * ```
560+ */
561+ predicate hasRuntimeEvaluatedBranch ( ) { exists ( this .getRuntimeEvaluatedBranch ( ) ) }
562+ }
563+
564+ /**
565+ * A C/C++ 'consteval if'. For example, the `if consteval` statement
566+ * in the following code:
567+ * ```cpp
568+ * if consteval {
569+ * ...
570+ * }
571+ * ```
572+ */
573+ class ConstevalIfStmt extends ConstevalOrNotConstevalIfStmt , @stmt_consteval_if {
574+ override string getAPrimaryQlClass ( ) { result = "ConstevallIfStmt" }
575+
576+ override string toString ( ) { result = "if consteval ..." }
577+
578+ override Stmt getCompileTimeEvaluatedBranch ( ) { result = this .getThen ( ) }
579+
580+ override Stmt getRuntimeEvaluatedBranch ( ) { result = this .getElse ( ) }
581+ }
582+
583+ /**
584+ * A C/C++ 'not consteval if'. For example, the `if ! consteval` statement
585+ * in the following code:
586+ * ```cpp
587+ * if ! consteval {
588+ * ...
589+ * }
590+ * ```
591+ */
592+ class NotConstevalIfStmt extends ConstevalOrNotConstevalIfStmt , @stmt_not_consteval_if {
593+ override string getAPrimaryQlClass ( ) { result = "NotConstevallIfStmt" }
594+
595+ override string toString ( ) { result = "if ! consteval ..." }
596+
597+ override Stmt getCompileTimeEvaluatedBranch ( ) { result = this .getElse ( ) }
598+
599+ override Stmt getRuntimeEvaluatedBranch ( ) { result = this .getThen ( ) }
600+ }
601+
440602private class TLoop = @stmt_while or @stmt_end_test_while or @stmt_range_based_for or @stmt_for;
441603
442604/**
0 commit comments