[vala/wip/code-transformer: 13/27] Move ConditionalExpression transformation into the CCodeTransformer
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/code-transformer: 13/27] Move ConditionalExpression transformation into the CCodeTransformer
- Date: Fri, 19 Apr 2019 13:31:29 +0000 (UTC)
commit 58e8e399d1cd173518d858efd8efb75aadc2d8aa
Author: Luca Bruno <lucabru src gnome org>
Date: Tue Dec 27 19:07:31 2011 +0100
Move ConditionalExpression transformation into the CCodeTransformer
codegen/valaccodetransformer.vala | 18 +++++++++++++
vala/valaconditionalexpression.vala | 50 +---------------------------------
vala/valaflowanalyzer.vala | 53 +++++++++++++++++++++++++++++++++++--
3 files changed, 70 insertions(+), 51 deletions(-)
---
diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala
index 4e31edcda..3a9c77235 100644
--- a/codegen/valaccodetransformer.vala
+++ b/codegen/valaccodetransformer.vala
@@ -166,4 +166,22 @@ public class Vala.CCodeTransformer : CodeTransformer {
base.visit_method_call (expr);
}
+
+ public override void visit_conditional_expression (ConditionalExpression expr) {
+ // convert to if statement
+ Expression replacement = null;
+ var formal_target_type = copy_type (expr.target_type);
+ var target_type = copy_type (expr.target_type);
+ begin_replace_expression (expr);
+
+ var result = b.add_temp_declaration (expr.value_type);
+ statements (@"if ($(expr.condition)) {
+ $result = $(expr.true_expression);
+ } else {
+ $result = $(expr.false_expression);
+ }");
+
+ replacement = return_temp_access (result, expr.value_type, target_type, formal_target_type);
+ end_replace_expression (replacement);
+ }
}
diff --git a/vala/valaconditionalexpression.vala b/vala/valaconditionalexpression.vala
index b6884f616..16e54064f 100644
--- a/vala/valaconditionalexpression.vala
+++ b/vala/valaconditionalexpression.vala
@@ -151,43 +151,14 @@ public class Vala.ConditionalExpression : Expression {
return false;
}
- // convert ternary expression into if statement
- // required for flow analysis and exception handling
-
- string temp_name = get_temp_name ();
-
true_expression.target_type = target_type;
false_expression.target_type = target_type;
- var local = new LocalVariable (null, temp_name, null, source_reference);
- var decl = new DeclarationStatement (local, source_reference);
-
- var true_local = new LocalVariable (null, temp_name, true_expression,
true_expression.source_reference);
- var true_block = new Block (true_expression.source_reference);
- var true_decl = new DeclarationStatement (true_local, true_expression.source_reference);
- true_block.add_statement (true_decl);
-
- var false_local = new LocalVariable (null, temp_name, false_expression,
false_expression.source_reference);
- var false_block = new Block (false_expression.source_reference);
- var false_decl = new DeclarationStatement (false_local, false_expression.source_reference);
- false_block.add_statement (false_decl);
-
- var if_stmt = new IfStatement (condition, true_block, false_block, source_reference);
-
- insert_statement (context.analyzer.get_insert_block (this), decl);
- insert_statement (context.analyzer.get_insert_block (this), if_stmt);
-
- if (!if_stmt.check (context) || true_expression.error || false_expression.error) {
+ if (!condition.check (context) || !true_expression.check (context) || !false_expression.check
(context)) {
error = true;
return false;
}
- true_expression = true_local.initializer;
- false_expression = false_local.initializer;
-
- true_block.remove_local_variable (true_local);
- false_block.remove_local_variable (false_local);
-
if (false_expression.value_type.compatible (true_expression.value_type)) {
value_type = true_expression.value_type.copy ();
} else if (true_expression.value_type.compatible (false_expression.value_type)) {
@@ -202,28 +173,9 @@ public class Vala.ConditionalExpression : Expression {
value_type.floating_reference = false;
value_type.check (context);
- local.variable_type = value_type;
- decl.check (context);
-
true_expression.target_type = value_type;
false_expression.target_type = value_type;
- var true_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name,
true_expression.source_reference), true_expression, AssignmentOperator.SIMPLE,
true_expression.source_reference), true_expression.source_reference);
-
- var false_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple
(local.name, false_expression.source_reference), false_expression, AssignmentOperator.SIMPLE,
false_expression.source_reference), false_expression.source_reference);
-
- true_block.replace_statement (true_decl, true_stmt);
- false_block.replace_statement (false_decl, false_stmt);
- true_stmt.check (context);
- false_stmt.check (context);
-
- var ma = new MemberAccess.simple (local.name, source_reference);
- ma.formal_target_type = formal_target_type;
- ma.target_type = target_type;
-
- parent_node.replace_expression (this, ma);
- ma.check (context);
-
return true;
}
}
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index a0ad0b615..8ebb5422b 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -1258,8 +1258,9 @@ public class Vala.FlowAnalyzer : CodeVisitor {
}
public override void visit_expression (Expression expr) {
- // lambda expression is handled separately
- if (!(expr is LambdaExpression)) {
+ // lambda expression and conditional expression are handled separately
+ // an expression can be unreachable due to a conditional expression
+ if (!(expr is LambdaExpression) && !(expr is ConditionalExpression) && !unreachable (expr)) {
expr.accept_children (this);
}
}
@@ -1272,6 +1273,54 @@ public class Vala.FlowAnalyzer : CodeVisitor {
handle_errors (expr);
}
+ public override void visit_conditional_expression (ConditionalExpression expr) {
+ if (unreachable (expr)) {
+ return;
+ }
+
+ // condition
+ current_block.add_node (expr.condition);
+ handle_errors (expr.condition);
+
+ // true block
+ var last_block = current_block;
+ if (always_false (expr.condition)) {
+ mark_unreachable ();
+ } else {
+ current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
+ last_block.connect (current_block);
+ }
+ expr.true_expression.accept (this);
+
+ // false block
+ var last_true_block = current_block;
+ if (always_true (expr.condition)) {
+ mark_unreachable ();
+ } else {
+ current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
+ last_block.connect (current_block);
+ }
+ if (expr.false_expression != null) {
+ expr.false_expression.accept (this);
+ }
+
+ // after if/else
+ var last_false_block = current_block;
+ // reachable?
+ if (last_true_block != null || last_false_block != null) {
+ current_block = new BasicBlock ();
+ all_basic_blocks.add (current_block);
+ if (last_true_block != null) {
+ last_true_block.connect (current_block);
+ }
+ if (last_false_block != null) {
+ last_false_block.connect (current_block);
+ }
+ }
+ }
+
private bool unreachable (CodeNode node) {
if (current_block == null) {
node.unreachable = true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]