@@ -17,24 +17,41 @@ TranslatedExpr getTranslatedExpr(Expr expr) {
1717}
1818
1919/**
20- * The IR translation of an expression that was either directly present in the
21- * AST as an `Expr` (`TranslatedExpr`) or was synthesized from something other
22- * than an `Expr` .
20+ * The IR translation of some part of an expression.
21+ * A single `Expr` may consist of multiple `TranslatedExpr` objects. Every
22+ * `Expr` has a single `TranslatedCoreExpr`, which produces the result of the
23+ * expression before any implicit lvalue-to-rvalue conversion. Any expression
24+ * with an lvalue-to-rvalue conversion will also have a `TranslatedLoad` to
25+ * perform that conversion on the original result. A few expressions have
26+ * additional `TranslatedExpr` objects that compute intermediate values, such
27+ * as the `TranslatedAllocatorCall` and `TranslatedAllocationSize` within the
28+ * translation of a `NewExpr`.
2329 */
24- abstract class TranslatedOrSynthesizedExpr extends TranslatedElement {
30+ abstract class TranslatedExpr extends TranslatedElement {
31+ Expr expr ;
32+
2533 /**
2634 * Gets the instruction that produces the result of the expression.
2735 */
2836 abstract Instruction getResult ( ) ;
29- }
3037
31- /**
32- * The IR translation of some part of an expression. This could be the
33- * expression itself (`TranslatedExpr`), or some other construct synthesized
34- * from an `Expr` (e.g. `TranslatedAllocatorCall`).
35- */
36- abstract class TranslatedFromExpr extends TranslatedElement {
37- Expr expr ;
38+ /**
39+ * Holds if this `TranslatedExpr` produces the final result of the original
40+ * expression from the AST.
41+ *
42+ * For example, in `y = x;`, the TranslatedLoad for the VariableAccess `x`
43+ * produces the result of that VariableAccess expression, but the
44+ * TranslatedVariableAccess for `x` does not. The TranslatedVariableAccess
45+ * for `y` does produce its result, however, because there is no load on `y`.
46+ */
47+ abstract predicate producesExprResult ( ) ;
48+
49+ /**
50+ * Gets the type of the result produced by this expression.
51+ */
52+ final Type getResultType ( ) {
53+ result = expr .getType ( ) .getUnspecifiedType ( )
54+ }
3855
3956 override final Locatable getAST ( ) {
4057 result = expr
@@ -44,6 +61,13 @@ abstract class TranslatedFromExpr extends TranslatedElement {
4461 result = expr .getEnclosingFunction ( )
4562 }
4663
64+ /**
65+ * Gets the expression from which this `TranslatedExpr` is generated.
66+ */
67+ final Expr getExpr ( ) {
68+ result = expr
69+ }
70+
4771 /**
4872 * Gets the `TranslatedFunction` containing this expression.
4973 */
@@ -53,34 +77,17 @@ abstract class TranslatedFromExpr extends TranslatedElement {
5377}
5478
5579/**
56- * The IR translation of an expression.
80+ * The IR translation of the "core" part of an expression. This is the part of
81+ * the expression that produces the result value of the expression, before any
82+ * lvalue-to-rvalue conversion on the result. Every expression has a single
83+ * `TranslatedCoreExpr`.
5784 */
58- abstract class TranslatedExpr extends TranslatedOrSynthesizedExpr ,
59- TranslatedFromExpr {
85+ abstract class TranslatedCoreExpr extends TranslatedExpr {
6086 override final string toString ( ) {
6187 result = expr .toString ( )
6288 }
6389
64- final Expr getExpr ( ) {
65- result = expr
66- }
67-
68- final Type getResultType ( ) {
69- result = expr .getType ( ) .getUnspecifiedType ( )
70- }
71-
72- /**
73- * Holds if this `TranslatedExpr` produces the final result of the original
74- * expression from the AST.
75- *
76- * For example, in `y = x;`, the TranslatedLoad for the VariableAccess `x`
77- * produces the result of that VariableAccess expression, but the
78- * TranslatedVariableAccess for `x` does not. The TranslatedVariableAccess
79- * for `y` does produce its result, however, because there is no load on `y`.
80- */
81- final predicate producesExprResult ( ) {
82- // A load always produces the result of the expression.
83- this instanceof TranslatedLoad or
90+ override final predicate producesExprResult ( ) {
8491 // If there's no load, then this is the only TranslatedExpr for this
8592 // expression.
8693 not expr .hasLValueToRValueConversion ( ) or
@@ -110,7 +117,7 @@ abstract class TranslatedExpr extends TranslatedOrSynthesizedExpr,
110117 }
111118}
112119
113- class TranslatedConditionValue extends TranslatedExpr , ConditionContext ,
120+ class TranslatedConditionValue extends TranslatedCoreExpr , ConditionContext ,
114121 TTranslatedConditionValue {
115122 TranslatedConditionValue ( ) {
116123 this = TTranslatedConditionValue ( expr )
@@ -286,11 +293,19 @@ class TranslatedConditionValue extends TranslatedExpr, ConditionContext,
286293 }
287294}
288295
296+ /**
297+ * IR translation of an implicit lvalue-to-rvalue conversion on the result of
298+ * an expression.
299+ */
289300class TranslatedLoad extends TranslatedExpr , TTranslatedLoad {
290301 TranslatedLoad ( ) {
291302 this = TTranslatedLoad ( expr )
292303 }
293304
305+ override string toString ( ) {
306+ result = "Load of " + expr .toString ( )
307+ }
308+
294309 override Instruction getFirstInstruction ( ) {
295310 result = getOperand ( ) .getFirstInstruction ( )
296311 }
@@ -303,8 +318,11 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
303318 Type resultType , boolean isGLValue ) {
304319 tag = LoadTag ( ) and
305320 opcode instanceof Opcode:: Load and
306- resultType = getResultType ( ) and
307- isGLValue = isResultGLValue ( )
321+ resultType = expr .getType ( ) .getUnspecifiedType ( ) and
322+ if expr .isGLValueCategory ( ) then
323+ isGLValue = true
324+ else
325+ isGLValue = false
308326 }
309327
310328 override Instruction getInstructionSuccessor ( InstructionTag tag ,
@@ -337,8 +355,13 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad {
337355 )
338356 }
339357
340- private TranslatedExpr getOperand ( ) {
341- result .getExpr ( ) = expr and not result instanceof TranslatedLoad
358+ override final predicate producesExprResult ( ) {
359+ // A load always produces the result of the expression.
360+ any ( )
361+ }
362+
363+ private TranslatedCoreExpr getOperand ( ) {
364+ result .getExpr ( ) = expr
342365 }
343366}
344367
@@ -930,21 +953,24 @@ class TranslatedFunctionAccess extends TranslatedNonConstantExpr {
930953 }
931954}
932955
933- abstract class TranslatedNonLoadExpr extends TranslatedExpr ,
934- TTranslatedNonLoadExpr {
935- TranslatedNonLoadExpr ( ) {
936- this = TTranslatedNonLoadExpr ( expr )
937- }
938- }
939-
940- abstract class TranslatedNonConstantExpr extends TranslatedNonLoadExpr {
956+ /**
957+ * IR translation of an expression whose value is not known at compile time.
958+ */
959+ abstract class TranslatedNonConstantExpr extends TranslatedCoreExpr {
941960 TranslatedNonConstantExpr ( ) {
961+ this = TTranslatedValueExpr ( expr ) and
942962 not expr .isConstant ( )
943963 }
944964}
945965
946- abstract class TranslatedConstantExpr extends TranslatedNonLoadExpr {
966+ /**
967+ * IR translation of an expression with a compile-time constant value. This
968+ * includes not only literals, but also "integral constant expressions" (e.g.
969+ * `1 + 2`).
970+ */
971+ abstract class TranslatedConstantExpr extends TranslatedCoreExpr {
947972 TranslatedConstantExpr ( ) {
973+ this = TTranslatedValueExpr ( expr ) and
948974 expr .isConstant ( )
949975 }
950976
@@ -1022,7 +1048,15 @@ class TranslatedStringLiteral extends TranslatedConstantExpr {
10221048 }
10231049}
10241050
1025- abstract class TranslatedValueExpr extends TranslatedNonConstantExpr {
1051+ /**
1052+ * IR translation of an expression that performs a single operation on its
1053+ * operands and returns the result.
1054+ */
1055+ abstract class TranslatedSingleInstructionExpr extends
1056+ TranslatedNonConstantExpr {
1057+ /**
1058+ * Gets the `Opcode` of the operation to be performed.
1059+ */
10261060 abstract Opcode getOpcode ( ) ;
10271061
10281062 override final predicate hasInstruction ( Opcode opcode , InstructionTag tag ,
@@ -1038,7 +1072,7 @@ abstract class TranslatedValueExpr extends TranslatedNonConstantExpr {
10381072 }
10391073}
10401074
1041- class TranslatedUnaryExpr extends TranslatedValueExpr {
1075+ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr {
10421076 TranslatedUnaryExpr ( ) {
10431077 expr instanceof NotExpr or
10441078 expr instanceof ComplementExpr or
@@ -1323,7 +1357,10 @@ private Opcode comparisonOpcode(ComparisonOperation expr) {
13231357 expr instanceof GEExpr and result instanceof Opcode:: CompareGE
13241358}
13251359
1326- class TranslatedBinaryOperation extends TranslatedValueExpr {
1360+ /**
1361+ * IR translation of a simple binary operation.
1362+ */
1363+ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
13271364 TranslatedBinaryOperation ( ) {
13281365 expr instanceof BinaryArithmeticOperation or
13291366 expr instanceof BinaryBitwiseOperation or
@@ -1735,7 +1772,7 @@ class TranslatedAssignOperation extends TranslatedAssignment {
17351772 * call in the source code, or could be a call that is part of the translation
17361773 * of a higher-level constructor (e.g. the allocator call in a `NewExpr`).
17371774 */
1738- abstract class TranslatedCall extends TranslatedOrSynthesizedExpr {
1775+ abstract class TranslatedCall extends TranslatedExpr {
17391776 override final TranslatedElement getChild ( int id ) {
17401777 // We choose the child's id in the order of evaluation.
17411778 // The qualifier is evaluated before the call target, because the value of
@@ -1868,7 +1905,7 @@ abstract class TranslatedCall extends TranslatedOrSynthesizedExpr {
18681905 * Gets the argument with the specified `index`. Does not include the `this`
18691906 * argument.
18701907 */
1871- abstract TranslatedOrSynthesizedExpr getArgument ( int index ) ;
1908+ abstract TranslatedExpr getArgument ( int index ) ;
18721909
18731910 /**
18741911 * If there are any arguments, gets the first instruction of the first
@@ -1894,8 +1931,8 @@ abstract class TranslatedCall extends TranslatedOrSynthesizedExpr {
18941931 * We have to synthesize this because not all `NewExpr` nodes have an allocator
18951932 * call, and even the ones that do pass an `ErrorExpr` as the argument.
18961933 */
1897- abstract class TranslatedAllocationSize extends TranslatedOrSynthesizedExpr ,
1898- TranslatedFromExpr , TTranslatedAllocationSize {
1934+ abstract class TranslatedAllocationSize extends TranslatedExpr ,
1935+ TTranslatedAllocationSize {
18991936 NewOrNewArrayExpr newExpr ;
19001937
19011938 TranslatedAllocationSize ( ) {
@@ -1907,6 +1944,10 @@ abstract class TranslatedAllocationSize extends TranslatedOrSynthesizedExpr,
19071944 result = "Allocation size for " + newExpr .toString ( )
19081945 }
19091946
1947+ override final predicate producesExprResult ( ) {
1948+ none ( )
1949+ }
1950+
19101951 override final Instruction getResult ( ) {
19111952 result = getInstruction ( AllocationSizeTag ( ) )
19121953 }
@@ -2050,8 +2091,8 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize {
20502091 * The IR translation of a call to `operator new` as part of a `new` or `new[]`
20512092 * expression.
20522093 */
2053- class TranslatedAllocatorCall extends TTranslatedAllocatorCall , TranslatedCall ,
2054- TranslatedFromExpr {
2094+ class TranslatedAllocatorCall extends TTranslatedAllocatorCall ,
2095+ TranslatedCall {
20552096 NewOrNewArrayExpr newExpr ;
20562097
20572098 TranslatedAllocatorCall ( ) {
@@ -2063,6 +2104,10 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall,
20632104 result = "Allocator call for " + newExpr .toString ( )
20642105 }
20652106
2107+ override final predicate producesExprResult ( ) {
2108+ none ( )
2109+ }
2110+
20662111 override final Instruction getFirstCallTargetInstruction ( ) {
20672112 result = getInstruction ( CallTargetTag ( ) )
20682113 }
@@ -2109,7 +2154,7 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedCall,
21092154 any ( )
21102155 }
21112156
2112- override final TranslatedOrSynthesizedExpr getArgument ( int index ) {
2157+ override final TranslatedExpr getArgument ( int index ) {
21132158 // If the allocator is the default operator new(void*), there will be no
21142159 // allocator call in the AST. Otherwise, there will be an allocator call
21152160 // that includes all arguments to the allocator, including the size,
@@ -2152,7 +2197,7 @@ abstract class TranslatedCallExpr extends TranslatedNonConstantExpr,
21522197 result = getTranslatedExpr ( call .getQualifier ( ) .getFullyConverted ( ) )
21532198 }
21542199
2155- override final TranslatedOrSynthesizedExpr getArgument ( int index ) {
2200+ override final TranslatedExpr getArgument ( int index ) {
21562201 result = getTranslatedExpr ( call .getArgument ( index ) .getFullyConverted ( ) )
21572202 }
21582203}
0 commit comments