@@ -294,6 +294,84 @@ class IfStmt extends ConditionalStmt, @stmt_if {
294294 }
295295}
296296
297+ /**
298+ * A C/C++ 'constexpr if' statement.
299+ */
300+ class ConstexprIfStmt extends ConditionalStmt , @stmt_constexpr_if {
301+
302+ /**
303+ * Gets the condition expression of this 'constexpr if' statement.
304+ *
305+ * For example, for
306+ * ```
307+ * if constexpr (b) { x = 1; }
308+ * ```
309+ * the result is `b`.
310+ */
311+ Expr getCondition ( ) { result = this .getChild ( 0 ) }
312+
313+ override Expr getControllingExpr ( ) { result = this .getCondition ( ) }
314+
315+ /**
316+ * Gets the 'then' statement of this 'constexpr if' statement.
317+ *
318+ * For example, for
319+ * ```
320+ * if constexpr (b) { x = 1; }
321+ * ```
322+ * the result is the `Block` `{ x = 1; }`.
323+ */
324+ Stmt getThen ( ) { constexpr_if_then ( underlyingElement ( this ) , unresolveElement ( result ) ) }
325+
326+ /**
327+ * Gets the 'else' statement of this 'constexpr if' statement, if any.
328+ *
329+ * For example, for
330+ * ```
331+ * if constexpr (b) { x = 1; } else { x = 2; }
332+ * ```
333+ * the result is the `Block` `{ x = 2; }`, and for
334+ * ```
335+ * if constexpr (b) { x = 1; }
336+ * ```
337+ * there is no result.
338+ */
339+ Stmt getElse ( ) { constexpr_if_else ( underlyingElement ( this ) , unresolveElement ( result ) ) }
340+
341+ /**
342+ * Holds if this 'constexpr if' statement has an 'else' statement.
343+ *
344+ * For example, this holds for
345+ * ```
346+ * if constexpr (b) { x = 1; } else { x = 2; }
347+ * ```
348+ * but not for
349+ * ```
350+ * if constexpr (b) { x = 1; }
351+ * ```
352+ */
353+ predicate hasElse ( ) { exists ( Stmt s | this .getElse ( ) = s ) }
354+
355+ override string toString ( ) { result = "if constexpr (...) ... " }
356+
357+ override predicate mayBeImpure ( ) {
358+ this .getCondition ( ) .mayBeImpure ( ) or
359+ this .getThen ( ) .mayBeImpure ( ) or
360+ this .getElse ( ) .mayBeImpure ( )
361+ }
362+ override predicate mayBeGloballyImpure ( ) {
363+ this .getCondition ( ) .mayBeGloballyImpure ( ) or
364+ this .getThen ( ) .mayBeGloballyImpure ( ) or
365+ this .getElse ( ) .mayBeGloballyImpure ( )
366+ }
367+
368+ override MacroInvocation getGeneratingMacro ( ) {
369+ result .getAnExpandedElement ( ) = this .getCondition ( ) and
370+ this .getThen ( ) .getGeneratingMacro ( ) = result and
371+ ( this .hasElse ( ) implies this .getElse ( ) .getGeneratingMacro ( ) = result )
372+ }
373+ }
374+
297375/**
298376 * A C/C++ loop, that is, either a 'while' loop, a 'for' loop, or a
299377 * 'do' loop.
0 commit comments