@@ -349,7 +349,7 @@ class UnknownType extends BuiltInType {
349349 override string getAPrimaryQlClass ( ) { result = "UnknownType" }
350350}
351351
352- private predicate isArithmeticType ( @builtintype type , int kind ) {
352+ private predicate isBuiltInArithmeticType ( @builtintype type , int kind ) {
353353 builtintypes ( type , _, kind , _, _, _) and
354354 kind >= 4 and
355355 kind != 34 and // Exclude decltype(nullptr)
@@ -378,14 +378,49 @@ class ScalableVectorCount extends BuiltInType {
378378 * operations may be performed. Examples of arithmetic types include
379379 * `char`, `int`, `float`, and `bool`.
380380 */
381- class ArithmeticType extends BuiltInType {
382- ArithmeticType ( ) { isArithmeticType ( underlyingElement ( this ) , _) }
383-
381+ abstract private class ArithmeticTypeImpl extends Type {
384382 override string getAPrimaryQlClass ( ) { result = "ArithmeticType" }
385383}
386384
387- private predicate isIntegralType ( @builtintype type , int kind ) {
388- isArithmeticType ( type , kind ) and
385+ final class ArithmeticType = ArithmeticTypeImpl ;
386+
387+ /**
388+ * A C/C++ arithmetic type that is not a bit-precise integer.
389+ */
390+ class BuiltInArithmeticType extends Type , BuiltInType {
391+ BuiltInArithmeticType ( ) { isBuiltInArithmeticType ( underlyingElement ( this ) , _) }
392+ }
393+
394+ /**
395+ * A C23 bit-precise integer (`_BitInt`).
396+ */
397+ class BitPreciseArithmeticType extends Type {
398+ boolean isSigned ;
399+ int bitWidth ;
400+
401+ BitPreciseArithmeticType ( ) { bit_precise_types ( underlyingElement ( this ) , isSigned , bitWidth ) }
402+
403+ override string toString ( ) { result = this .getName ( ) }
404+
405+ override string getName ( ) {
406+ isSigned = true and result = "_BitInt(" + bitWidth + ")"
407+ or
408+ isSigned = false and result = "unsigned _BitInt(" + bitWidth + ")"
409+ }
410+
411+ override string explain ( ) { result = this .getName ( ) }
412+
413+ override predicate isDeeplyConstBelow ( ) { any ( ) } // No subparts
414+
415+ /* Holds if this bit-precise type is signed. */
416+ predicate isSigned ( ) { isSigned = true }
417+
418+ /* Yields the bit width of the bit-precise type */
419+ int getBitWith ( ) { result = bitWidth }
420+ }
421+
422+ private predicate isBuiltInIntegralType ( @builtintype type , int kind ) {
423+ isBuiltInArithmeticType ( type , kind ) and
389424 (
390425 kind < 24
391426 or
@@ -420,10 +455,13 @@ private predicate isIntegralType(@builtintype type, int kind) {
420455class IntegralOrEnumType extends Type {
421456 IntegralOrEnumType ( ) {
422457 // Integral type
423- isIntegralType ( underlyingElement ( this ) , _)
458+ isBuiltInIntegralType ( underlyingElement ( this ) , _)
424459 or
425460 // Enum type
426461 usertypes ( underlyingElement ( this ) , _, [ 4 , 13 ] )
462+ or
463+ // Bit-precise integer type (`_BitInt`)
464+ bit_precise_types ( underlyingElement ( this ) , _, _)
427465 }
428466}
429467
@@ -499,19 +537,54 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
499537 * char c;
500538 * ```
501539 */
502- class IntegralType extends ArithmeticType , IntegralOrEnumType {
503- int kind ;
504-
505- IntegralType ( ) { isIntegralType ( underlyingElement ( this ) , kind ) }
506-
540+ abstract private class IntegralTypeImpl extends ArithmeticTypeImpl , IntegralOrEnumType {
507541 /** Holds if this integral type is signed. */
508- predicate isSigned ( ) { builtintypes ( underlyingElement ( this ) , _ , _ , _ , - 1 , _ ) }
542+ abstract predicate isSigned ( ) ;
509543
510544 /** Holds if this integral type is unsigned. */
511- predicate isUnsigned ( ) { builtintypes ( underlyingElement ( this ) , _ , _ , _ , 1 , _ ) }
545+ abstract predicate isUnsigned ( ) ;
512546
513547 /** Holds if this integral type is explicitly signed. */
514- predicate isExplicitlySigned ( ) {
548+ abstract predicate isExplicitlySigned ( ) ;
549+
550+ /** Holds if this integral type is explicitly unsigned. */
551+ abstract predicate isExplicitlyUnsigned ( ) ;
552+
553+ /** Holds if this integral type is implicitly signed. */
554+ abstract predicate isImplicitlySigned ( ) ;
555+
556+ /**
557+ * Gets the unsigned type corresponding to this integral type. For
558+ * example on a `short`, this would give the type `unsigned short`.
559+ */
560+ abstract IntegralType getUnsigned ( ) ;
561+
562+ /**
563+ * Gets the canonical type corresponding to this integral type.
564+ *
565+ * For a plain type, this gives the same type (e.g. `short` -> `short`).
566+ * For an explicitly unsigned type, this gives the same type (e.g. `unsigned short` -> `unsigned short`).
567+ * For an explicitly signed type, this gives the plain version of that type (e.g. `signed short` -> `short`), except
568+ * that `signed char` -> `signed char`.
569+ */
570+ abstract IntegralType getCanonicalArithmeticType ( ) ;
571+ }
572+
573+ final class IntegralType = IntegralTypeImpl ;
574+
575+ /**
576+ * A C/C++ integral type that is not a bit-precise integer.
577+ */
578+ class BuiltInIntegralType extends IntegralTypeImpl , BuiltInArithmeticType {
579+ int kind ;
580+
581+ BuiltInIntegralType ( ) { isBuiltInIntegralType ( underlyingElement ( this ) , kind ) }
582+
583+ override predicate isSigned ( ) { builtintypes ( underlyingElement ( this ) , _, _, _, - 1 , _) }
584+
585+ override predicate isUnsigned ( ) { builtintypes ( underlyingElement ( this ) , _, _, _, 1 , _) }
586+
587+ override predicate isExplicitlySigned ( ) {
515588 builtintypes ( underlyingElement ( this ) , _, 7 , _, _, _) or
516589 builtintypes ( underlyingElement ( this ) , _, 10 , _, _, _) or
517590 builtintypes ( underlyingElement ( this ) , _, 13 , _, _, _) or
@@ -520,8 +593,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
520593 builtintypes ( underlyingElement ( this ) , _, 37 , _, _, _)
521594 }
522595
523- /** Holds if this integral type is explicitly unsigned. */
524- predicate isExplicitlyUnsigned ( ) {
596+ override predicate isExplicitlyUnsigned ( ) {
525597 builtintypes ( underlyingElement ( this ) , _, 6 , _, _, _) or
526598 builtintypes ( underlyingElement ( this ) , _, 9 , _, _, _) or
527599 builtintypes ( underlyingElement ( this ) , _, 12 , _, _, _) or
@@ -530,8 +602,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
530602 builtintypes ( underlyingElement ( this ) , _, 36 , _, _, _)
531603 }
532604
533- /** Holds if this integral type is implicitly signed. */
534- predicate isImplicitlySigned ( ) {
605+ override predicate isImplicitlySigned ( ) {
535606 builtintypes ( underlyingElement ( this ) , _, 5 , _, - 1 , _) or
536607 builtintypes ( underlyingElement ( this ) , _, 8 , _, - 1 , _) or
537608 builtintypes ( underlyingElement ( this ) , _, 11 , _, - 1 , _) or
@@ -540,33 +611,42 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
540611 builtintypes ( underlyingElement ( this ) , _, 35 , _, - 1 , _)
541612 }
542613
543- /**
544- * Gets the unsigned type corresponding to this integral type. For
545- * example on a `short`, this would give the type `unsigned short`.
546- */
547- IntegralType getUnsigned ( ) {
614+ override IntegralType getUnsigned ( ) {
548615 exists ( int unsignedKind |
549616 integralTypeMapping ( kind , _, unsignedKind , _) and
550617 builtintypes ( unresolveElement ( result ) , _, unsignedKind , _, _, _)
551618 )
552619 }
553620
554- /**
555- * Gets the canonical type corresponding to this integral type.
556- *
557- * For a plain type, this gives the same type (e.g. `short` -> `short`).
558- * For an explicitly unsigned type, this gives the same type (e.g. `unsigned short` -> `unsigned short`).
559- * For an explicitly signed type, this gives the plain version of that type (e.g. `signed short` -> `short`), except
560- * that `signed char` -> `signed char`.
561- */
562- IntegralType getCanonicalArithmeticType ( ) {
621+ override IntegralType getCanonicalArithmeticType ( ) {
563622 exists ( int canonicalKind |
564623 integralTypeMapping ( kind , canonicalKind , _, _) and
565624 builtintypes ( unresolveElement ( result ) , _, canonicalKind , _, _, _)
566625 )
567626 }
568627}
569628
629+ /**
630+ * A C23 bit-precise integer (`_BitInt`).
631+ */
632+ class BitPreciseIntegralType extends IntegralTypeImpl , BitPreciseArithmeticType {
633+ override predicate isSigned ( ) { this .( BitPreciseArithmeticType ) .isSigned ( ) }
634+
635+ override predicate isUnsigned ( ) { not this .isSigned ( ) }
636+
637+ override predicate isExplicitlySigned ( ) { this .isSigned ( ) }
638+
639+ override predicate isExplicitlyUnsigned ( ) { this .isUnsigned ( ) }
640+
641+ override predicate isImplicitlySigned ( ) { none ( ) }
642+
643+ override IntegralType getUnsigned ( ) {
644+ bit_precise_types ( unresolveElement ( result ) , false , this .( BitPreciseArithmeticType ) .getBitWith ( ) )
645+ }
646+
647+ override IntegralType getCanonicalArithmeticType ( ) { result = this }
648+ }
649+
570650/**
571651 * The C/C++ boolean type. See 4.2. This is the C `_Bool` type
572652 * or the C++ `bool` type. For example:
@@ -575,7 +655,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
575655 * _Bool c, d; // C
576656 * ```
577657 */
578- class BoolType extends IntegralType {
658+ class BoolType extends BuiltInIntegralType {
579659 BoolType ( ) { builtintypes ( underlyingElement ( this ) , _, 4 , _, _, _) }
580660
581661 override string getAPrimaryQlClass ( ) { result = "BoolType" }
@@ -591,7 +671,7 @@ class BoolType extends IntegralType {
591671 * unsigned char e, f;
592672 * ```
593673 */
594- class CharType extends IntegralType {
674+ class CharType extends BuiltInIntegralType {
595675 CharType ( ) { builtintypes ( underlyingElement ( this ) , _, [ 5 , 6 , 7 ] , _, _, _) }
596676}
597677
@@ -641,7 +721,7 @@ class SignedCharType extends CharType {
641721 * signed short ss;
642722 * ```
643723 */
644- class ShortType extends IntegralType {
724+ class ShortType extends BuiltInIntegralType {
645725 ShortType ( ) {
646726 builtintypes ( underlyingElement ( this ) , _, 8 , _, _, _) or
647727 builtintypes ( underlyingElement ( this ) , _, 9 , _, _, _) or
@@ -658,7 +738,7 @@ class ShortType extends IntegralType {
658738 * unsigned int ui;
659739 * ```
660740 */
661- class IntType extends IntegralType {
741+ class IntType extends BuiltInIntegralType {
662742 IntType ( ) {
663743 builtintypes ( underlyingElement ( this ) , _, 11 , _, _, _) or
664744 builtintypes ( underlyingElement ( this ) , _, 12 , _, _, _) or
@@ -675,7 +755,7 @@ class IntType extends IntegralType {
675755 * long l;
676756 * ```
677757 */
678- class LongType extends IntegralType {
758+ class LongType extends BuiltInIntegralType {
679759 LongType ( ) {
680760 builtintypes ( underlyingElement ( this ) , _, 14 , _, _, _) or
681761 builtintypes ( underlyingElement ( this ) , _, 15 , _, _, _) or
@@ -692,7 +772,7 @@ class LongType extends IntegralType {
692772 * signed long long sll;
693773 * ```
694774 */
695- class LongLongType extends IntegralType {
775+ class LongLongType extends BuiltInIntegralType {
696776 LongLongType ( ) {
697777 builtintypes ( underlyingElement ( this ) , _, 17 , _, _, _) or
698778 builtintypes ( underlyingElement ( this ) , _, 18 , _, _, _) or
@@ -710,7 +790,7 @@ class LongLongType extends IntegralType {
710790 * unsigned __int128 ui128;
711791 * ```
712792 */
713- class Int128Type extends IntegralType {
793+ class Int128Type extends BuiltInIntegralType {
714794 Int128Type ( ) {
715795 builtintypes ( underlyingElement ( this ) , _, 35 , _, _, _) or
716796 builtintypes ( underlyingElement ( this ) , _, 36 , _, _, _) or
@@ -865,7 +945,7 @@ private predicate floatingPointTypeMapping(
865945 * fixed-size floating-point types like `_Float32`, and the extended-precision floating-point types
866946 * like `_Float64x`. It also includes the complex and imaginary versions of all of these types.
867947 */
868- class FloatingPointType extends ArithmeticType {
948+ class FloatingPointType extends ArithmeticTypeImpl , BuiltInType {
869949 final int base ;
870950 final TypeDomain domain ;
871951 final int realKind ;
@@ -1003,7 +1083,7 @@ class VoidType extends BuiltInType {
10031083 * wchar_t wc;
10041084 * ```
10051085 */
1006- class WideCharType extends IntegralType {
1086+ class WideCharType extends BuiltInIntegralType {
10071087 WideCharType ( ) { builtintypes ( underlyingElement ( this ) , _, 33 , _, _, _) }
10081088
10091089 override string getAPrimaryQlClass ( ) { result = "WideCharType" }
@@ -1015,7 +1095,7 @@ class WideCharType extends IntegralType {
10151095 * char8_t c8;
10161096 * ```
10171097 */
1018- class Char8Type extends IntegralType {
1098+ class Char8Type extends BuiltInIntegralType {
10191099 Char8Type ( ) { builtintypes ( underlyingElement ( this ) , _, 51 , _, _, _) }
10201100
10211101 override string getAPrimaryQlClass ( ) { result = "Char8Type" }
@@ -1027,7 +1107,7 @@ class Char8Type extends IntegralType {
10271107 * char16_t c16;
10281108 * ```
10291109 */
1030- class Char16Type extends IntegralType {
1110+ class Char16Type extends BuiltInIntegralType {
10311111 Char16Type ( ) { builtintypes ( underlyingElement ( this ) , _, 43 , _, _, _) }
10321112
10331113 override string getAPrimaryQlClass ( ) { result = "Char16Type" }
@@ -1039,7 +1119,7 @@ class Char16Type extends IntegralType {
10391119 * char32_t c32;
10401120 * ```
10411121 */
1042- class Char32Type extends IntegralType {
1122+ class Char32Type extends BuiltInIntegralType {
10431123 Char32Type ( ) { builtintypes ( underlyingElement ( this ) , _, 44 , _, _, _) }
10441124
10451125 override string getAPrimaryQlClass ( ) { result = "Char32Type" }
0 commit comments