@@ -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,50 @@ 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 ) , _) }
381+ abstract private class ArithmeticTypeImpl extends Type { }
383382
384- override string getAPrimaryQlClass ( ) { result = "ArithmeticType" }
383+ final class ArithmeticType = ArithmeticTypeImpl ;
384+
385+ /**
386+ * A C/C++ arithmetic type that is not a bit-precise integer.
387+ */
388+ class BuiltInArithmeticType extends ArithmeticTypeImpl , BuiltInType {
389+ BuiltInArithmeticType ( ) { isBuiltInArithmeticType ( underlyingElement ( this ) , _) }
390+
391+ override string getAPrimaryQlClass ( ) { result = "BuiltInArithmeticType" }
392+ }
393+
394+ /**
395+ * A C23 bit-precise integer (`_BitInt`).
396+ */
397+ class BitPreciseArithmeticType extends ArithmeticTypeImpl {
398+ boolean isSigned ;
399+ boolean isExplicitlySigned ;
400+ int bitWidth ;
401+
402+ BitPreciseArithmeticType ( ) {
403+ bit_precise_types ( underlyingElement ( this ) , isSigned , isExplicitlySigned , bitWidth )
404+ }
405+
406+ override string toString ( ) { result = this .getName ( ) }
407+
408+ override string getName ( ) {
409+ isSigned = true and isExplicitlySigned = true and result = "signed _BitInt(" + bitWidth + ")"
410+ or
411+ isSigned = true and isExplicitlySigned = false and result = "_BitInt(" + bitWidth + ")"
412+ or
413+ isSigned = false and result = "unsigned _BitInt(" + bitWidth + ")"
414+ }
415+
416+ override string explain ( ) { result = this .getName ( ) }
417+
418+ override predicate isDeeplyConstBelow ( ) { any ( ) } // No subparts
419+
420+ override string getAPrimaryQlClass ( ) { result = "BitPreciseArithmeticType" }
385421}
386422
387- private predicate isIntegralType ( @builtintype type , int kind ) {
388- isArithmeticType ( type , kind ) and
423+ private predicate isBuiltInIntegralType ( @builtintype type , int kind ) {
424+ isBuiltInArithmeticType ( type , kind ) and
389425 (
390426 kind < 24
391427 or
@@ -420,10 +456,13 @@ private predicate isIntegralType(@builtintype type, int kind) {
420456class IntegralOrEnumType extends Type {
421457 IntegralOrEnumType ( ) {
422458 // Integral type
423- isIntegralType ( underlyingElement ( this ) , _)
459+ isBuiltInIntegralType ( underlyingElement ( this ) , _)
424460 or
425461 // Enum type
426462 usertypes ( underlyingElement ( this ) , _, [ 4 , 13 ] )
463+ or
464+ // Bit-precise integer type (`_BitInt`)
465+ bit_precise_types ( underlyingElement ( this ) , _, _, _)
427466 }
428467}
429468
@@ -499,19 +538,54 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
499538 * char c;
500539 * ```
501540 */
502- class IntegralType extends ArithmeticType , IntegralOrEnumType {
503- int kind ;
504-
505- IntegralType ( ) { isIntegralType ( underlyingElement ( this ) , kind ) }
506-
541+ abstract private class IntegralTypeImpl extends ArithmeticTypeImpl , IntegralOrEnumType {
507542 /** Holds if this integral type is signed. */
508- predicate isSigned ( ) { builtintypes ( underlyingElement ( this ) , _ , _ , _ , - 1 , _ ) }
543+ abstract predicate isSigned ( ) ;
509544
510545 /** Holds if this integral type is unsigned. */
511- predicate isUnsigned ( ) { builtintypes ( underlyingElement ( this ) , _ , _ , _ , 1 , _ ) }
546+ abstract predicate isUnsigned ( ) ;
512547
513548 /** Holds if this integral type is explicitly signed. */
514- predicate isExplicitlySigned ( ) {
549+ abstract predicate isExplicitlySigned ( ) ;
550+
551+ /** Holds if this integral type is explicitly unsigned. */
552+ abstract predicate isExplicitlyUnsigned ( ) ;
553+
554+ /** Holds if this integral type is implicitly signed. */
555+ abstract predicate isImplicitlySigned ( ) ;
556+
557+ /**
558+ * Gets the unsigned type corresponding to this integral type. For
559+ * example on a `short`, this would give the type `unsigned short`.
560+ */
561+ abstract IntegralType getUnsigned ( ) ;
562+
563+ /**
564+ * Gets the canonical type corresponding to this integral type.
565+ *
566+ * For a plain type, this gives the same type (e.g. `short` -> `short`).
567+ * For an explicitly unsigned type, this gives the same type (e.g. `unsigned short` -> `unsigned short`).
568+ * For an explicitly signed type, this gives the plain version of that type (e.g. `signed short` -> `short`), except
569+ * that `signed char` -> `signed char`.
570+ */
571+ abstract IntegralType getCanonicalArithmeticType ( ) ;
572+ }
573+
574+ final class IntegralType = IntegralTypeImpl ;
575+
576+ /**
577+ * A C/C++ integral type that is not a bit-precise integer.
578+ */
579+ class BuiltInIntegralType extends IntegralTypeImpl , BuiltInArithmeticType {
580+ int kind ;
581+
582+ BuiltInIntegralType ( ) { isBuiltInIntegralType ( underlyingElement ( this ) , kind ) }
583+
584+ override predicate isSigned ( ) { builtintypes ( underlyingElement ( this ) , _, _, _, - 1 , _) }
585+
586+ override predicate isUnsigned ( ) { builtintypes ( underlyingElement ( this ) , _, _, _, 1 , _) }
587+
588+ override predicate isExplicitlySigned ( ) {
515589 builtintypes ( underlyingElement ( this ) , _, 7 , _, _, _) or
516590 builtintypes ( underlyingElement ( this ) , _, 10 , _, _, _) or
517591 builtintypes ( underlyingElement ( this ) , _, 13 , _, _, _) or
@@ -520,8 +594,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
520594 builtintypes ( underlyingElement ( this ) , _, 37 , _, _, _)
521595 }
522596
523- /** Holds if this integral type is explicitly unsigned. */
524- predicate isExplicitlyUnsigned ( ) {
597+ override predicate isExplicitlyUnsigned ( ) {
525598 builtintypes ( underlyingElement ( this ) , _, 6 , _, _, _) or
526599 builtintypes ( underlyingElement ( this ) , _, 9 , _, _, _) or
527600 builtintypes ( underlyingElement ( this ) , _, 12 , _, _, _) or
@@ -530,8 +603,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
530603 builtintypes ( underlyingElement ( this ) , _, 36 , _, _, _)
531604 }
532605
533- /** Holds if this integral type is implicitly signed. */
534- predicate isImplicitlySigned ( ) {
606+ override predicate isImplicitlySigned ( ) {
535607 builtintypes ( underlyingElement ( this ) , _, 5 , _, - 1 , _) or
536608 builtintypes ( underlyingElement ( this ) , _, 8 , _, - 1 , _) or
537609 builtintypes ( underlyingElement ( this ) , _, 11 , _, - 1 , _) or
@@ -540,33 +612,44 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
540612 builtintypes ( underlyingElement ( this ) , _, 35 , _, - 1 , _)
541613 }
542614
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 ( ) {
615+ override IntegralType getUnsigned ( ) {
548616 exists ( int unsignedKind |
549617 integralTypeMapping ( kind , _, unsignedKind , _) and
550618 builtintypes ( unresolveElement ( result ) , _, unsignedKind , _, _, _)
551619 )
552620 }
553621
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 ( ) {
622+ override IntegralType getCanonicalArithmeticType ( ) {
563623 exists ( int canonicalKind |
564624 integralTypeMapping ( kind , canonicalKind , _, _) and
565625 builtintypes ( unresolveElement ( result ) , _, canonicalKind , _, _, _)
566626 )
567627 }
568628}
569629
630+ /**
631+ * A C23 bit-precise integer (`_BitInt`).
632+ */
633+ class BitPreciseType extends IntegralTypeImpl , BitPreciseArithmeticType {
634+ override predicate isSigned ( ) { isSigned = true }
635+
636+ override predicate isUnsigned ( ) { not this .isSigned ( ) }
637+
638+ override predicate isExplicitlySigned ( ) { isExplicitlySigned = true }
639+
640+ override predicate isExplicitlyUnsigned ( ) { this .isUnsigned ( ) }
641+
642+ override predicate isImplicitlySigned ( ) { not this .isExplicitlySigned ( ) }
643+
644+ override IntegralType getUnsigned ( ) {
645+ bit_precise_types ( unresolveElement ( result ) , false , false , bitWidth )
646+ }
647+
648+ override IntegralType getCanonicalArithmeticType ( ) {
649+ bit_precise_types ( unresolveElement ( result ) , isSigned , false , bitWidth )
650+ }
651+ }
652+
570653/**
571654 * The C/C++ boolean type. See 4.2. This is the C `_Bool` type
572655 * or the C++ `bool` type. For example:
@@ -575,7 +658,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
575658 * _Bool c, d; // C
576659 * ```
577660 */
578- class BoolType extends IntegralType {
661+ class BoolType extends BuiltInIntegralType {
579662 BoolType ( ) { builtintypes ( underlyingElement ( this ) , _, 4 , _, _, _) }
580663
581664 override string getAPrimaryQlClass ( ) { result = "BoolType" }
@@ -591,7 +674,7 @@ class BoolType extends IntegralType {
591674 * unsigned char e, f;
592675 * ```
593676 */
594- class CharType extends IntegralType {
677+ class CharType extends BuiltInIntegralType {
595678 CharType ( ) { builtintypes ( underlyingElement ( this ) , _, [ 5 , 6 , 7 ] , _, _, _) }
596679}
597680
@@ -641,7 +724,7 @@ class SignedCharType extends CharType {
641724 * signed short ss;
642725 * ```
643726 */
644- class ShortType extends IntegralType {
727+ class ShortType extends BuiltInIntegralType {
645728 ShortType ( ) {
646729 builtintypes ( underlyingElement ( this ) , _, 8 , _, _, _) or
647730 builtintypes ( underlyingElement ( this ) , _, 9 , _, _, _) or
@@ -658,7 +741,7 @@ class ShortType extends IntegralType {
658741 * unsigned int ui;
659742 * ```
660743 */
661- class IntType extends IntegralType {
744+ class IntType extends BuiltInIntegralType {
662745 IntType ( ) {
663746 builtintypes ( underlyingElement ( this ) , _, 11 , _, _, _) or
664747 builtintypes ( underlyingElement ( this ) , _, 12 , _, _, _) or
@@ -675,7 +758,7 @@ class IntType extends IntegralType {
675758 * long l;
676759 * ```
677760 */
678- class LongType extends IntegralType {
761+ class LongType extends BuiltInIntegralType {
679762 LongType ( ) {
680763 builtintypes ( underlyingElement ( this ) , _, 14 , _, _, _) or
681764 builtintypes ( underlyingElement ( this ) , _, 15 , _, _, _) or
@@ -692,7 +775,7 @@ class LongType extends IntegralType {
692775 * signed long long sll;
693776 * ```
694777 */
695- class LongLongType extends IntegralType {
778+ class LongLongType extends BuiltInIntegralType {
696779 LongLongType ( ) {
697780 builtintypes ( underlyingElement ( this ) , _, 17 , _, _, _) or
698781 builtintypes ( underlyingElement ( this ) , _, 18 , _, _, _) or
@@ -710,7 +793,7 @@ class LongLongType extends IntegralType {
710793 * unsigned __int128 ui128;
711794 * ```
712795 */
713- class Int128Type extends IntegralType {
796+ class Int128Type extends BuiltInIntegralType {
714797 Int128Type ( ) {
715798 builtintypes ( underlyingElement ( this ) , _, 35 , _, _, _) or
716799 builtintypes ( underlyingElement ( this ) , _, 36 , _, _, _) or
@@ -865,7 +948,7 @@ private predicate floatingPointTypeMapping(
865948 * fixed-size floating-point types like `_Float32`, and the extended-precision floating-point types
866949 * like `_Float64x`. It also includes the complex and imaginary versions of all of these types.
867950 */
868- class FloatingPointType extends ArithmeticType {
951+ class FloatingPointType extends BuiltInArithmeticType {
869952 final int base ;
870953 final TypeDomain domain ;
871954 final int realKind ;
@@ -1003,7 +1086,7 @@ class VoidType extends BuiltInType {
10031086 * wchar_t wc;
10041087 * ```
10051088 */
1006- class WideCharType extends IntegralType {
1089+ class WideCharType extends BuiltInIntegralType {
10071090 WideCharType ( ) { builtintypes ( underlyingElement ( this ) , _, 33 , _, _, _) }
10081091
10091092 override string getAPrimaryQlClass ( ) { result = "WideCharType" }
@@ -1015,7 +1098,7 @@ class WideCharType extends IntegralType {
10151098 * char8_t c8;
10161099 * ```
10171100 */
1018- class Char8Type extends IntegralType {
1101+ class Char8Type extends BuiltInIntegralType {
10191102 Char8Type ( ) { builtintypes ( underlyingElement ( this ) , _, 51 , _, _, _) }
10201103
10211104 override string getAPrimaryQlClass ( ) { result = "Char8Type" }
@@ -1027,7 +1110,7 @@ class Char8Type extends IntegralType {
10271110 * char16_t c16;
10281111 * ```
10291112 */
1030- class Char16Type extends IntegralType {
1113+ class Char16Type extends BuiltInIntegralType {
10311114 Char16Type ( ) { builtintypes ( underlyingElement ( this ) , _, 43 , _, _, _) }
10321115
10331116 override string getAPrimaryQlClass ( ) { result = "Char16Type" }
@@ -1039,7 +1122,7 @@ class Char16Type extends IntegralType {
10391122 * char32_t c32;
10401123 * ```
10411124 */
1042- class Char32Type extends IntegralType {
1125+ class Char32Type extends BuiltInIntegralType {
10431126 Char32Type ( ) { builtintypes ( underlyingElement ( this ) , _, 44 , _, _, _) }
10441127
10451128 override string getAPrimaryQlClass ( ) { result = "Char32Type" }
0 commit comments