@@ -92,8 +92,9 @@ class Type extends Locatable, @type {
9292 /**
9393 * Gets this type after typedefs have been resolved.
9494 *
95- * The result of this predicate will be the type itself, except in the case of a TypedefType or a Decltype,
96- * in which case the result will be type which results from (possibly recursively) resolving typedefs.
95+ * The result of this predicate will be the type itself, except in the case of a TypedefType, a Decltype,
96+ * or a TypeofExprType, in which case the result will be type which results from (possibly recursively)
97+ * resolving typedefs.
9798 */
9899 pragma [ nomagic]
99100 Type getUnderlyingType ( ) { result = this }
@@ -1118,17 +1119,19 @@ class DerivedType extends Type, @derivedtype {
11181119 * ```
11191120 */
11201121class Decltype extends Type , @decltype {
1122+ Decltype ( ) { decltypes ( underlyingElement ( this ) , _, 0 , _, _) }
1123+
11211124 override string getAPrimaryQlClass ( ) { result = "Decltype" }
11221125
11231126 /**
11241127 * The expression whose type is being obtained by this decltype.
11251128 */
1126- Expr getExpr ( ) { decltypes ( underlyingElement ( this ) , unresolveElement ( result ) , _, _) }
1129+ Expr getExpr ( ) { decltypes ( underlyingElement ( this ) , unresolveElement ( result ) , _, _, _ ) }
11271130
11281131 /**
11291132 * The type immediately yielded by this decltype.
11301133 */
1131- Type getBaseType ( ) { decltypes ( underlyingElement ( this ) , _, unresolveElement ( result ) , _) }
1134+ Type getBaseType ( ) { decltypes ( underlyingElement ( this ) , _, _ , unresolveElement ( result ) , _) }
11321135
11331136 /**
11341137 * Whether an extra pair of parentheses around the expression would change the semantics of this decltype.
@@ -1142,7 +1145,7 @@ class Decltype extends Type, @decltype {
11421145 * ```
11431146 * Please consult the C++11 standard for more details.
11441147 */
1145- predicate parenthesesWouldChangeMeaning ( ) { decltypes ( underlyingElement ( this ) , _, _, true ) }
1148+ predicate parenthesesWouldChangeMeaning ( ) { decltypes ( underlyingElement ( this ) , _, _, _ , true ) }
11461149
11471150 override Type getUnderlyingType ( ) { result = this .getBaseType ( ) .getUnderlyingType ( ) }
11481151
@@ -1183,6 +1186,127 @@ class Decltype extends Type, @decltype {
11831186 }
11841187}
11851188
1189+ /**
1190+ * An instance of the C23 `typeof` operator taking an expression as its argument.
1191+ * For example:
1192+ * ```
1193+ * int a;
1194+ * typeof(a) b;
1195+ * ```
1196+ */
1197+ class TypeofExprType extends Type , @decltype {
1198+ TypeofExprType ( ) { decltypes ( underlyingElement ( this ) , _, 1 , _, _) }
1199+
1200+ override string getAPrimaryQlClass ( ) { result = "TypeofExprType" }
1201+
1202+ /**
1203+ * The expression whose type is being obtained by this typeof.
1204+ */
1205+ Expr getExpr ( ) { decltypes ( underlyingElement ( this ) , unresolveElement ( result ) , _, _, _) }
1206+
1207+ /**
1208+ * The type immediately yielded by this typeof.
1209+ */
1210+ Type getBaseType ( ) { decltypes ( underlyingElement ( this ) , _, _, unresolveElement ( result ) , _) }
1211+
1212+ override Type getUnderlyingType ( ) { result = this .getBaseType ( ) .getUnderlyingType ( ) }
1213+
1214+ override Type stripTopLevelSpecifiers ( ) { result = this .getBaseType ( ) .stripTopLevelSpecifiers ( ) }
1215+
1216+ override Type stripType ( ) { result = this .getBaseType ( ) .stripType ( ) }
1217+
1218+ override Type resolveTypedefs ( ) { result = this .getBaseType ( ) .resolveTypedefs ( ) }
1219+
1220+ override Location getLocation ( ) { result = this .getExpr ( ) .getLocation ( ) }
1221+
1222+ override string toString ( ) { result = "typeof(...)" }
1223+
1224+ override string getName ( ) { none ( ) }
1225+
1226+ override int getSize ( ) { result = this .getBaseType ( ) .getSize ( ) }
1227+
1228+ override int getAlignment ( ) { result = this .getBaseType ( ) .getAlignment ( ) }
1229+
1230+ override int getPointerIndirectionLevel ( ) {
1231+ result = this .getBaseType ( ) .getPointerIndirectionLevel ( )
1232+ }
1233+
1234+ override string explain ( ) {
1235+ result = "typeof resulting in {" + this .getBaseType ( ) .explain ( ) + "}"
1236+ }
1237+
1238+ override predicate involvesReference ( ) { this .getBaseType ( ) .involvesReference ( ) }
1239+
1240+ override predicate involvesTemplateParameter ( ) { this .getBaseType ( ) .involvesTemplateParameter ( ) }
1241+
1242+ override predicate isDeeplyConst ( ) { this .getBaseType ( ) .isDeeplyConst ( ) }
1243+
1244+ override predicate isDeeplyConstBelow ( ) { this .getBaseType ( ) .isDeeplyConstBelow ( ) }
1245+
1246+ override Specifier internal_getAnAdditionalSpecifier ( ) {
1247+ result = this .getBaseType ( ) .getASpecifier ( )
1248+ }
1249+ }
1250+
1251+ /**
1252+ * A type obtained by applying a type transforming intrinsic or the C23 `typeof`
1253+ * operator to a type.
1254+ * For example:
1255+ * ```
1256+ * __make_unsigned(int) x;
1257+ * typeof_unqual(const int) y;
1258+ * ```
1259+ */
1260+ class TransformedType extends Type , @type_operator {
1261+ override string getAPrimaryQlClass ( ) { result = "TransformedType" }
1262+
1263+ /**
1264+ * The type immediately yielded by this transformation.
1265+ */
1266+ Type getBaseType ( ) { type_operators ( underlyingElement ( this ) , _, _, unresolveElement ( result ) ) }
1267+
1268+ /**
1269+ * The type transformed.
1270+ */
1271+ Type getTransformedType ( ) {
1272+ type_operators ( underlyingElement ( this ) , unresolveElement ( result ) , _, _)
1273+ }
1274+
1275+ override Type getUnderlyingType ( ) { result = this .getBaseType ( ) .getUnderlyingType ( ) }
1276+
1277+ override Type stripTopLevelSpecifiers ( ) { result = this .getBaseType ( ) .stripTopLevelSpecifiers ( ) }
1278+
1279+ override Type stripType ( ) { result = this .getBaseType ( ) .stripType ( ) }
1280+
1281+ override Type resolveTypedefs ( ) { result = this .getBaseType ( ) .resolveTypedefs ( ) }
1282+
1283+ override string getName ( ) { none ( ) }
1284+
1285+ override int getSize ( ) { result = this .getBaseType ( ) .getSize ( ) }
1286+
1287+ override int getAlignment ( ) { result = this .getBaseType ( ) .getAlignment ( ) }
1288+
1289+ override int getPointerIndirectionLevel ( ) {
1290+ result = this .getBaseType ( ) .getPointerIndirectionLevel ( )
1291+ }
1292+
1293+ override string explain ( ) {
1294+ result = "type transformation resulting in {" + this .getBaseType ( ) .explain ( ) + "}"
1295+ }
1296+
1297+ override predicate involvesReference ( ) { this .getBaseType ( ) .involvesReference ( ) }
1298+
1299+ override predicate involvesTemplateParameter ( ) { this .getBaseType ( ) .involvesTemplateParameter ( ) }
1300+
1301+ override predicate isDeeplyConst ( ) { this .getBaseType ( ) .isDeeplyConst ( ) }
1302+
1303+ override predicate isDeeplyConstBelow ( ) { this .getBaseType ( ) .isDeeplyConstBelow ( ) }
1304+
1305+ override Specifier internal_getAnAdditionalSpecifier ( ) {
1306+ result = this .getBaseType ( ) .getASpecifier ( )
1307+ }
1308+ }
1309+
11861310/**
11871311 * A C/C++ pointer type. See 4.9.1.
11881312 * ```
0 commit comments