vala r2018 - in trunk: . compiler vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2018 - in trunk: . compiler vala
- Date: Fri, 14 Nov 2008 18:22:30 +0000 (UTC)
Author: juergbi
Date: Fri Nov 14 18:22:29 2008
New Revision: 2018
URL: http://svn.gnome.org/viewvc/vala?rev=2018&view=rev
Log:
2008-11-14 JÃrg Billeter <j bitron ch>
* vala/Makefile.am:
* vala/valaassignment.vala:
* vala/valabasicblock.vala:
* vala/valabinaryexpression.vala:
* vala/valacastexpression.vala:
* vala/valacatchclause.vala:
* vala/valacodenode.vala:
* vala/valadeclarationstatement.vala:
* vala/valaelementaccess.vala:
* vala/valaexpressionstatement.vala:
* vala/valaflowanalyzer.vala:
* vala/valaforeachstatement.vala:
* vala/valainvocationexpression.vala:
* vala/valamemberaccess.vala:
* vala/valaobjectcreationexpression.vala:
* vala/valaparenthesizedexpression.vala:
* vala/valaphifunction.vala:
* vala/valapointerindirection.vala:
* vala/valareferencetransferexpression.vala:
* vala/valareturnstatement.vala:
* vala/valathrowstatement.vala:
* vala/valaunaryexpression.vala:
* compiler/valacompiler.vala:
Report use of possibly uninitialized variables, fixes bug 508477
and bug 556861
Added:
trunk/vala/valaflowanalyzer.vala (contents, props changed)
- copied, changed from r2016, /trunk/vala/valacfgbuilder.vala
trunk/vala/valaphifunction.vala
Removed:
trunk/vala/valacfgbuilder.vala
Modified:
trunk/ChangeLog
trunk/compiler/valacompiler.vala
trunk/vala/Makefile.am
trunk/vala/valaassignment.vala
trunk/vala/valabasicblock.vala
trunk/vala/valabinaryexpression.vala
trunk/vala/valacastexpression.vala
trunk/vala/valacatchclause.vala
trunk/vala/valacodenode.vala
trunk/vala/valadeclarationstatement.vala
trunk/vala/valaelementaccess.vala
trunk/vala/valaexpressionstatement.vala
trunk/vala/valaforeachstatement.vala
trunk/vala/valainvocationexpression.vala
trunk/vala/valamemberaccess.vala
trunk/vala/valaobjectcreationexpression.vala
trunk/vala/valaparenthesizedexpression.vala
trunk/vala/valapointerindirection.vala
trunk/vala/valareferencetransferexpression.vala
trunk/vala/valareturnstatement.vala
trunk/vala/valathrowstatement.vala
trunk/vala/valaunaryexpression.vala
Modified: trunk/compiler/valacompiler.vala
==============================================================================
--- trunk/compiler/valacompiler.vala (original)
+++ trunk/compiler/valacompiler.vala Fri Nov 14 18:22:29 2008
@@ -256,8 +256,8 @@
return quit ();
}
- var cfg_builder = new CFGBuilder ();
- cfg_builder.build_cfg (context);
+ var flow_analyzer = new FlowAnalyzer ();
+ flow_analyzer.analyze (context);
if (Report.get_errors () > 0) {
return quit ();
Modified: trunk/vala/Makefile.am
==============================================================================
--- trunk/vala/Makefile.am (original)
+++ trunk/vala/Makefile.am Fri Nov 14 18:22:29 2008
@@ -30,7 +30,6 @@
valabreakstatement.vala \
valacastexpression.vala \
valacatchclause.vala \
- valacfgbuilder.vala \
valacharacterliteral.vala \
valaclass.vala \
valaclasstype.vala \
@@ -64,6 +63,7 @@
valaexpressionstatement.vala \
valafield.vala \
valafieldprototype.vala \
+ valaflowanalyzer.vala \
valaforeachstatement.vala \
valaformalparameter.vala \
valaforstatement.vala \
@@ -99,6 +99,7 @@
valaobjecttypesymbol.vala \
valaparenthesizedexpression.vala \
valaparser.vala \
+ valaphifunction.vala \
valapointerindirection.vala \
valapointertype.vala \
valapostfixexpression.vala \
Modified: trunk/vala/valaassignment.vala
==============================================================================
--- trunk/vala/valaassignment.vala (original)
+++ trunk/vala/valaassignment.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents an assignment expression in the source code.
@@ -376,6 +376,26 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ right.get_defined_variables (collection);
+ left.get_defined_variables (collection);
+ var local = left.symbol_reference as LocalVariable;
+ if (local != null) {
+ collection.add (local);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ var ma = left as MemberAccess;
+ var ea = left as ElementAccess;
+ if (ma != null && ma.inner != null) {
+ ma.inner.get_used_variables (collection);
+ } else if (ea != null) {
+ ea.get_used_variables (collection);
+ }
+ right.get_used_variables (collection);
+ }
}
public enum Vala.AssignmentOperator {
Modified: trunk/vala/valabasicblock.vala
==============================================================================
--- trunk/vala/valabasicblock.vala (original)
+++ trunk/vala/valabasicblock.vala Fri Nov 14 18:22:29 2008
@@ -30,9 +30,17 @@
public class Vala.BasicBlock {
private Gee.List<CodeNode> nodes = new ArrayList<CodeNode> ();
+ // control flow graph
private Gee.List<weak BasicBlock> predecessors = new ArrayList<weak BasicBlock> ();
private Gee.List<BasicBlock> successors = new ArrayList<BasicBlock> ();
+ // dominator tree
+ public BasicBlock parent { get; private set; }
+ Gee.List<BasicBlock> children = new ArrayList<BasicBlock> ();
+ Set<BasicBlock> df = new HashSet<BasicBlock> ();
+
+ Set<PhiFunction> phi_functions = new HashSet<PhiFunction> ();
+
public BasicBlock () {
}
@@ -46,6 +54,10 @@
nodes.add (node);
}
+ public Gee.List<CodeNode> get_nodes () {
+ return nodes;
+ }
+
public void connect (BasicBlock target) {
if (!successors.contains (target)) {
successors.add (target);
@@ -62,4 +74,29 @@
public Gee.List<weak BasicBlock> get_successors () {
return new ReadOnlyList<weak BasicBlock> (successors);
}
+
+ public void add_child (BasicBlock block) {
+ children.add (block);
+ block.parent = this;
+ }
+
+ public Gee.List<BasicBlock> get_children () {
+ return children;
+ }
+
+ public void add_dominator_frontier (BasicBlock block) {
+ df.add (block);
+ }
+
+ public Gee.Set<BasicBlock> get_dominator_frontier () {
+ return df;
+ }
+
+ public void add_phi_function (PhiFunction phi) {
+ phi_functions.add (phi);
+ }
+
+ public Gee.Set<PhiFunction> get_phi_functions () {
+ return phi_functions;
+ }
}
Modified: trunk/vala/valabinaryexpression.vala
==============================================================================
--- trunk/vala/valabinaryexpression.vala (original)
+++ trunk/vala/valabinaryexpression.vala Fri Nov 14 18:22:29 2008
@@ -300,6 +300,16 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ left.get_defined_variables (collection);
+ right.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ left.get_used_variables (collection);
+ right.get_used_variables (collection);
+ }
}
public enum Vala.BinaryOperator {
Modified: trunk/vala/valacastexpression.vala
==============================================================================
--- trunk/vala/valacastexpression.vala (original)
+++ trunk/vala/valacastexpression.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a type cast in the source code.
@@ -123,4 +123,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ inner.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ inner.get_used_variables (collection);
+ }
}
Modified: trunk/vala/valacatchclause.vala
==============================================================================
--- trunk/vala/valacatchclause.vala (original)
+++ trunk/vala/valacatchclause.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a catch clause in a try statement in the source code.
@@ -119,4 +119,8 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ collection.add (error_variable);
+ }
}
Modified: trunk/vala/valacodenode.vala
==============================================================================
--- trunk/vala/valacodenode.vala (original)
+++ trunk/vala/valacodenode.vala Fri Nov 14 18:22:29 2008
@@ -177,4 +177,10 @@
return str.append (" */").str;
}
+
+ public virtual void get_defined_variables (Collection<LocalVariable> collection) {
+ }
+
+ public virtual void get_used_variables (Collection<LocalVariable> collection) {
+ }
}
Modified: trunk/vala/valadeclarationstatement.vala
==============================================================================
--- trunk/vala/valadeclarationstatement.vala (original)
+++ trunk/vala/valadeclarationstatement.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a local variable or constant declaration statement in the source code.
@@ -71,4 +71,19 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ var local = declaration as LocalVariable;
+ if (local != null && local.initializer != null) {
+ local.initializer.get_defined_variables (collection);
+ collection.add (local);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ var local = declaration as LocalVariable;
+ if (local != null && local.initializer != null) {
+ local.initializer.get_used_variables (collection);
+ }
+ }
}
Modified: trunk/vala/valaelementaccess.vala
==============================================================================
--- trunk/vala/valaelementaccess.vala (original)
+++ trunk/vala/valaelementaccess.vala Fri Nov 14 18:22:29 2008
@@ -208,4 +208,18 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ container.get_defined_variables (collection);
+ foreach (Expression index in indices) {
+ index.get_defined_variables (collection);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ container.get_used_variables (collection);
+ foreach (Expression index in indices) {
+ index.get_used_variables (collection);
+ }
+ }
}
Modified: trunk/vala/valaexpressionstatement.vala
==============================================================================
--- trunk/vala/valaexpressionstatement.vala (original)
+++ trunk/vala/valaexpressionstatement.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* A code statement that evaluates a given expression. The value computed by the
@@ -103,4 +103,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ expression.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ expression.get_used_variables (collection);
+ }
}
Copied: trunk/vala/valaflowanalyzer.vala (from r2016, /trunk/vala/valacfgbuilder.vala)
==============================================================================
--- /trunk/vala/valacfgbuilder.vala (original)
+++ trunk/vala/valaflowanalyzer.vala Fri Nov 14 18:22:29 2008
@@ -1,4 +1,4 @@
-/* valacfgbuilder.vala
+/* valaflowanalyzer.vala
*
* Copyright (C) 2008 JÃrg Billeter
*
@@ -26,7 +26,7 @@
/**
* Code visitor building the control flow graph.
*/
-public class Vala.CFGBuilder : CodeVisitor {
+public class Vala.FlowAnalyzer : CodeVisitor {
private class JumpTarget {
public bool is_break_target { get; set; }
public bool is_continue_target { get; set; }
@@ -74,7 +74,11 @@
private bool unreachable_reported;
private Gee.List<JumpTarget> jump_stack = new ArrayList<JumpTarget> ();
- public CFGBuilder () {
+ Map<Symbol, Gee.List<LocalVariable>> var_map;
+ Set<LocalVariable> used_vars;
+ Map<LocalVariable, PhiFunction> phi_functions;
+
+ public FlowAnalyzer () {
}
/**
@@ -82,7 +86,7 @@
*
* @param context a code context
*/
- public void build_cfg (CodeContext context) {
+ public void analyze (CodeContext context) {
this.context = context;
/* we're only interested in non-pkg source files */
@@ -159,6 +163,308 @@
current_block.connect (m.exit_block);
}
+
+ build_dominator_tree (m);
+ build_dominator_frontier (m);
+ insert_phi_functions (m);
+ check_variables (m);
+ }
+
+ Gee.List<BasicBlock> get_depth_first_list (Method m) {
+ var list = new ArrayList<BasicBlock> ();
+ depth_first_traverse (m.entry_block, list);
+ return list;
+ }
+
+ void depth_first_traverse (BasicBlock current, Gee.List<BasicBlock> list) {
+ if (current in list) {
+ return;
+ }
+ list.add (current);
+ foreach (BasicBlock succ in current.get_successors ()) {
+ depth_first_traverse (succ, list);
+ }
+ }
+
+ void build_dominator_tree (Method m) {
+ // set dom(n) = {E,1,2...,N,X} forall n
+ var dom = new HashMap<BasicBlock, Set<BasicBlock>> ();
+ var block_list = get_depth_first_list (m);
+ foreach (BasicBlock block in block_list) {
+ var block_set = new HashSet<BasicBlock> ();
+ foreach (BasicBlock b in block_list) {
+ block_set.add (b);
+ }
+ dom.set (block, block_set);
+ }
+
+ // set dom(E) = {E}
+ var entry_dom_set = new HashSet<BasicBlock> ();
+ entry_dom_set.add (m.entry_block);
+ dom.set (m.entry_block, entry_dom_set);
+
+ bool changes = true;
+ while (changes) {
+ changes = false;
+ foreach (BasicBlock block in block_list) {
+ // intersect dom(pred) forall pred: pred = predecessor(s)
+ var dom_set = new HashSet<BasicBlock> ();
+ bool first = true;
+ foreach (BasicBlock pred in block.get_predecessors ()) {
+ var pred_dom_set = dom.get (pred);
+ if (first) {
+ foreach (BasicBlock dom_block in pred_dom_set) {
+ dom_set.add (dom_block);
+ }
+ first = false;
+ } else {
+ var remove_queue = new ArrayList<BasicBlock> ();
+ foreach (BasicBlock dom_block in dom_set) {
+ if (!(dom_block in pred_dom_set)) {
+ remove_queue.add (dom_block);
+ }
+ }
+ foreach (BasicBlock dom_block in remove_queue) {
+ dom_set.remove (dom_block);
+ }
+ }
+ }
+ // unite with s
+ dom_set.add (block);
+
+ // check for changes
+ if (dom.get (block).size != dom_set.size) {
+ changes = true;
+ } else {
+ foreach (BasicBlock dom_block in dom.get (block)) {
+ if (!(dom_block in dom_set)) {
+ changes = true;
+ }
+ }
+ }
+ // update set in map
+ dom.set (block, dom_set);
+ }
+ }
+
+ // build tree
+ foreach (BasicBlock block in block_list) {
+ if (block == m.entry_block) {
+ continue;
+ }
+
+ BasicBlock immediate_dominator = null;
+ foreach (BasicBlock dominator in dom.get (block)) {
+ if (dominator == block) {
+ continue;
+ }
+
+ if (immediate_dominator == null) {
+ immediate_dominator = dominator;
+ } else {
+ // if immediate_dominator dominates dominator,
+ // update immediate_dominator
+ if (immediate_dominator in dom.get (dominator)) {
+ immediate_dominator = dominator;
+ }
+ }
+ }
+
+ immediate_dominator.add_child (block);
+ }
+ }
+
+ void build_dominator_frontier (Method m) {
+ var block_list = get_depth_first_list (m);
+ for (int i = block_list.size - 1; i >= 0; i--) {
+ var block = block_list[i];
+
+ foreach (BasicBlock succ in block.get_successors ()) {
+ // if idom(succ) != block
+ if (succ.parent != block) {
+ block.add_dominator_frontier (succ);
+ }
+ }
+
+ foreach (BasicBlock child in block.get_children ()) {
+ foreach (BasicBlock child_frontier in child.get_dominator_frontier ()) {
+ // if idom(child_frontier) != block
+ if (child_frontier.parent != block) {
+ block.add_dominator_frontier (child_frontier);
+ }
+ }
+ }
+ }
+ }
+
+ Map<LocalVariable, Set<BasicBlock>> get_assignment_map (Method m) {
+ var map = new HashMap<LocalVariable, Set<BasicBlock>> ();
+ foreach (BasicBlock block in get_depth_first_list (m)) {
+ var defined_variables = new ArrayList<LocalVariable> ();
+ foreach (CodeNode node in block.get_nodes ()) {
+ node.get_defined_variables (defined_variables);
+ }
+
+ foreach (LocalVariable local in defined_variables) {
+ var block_set = map.get (local);
+ if (block_set == null) {
+ block_set = new HashSet<BasicBlock> ();
+ map.set (local, block_set);
+ }
+ block_set.add (block);
+ }
+ }
+ return map;
+ }
+
+ void insert_phi_functions (Method m) {
+ var assign = get_assignment_map (m);
+
+ int counter = 0;
+ var work_list = new ArrayList<BasicBlock> ();
+
+ var added = new HashMap<BasicBlock, int> ();
+ var phi = new HashMap<BasicBlock, int> ();
+ foreach (BasicBlock block in get_depth_first_list (m)) {
+ added.set (block, 0);
+ phi.set (block, 0);
+ }
+
+ foreach (LocalVariable local in assign.get_keys ()) {
+ counter++;
+ foreach (BasicBlock block in assign.get (local)) {
+ work_list.add (block);
+ added.set (block, counter);
+ }
+ while (work_list.size > 0) {
+ BasicBlock block = work_list.get (0);
+ work_list.remove_at (0);
+ foreach (BasicBlock frontier in block.get_dominator_frontier ()) {
+ int blockPhi = phi.get (frontier);
+ if (blockPhi < counter) {
+ frontier.add_phi_function (new PhiFunction (local, frontier.get_predecessors ().size));
+ phi.set (frontier, counter);
+ int block_added = added.get (frontier);
+ if (block_added < counter) {
+ added.set (frontier, counter);
+ work_list.add (frontier);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void check_variables (Method m) {
+ var_map = new HashMap<Symbol, Gee.List<LocalVariable>>();
+ used_vars = new HashSet<LocalVariable> ();
+ phi_functions = new HashMap<LocalVariable, PhiFunction> ();
+
+ check_block_variables (m, m.entry_block);
+
+ // check for variables used before initialization
+ var used_vars_queue = new ArrayList<LocalVariable> ();
+ foreach (LocalVariable local in used_vars) {
+ used_vars_queue.add (local);
+ }
+ while (used_vars_queue.size > 0) {
+ LocalVariable used_var = used_vars_queue[0];
+ used_vars_queue.remove_at (0);
+
+ PhiFunction phi = phi_functions.get (used_var);
+ if (phi != null) {
+ foreach (LocalVariable local in phi.operands) {
+ if (local == null) {
+ Report.error (used_var.source_reference, "use of possibly unassigned local variable `%s'".printf (used_var.name));
+ continue;
+ }
+ if (!(local in used_vars)) {
+ local.source_reference = used_var.source_reference;
+ used_vars.add (local);
+ used_vars_queue.add (local);
+ }
+ }
+ }
+ }
+ }
+
+ void check_block_variables (Method m, BasicBlock block) {
+ foreach (PhiFunction phi in block.get_phi_functions ()) {
+ LocalVariable versioned_var = process_assignment (m, var_map, phi.original_variable);
+
+ phi_functions.set (versioned_var, phi);
+ }
+
+ foreach (CodeNode node in block.get_nodes ()) {
+ var used_variables = new ArrayList<LocalVariable> ();
+ node.get_used_variables (used_variables);
+
+ foreach (LocalVariable var_symbol in used_variables) {
+ var variable_stack = var_map.get (var_symbol);
+ if (variable_stack == null || variable_stack.size == 0) {
+ Report.error (node.source_reference, "use of possibly unassigned local variable `%s'".printf (var_symbol.name));
+ continue;
+ }
+ var versioned_local = variable_stack.get (variable_stack.size - 1);
+ if (!(versioned_local in used_vars)) {
+ versioned_local.source_reference = node.source_reference;
+ }
+ used_vars.add (versioned_local);
+ }
+
+ var defined_variables = new ArrayList<LocalVariable> ();
+ node.get_defined_variables (defined_variables);
+
+ foreach (LocalVariable local in defined_variables) {
+ process_assignment (m, var_map, local);
+ }
+ }
+
+ foreach (BasicBlock succ in block.get_successors ()) {
+ int j = 0;
+ foreach (BasicBlock pred in succ.get_predecessors ()) {
+ if (pred == block) {
+ break;
+ }
+ j++;
+ }
+
+ foreach (PhiFunction phi in succ.get_phi_functions ()) {
+ var variable_stack = var_map.get (phi.original_variable);
+ if (variable_stack != null && variable_stack.size > 0) {
+ phi.operands.set (j, variable_stack.get (variable_stack.size - 1));
+ }
+ }
+ }
+
+ foreach (BasicBlock child in block.get_children ()) {
+ check_block_variables (m, child);
+ }
+
+ foreach (PhiFunction phi in block.get_phi_functions ()) {
+ var variable_stack = var_map.get (phi.original_variable);
+ variable_stack.remove_at (variable_stack.size - 1);
+ }
+ foreach (CodeNode node in block.get_nodes ()) {
+ var defined_variables = new ArrayList<LocalVariable> ();
+ node.get_defined_variables (defined_variables);
+
+ foreach (LocalVariable local in defined_variables) {
+ var variable_stack = var_map.get (local);
+ variable_stack.remove_at (variable_stack.size - 1);
+ }
+ }
+ }
+
+ LocalVariable process_assignment (Method m, Map<Symbol, Gee.List<LocalVariable>> var_map, LocalVariable var_symbol) {
+ var variable_stack = var_map.get (var_symbol);
+ if (variable_stack == null) {
+ variable_stack = new ArrayList<LocalVariable> ();
+ var_map.set (var_symbol, variable_stack);
+ }
+ LocalVariable versioned_var = new LocalVariable (var_symbol.variable_type, var_symbol.name, null, var_symbol.source_reference);
+ variable_stack.add (versioned_var);
+ return versioned_var;
}
public override void visit_property (Property prop) {
@@ -311,9 +617,13 @@
}
}
+ if (!has_default_label) {
+ condition_block.connect (after_switch_block);
+ }
+
// after switch
// reachable?
- if (!has_default_label || after_switch_block.get_predecessors ().size > 0) {
+ if (after_switch_block.get_predecessors ().size > 0) {
current_block = after_switch_block;
} else {
current_block = null;
@@ -476,6 +786,7 @@
var last_block = current_block;
last_block.connect (loop_block);
current_block = loop_block;
+ current_block.add_node (stmt);
stmt.body.accept (this);
if (current_block != null) {
current_block.connect (loop_block);
@@ -695,6 +1006,7 @@
Report.warning (jump_target.catch_clause.source_reference, "unreachable catch clause detected");
} else {
current_block = jump_target.basic_block;
+ current_block.add_node (jump_target.catch_clause);
jump_target.catch_clause.body.accept (this);
if (current_block != null) {
if (finally_block != null) {
Modified: trunk/vala/valaforeachstatement.vala
==============================================================================
--- trunk/vala/valaforeachstatement.vala (original)
+++ trunk/vala/valaforeachstatement.vala Fri Nov 14 18:22:29 2008
@@ -1,6 +1,6 @@
/* valaforeachstatement.vala
*
- * Copyright (C) 2006-2007 JÃrg Billeter
+ * Copyright (C) 2006-2008 JÃrg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a foreach statement in the source code. Foreach statements iterate
@@ -247,4 +247,8 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ collection.add (element_variable);
+ }
}
Modified: trunk/vala/valainvocationexpression.vala
==============================================================================
--- trunk/vala/valainvocationexpression.vala (original)
+++ trunk/vala/valainvocationexpression.vala Fri Nov 14 18:22:29 2008
@@ -420,4 +420,20 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ call.get_defined_variables (collection);
+
+ foreach (Expression arg in argument_list) {
+ arg.get_defined_variables (collection);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ call.get_used_variables (collection);
+
+ foreach (Expression arg in argument_list) {
+ arg.get_used_variables (collection);
+ }
+ }
}
Modified: trunk/vala/valamemberaccess.vala
==============================================================================
--- trunk/vala/valamemberaccess.vala (original)
+++ trunk/vala/valamemberaccess.vala Fri Nov 14 18:22:29 2008
@@ -535,4 +535,20 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ if (inner != null) {
+ inner.get_defined_variables (collection);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ if (inner != null) {
+ inner.get_used_variables (collection);
+ }
+ var local = symbol_reference as LocalVariable;
+ if (local != null) {
+ collection.add (local);
+ }
+ }
}
Modified: trunk/vala/valaobjectcreationexpression.vala
==============================================================================
--- trunk/vala/valaobjectcreationexpression.vala (original)
+++ trunk/vala/valaobjectcreationexpression.vala Fri Nov 14 18:22:29 2008
@@ -360,4 +360,16 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ foreach (Expression arg in argument_list) {
+ arg.get_defined_variables (collection);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ foreach (Expression arg in argument_list) {
+ arg.get_used_variables (collection);
+ }
+ }
}
Modified: trunk/vala/valaparenthesizedexpression.vala
==============================================================================
--- trunk/vala/valaparenthesizedexpression.vala (original)
+++ trunk/vala/valaparenthesizedexpression.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a parenthesized expression in the source code.
@@ -104,4 +104,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ inner.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ inner.get_used_variables (collection);
+ }
}
Added: trunk/vala/valaphifunction.vala
==============================================================================
--- (empty file)
+++ trunk/vala/valaphifunction.vala Fri Nov 14 18:22:29 2008
@@ -0,0 +1,37 @@
+/* valaphifunction.vala
+ *
+ * Copyright (C) 2008 JÃrg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * JÃrg Billeter <j bitron ch>
+ */
+
+using Gee;
+
+public class Vala.PhiFunction {
+ public LocalVariable original_variable { get; private set; }
+
+ public Gee.List<LocalVariable?> operands { get; private set; }
+
+ public PhiFunction (LocalVariable variable, int num_of_ops) {
+ this.original_variable = variable;
+ this.operands = new ArrayList<LocalVariable?> ();
+ for (int i = 0; i < num_of_ops; i++) {
+ this.operands.add ((LocalVariable) null);
+ }
+ }
+}
Modified: trunk/vala/valapointerindirection.vala
==============================================================================
--- trunk/vala/valapointerindirection.vala (original)
+++ trunk/vala/valapointerindirection.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a pointer indirection in the source code, e.g. `*pointer'.
@@ -101,4 +101,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ inner.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ inner.get_used_variables (collection);
+ }
}
Modified: trunk/vala/valareferencetransferexpression.vala
==============================================================================
--- trunk/vala/valareferencetransferexpression.vala (original)
+++ trunk/vala/valareferencetransferexpression.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a reference transfer expression in the source code, e.g. `#foo'.
@@ -107,4 +107,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ inner.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ inner.get_used_variables (collection);
+ }
}
Modified: trunk/vala/valareturnstatement.vala
==============================================================================
--- trunk/vala/valareturnstatement.vala (original)
+++ trunk/vala/valareturnstatement.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a return statement in the source code.
@@ -141,4 +141,16 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ if (return_expression != null) {
+ return_expression.get_defined_variables (collection);
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ if (return_expression != null) {
+ return_expression.get_used_variables (collection);
+ }
+ }
}
Modified: trunk/vala/valathrowstatement.vala
==============================================================================
--- trunk/vala/valathrowstatement.vala (original)
+++ trunk/vala/valathrowstatement.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents a throw statement in the source code.
@@ -94,4 +94,12 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ error_expression.get_defined_variables (collection);
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ error_expression.get_used_variables (collection);
+ }
}
Modified: trunk/vala/valaunaryexpression.vala
==============================================================================
--- trunk/vala/valaunaryexpression.vala (original)
+++ trunk/vala/valaunaryexpression.vala Fri Nov 14 18:22:29 2008
@@ -20,7 +20,7 @@
* JÃrg Billeter <j bitron ch>
*/
-using GLib;
+using Gee;
/**
* Represents an expression with one operand in the source code.
@@ -225,6 +225,22 @@
return !error;
}
+
+ public override void get_defined_variables (Collection<LocalVariable> collection) {
+ inner.get_defined_variables (collection);
+ if (operator == UnaryOperator.OUT || operator == UnaryOperator.REF) {
+ var local = inner.symbol_reference as LocalVariable;
+ if (local != null) {
+ collection.add (local);
+ }
+ }
+ }
+
+ public override void get_used_variables (Collection<LocalVariable> collection) {
+ if (operator != UnaryOperator.OUT) {
+ inner.get_used_variables (collection);
+ }
+ }
}
public enum Vala.UnaryOperator {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]