@@ -9,6 +9,9 @@ module Cpp14Literal {
9
9
/** An numeric literal. */
10
10
abstract class NumericLiteral extends StandardLibrary:: Literal { }
11
11
12
+ /** Convenience for implementing class `UnrecognizedNumericLiteral` */
13
+ abstract private class RecognizedNumericLiteral extends StandardLibrary:: Literal { }
14
+
12
15
/** An integer literal. */
13
16
abstract class IntegerLiteral extends NumericLiteral {
14
17
predicate isSigned ( ) { not isUnsigned ( ) }
@@ -23,7 +26,7 @@ module Cpp14Literal {
23
26
* ```
24
27
* Octal literals must always start with the digit `0`.
25
28
*/
26
- class OctalLiteral extends IntegerLiteral {
29
+ class OctalLiteral extends IntegerLiteral , RecognizedNumericLiteral {
27
30
OctalLiteral ( ) { getValueText ( ) .regexpMatch ( "\\s*0[0-7']*[uUlL]*\\s*" ) }
28
31
29
32
override string getAPrimaryQlClass ( ) { result = "OctalLiteral" }
@@ -35,7 +38,7 @@ module Cpp14Literal {
35
38
* unsigned int32_t minus2 = 0xfffffffe;
36
39
* ```
37
40
*/
38
- class HexLiteral extends IntegerLiteral {
41
+ class HexLiteral extends IntegerLiteral , RecognizedNumericLiteral {
39
42
HexLiteral ( ) { getValueText ( ) .regexpMatch ( "\\s*0[xX][0-9a-fA-F']+[uUlL]*\\s*" ) }
40
43
41
44
override string getAPrimaryQlClass ( ) { result = "HexLiteral" }
@@ -47,7 +50,7 @@ module Cpp14Literal {
47
50
* unsigned int32_t binary = 0b101010;
48
51
* ```
49
52
*/
50
- class BinaryLiteral extends IntegerLiteral {
53
+ class BinaryLiteral extends IntegerLiteral , RecognizedNumericLiteral {
51
54
BinaryLiteral ( ) { getValueText ( ) .regexpMatch ( "\\s*0[bB][0-1']*[uUlL]*\\s*" ) }
52
55
53
56
override string getAPrimaryQlClass ( ) { result = "BinaryLiteral" }
@@ -59,7 +62,7 @@ module Cpp14Literal {
59
62
* unsigned int32_t decimal = 10340923;
60
63
* ```
61
64
*/
62
- class DecimalLiteral extends IntegerLiteral {
65
+ class DecimalLiteral extends IntegerLiteral , RecognizedNumericLiteral {
63
66
DecimalLiteral ( ) { getValueText ( ) .regexpMatch ( "\\s*[1-9][0-9']*[uUlL]*\\s*" ) }
64
67
65
68
override string getAPrimaryQlClass ( ) { result = "DecimalLiteral" }
@@ -71,7 +74,7 @@ module Cpp14Literal {
71
74
* double floating = 1.340923e-19;
72
75
* ```
73
76
*/
74
- class FloatingLiteral extends NumericLiteral {
77
+ class FloatingLiteral extends RecognizedNumericLiteral {
75
78
FloatingLiteral ( ) {
76
79
getValueText ( ) .regexpMatch ( "\\s*[0-9][0-9']*(\\.[0-9']+)?([eE][\\+\\-]?[0-9']+)?[flFL]?\\s*" ) and
77
80
// A decimal literal takes precedent
@@ -83,6 +86,23 @@ module Cpp14Literal {
83
86
override string getAPrimaryQlClass ( ) { result = "FloatingLiteral" }
84
87
}
85
88
89
+ /**
90
+ * Literal values with conversions and macros cannot always be trivially
91
+ * parsed from `Literal.getValueText()`, and have loss of required
92
+ * information in `Literal.getValue()`. This class covers cases that appear
93
+ * to be `NumericLiteral`s but cannot be determined to be a hex, decimal,
94
+ * octal, binary, or float literal, but still are parsed as a Literal with a
95
+ * number value.
96
+ */
97
+ class UnrecognizedNumericLiteral extends NumericLiteral {
98
+ UnrecognizedNumericLiteral ( ) {
99
+ this .getValue ( ) .regexpMatch ( "[0-9.e]+" ) and
100
+ not this instanceof RecognizedNumericLiteral
101
+ }
102
+ }
103
+
104
+ predicate test ( RecognizedNumericLiteral r , string valueText ) { valueText = r .getValueText ( ) }
105
+
86
106
/**
87
107
* A character literal. For example:
88
108
* ```
0 commit comments