@@ -437,6 +437,168 @@ class ConstexprIfStmt extends ConditionalStmt, @stmt_constexpr_if {
437
437
}
438
438
}
439
439
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
+
440
602
private class TLoop = @stmt_while or @stmt_end_test_while or @stmt_range_based_for or @stmt_for;
441
603
442
604
/**
0 commit comments