[vala/emit: 4/4] WIP: Add CCodeBuilder
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/emit: 4/4] WIP: Add CCodeBuilder
- Date: Tue, 10 Aug 2010 07:31:24 +0000 (UTC)
commit fc9eaa3501ce181b0a81763095f11381ae4bd995
Author: Jürg Billeter <j bitron ch>
Date: Sun Aug 8 20:26:48 2010 +0200
WIP: Add CCodeBuilder
ccode/Makefile.am | 2 +
ccode/valaccodebuilder.vala | 104 +++++
ccode/valaccodedeclaration.vala | 65 +---
ccode/valaccodefilewriter.vala | 128 ++++++
ccode/valaccodefunction.vala | 4 +-
ccode/valaccodewriter.vala | 408 +++++++++++++------
codegen/valaccodearraymodule.vala | 88 ++---
codegen/valaccodeassignmentmodule.vala | 4 +-
codegen/valaccodebasemodule.vala | 626 +++++++++++++-----------------
codegen/valaccodecontrolflowmodule.vala | 219 ++++-------
codegen/valaccodememberaccessmodule.vala | 12 +-
codegen/valaccodemethodcallmodule.vala | 44 +--
codegen/valaccodemethodmodule.vala | 406 +++++++++++++-------
codegen/valaccodestructmodule.vala | 11 +-
codegen/valadovaarraymodule.vala | 2 +-
codegen/valadovaassignmentmodule.vala | 4 +-
codegen/valadovabasemodule.vala | 25 +-
codegen/valadovamemberaccessmodule.vala | 2 +-
codegen/valadovamethodcallmodule.vala | 10 +-
codegen/valadovavaluemodule.vala | 14 +-
codegen/valagasyncmodule.vala | 129 +++----
codegen/valagerrormodule.vala | 187 ++++------
codegen/valagobjectmodule.vala | 36 +-
codegen/valagsignalmodule.vala | 4 +-
codegen/valagtypemodule.vala | 210 ++++++-----
25 files changed, 1476 insertions(+), 1268 deletions(-)
---
diff --git a/ccode/Makefile.am b/ccode/Makefile.am
index 1fd4a0d..f53f38f 100644
--- a/ccode/Makefile.am
+++ b/ccode/Makefile.am
@@ -17,6 +17,7 @@ libvalaccode_la_VALASOURCES = \
valaccodebinaryexpression.vala \
valaccodeblock.vala \
valaccodebreakstatement.vala \
+ valaccodebuilder.vala \
valaccodecasestatement.vala \
valaccodecastexpression.vala \
valaccodecommaexpression.vala \
@@ -32,6 +33,7 @@ libvalaccode_la_VALASOURCES = \
valaccodeenumvalue.vala \
valaccodeexpression.vala \
valaccodeexpressionstatement.vala \
+ valaccodefilewriter.vala \
valaccodeformalparameter.vala \
valaccodeforstatement.vala \
valaccodefragment.vala \
diff --git a/ccode/valaccodebuilder.vala b/ccode/valaccodebuilder.vala
new file mode 100644
index 0000000..c66918b
--- /dev/null
+++ b/ccode/valaccodebuilder.vala
@@ -0,0 +1,104 @@
+/* valaccodebuilder.vala
+ *
+ * Copyright (C) 2010 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>
+ */
+
+public class Vala.CCodeBuilder : CCodeWriter {
+ class Context {
+ public StringBuilder decl_string = new StringBuilder ();
+ public StringBuilder code_string = new StringBuilder ();
+ }
+
+ class Node : CCodeNode {
+ public string str;
+
+ public Node (string str) {
+ this.str = str;
+ }
+
+ public override void write (CCodeWriter writer) {
+ writer.write_string (str);
+ }
+ }
+
+ List<Context> context_stack = new ArrayList<Context> ();
+ Context context = new Context ();
+
+ public CCodeBuilder () {
+ }
+
+ void push_context () {
+ context_stack.add (context);
+ context = new Context ();
+ }
+
+ void pop_context () {
+ context = context_stack[context_stack.size - 1];
+ context_stack.remove_at (context_stack.size - 1);
+ }
+
+ public override void write_begin_block () {
+ base.write_begin_block ();
+
+ push_context ();
+ }
+
+ public override void write_end_block () {
+ var block = context;
+ pop_context ();
+
+ var old_bol = bol;
+ bol = true;
+
+ write_string (block.decl_string.str);
+ write_string (block.code_string.str);
+
+ bol = old_bol;
+
+ base.write_end_block ();
+ }
+
+ public override void write_string (string s) {
+ if (writing_code) {
+ context.code_string.append (s);
+ } else {
+ context.decl_string.append (s);
+ }
+ bol = false;
+ }
+
+ public void append (CCodeNode node) {
+ node.write (this);
+ }
+
+ public CCodeNode get_node () {
+ if (!bol) {
+ write_newline ();
+ }
+ write_newline ();
+ return new Node (context.code_string.str);
+ }
+
+ public CCodeBlock get_block () {
+ var result = new CCodeBlock ();
+ result.add_statement (get_node ());
+ return result;
+ }
+}
diff --git a/ccode/valaccodedeclaration.vala b/ccode/valaccodedeclaration.vala
index 95216f8..60aa6c4 100644
--- a/ccode/valaccodedeclaration.vala
+++ b/ccode/valaccodedeclaration.vala
@@ -59,72 +59,9 @@ public class Vala.CCodeDeclaration : CCodeStatement {
}
}
- private bool has_initializer () {
- foreach (CCodeDeclarator decl in declarators) {
- var var_decl = decl as CCodeVariableDeclarator;
- if (var_decl != null && var_decl.initializer == null) {
- return false;
- }
- }
- return true;
- }
-
public override void write_declaration (CCodeWriter writer) {
- if ((modifiers & (CCodeModifiers.STATIC | CCodeModifiers.EXTERN)) != 0) {
- // combined declaration and initialization for static and extern variables
- writer.write_indent (line);
- if ((modifiers & CCodeModifiers.STATIC) != 0) {
- writer.write_string ("static ");
- }
- if ((modifiers & CCodeModifiers.VOLATILE) != 0) {
- writer.write_string ("volatile ");
- }
- if ((modifiers & CCodeModifiers.EXTERN) != 0 && !has_initializer ()) {
- writer.write_string ("extern ");
- }
- if ((modifiers & CCodeModifiers.THREAD_LOCAL) != 0) {
- writer.write_string ("thread_local ");
- }
- writer.write_string (type_name);
- writer.write_string (" ");
-
- bool first = true;
- foreach (CCodeDeclarator decl in declarators) {
- if (!first) {
- writer.write_string (", ");
- } else {
- first = false;
- }
- decl.write (writer);
- }
-
- if (CCodeModifiers.DEPRECATED in modifiers) {
- writer.write_string (" G_GNUC_DEPRECATED");
- }
-
- writer.write_string (";");
- writer.write_newline ();
- return;
- }
-
- writer.write_indent ();
- if ((modifiers & CCodeModifiers.REGISTER) == CCodeModifiers.REGISTER) {
- writer.write_string ("register ");
- }
- writer.write_string (type_name);
- writer.write_string (" ");
-
- bool first = true;
foreach (CCodeDeclarator decl in declarators) {
- if (!first) {
- writer.write_string (", ");
- } else {
- first = false;
- }
- decl.write_declaration (writer);
+ writer.write_declaration (type_name, decl, modifiers);
}
-
- writer.write_string (";");
- writer.write_newline ();
}
}
diff --git a/ccode/valaccodefilewriter.vala b/ccode/valaccodefilewriter.vala
new file mode 100644
index 0000000..cac80f4
--- /dev/null
+++ b/ccode/valaccodefilewriter.vala
@@ -0,0 +1,128 @@
+/* valaccodefilewriter.vala
+ *
+ * Copyright (C) 2006-2010 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 GLib;
+
+/**
+ * Represents a writer to write C source files.
+ */
+public class Vala.CCodeFileWriter : CCodeWriter {
+ /**
+ * Specifies the file to be written.
+ */
+ public string filename { get; set; }
+
+ /**
+ * Specifies the source file used to generate this one.
+ */
+ private string source_filename;
+
+ private string temp_filename;
+ private bool file_exists;
+
+ private FileStream? stream;
+
+ public CCodeFileWriter (string filename, string? source_filename = null) {
+ this.filename = filename;
+ this.source_filename = source_filename;
+ }
+
+ /**
+ * Opens the file.
+ *
+ * @return true if the file has been opened successfully,
+ * false otherwise
+ */
+ public bool open (bool write_version) {
+ file_exists = FileUtils.test (filename, FileTest.EXISTS);
+ if (file_exists) {
+ temp_filename = "%s.valatmp".printf (filename);
+ stream = FileStream.open (temp_filename, "w");
+ } else {
+ /*
+ * File doesn't exist. In case of a particular destination (-d flag),
+ * check and create the directory structure.
+ */
+ var dirname = Path.get_dirname (filename);
+ DirUtils.create_with_parents (dirname, 0755);
+ stream = FileStream.open (filename, "w");
+ }
+
+ if (stream == null) {
+ return false;
+ }
+
+ var opening = write_version ?
+ "/* %s generated by valac %s, the Vala compiler".printf (Path.get_basename (filename), Config.BUILD_VERSION) :
+ "/* %s generated by valac, the Vala compiler".printf (Path.get_basename (filename));
+ write_string (opening);
+
+ // Write the file name if known
+ if (source_filename != null) {
+ write_newline ();
+ write_string (" * generated from %s".printf (Path.get_basename (source_filename)));
+ }
+
+ write_string (", do not modify */");
+ write_newline ();
+ write_newline ();
+
+ return true;
+ }
+
+ /**
+ * Closes the file.
+ */
+ public void close () {
+ stream = null;
+
+ if (file_exists) {
+ var changed = true;
+
+ try {
+ var old_file = new MappedFile (filename, false);
+ var new_file = new MappedFile (temp_filename, false);
+ var len = old_file.get_length ();
+ if (len == new_file.get_length ()) {
+ if (Memory.cmp (old_file.get_contents (), new_file.get_contents (), len) == 0) {
+ changed = false;
+ }
+ }
+ old_file = null;
+ new_file = null;
+ } catch (FileError e) {
+ // assume changed if mmap comparison doesn't work
+ }
+
+ if (changed) {
+ FileUtils.rename (temp_filename, filename);
+ } else {
+ FileUtils.unlink (temp_filename);
+ }
+ }
+ }
+
+ public override void write_string (string s) {
+ stream.puts (s);
+ bol = false;
+ }
+}
diff --git a/ccode/valaccodefunction.vala b/ccode/valaccodefunction.vala
index d414fb2..87a8d02 100644
--- a/ccode/valaccodefunction.vala
+++ b/ccode/valaccodefunction.vala
@@ -43,12 +43,14 @@ public class Vala.CCodeFunction : CCodeNode {
public string attributes { get; set; }
+ public List<CCodeFormalParameter> parameters { get { return _parameters; } }
+
/**
* The function body.
*/
public CCodeBlock block { get; set; }
- private List<CCodeFormalParameter> parameters = new ArrayList<CCodeFormalParameter> ();
+ private List<CCodeFormalParameter> _parameters = new ArrayList<CCodeFormalParameter> ();
public CCodeFunction (string name, string return_type = "void") {
this.name = name;
diff --git a/ccode/valaccodewriter.vala b/ccode/valaccodewriter.vala
index 93f4a42..48d8fd5 100644
--- a/ccode/valaccodewriter.vala
+++ b/ccode/valaccodewriter.vala
@@ -1,6 +1,6 @@
/* valaccodewriter.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 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,22 +20,7 @@
* Jürg Billeter <j bitron ch>
*/
-using GLib;
-
-/**
- * Represents a writer to write C source files.
- */
-public class Vala.CCodeWriter {
- /**
- * Specifies the file to be written.
- */
- public string filename { get; set; }
-
- /**
- * Specifies the source file used to generate this one.
- */
- private string source_filename;
-
+public abstract class Vala.CCodeWriter {
/**
* Specifies whether to emit line directives.
*/
@@ -45,114 +30,46 @@ public class Vala.CCodeWriter {
* Specifies whether the output stream is at the beginning of a line.
*/
public bool bol {
- get { return _bol; }
+ get {
+ if (writing_code) {
+ return code_bol;
+ } else {
+ return decl_bol;
+ }
+ }
+ set {
+ if (writing_code) {
+ code_bol = value;
+ } else {
+ decl_bol = value;
+ }
+ }
}
- private string temp_filename;
- private bool file_exists;
-
- private FileStream? stream;
-
private int indent;
private int current_line_number = 1;
- private bool using_line_directive;
-
- /* at begin of line */
- private bool _bol = true;
-
- public CCodeWriter (string filename, string? source_filename = null) {
- this.filename = filename;
- this.source_filename = source_filename;
- }
-
- /**
- * Opens the file.
- *
- * @return true if the file has been opened successfully,
- * false otherwise
- */
- public bool open (bool write_version) {
- file_exists = FileUtils.test (filename, FileTest.EXISTS);
- if (file_exists) {
- temp_filename = "%s.valatmp".printf (filename);
- stream = FileStream.open (temp_filename, "w");
- } else {
- /*
- * File doesn't exist. In case of a particular destination (-d flag),
- * check and create the directory structure.
- */
- var dirname = Path.get_dirname (filename);
- DirUtils.create_with_parents (dirname, 0755);
- stream = FileStream.open (filename, "w");
- }
- if (stream == null) {
- return false;
- }
+ bool decl_bol = true;
+ bool code_bol = true;
- var opening = write_version ?
- "/* %s generated by valac %s, the Vala compiler".printf (Path.get_basename (filename), Config.BUILD_VERSION) :
- "/* %s generated by valac, the Vala compiler".printf (Path.get_basename (filename));
- write_string (opening);
+ public CCodeLineDirective? line { get; set; }
- // Write the file name if known
- if (source_filename != null) {
- write_newline ();
- write_string (" * generated from %s".printf (Path.get_basename (source_filename)));
- }
-
- write_string (", do not modify */");
- write_newline ();
- write_newline ();
+ public bool writing_code { get; set; default = true; }
- return true;
+ public CCodeWriter () {
}
/**
- * Closes the file.
- */
- public void close () {
- stream = null;
-
- if (file_exists) {
- var changed = true;
-
- try {
- var old_file = new MappedFile (filename, false);
- var new_file = new MappedFile (temp_filename, false);
- var len = old_file.get_length ();
- if (len == new_file.get_length ()) {
- if (Memory.cmp (old_file.get_contents (), new_file.get_contents (), len) == 0) {
- changed = false;
- }
- }
- old_file = null;
- new_file = null;
- } catch (FileError e) {
- // assume changed if mmap comparison doesn't work
- }
-
- if (changed) {
- FileUtils.rename (temp_filename, filename);
- } else {
- FileUtils.unlink (temp_filename);
- }
- }
- }
-
- /**
* Writes tabs according to the current indent level.
*/
public void write_indent (CCodeLineDirective? line = null) {
if (line_directives) {
if (line != null) {
- line.write (this);
- using_line_directive = true;
- } else if (using_line_directive) {
- // no corresponding Vala line, emit line directive for C line
- write_string ("#line %d \"%s\"".printf (current_line_number + 1, Path.get_basename (filename)));
- write_newline ();
- using_line_directive = false;
+ this.line = line;
+ }
+
+ if (this.line != null) {
+ this.line.write (this);
}
}
@@ -161,10 +78,10 @@ public class Vala.CCodeWriter {
}
for (int i = 0; i < indent; i++) {
- stream.putc ('\t');
+ write_string ("\t");
}
- _bol = false;
+ bol = false;
}
/**
@@ -172,45 +89,46 @@ public class Vala.CCodeWriter {
*
* @param s a string
*/
- public void write_string (string s) {
- stream.puts (s);
- _bol = false;
- }
-
+ public abstract void write_string (string s);
+
/**
* Writes a newline.
*/
public void write_newline () {
- stream.putc ('\n');
+ write_string ("\n");
current_line_number++;
- _bol = true;
+ bol = true;
}
/**
* Opens a new block, increasing the indent level.
*/
- public void write_begin_block () {
+ public virtual void write_begin_block () {
if (!bol) {
- stream.putc (' ');
+ write_string (" ");
} else {
write_indent ();
}
- stream.putc ('{');
+ write_string ("{");
write_newline ();
indent++;
}
-
+
/**
* Closes the current block, decreasing the indent level.
*/
- public void write_end_block () {
+ public virtual void write_end_block () {
assert (indent > 0);
-
+
indent--;
write_indent ();
- stream.putc ('}');
+ write_string ("}");
}
-
+
+ public void close () {
+ write_end_block ();
+ }
+
/**
* Writes the specified text as comment.
*
@@ -219,7 +137,7 @@ public class Vala.CCodeWriter {
public void write_comment (string text) {
try {
write_indent ();
- stream.puts ("/*");
+ write_string ("/*");
bool first = true;
// discard tabs at beginning of line
@@ -238,16 +156,246 @@ public class Vala.CCodeWriter {
var lineparts = regex.replace_literal (line, -1, 0, "").split ("*/");
for (int i = 0; lineparts[i] != null; i++) {
- stream.puts (lineparts[i]);
+ write_string (lineparts[i]);
if (lineparts[i+1] != null) {
- stream.puts ("* /");
+ write_string ("* /");
}
}
}
- stream.puts ("*/");
+ write_string ("*/");
write_newline ();
} catch (RegexError e) {
// ignore
}
}
+
+ /* TODO: also write expressions without creating CCodeNodes using stack/RPN logic
+ return writer object to allow chaining
+ writer.load_integer (42).load_integer (23).add ().call ("sqrt");
+ */
+
+ public void write_expression (CCodeNode expression) {
+ var comma = expression as CCodeCommaExpression;
+ if (comma != null) {
+ foreach (var inner in comma.get_inner ()) {
+ write_indent ();
+ inner.write (this);
+ write_string (";");
+ }
+ return;
+ }
+
+ write_indent ();
+ expression.write (this);
+ write_string (";");
+ write_newline ();
+ }
+
+ public void open_function (string name, string return_type, List<CCodeFormalParameter> parameters, CCodeModifiers modifiers = 0, string? attributes = null) {
+ write_function (name, return_type, parameters, modifiers, attributes);
+ write_begin_block ();
+ }
+
+ void write_function (string name, string return_type, List<CCodeFormalParameter> parameters, CCodeModifiers modifiers = 0, string? attributes = null) {
+ write_indent ();
+ if (CCodeModifiers.STATIC in modifiers) {
+ write_string ("static ");
+ }
+ if (CCodeModifiers.INLINE in modifiers) {
+ write_string ("inline ");
+ }
+ write_string (return_type);
+ write_string (" ");
+ write_string (name);
+ write_string (" (");
+
+ bool first = true;
+ foreach (CCodeFormalParameter param in parameters) {
+ if (!first) {
+ write_string (", ");
+ } else {
+ first = false;
+ }
+ param.write (this);
+ }
+ if (first) {
+ write_string ("void");
+ }
+
+ write_string (")");
+
+ if (CCodeModifiers.DEPRECATED in modifiers) {
+ write_string (" G_GNUC_DEPRECATED");
+ }
+
+ if (attributes != null) {
+ write_string (" ");
+ write_string (attributes);
+ }
+ }
+
+ public void write_function_declaration (string name, string return_type, List<CCodeFormalParameter> parameters, CCodeModifiers modifiers = 0, string attributes = "") {
+ write_function (name, return_type, parameters, modifiers, attributes);
+ write_string (";");
+ write_newline ();
+ }
+
+ public void write_declaration (string type_name, CCodeDeclarator declarator, CCodeModifiers modifiers = 0) {
+ writing_code = false;
+
+ bool has_initializer = declarator is CCodeVariableDeclarator &&
+ ((CCodeVariableDeclarator) declarator).initializer != null;
+
+ if ((modifiers & (CCodeModifiers.STATIC | CCodeModifiers.EXTERN)) != 0) {
+ // combined declaration and initialization for static and extern variables
+ write_indent ();
+ if ((modifiers & CCodeModifiers.STATIC) != 0) {
+ write_string ("static ");
+ }
+ if ((modifiers & CCodeModifiers.VOLATILE) != 0) {
+ write_string ("volatile ");
+ }
+ if ((modifiers & CCodeModifiers.EXTERN) != 0 && !has_initializer) {
+ write_string ("extern ");
+ }
+ if ((modifiers & CCodeModifiers.THREAD_LOCAL) != 0) {
+ write_string ("thread_local ");
+ }
+ write_string (type_name);
+ write_string (" ");
+
+ declarator.write (this);
+
+ if (CCodeModifiers.DEPRECATED in modifiers) {
+ write_string (" G_GNUC_DEPRECATED");
+ }
+
+ write_string (";");
+ write_newline ();
+
+ writing_code = true;
+ return;
+ }
+
+ write_indent ();
+ if ((modifiers & CCodeModifiers.REGISTER) == CCodeModifiers.REGISTER) {
+ write_string ("register ");
+ }
+ write_string (type_name);
+ write_string (" ");
+
+ declarator.write_declaration (this);
+
+ write_string (";");
+ write_newline ();
+
+ writing_code = true;
+ }
+
+ public void open_if (CCodeNode condition) {
+ write_indent ();
+ write_string ("if (");
+ condition.write (this);
+ write_string (")");
+ write_begin_block ();
+ }
+
+ public void add_else () {
+ write_end_block ();
+ write_string (" else");
+ write_begin_block ();
+ }
+
+ public void open_switch (CCodeNode condition) {
+ write_indent ();
+ write_string ("switch (");
+ condition.write (this);
+ write_string (")");
+ write_begin_block ();
+ }
+
+ public void add_default () {
+ write_indent ();
+ write_string ("default:");
+ write_newline ();
+ }
+
+ public void add_case (CCodeNode expression) {
+ write_indent ();
+ write_string ("case ");
+ expression.write (this);
+ write_string (":");
+ write_newline ();
+ }
+
+ public void add_label (string label) {
+ write_indent ();
+ write_string (label);
+ write_string (":");
+ write_newline ();
+ }
+
+ public void write_goto (string target) {
+ write_indent ();
+ write_string ("goto ");
+ write_string (target);
+ write_string (";");
+ write_newline ();
+ }
+
+ public void open_while (CCodeNode condition) {
+ write_indent ();
+ write_string ("while (");
+ condition.write (this);
+ write_string (")");
+ write_begin_block ();
+ }
+
+ public void open_for (CCodeNode initializer, CCodeNode condition, CCodeNode iterator) {
+ write_indent ();
+ write_string ("for (");
+ initializer.write (this);
+ write_string ("; ");
+ condition.write (this);
+ write_string ("; ");
+ iterator.write (this);
+ write_string (")");
+ write_begin_block ();
+ }
+
+ public void write_return (CCodeNode? expression = null) {
+ write_indent ();
+ if (expression == null) {
+ write_string ("return;");
+ } else {
+ write_string ("return ");
+ expression.write (this);
+ write_string (";");
+ }
+ write_newline ();
+ }
+
+ public void add_break () {
+ write_indent ();
+ write_string ("break;");
+ write_newline ();
+ }
+
+ public void add_continue () {
+ write_indent ();
+ write_string ("continue;");
+ write_newline ();
+ }
+
+ public List<CCodeFormalParameter> parameters (CCodeFormalParameter? parameter = null, ...) {
+ var args = va_list ();
+
+ var list = new ArrayList<CCodeFormalParameter> ();
+ while (parameter != null) {
+ list.add (parameter);
+ parameter = args.arg ();
+ }
+
+ return list;
+ }
}
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index a0a6ab4..edf17d6 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -48,7 +48,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
append_initializer_list (ce, name_cnode, expr.initializer_list, expr.rank, ref i);
@@ -80,7 +80,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
size.ccodenode = name_cnode;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
csize = new CCodeAssignment (name_cnode, csize);
}
@@ -112,7 +112,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ce.append_expression (new CCodeAssignment (name_cnode, gnew));
@@ -442,15 +442,15 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var len_var = get_temp_variable (int_type);
len_var.source_reference = expr.source_reference;
- temp_vars.add (len_var);
+ emit_temp_var (len_var);
var slice_var = get_temp_variable (expr.value_type, true, expr);
- temp_vars.add (slice_var);
+ emit_temp_var (slice_var);
if (!is_pure_ccode_expression (cstart)) {
// avoid double evaluation of start
var start_var = get_temp_variable (int_type);
- temp_vars.add (start_var);
+ emit_temp_var (start_var);
var start_assignment = new CCodeAssignment (get_variable_cexpression (start_var.name), cstart);
ccomma.append_expression (start_assignment);
@@ -688,7 +688,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
}
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -766,14 +766,12 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
// definition
- var block = new CCodeBlock ();
+ push_context (new EmitContext ());
- if (requires_copy (array_type.element_type)) {
- push_context (new EmitContext ());
+ ccode.write_begin_block ();
- var cdecl = new CCodeDeclaration (array_type.get_cname ());
+ if (requires_copy (array_type.element_type)) {
var cvardecl = new CCodeVariableDeclarator ("result");
- cdecl.add_declarator (cvardecl);
var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
@@ -785,27 +783,18 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
gnew.add_argument (length_expr);
cvardecl.initializer = gnew;
- block.add_statement (cdecl);
-
- var idx_decl = new CCodeDeclaration ("int");
- idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
- block.add_statement (idx_decl);
+ ccode.write_declaration (array_type.get_cname (), cvardecl);
- var loop_body = new CCodeBlock ();
- loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+ ccode.write_declaration ("int", new CCodeVariableDeclarator ("i"));
- var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- block.add_statement (cfor);
+ ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
+ new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")),
+ new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.write_expression (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type)));
+ ccode.close ();
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- block.add_statement (cfrag);
-
- pop_context ();
+ ccode.write_return (new CCodeIdentifier ("result"));
} else {
var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
dup_call.add_argument (new CCodeIdentifier ("self"));
@@ -814,16 +803,20 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
- block.add_statement (new CCodeReturnStatement (dup_call));
+ ccode.write_return (dup_call);
}
+ ccode.write_end_block ();
+
// append to file
source_declarations.add_type_member_declaration (function.copy ());
- function.block = block;
+ function.block = ccode.get_block ();
source_type_member_definition.append (function);
+ pop_context ();
+
return dup_func;
}
@@ -845,28 +838,21 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
// definition
- var block = new CCodeBlock ();
+ push_context (new EmitContext ());
- if (requires_copy (array_type.element_type)) {
- push_context (new EmitContext ());
+ ccode.write_begin_block ();
- var idx_decl = new CCodeDeclaration ("int");
- idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
- block.add_statement (idx_decl);
+ if (requires_copy (array_type.element_type)) {
+ ccode.write_declaration ("int", new CCodeVariableDeclarator ("i"));
- var loop_body = new CCodeBlock ();
- loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("dest"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+ ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
+ new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeConstant ("%d".printf (array_type.length))),
+ new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeConstant ("%d".printf (array_type.length))), loop_body);
- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- block.add_statement (cfor);
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- block.add_statement (cfrag);
+ ccode.write_expression (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("dest"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type)));
- pop_context ();
+ ccode.close ();
} else {
source_declarations.add_include ("string.h");
@@ -878,16 +864,20 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call));
- block.add_statement (new CCodeExpressionStatement (dup_call));
+ ccode.write_expression (dup_call);
}
+ ccode.write_end_block ();
+
// append to file
source_declarations.add_type_member_declaration (function.copy ());
- function.block = block;
+ function.block = ccode.get_block ();
source_type_member_definition.append (function);
+ pop_context ();
+
return dup_func;
}
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index c1009b2..d3bba10 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -130,13 +130,13 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
var lhs_value_type = assignment.left.value_type.copy ();
string lhs_temp_name = "_tmp%d_".printf (next_temp_var_id++);
var lhs_temp = new LocalVariable (lhs_value_type, "*" + lhs_temp_name);
- temp_vars.add (lhs_temp);
+ emit_temp_var (lhs_temp);
outer_ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (lhs_temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, lhs)));
lhs = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (lhs_temp_name)));
}
var temp_decl = get_temp_variable (assignment.left.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), rhs));
if (unref_old) {
/* unref old value */
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index e71fa5b..5939fc1 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -31,8 +31,8 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public Symbol? current_symbol;
public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
public TryStatement current_try;
+ public CCodeBuilder ccode = new CCodeBuilder ();
public CCodeSwitchStatement state_switch_statement;
- public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
public int next_temp_var_id;
public bool current_method_inner_error;
@@ -154,12 +154,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public CCodeFragment source_signal_marshaller_declaration;
public CCodeFragment source_type_member_definition;
- public CCodeFragment class_init_fragment;
- public CCodeFragment base_init_fragment;
- public CCodeFragment class_finalize_fragment;
- public CCodeFragment base_finalize_fragment;
- public CCodeFragment instance_init_fragment;
- public CCodeFragment instance_finalize_fragment;
+ public EmitContext class_init_context;
+ public EmitContext base_init_context;
+ public EmitContext class_finalize_context;
+ public EmitContext base_finalize_context;
+ public EmitContext instance_init_context;
+ public EmitContext instance_finalize_context;
public CCodeFragment source_signal_marshaller_definition;
public CCodeStruct param_spec_struct;
@@ -167,9 +167,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public CCodeEnum prop_enum;
public CCodeFunction function;
- // code nodes to be inserted before the current statement
- // used by async method calls in coroutines
- public CCodeFragment pre_statement_fragment;
+ public CCodeBuilder ccode { get { return emit_context.ccode; } }
// case statements to be inserted for the couroutine state
public CCodeSwitchStatement state_switch_statement {
@@ -177,8 +175,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
set { emit_context.state_switch_statement = value; }
}
- /* all temporary variables */
- public ArrayList<LocalVariable> temp_vars { get { return emit_context.temp_vars; } }
/* temporary variables that own their content */
public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
/* cache to check whether a certain marshaller has been created yet */
@@ -446,7 +442,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// generate C header file for public API
if (context.header_filename != null) {
- var writer = new CCodeWriter (context.header_filename);
+ var writer = new CCodeFileWriter (context.header_filename);
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -485,7 +481,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// generate C header file for internal API
if (context.internal_header_filename != null) {
- var writer = new CCodeWriter (context.internal_header_filename);
+ var writer = new CCodeFileWriter (context.internal_header_filename);
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -672,7 +668,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
source_declarations.add_include ("gobject/gvaluecollector.h");
}
- var writer = new CCodeWriter (source_file.get_csource_filename (), source_file.filename);
+ var writer = new CCodeFileWriter (source_file.get_csource_filename (), source_file.filename);
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -809,13 +805,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
/* stuff meant for all lockable members */
if (m is Lockable && ((Lockable) m).get_lock_used ()) {
CCodeExpression l = new CCodeIdentifier ("self");
- CCodeFragment init_fragment = class_init_fragment;
- CCodeFragment finalize_fragment = class_finalize_fragment;
+ var init_context = class_init_context;
+ var finalize_context = class_finalize_context;
if (m.is_instance_member ()) {
l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m.name));
- init_fragment = instance_init_fragment;
- finalize_fragment = instance_finalize_fragment;
+ init_context = instance_init_context;
+ finalize_context = instance_finalize_context;
} else if (m.is_class_member ()) {
TypeSymbol parent = (TypeSymbol)m.parent_symbol;
@@ -826,14 +822,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
l = new CCodeIdentifier (get_symbol_lock_name ("%s_%s".printf(m.parent_symbol.get_lower_case_cname (), m.name)));
}
+ push_context (init_context);
var initf = new CCodeFunctionCall (new CCodeIdentifier (mutex_type.default_construction_method.get_cname ()));
initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- init_fragment.append (new CCodeExpressionStatement (initf));
+ ccode.write_expression (initf);
+ pop_context ();
- if (finalize_fragment != null) {
+ if (finalize_context != null) {
+ push_context (finalize_context);
var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free"));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- finalize_fragment.append (new CCodeExpressionStatement (fc));
+ ccode.write_expression (fc);
+ pop_context ();
}
}
}
@@ -977,10 +977,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
check_type (f.variable_type);
- if (f.initializer != null) {
- f.initializer.emit (this);
- }
-
var cl = f.parent_symbol as Class;
bool is_gtypeinstance = (cl != null && !cl.is_compact);
@@ -999,9 +995,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (f.initializer != null) {
+ push_context (instance_init_context);
+
+ f.initializer.emit (this);
+
var rhs = (CCodeExpression) f.initializer.ccodenode;
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ ccode.write_expression (new CCodeAssignment (lhs, rhs));
if (f.variable_type is ArrayType && !f.no_array_length &&
f.initializer is ArrayCreationExpression) {
@@ -1016,30 +1016,31 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var array_len_lhs = get_array_length_cexpression (ma, dim);
var size = sizes[dim - 1];
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+ ccode.write_expression (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode));
}
if (array_type.rank == 1 && f.is_internal_symbol ()) {
var lhs_array_size = get_array_size_cexpression (ma);
var rhs_array_len = get_array_length_cexpression (ma, 1);
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs_array_size, rhs_array_len)));
+ ccode.write_expression (new CCodeAssignment (lhs_array_size, rhs_array_len));
}
}
- append_temp_decl (instance_init_fragment, temp_vars);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- instance_init_fragment.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
- temp_vars.clear ();
temp_ref_vars.clear ();
+
+ pop_context ();
}
- if (requires_destroy (f.variable_type) && instance_finalize_fragment != null) {
+ if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
+ push_context (instance_finalize_context);
+
var this_access = new MemberAccess.simple ("this");
this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
@@ -1053,7 +1054,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess (this_access, f.name);
ma.symbol_reference = f;
ma.value_type = f.variable_type.copy ();
- instance_finalize_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (lhs, f.variable_type, ma));
+
+ pop_context ();
}
} else if (f.binding == MemberBinding.CLASS) {
if (!is_gtypeinstance) {
@@ -1071,21 +1074,24 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (f.initializer != null) {
- var rhs = (CCodeExpression) f.initializer.ccodenode;
+ push_context (class_init_context);
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ f.initializer.emit (this);
+
+ var rhs = (CCodeExpression) f.initializer.ccodenode;
- append_temp_decl (class_init_fragment, temp_vars);
+ ccode.write_expression (new CCodeAssignment (lhs, rhs));
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- class_init_fragment.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
- temp_vars.clear ();
temp_ref_vars.clear ();
+
+ pop_context ();
}
} else {
generate_field_declaration (f, source_declarations);
@@ -1102,7 +1108,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var var_decl = new CCodeVariableDeclarator (f.get_cname (), null, f.variable_type.get_cdeclarator_suffix ());
var_decl.initializer = default_value_for_type (f.variable_type, true);
+ push_context (class_init_context);
+
if (f.initializer != null) {
+ f.initializer.emit (this);
+
var init = (CCodeExpression) f.initializer.ccodenode;
if (is_constant_ccode_expression (init)) {
var_decl.initializer = init;
@@ -1192,9 +1202,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
frag.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, tmp)));
block.add_statement (frag);
- class_init_fragment.append (block);
+ ccode.append (block);
} else {
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ ccode.write_expression (new CCodeAssignment (lhs, rhs));
}
if (f.variable_type is ArrayType && !f.no_array_length &&
@@ -1207,12 +1217,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var array_len_lhs = get_array_length_cexpression (ma, dim);
var size = sizes[dim - 1];
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+ ccode.write_expression (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode));
}
}
-
- append_temp_decl (class_init_fragment, temp_vars);
- temp_vars.clear ();
} else {
f.error = true;
Report.error (f.source_reference, "Non-constant field initializers not supported in this context");
@@ -1220,6 +1227,8 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
}
+
+ pop_context ();
}
}
@@ -1416,10 +1425,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
acc.result_var.accept (this);
}
- if (acc.body != null) {
- acc.body.emit (this);
- }
-
var t = (TypeSymbol) prop.parent_symbol;
if (acc.construction && !t.is_subtype_of (gobject_type)) {
@@ -1464,6 +1469,76 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cvalueparam = new CCodeFormalParameter ("value", acc.value_type.get_cname ());
}
+ bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
+
+ string cname;
+ if (is_virtual) {
+ if (acc.readable) {
+ cname = "%s_real_get_%s".printf (t.get_lower_case_cname (null), prop.name);
+ } else {
+ cname = "%s_real_set_%s".printf (t.get_lower_case_cname (null), prop.name);
+ }
+ } else {
+ cname = acc.get_cname ();
+ }
+
+ string return_type;
+ if (acc.writable || acc.construction || returns_real_struct) {
+ return_type = "void";
+ } else {
+ return_type = acc.value_type.get_cname ();
+ }
+
+ ObjectType base_type = null;
+ if (prop.binding == MemberBinding.INSTANCE) {
+ if (is_virtual) {
+ if (prop.base_property != null) {
+ base_type = new ObjectType ((ObjectTypeSymbol) prop.base_property.parent_symbol);
+ } else if (prop.base_interface_property != null) {
+ base_type = new ObjectType ((ObjectTypeSymbol) prop.base_interface_property.parent_symbol);
+ }
+ }
+ }
+
+
+ var parameters = ccode.parameters ();
+ if (prop.binding == MemberBinding.INSTANCE) {
+ if (is_virtual) {
+ parameters.add (new CCodeFormalParameter ("base", base_type.get_cname ()));
+ } else {
+ parameters.add (cselfparam);
+ }
+ }
+ if (acc.writable || acc.construction || returns_real_struct) {
+ parameters.add (cvalueparam);
+ }
+
+ CCodeModifiers modifiers = 0;
+ if (prop.is_private_symbol () || !(acc.readable || acc.writable) || acc.access == SymbolAccessibility.PRIVATE) {
+ // accessor function should be private if the property is an internal symbol or it's a construct-only setter
+ modifiers = CCodeModifiers.STATIC;
+ }
+
+ ccode.open_function (cname, return_type, parameters, modifiers);
+
+ if (acc.readable && !returns_real_struct) {
+ // do not declare result variable if exit block is known to be unreachable
+ if (acc.return_block == null || acc.return_block.get_predecessors ().size > 0) {
+ ccode.write_declaration (acc.value_type.get_cname (), new CCodeVariableDeclarator ("result"));
+ }
+ }
+
+ if (is_virtual) {
+ ccode.write_declaration (this_type.get_cname (), new CCodeVariableDeclarator ("self"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), transform_expression (new CCodeIdentifier ("base"), base_type, this_type)));
+ }
+
+ if (acc.body != null) {
+ acc.body.emit (this);
+ }
+
+ ccode.close ();
+
if (prop.is_abstract || prop.is_virtual) {
if (acc.readable && !returns_real_struct) {
function = new CCodeFunction (acc.get_cname (), current_return_type.get_cname ());
@@ -1549,33 +1624,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (!prop.is_abstract) {
- bool is_virtual = prop.base_property != null || prop.base_interface_property != null;
-
- string cname;
- if (is_virtual) {
- if (acc.readable) {
- cname = "%s_real_get_%s".printf (t.get_lower_case_cname (null), prop.name);
- } else {
- cname = "%s_real_set_%s".printf (t.get_lower_case_cname (null), prop.name);
- }
- } else {
- cname = acc.get_cname ();
- }
-
if (acc.writable || acc.construction || returns_real_struct) {
function = new CCodeFunction (cname, "void");
} else {
function = new CCodeFunction (cname, acc.value_type.get_cname ());
}
- ObjectType base_type = null;
if (prop.binding == MemberBinding.INSTANCE) {
if (is_virtual) {
- if (prop.base_property != null) {
- base_type = new ObjectType ((ObjectTypeSymbol) prop.base_property.parent_symbol);
- } else if (prop.base_interface_property != null) {
- base_type = new ObjectType ((ObjectTypeSymbol) prop.base_interface_property.parent_symbol);
- }
function.modifiers |= CCodeModifiers.STATIC;
function.add_parameter (new CCodeFormalParameter ("base", base_type.get_cname ()));
} else {
@@ -1608,22 +1664,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- function.block = (CCodeBlock) acc.body.ccodenode;
-
- if (is_virtual) {
- var cdecl = new CCodeDeclaration (this_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", transform_expression (new CCodeIdentifier ("base"), base_type, this_type)));
- function.block.prepend_statement (cdecl);
- }
-
- if (acc.readable && !returns_real_struct) {
- // do not declare result variable if exit block is known to be unreachable
- if (acc.return_block == null || acc.return_block.get_predecessors ().size > 0) {
- var cdecl = new CCodeDeclaration (acc.value_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
- function.block.prepend_statement (cdecl);
- }
- }
+ function.block = emit_context.ccode.get_block ();
if (current_method_inner_error) {
var cdecl = new CCodeDeclaration ("GError *");
@@ -1653,37 +1694,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
function.block.add_statement (new CCodeExpressionStatement (notify_call));
}
- source_type_member_definition.append (function);
+ source_type_member_definition.append (emit_context.ccode.get_node ());
}
pop_context ();
}
public override void visit_destructor (Destructor d) {
- bool old_method_inner_error = current_method_inner_error;
- current_method_inner_error = false;
-
- d.body.emit (this);
-
if (d.binding == MemberBinding.STATIC && !in_plugin) {
Report.error (d.source_reference, "static destructors are only supported for dynamic types");
d.error = true;
return;
}
-
- CCodeFragment cfrag = new CCodeFragment ();
-
- if (current_method_inner_error) {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- cfrag.append (cdecl);
- }
-
- cfrag.append (d.body.ccodenode);
-
- d.ccodenode = cfrag;
-
- current_method_inner_error = old_method_inner_error;
}
public int get_block_id (Block b) {
@@ -1695,7 +1717,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return result;
}
- void capture_parameter (FormalParameter param, CCodeStruct data, CCodeBlock cblock, int block_id, CCodeBlock free_block) {
+ void capture_parameter (FormalParameter param, CCodeStruct data, int block_id, CCodeBlock free_block) {
generate_type_declaration (param.variable_type, source_declarations);
var param_type = param.variable_type.copy ();
@@ -1719,20 +1741,20 @@ public class Vala.CCodeBaseModule : CodeGenerator {
param.captured = true;
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam));
if (param.variable_type is ArrayType) {
var array_type = (ArrayType) param.variable_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim))));
}
} else if (param.variable_type is DelegateType) {
data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))));
if (param.variable_type.value_owned) {
data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)))));
}
}
@@ -1757,16 +1779,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public override void visit_block (Block b) {
emit_context.push_symbol (b);
- foreach (Statement stmt in b.get_statements ()) {
- stmt.emit (this);
- }
-
var local_vars = b.get_local_variables ();
- foreach (LocalVariable local in local_vars) {
- local.active = false;
+
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.write_begin_block ();
}
-
- var cblock = new CCodeBlock ();
if (b.captured) {
var parent_block = next_closure_block (b.parent_symbol);
@@ -1842,15 +1859,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (struct_name + "*", "_data%d_".printf (block_id));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_data%d_".printf (block_id)), data_alloc)));
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression ("_data%d_".printf (block_id)), data_alloc));
} else {
- var data_decl = new CCodeDeclaration (struct_name + "*");
- data_decl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc));
- cblock.add_statement (data_decl);
+ ccode.write_declaration (struct_name + "*", new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc));
}
// initialize ref_count
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_ref_count_"), new CCodeIdentifier ("1"))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_ref_count_"), new CCodeIdentifier ("1")));
if (parent_block != null) {
int parent_block_id = get_block_id (parent_block);
@@ -1858,14 +1873,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (parent_block_id)));
ref_call.add_argument (get_variable_cexpression ("_data%d_".printf (parent_block_id)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call));
} else if (in_constructor || (current_method != null && current_method.binding == MemberBinding.INSTANCE &&
(!(current_method is CreationMethod) || current_method.body != b)) ||
(current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) {
var ref_call = new CCodeFunctionCall (get_dup_func_expression (new ObjectType (current_class), b.source_reference));
ref_call.add_argument (get_result_cexpression ("self"));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), ref_call)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), ref_call));
}
if (b.parent_symbol is Method) {
@@ -1874,7 +1889,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// parameters are captured with the top-level block of the method
foreach (var param in m.get_parameters ()) {
if (param.captured) {
- capture_parameter (param, data, cblock, block_id, free_block);
+ capture_parameter (param, data, block_id, free_block);
}
}
@@ -1884,24 +1899,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// async method is suspended while waiting for callback,
// so we never need to care about memory management of async data
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_async_data_"), new CCodeIdentifier ("data"))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_async_data_"), new CCodeIdentifier ("data")));
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
} else if (b.parent_symbol is PropertyAccessor) {
var acc = (PropertyAccessor) b.parent_symbol;
if (!acc.readable && acc.value_parameter.captured) {
- capture_parameter (acc.value_parameter, data, cblock, block_id, free_block);
+ capture_parameter (acc.value_parameter, data, block_id, free_block);
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
}
var typedef = new CCodeTypeDefinition ("struct _" + struct_name, new CCodeVariableDeclarator (struct_name));
@@ -1939,28 +1944,19 @@ public class Vala.CCodeBaseModule : CodeGenerator {
source_type_member_definition.append (unref_fun);
}
- foreach (CodeNode stmt in b.get_statements ()) {
- if (stmt.error || stmt.unreachable) {
- continue;
- }
-
- if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (stmt.ccodenode);
- }
+ foreach (Statement stmt in b.get_statements ()) {
+ stmt.emit (this);
}
// free in reverse order
for (int i = local_vars.size - 1; i >= 0; i--) {
var local = local_vars[i];
+ local.active = false;
if (!local.unreachable && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -1971,7 +1967,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
ma.value_type = param.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
}
}
}
@@ -1981,10 +1977,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cblock.add_statement (new CCodeExpressionStatement (data_unref));
+ ccode.write_expression (data_unref);
}
- b.ccodenode = cblock;
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.write_end_block ();
+ }
emit_context.pop_symbol ();
}
@@ -1995,16 +1993,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public override void visit_declaration_statement (DeclarationStatement stmt) {
stmt.declaration.accept (this);
-
- stmt.ccodenode = stmt.declaration.ccodenode;
-
- var local = stmt.declaration as LocalVariable;
- if (local != null && local.initializer != null) {
- create_temp_decl (stmt, local.initializer.temp_vars);
- }
-
- create_temp_decl (stmt, temp_vars);
- temp_vars.clear ();
}
public CCodeExpression get_variable_cexpression (string name) {
@@ -2071,12 +2059,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (!array_type.fixed_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
var len_var = new LocalVariable (int_type.copy (), get_array_length_cname (get_variable_cname (local.name), dim));
- temp_vars.add (len_var);
+ emit_temp_var (len_var);
}
if (array_type.rank == 1) {
var size_var = new LocalVariable (int_type.copy (), get_array_size_cname (get_variable_cname (local.name)));
- temp_vars.add (size_var);
+ emit_temp_var (size_var);
}
}
} else if (local.variable_type is DelegateType) {
@@ -2085,10 +2073,10 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (d.has_target) {
// create variable to store delegate target
var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_variable_cname (local.name)));
- temp_vars.add (target_var);
+ emit_temp_var (target_var);
if (deleg_type.value_owned) {
var target_destroy_notify_var = new LocalVariable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
- temp_vars.add (target_destroy_notify_var);
+ emit_temp_var (target_destroy_notify_var);
}
}
}
@@ -2111,7 +2099,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (local.variable_type, true, local, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), rhs));
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -2136,7 +2124,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (local.variable_type, true, local, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), rhs));
CCodeExpression lhs_delegate_target_destroy_notify;
@@ -2185,19 +2173,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- var cfrag = new CCodeFragment ();
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
if (local.captured) {
if (local.initializer != null) {
if (has_simple_struct_initializer (local)) {
- cfrag.append (new CCodeExpressionStatement (rhs));
+ ccode.write_expression (rhs);
} else {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs));
}
}
} else if (current_method != null && current_method.coroutine) {
@@ -2205,9 +2186,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (local.initializer != null) {
if (has_simple_struct_initializer (local)) {
- cfrag.append (new CCodeExpressionStatement (rhs));
+ ccode.write_expression (rhs);
} else {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (local.name)), rhs)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (local.name)), rhs));
}
}
} else {
@@ -2222,10 +2203,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cvar.line = rhs.line;
}
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
- cdecl.add_declarator (cvar);
- cfrag.append (cdecl);
-
// try to initialize uninitialized variables
// initialization not necessary for variables stored in closure
if (cvar.initializer == null) {
@@ -2233,8 +2210,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cvar.init0 = true;
}
+ ccode.write_declaration (local.variable_type.get_cname (), cvar);
+
+ if (cvar.initializer != null && !cvar.init0) {
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (local.name), rhs));
+ }
+
if (post_stmt != null) {
- cfrag.append (post_stmt);
+ ccode.append (post_stmt);
}
}
@@ -2254,16 +2237,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccopy.add_argument (get_variable_cexpression (local.name));
ccopy.add_argument ((CCodeExpression) local.initializer.ccodenode);
ccopy.add_argument (size);
- cfrag.append (new CCodeExpressionStatement (ccopy));
+ ccode.write_expression (ccopy);
}
}
if (local.initializer != null && local.initializer.tree_can_fail) {
- add_simple_check (local.initializer, cfrag);
+ add_simple_check (local.initializer);
}
- local.ccodenode = cfrag;
-
local.active = true;
}
@@ -2301,7 +2282,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
} else {
// used as expression
var temp_decl = get_temp_variable (list.target_type, false, list);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
@@ -3105,19 +3086,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
* we unref temporary variables at the end of a full
* expression
*/
-
- /* can't automatically deep copy lists yet, so do it
- * manually for now
- * replace with
- * expr.temp_vars = temp_vars;
- * when deep list copying works
- */
- expr.temp_vars.clear ();
- foreach (LocalVariable local in temp_vars) {
- expr.temp_vars.add (local);
- }
- temp_vars.clear ();
-
if (((List<LocalVariable>) temp_ref_vars).size == 0) {
/* nothing to do without temporary variables */
return;
@@ -3137,7 +3105,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
full_expr_var = get_temp_variable (expr_type, true, expr, false);
- expr.temp_vars.add (full_expr_var);
+ emit_temp_var (full_expr_var);
expr_list.append_expression (new CCodeAssignment (get_variable_cexpression (full_expr_var.name), (CCodeExpression) expr.ccodenode));
}
@@ -3158,62 +3126,57 @@ public class Vala.CCodeBaseModule : CodeGenerator {
temp_ref_vars.clear ();
}
- public void append_temp_decl (CCodeFragment cfrag, List<LocalVariable> temp_vars) {
- foreach (LocalVariable local in temp_vars) {
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
-
- var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
- // sets #line
- local.ccodenode = vardecl;
- cdecl.add_declarator (vardecl);
-
- var st = local.variable_type.data_type as Struct;
- var array_type = local.variable_type as ArrayType;
-
- if (local.name.has_prefix ("*")) {
- // do not dereference unintialized variable
- // initialization is not needed for these special
- // pointer temp variables
- // used to avoid side-effects in assignments
- } else if (local.no_init) {
- // no initialization necessary for this temp var
- } else if (!local.variable_type.nullable &&
- (st != null && !st.is_simple_type ()) ||
- (array_type != null && array_type.fixed_length)) {
- // 0-initialize struct with struct initializer { 0 }
- // necessary as they will be passed by reference
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
+ public void emit_temp_var (LocalVariable local) {
+ var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
+ // sets #line
+ local.ccodenode = vardecl;
- vardecl.initializer = clist;
- vardecl.init0 = true;
- } else if (local.variable_type.is_reference_type_or_type_parameter () ||
- local.variable_type.nullable ||
- local.variable_type is DelegateType) {
- vardecl.initializer = new CCodeConstant ("NULL");
- vardecl.init0 = true;
- }
+ var st = local.variable_type.data_type as Struct;
+ var array_type = local.variable_type as ArrayType;
+
+ if (local.name.has_prefix ("*")) {
+ // do not dereference unintialized variable
+ // initialization is not needed for these special
+ // pointer temp variables
+ // used to avoid side-effects in assignments
+ } else if (local.no_init) {
+ // no initialization necessary for this temp var
+ } else if (!local.variable_type.nullable &&
+ (st != null && !st.is_simple_type ()) ||
+ (array_type != null && array_type.fixed_length)) {
+ // 0-initialize struct with struct initializer { 0 }
+ // necessary as they will be passed by reference
+ var clist = new CCodeInitializerList ();
+ clist.append (new CCodeConstant ("0"));
- if (current_method != null && current_method.coroutine) {
- closure_struct.add_field (local.variable_type.get_cname (), local.name);
+ vardecl.initializer = clist;
+ vardecl.init0 = true;
+ } else if (local.variable_type.is_reference_type_or_type_parameter () ||
+ local.variable_type.nullable ||
+ local.variable_type is DelegateType) {
+ vardecl.initializer = new CCodeConstant ("NULL");
+ vardecl.init0 = true;
+ }
- // even though closure struct is zerod, we need to initialize temporary variables
- // as they might be used multiple times when declared in a loop
+ if (current_method != null && current_method.coroutine) {
+ closure_struct.add_field (local.variable_type.get_cname (), local.name);
- if (vardecl.initializer is CCodeInitializerList) {
- // C does not support initializer lists in assignments, use memset instead
- source_declarations.add_include ("string.h");
- var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name)));
- memset_call.add_argument (new CCodeConstant ("0"));
- memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (local.variable_type.get_cname ())));
- cfrag.append (new CCodeExpressionStatement (memset_call));
- } else if (vardecl.initializer != null) {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (local.name), vardecl.initializer)));
- }
- } else {
- cfrag.append (cdecl);
+ // even though closure struct is zerod, we need to initialize temporary variables
+ // as they might be used multiple times when declared in a loop
+
+ if (vardecl.initializer is CCodeInitializerList) {
+ // C does not support initializer lists in assignments, use memset instead
+ source_declarations.add_include ("string.h");
+ var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name)));
+ memset_call.add_argument (new CCodeConstant ("0"));
+ memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (local.variable_type.get_cname ())));
+ ccode.write_expression (memset_call);
+ } else if (vardecl.initializer != null) {
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (local.name), vardecl.initializer));
}
+ } else {
+ ccode.write_declaration (local.variable_type.get_cname (), vardecl);
}
}
@@ -3223,62 +3186,26 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return;
}
- stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
+ ccode.write_expression ((CCodeExpression) stmt.expression.ccodenode);
/* free temporary objects and handle errors */
- if (((List<LocalVariable>) temp_vars).size == 0
- && pre_statement_fragment == null
- && (!stmt.tree_can_fail || !stmt.expression.tree_can_fail)) {
- /* nothing to do without temporary variables and errors */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
- cfrag.append (stmt.ccodenode);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
// simple case, no node breakdown necessary
- add_simple_check (stmt.expression, cfrag);
+ add_simple_check (stmt.expression);
}
- stmt.ccodenode = cfrag;
-
- temp_vars.clear ();
temp_ref_vars.clear ();
}
-
- public void create_temp_decl (Statement stmt, List<LocalVariable> temp_vars) {
- /* declare temporary variables */
-
- if (temp_vars.size == 0) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- cfrag.append (stmt.ccodenode);
-
- stmt.ccodenode = cfrag;
- }
- public virtual void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public virtual void append_local_free (Symbol sym, bool stop_at_loop = false) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -3289,7 +3216,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -3298,7 +3225,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.write_expression (data_unref);
}
if (stop_at_loop) {
@@ -3310,13 +3237,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_local_free (sym.parent_symbol, cfrag, stop_at_loop);
+ append_local_free (sym.parent_symbol, stop_at_loop);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- public void append_error_free (Symbol sym, CCodeFragment cfrag, TryStatement current_try) {
+ public void append_error_free (Symbol sym, TryStatement current_try) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -3326,7 +3253,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (!local.unreachable && local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -3335,7 +3262,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.write_expression (data_unref);
}
if (sym == current_try.body) {
@@ -3343,32 +3270,23 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_error_free (sym.parent_symbol, cfrag, current_try);
+ append_error_free (sym.parent_symbol, current_try);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- private void append_param_free (Method m, CCodeFragment cfrag) {
+ private void append_param_free (Method m) {
foreach (FormalParameter param in m.get_parameters ()) {
if (!param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
ma.value_type = param.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
}
}
}
- public void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
- var cfrag = new CCodeFragment ();
-
- append_local_free (current_symbol, cfrag, stop_at_loop);
-
- cfrag.append (stmt.ccodenode);
- stmt.ccodenode = cfrag;
- }
-
public bool variable_accessible_in_finally (LocalVariable local) {
if (current_try == null) {
return false;
@@ -3427,7 +3345,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
stmt.return_expression.ccodenode = ccomma;
- stmt.return_expression.temp_vars.add (return_expr_decl);
+ emit_temp_var (return_expr_decl);
} else if ((current_method != null || current_property_accessor != null) && current_return_type is DelegateType) {
var delegate_type = (DelegateType) current_return_type;
if (delegate_type.delegate_symbol.has_target) {
@@ -3454,52 +3372,37 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
stmt.return_expression.ccodenode = ccomma;
- stmt.return_expression.temp_vars.add (return_expr_decl);
+ emit_temp_var (return_expr_decl);
}
}
- var cfrag = new CCodeFragment ();
-
if (stmt.return_expression != null) {
// assign method result to `result'
CCodeExpression result_lhs = get_result_cexpression ();
if (current_return_type.is_real_non_null_struct_type () && (current_method == null || !current_method.coroutine)) {
result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs);
}
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode)));
+ ccode.write_expression (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode));
}
// free local variables
- append_local_free (current_symbol, cfrag);
+ append_local_free (current_symbol);
if (current_method != null) {
// check postconditions
foreach (Expression postcondition in current_method.get_postconditions ()) {
- cfrag.append (create_postcondition_statement (postcondition));
+ ccode.append (create_postcondition_statement (postcondition));
}
}
- CCodeReturnStatement creturn = null;
if (current_method is CreationMethod) {
- creturn = new CCodeReturnStatement (new CCodeIdentifier ("self"));
- cfrag.append (creturn);
+ ccode.write_return (new CCodeIdentifier ("self"));
} else if (current_method != null && current_method.coroutine) {
} else if (current_return_type is VoidType || current_return_type.is_real_non_null_struct_type ()) {
// structs are returned via out parameter
- creturn = new CCodeReturnStatement ();
- cfrag.append (creturn);
+ ccode.write_return ();
} else {
- creturn = new CCodeReturnStatement (new CCodeIdentifier ("result"));
- cfrag.append (creturn);
- }
-
- stmt.ccodenode = cfrag;
- if (creturn != null) {
- creturn.line = stmt.ccodenode.line;
- }
-
- if (stmt.return_expression != null) {
- create_temp_decl (stmt, stmt.return_expression.temp_vars);
+ ccode.write_return (new CCodeIdentifier ("result"));
}
if (return_expression_symbol != null) {
@@ -3668,7 +3571,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
var regex_var = get_temp_variable (regex_type, true, expr, false);
- expr.temp_vars.add (regex_var);
+ emit_temp_var (regex_var);
var cdecl = new CCodeDeclaration ("GRegex*");
@@ -3756,7 +3659,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// assign current value to temp variable
var temp_decl = get_temp_variable (prop.property_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), (CCodeExpression) expr.inner.ccodenode));
// increment/decrement property
@@ -3867,7 +3770,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// (copy (&expr, &temp), temp)
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -3967,7 +3870,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return ccall;
} else {
var decl = get_temp_variable (expression_type, false, node, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -4190,7 +4093,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
} else {
var temp_decl = get_temp_variable (expr.type_reference, false, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
}
@@ -4487,7 +4390,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (param.variable_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -4559,7 +4462,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
expr.append_array_size (len_call);
} else if (to is StructValueType) {
var temp_decl = get_temp_variable (to, true, null, true);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var ctemp = get_variable_cexpression (temp_decl.name);
rv = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeCastExpression (rv, (new PointerType(to)).get_cname ()));
@@ -4607,7 +4510,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var temp_decl = get_temp_variable (int_type, false, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
cfunc.add_parameter (new CCodeFormalParameter (get_array_length_cname ("result", dim), "int*"));
@@ -4661,7 +4564,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.inner.value_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var ctemp = get_variable_cexpression (temp_decl.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) expr.inner.ccodenode);
@@ -4725,7 +4628,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
/* (tmp = var, var = null, tmp) */
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.value_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression) expr.inner.ccodenode));
@@ -4743,7 +4646,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var lbe = (BinaryExpression) expr.left;
var temp_decl = get_temp_variable (lbe.right.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
var clbe = (CCodeBinaryExpression) lbe.ccodenode;
@@ -5125,7 +5028,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// treat void* special to not leak memory with void* method parameters
} else if (requires_destroy (expression_type)) {
var decl = get_temp_variable (expression_type, true, expression_type, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
temp_ref_vars.insert (0, decl);
cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr);
@@ -5135,7 +5038,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (cexpr);
for (int dim = 1; dim <= array_type.rank; dim++) {
var len_decl = new LocalVariable (int_type.copy (), get_array_length_cname (decl.name, dim));
- temp_vars.add (len_decl);
+ emit_temp_var (len_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (len_decl.name), get_array_length_cexpression (expr, dim)));
}
ccomma.append_expression (get_variable_cexpression (decl.name));
@@ -5145,9 +5048,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (cexpr);
var target_decl = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (decl.name));
- temp_vars.add (target_decl);
+ emit_temp_var (target_decl);
var target_destroy_notify_decl = new LocalVariable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")), get_delegate_target_destroy_notify_cname (decl.name));
- temp_vars.add (target_destroy_notify_decl);
+ emit_temp_var (target_destroy_notify_decl);
CCodeExpression target_destroy_notify;
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (target_decl.name), get_delegate_target_cexpression (expr, out target_destroy_notify)));
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (target_destroy_notify_decl.name), target_destroy_notify));
@@ -5166,7 +5069,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (gvalue_boxing) {
// implicit conversion to GValue
var decl = get_temp_variable (target_type, true, target_type);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ccomma = new CCodeCommaExpression ();
@@ -5258,7 +5161,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
} else {
var decl = get_temp_variable (expression_type, expression_type.value_owned, expression_type, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (decl.name), cexpr));
@@ -5380,7 +5283,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -5401,7 +5304,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
CCodeExpression rv;
if (array_type != null && !prop.no_array_length) {
var temp_var = get_temp_variable (prop.property_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccall.add_argument (get_variable_cexpression (temp_var.name));
@@ -5455,7 +5358,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (e.value_type, true, null, false);
var ctemp = get_variable_cexpression (temp_decl.name);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (ctemp, ce));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
return ccomma;
@@ -5725,9 +5628,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
-
pop_context ();
source_declarations.add_type_member_declaration (function.copy ());
@@ -5811,7 +5711,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return new CCodeConstant ("");
}
- public virtual void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
+ public virtual void add_simple_check (CodeNode node, bool always_fails = false) {
}
}
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index 00a31a8..0d9d185 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -26,24 +26,22 @@ using GLib;
public class Vala.CCodeControlFlowModule : CCodeMethodModule {
public override void visit_if_statement (IfStatement stmt) {
+ ccode.open_if (stmt.condition.ccodenode);
+
stmt.true_statement.emit (this);
+
if (stmt.false_statement != null) {
+ ccode.add_else ();
stmt.false_statement.emit (this);
}
- if (stmt.false_statement != null) {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
- } else {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
- }
-
- create_temp_decl (stmt, stmt.condition.temp_vars);
+ ccode.close ();
}
- void visit_string_switch_statement (SwitchStatement stmt) {
+ /*void visit_string_switch_statement (SwitchStatement stmt) {
// we need a temporary variable to save the property value
var temp_var = get_temp_variable (stmt.expression.value_type, stmt.expression.value_type.value_owned, stmt, false);
- stmt.expression.temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ctemp = get_variable_cexpression (temp_var.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
@@ -62,7 +60,7 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
temp_var = get_temp_variable (gquark_type);
- stmt.expression.temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
int label_count = 0;
@@ -92,7 +90,6 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
cinit = new CCodeAssignment (ctemp, ccond);
cswitchblock.append (new CCodeExpressionStatement (cinit));
- create_temp_decl (stmt, stmt.expression.temp_vars);
if (stmt.expression.value_type.value_owned) {
// free owned string
@@ -185,40 +182,24 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
}
cswitchblock.append (ctopstmt);
- }
+ }*/
public override void visit_switch_statement (SwitchStatement stmt) {
- foreach (SwitchSection section in stmt.get_sections ()) {
- section.emit (this);
- }
-
- if (stmt.expression.value_type.compatible (string_type)) {
+ /*if (stmt.expression.value_type.compatible (string_type)) {
visit_string_switch_statement (stmt);
return;
- }
+ }*/
- var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
- stmt.ccodenode = cswitch;
+ ccode.open_switch ((CCodeExpression) stmt.expression.ccodenode);
foreach (SwitchSection section in stmt.get_sections ()) {
if (section.has_default_label ()) {
- cswitch.add_statement (new CCodeLabel ("default"));
- var cdefaultblock = new CCodeBlock ();
- cswitch.add_statement (cdefaultblock);
- foreach (CodeNode default_stmt in section.get_statements ()) {
- cdefaultblock.add_statement (default_stmt.ccodenode);
- }
- continue;
+ ccode.add_default ();
}
-
- foreach (SwitchLabel label in section.get_labels ()) {
- cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
- }
-
- cswitch.add_statement (section.ccodenode);
+ section.emit (this);
}
-
- create_temp_decl (stmt, stmt.expression.temp_vars);
+
+ ccode.close ();
}
public override void visit_switch_label (SwitchLabel label) {
@@ -226,33 +207,27 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
label.expression.emit (this);
visit_end_full_expression (label.expression);
+
+ ccode.add_case ((CCodeExpression) label.expression.ccodenode);
}
}
public override void visit_loop (Loop stmt) {
- stmt.body.emit (this);
-
if (context.profile == Profile.GOBJECT) {
- stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("TRUE"), (CCodeStatement) stmt.body.ccodenode);
+ ccode.open_while (new CCodeConstant ("TRUE"));
} else {
source_declarations.add_include ("stdbool.h");
- stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("true"), (CCodeStatement) stmt.body.ccodenode);
+ ccode.open_while (new CCodeConstant ("true"));
}
- }
- public override void visit_foreach_statement (ForeachStatement stmt) {
stmt.body.emit (this);
- visit_block (stmt);
+ ccode.close ();
+ }
- var cblock = new CCodeBlock ();
- // sets #line
- stmt.ccodenode = cblock;
+ public override void visit_foreach_statement (ForeachStatement stmt) {
+ ccode.write_begin_block ();
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, stmt.collection.temp_vars);
- cblock.add_statement (cfrag);
-
var collection_backup = stmt.collection_variable;
var collection_type = collection_backup.variable_type.copy ();
@@ -264,20 +239,15 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (collection_type.get_cname (), collection_backup.name);
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (collection_backup.name), (CCodeExpression) stmt.collection.ccodenode)));
} else {
- var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
- var ccolvardecl = new CCodeVariableDeclarator (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
- ccolvardecl.line = cblock.line;
- ccoldecl.add_declarator (ccolvardecl);
- cblock.add_statement (ccoldecl);
+ var ccolvardecl = new CCodeVariableDeclarator (collection_backup.name);
+ ccode.write_declaration (collection_type.get_cname (), ccolvardecl);
}
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (collection_backup.name), (CCodeExpression) stmt.collection.ccodenode));
if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
// exception handling
- cfrag = new CCodeFragment ();
- add_simple_check (stmt.collection, cfrag);
- cblock.add_statement (cfrag);
+ add_simple_check (stmt.collection);
}
if (stmt.collection.value_type is ArrayType) {
@@ -288,24 +258,24 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
// store array length for use by _vala_array_free
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", get_array_length_cname (collection_backup.name, 1));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (collection_backup.name, 1)), array_len)));
} else {
- var clendecl = new CCodeDeclaration ("int");
- clendecl.add_declarator (new CCodeVariableDeclarator (get_array_length_cname (collection_backup.name, 1), array_len));
- cblock.add_statement (clendecl);
+ ccode.write_declaration ("int", new CCodeVariableDeclarator (get_array_length_cname (collection_backup.name, 1)));
}
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (collection_backup.name, 1)), array_len));
var it_name = (stmt.variable_name + "_it");
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", it_name);
} else {
- var citdecl = new CCodeDeclaration ("int");
- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
- cblock.add_statement (citdecl);
+ ccode.write_declaration ("int", new CCodeVariableDeclarator (it_name));
}
-
- var cbody = new CCodeBlock ();
+
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (collection_backup.name), get_variable_cexpression (it_name));
@@ -313,19 +283,12 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_type.value_owned = false;
element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator (stmt.variable_name, element_expr));
- cbody.add_statement (cdecl);
+ ccode.write_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
// add array length variable for stacked arrays
if (stmt.type_reference is ArrayType) {
@@ -333,23 +296,16 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
for (int dim = 1; dim <= inner_array_type.rank; dim++) {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", get_array_length_cname (stmt.variable_name, dim));
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (stmt.variable_name, dim)), new CCodeConstant ("-1"))));
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (stmt.variable_name, dim)), new CCodeConstant ("-1")));
} else {
- var cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator (get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
- cbody.add_statement (cdecl);
+ ccode.write_declaration ("int", new CCodeVariableDeclarator (get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
}
}
}
- cbody.add_statement (stmt.body.ccodenode);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
+ stmt.body.emit (this);
- var cfor = new CCodeForStatement (ccond, cbody);
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
- cblock.add_statement (cfor);
+ ccode.close ();
} else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
// iterating over a GList or GSList
@@ -358,14 +314,14 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (collection_type.get_cname (), it_name);
} else {
- var citdecl = new CCodeDeclaration (collection_type.get_cname ());
- var citvardecl = new CCodeVariableDeclarator (it_name);
- citvardecl.line = cblock.line;
- citdecl.add_declarator (citvardecl);
- cblock.add_statement (citdecl);
+ ccode.write_declaration (collection_type.get_cname (), new CCodeVariableDeclarator (it_name));
}
- var cbody = new CCodeBlock ();
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (collection_backup.name)),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
CCodeExpression element_expr = new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "data");
@@ -380,32 +336,16 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_expr = convert_from_generic_pointer (element_expr, element_data_type);
element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- cbody.add_statement (cdecl);
+ ccode.write_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
-
- cbody.add_statement (stmt.body.ccodenode);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
-
- var cfor = new CCodeForStatement (ccond, cbody);
-
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (collection_backup.name)));
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
+
+ stmt.body.emit (this);
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
- cblock.add_statement (cfor);
+ ccode.close ();
} else if (stmt.collection.value_type.compatible (new ObjectType (gvaluearray_type))) {
// iterating over a GValueArray
@@ -414,14 +354,14 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (uint_type.get_cname (), arr_index);
} else {
- var citdecl = new CCodeDeclaration (uint_type.get_cname ());
- var citvardecl = new CCodeVariableDeclarator (arr_index);
- citvardecl.line = cblock.line;
- citdecl.add_declarator (citvardecl);
- cblock.add_statement (citdecl);
+ ccode.write_declaration (uint_type.get_cname (), new CCodeVariableDeclarator (arr_index));
}
- var cbody = new CCodeBlock ();
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values"));
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth"));
get_item.add_argument (get_variable_cexpression (collection_backup.name));
@@ -433,56 +373,39 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_expr = get_ref_cexpression (stmt.type_reference, element_expr, null, new StructValueType (gvalue_type));
}
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- cbody.add_statement (cdecl);
+ ccode.write_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
- cbody.add_statement (stmt.body.ccodenode);
+ stmt.body.emit (this);
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values"));
-
- var cfor = new CCodeForStatement (ccond, cbody);
-
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")));
-
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
-
- cblock.add_statement (cfor);
+ ccode.close ();
}
foreach (LocalVariable local in stmt.get_local_variables ()) {
if (requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- var cunref = new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
- cunref.line = cblock.line;
- cblock.add_statement (cunref);
+ ccode.write_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
+
+ ccode.write_end_block ();
}
public override void visit_break_statement (BreakStatement stmt) {
- stmt.ccodenode = new CCodeBreakStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_break ();
}
public override void visit_continue_statement (ContinueStatement stmt) {
- stmt.ccodenode = new CCodeContinueStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_continue ();
}
}
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index d96a8a7..d18c5bc 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -69,7 +69,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
// instance expression has side-effects
// store in temp. variable
var temp_var = get_temp_variable (expr.inner.value_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ctemp = get_variable_cexpression (temp_var.name);
inst = new CCodeAssignment (ctemp, pub_inst);
expr.inner.ccodenode = ctemp;
@@ -264,7 +264,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), pub_inst));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -281,7 +281,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (base_property.get_accessor.value_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
ccomma.append_expression (ccall);
ccomma.append_expression (ctemp);
@@ -292,7 +292,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
for (int dim = 1; dim <= array_type.rank; dim++) {
var temp_var = get_temp_variable (int_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
expr.append_array_size (ctemp);
}
@@ -301,7 +301,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
expr.delegate_target = ctemp;
}
@@ -332,7 +332,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
ccall.add_argument (new CCodeConstant ("NULL"));
ccomma.append_expression (ccall);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index c3a03e7..0543d07 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -195,7 +195,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -348,14 +348,14 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
if (param.array_length_type != null) {
if (param.direction == ParameterDirection.OUT) {
var temp_array_length = get_temp_variable (new CType (param.array_length_type));
- temp_vars.add (temp_array_length);
+ emit_temp_var (temp_array_length);
array_length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_array_length.name));
var comma = new CCodeCommaExpression ();
LocalVariable? temp_result = null;
if (!(m.return_type is VoidType)) {
temp_result = get_temp_variable (m.return_type);
- temp_vars.add (temp_result);
+ emit_temp_var (temp_result);
ccall_expr = new CCodeAssignment (get_variable_cexpression (temp_result.name), ccall_expr);
}
@@ -425,7 +425,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (arg.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), cexpr));
cexpr = get_variable_cexpression (temp_decl.name);
@@ -446,7 +446,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
if (param.direction == ParameterDirection.REF) {
@@ -463,14 +463,14 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
ccomma.append_expression (ccall_expr);
} else {
ret_temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
- temp_vars.add (ret_temp_var);
+ emit_temp_var (ret_temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr));
}
var cassign_comma = new CCodeCommaExpression ();
var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned, null, false);
- temp_vars.add (assign_temp_var);
+ emit_temp_var (assign_temp_var);
cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg)));
@@ -530,7 +530,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall_expr = new CCodeAssignment (temp_ref, ccall_expr);
@@ -549,7 +549,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -565,7 +565,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -575,7 +575,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
temp_var = get_temp_variable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")));
temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position + 0.01), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -594,7 +594,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall_expr = new CCodeAssignment (temp_ref, ccall_expr);
@@ -607,7 +607,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (int_type);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (deleg.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -623,7 +623,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (deleg.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -680,7 +680,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type ());
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (-3), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -738,20 +738,16 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
if (expr.is_yield_expression) {
- if (pre_statement_fragment == null) {
- pre_statement_fragment = new CCodeFragment ();
- }
-
// set state before calling async function to support immediate callbacks
int state = next_coroutine_state++;
state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
state_switch_statement.add_statement (new CCodeGotoStatement ("_state_%d".printf (state)));
- pre_statement_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ()))));
- pre_statement_fragment.append (new CCodeExpressionStatement (async_call));
- pre_statement_fragment.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
- pre_statement_fragment.append (new CCodeLabel ("_state_%d".printf (state)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ())));
+ ccode.write_expression (async_call);
+ ccode.write_return (new CCodeConstant ("FALSE"));
+ ccode.add_label ("_state_%d".printf (state));
}
if (m is ArrayResizeMethod) {
@@ -763,7 +759,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_decl = get_temp_variable (int_type);
var temp_ref = get_variable_cexpression (temp_decl.name);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
/* memset needs string.h */
source_declarations.add_include ("string.h");
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 747631d..df716a7 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -307,6 +307,30 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
m.result_var.accept (this);
}
+
+ function = new CCodeFunction (m.get_real_cname ());
+
+ if (m.is_inline) {
+ function.modifiers |= CCodeModifiers.INLINE;
+ }
+
+ if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) {
+ if (!m.coroutine) {
+ if (m.base_method != null || m.base_interface_method != null) {
+ // declare *_real_* function
+ function.modifiers |= CCodeModifiers.STATIC;
+ } else if (m.is_private_symbol ()) {
+ function.modifiers |= CCodeModifiers.STATIC;
+ }
+ }
+ }
+
+ var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+ generate_cparameters (m, source_declarations, cparam_map, function);
+
+ ccode.open_function (function.name, function.return_type, function.parameters, function.modifiers);
+
foreach (Expression precondition in m.get_preconditions ()) {
precondition.emit (this);
}
@@ -316,29 +340,256 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
if (m.body != null) {
- m.body.emit (this);
- }
+#if 0
+ if (m.coroutine) {
+ var co_function = new CCodeFunction (m.get_real_cname () + "_co", "gboolean");
+ // data struct to hold parameters, local variables, and the return value
+ co_function.add_parameter (new CCodeFormalParameter ("data", Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data*"));
- in_static_or_class_context = false;
+ co_function.modifiers |= CCodeModifiers.STATIC;
+ source_declarations.add_type_member_declaration (co_function.copy ());
- if (m is CreationMethod) {
- if (in_gobject_creation_method && m.body != null) {
- var cblock = (CCodeBlock) m.body.ccodenode;
+ // let gcc know that this can't happen
+ current_state_switch.add_statement (new CCodeLabel ("default"));
+ current_state_switch.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached"))));
+
+ co_function.block = new CCodeBlock ();
+ co_function.block.add_statement (current_state_switch);
+
+ // coroutine body
+ co_function.block.add_statement (new CCodeLabel ("_state_0"));
+ co_function.block.add_statement (function.block);
+
+ // epilogue
+ co_function.block.add_statement (complete_async ());
+
+ source_type_member_definition.append (co_function);
+ }
+#endif
+
+ if (m.closure) {
+ // add variables for parent closure blocks
+ // as closures only have one parameter for the innermost closure block
+ var closure_block = current_closure_block;
+ int block_id = get_block_id (closure_block);
+ while (true) {
+ var parent_closure_block = next_closure_block (closure_block.parent_symbol);
+ if (parent_closure_block == null) {
+ break;
+ }
+ int parent_block_id = get_block_id (parent_closure_block);
+
+ var parent_data = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id));
+ ccode.write_declaration ("Block%dData*".printf (parent_block_id), new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id)));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("_data%d_".printf (parent_block_id)), parent_data));
+
+ closure_block = parent_closure_block;
+ block_id = parent_block_id;
+ }
+
+ // add self variable for closures
+ // as closures have block data parameter
+ if (m.binding == MemberBinding.INSTANCE) {
+ var cself = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self");
+ ccode.write_declaration ("%s *".printf (current_class.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), cself));
+ }
+ } else if (m.parent_symbol is Class && !m.coroutine) {
+ var cl = (Class) m.parent_symbol;
+ if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
+ Method base_method;
+ ReferenceType base_expression_type;
+ if (m.overrides) {
+ base_method = m.base_method;
+ base_expression_type = new ObjectType ((Class) base_method.parent_symbol);
+ } else {
+ base_method = m.base_interface_method;
+ base_expression_type = new ObjectType ((Interface) base_method.parent_symbol);
+ }
+ var self_target_type = new ObjectType (cl);
+ CCodeExpression cself = transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
+
+ ccode.write_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), cself));
+ } else if (m.binding == MemberBinding.INSTANCE
+ && !(m is CreationMethod)) {
+ var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
+ if (ccheckstmt != null) {
+ ccheckstmt.line = function.line;
+ ccode.append (ccheckstmt);
+ }
+ }
+ }
+
+ foreach (FormalParameter param in m.get_parameters ()) {
+ if (param.ellipsis) {
+ break;
+ }
+
+ if (param.direction != ParameterDirection.OUT) {
+ var t = param.variable_type.data_type;
+ if (t != null && t.is_reference_type ()) {
+ var type_check = create_method_type_check_statement (m, creturn_type, t, !param.variable_type.nullable, get_variable_cname (param.name));
+ if (type_check != null) {
+ type_check.line = function.line;
+ ccode.append (type_check);
+ }
+ }
+ } else if (!m.coroutine) {
+ var t = param.variable_type.data_type;
+ if ((t != null && t.is_reference_type ()) || param.variable_type is ArrayType) {
+ // ensure that the passed reference for output parameter is cleared
+ var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (param.name)), new CCodeConstant ("NULL"));
+ var cblock = new CCodeBlock ();
+ cblock.add_statement (new CCodeExpressionStatement (a));
+
+ var condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (param.name), new CCodeConstant ("NULL"));
+ var if_statement = new CCodeIfStatement (condition, cblock);
+ ccode.append (if_statement);
+ }
+ }
+ }
+
+ if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
+ var vardecl = new CCodeVariableDeclarator ("result", default_value_for_type (m.return_type, true));
+ vardecl.init0 = true;
+ ccode.write_declaration (m.return_type.get_cname (), vardecl);
+ }
+
+ if (m is CreationMethod) {
+ if (in_gobject_creation_method) {
+ if (!((CreationMethod) m).chain_up) {
+ if (current_class.get_type_parameters ().size > 0) {
+ // declare construction parameter array
+ var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+ cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
+ cparamsinit.add_argument (new CCodeConstant ((3 * current_class.get_type_parameters ().size).to_string ()));
+
+ ccode.write_declaration ("GParameter *", new CCodeVariableDeclarator ("__params"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("__params"), cparamsinit));
+
+ ccode.write_declaration ("GParameter *", new CCodeVariableDeclarator ("__params_it"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("__params_it"), new CCodeIdentifier ("__params")));
+ }
+
+ /* type, dup func, and destroy func properties for generic types */
+ foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
+ CCodeConstant prop_name;
+ CCodeIdentifier param_name;
+
+ prop_name = new CCodeConstant ("\"%s-type\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
+ ccode.write_expression (get_construct_property_assignment (prop_name, new IntegerType ((Struct) gtype_type), param_name));
+
+ prop_name = new CCodeConstant ("\"%s-dup-func\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
+ ccode.write_expression (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name));
+
+ prop_name = new CCodeConstant ("\"%s-destroy-func\"".printf (type_param.name.down ()));
+ param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
+ ccode.write_expression (get_construct_property_assignment (prop_name, new PointerType (new VoidType ()), param_name));
+ }
+ }
+
+ add_object_creation (current_class.get_type_parameters ().size > 0);
+ } else if (is_gtypeinstance_creation_method (m)) {
+ var cl = (Class) m.parent_symbol;
+ ccode.write_declaration (cl.get_cname () + "*", new CCodeVariableDeclarator ("self"));
+
+ if (!((CreationMethod) m).chain_up) {
+ // TODO implicitly chain up to base class as in add_object_creation
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
+ ccall.add_argument (new CCodeIdentifier ("object_type"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), new CCodeCastExpression (ccall, cl.get_cname () + "*")));
+
+ /* type, dup func, and destroy func fields for generic types */
+ foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
+ CCodeIdentifier param_name;
+ CCodeAssignment assign;
+
+ var priv_access = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv");
+
+ param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ ccode.write_expression (assign);
- if (!((CreationMethod) m).chain_up) {
- prepend_object_creation (cblock, current_class.get_type_parameters ().size > 0);
+ param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ ccode.write_expression (assign);
+
+ param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
+ assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
+ ccode.write_expression (assign);
+ }
+ }
+ } else if (current_type_symbol is Class) {
+ var cl = (Class) m.parent_symbol;
+ ccode.write_declaration (cl.get_cname () + "*", new CCodeVariableDeclarator ("self"));
+
+ if (!((CreationMethod) m).chain_up) {
+ // TODO implicitly chain up to base class as in add_object_creation
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+ ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
+ }
+
+ if (cl.base_class == null) {
+ // derived compact classes do not have fields
+ var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (cl.get_lower_case_cname (null))));
+ cinitcall.add_argument (new CCodeIdentifier ("self"));
+ ccode.write_expression (cinitcall);
+ }
} else {
- var cdeclaration = new CCodeDeclaration ("%s *".printf (((Class) current_type_symbol).get_cname ()));
- cdeclaration.add_declarator (new CCodeVariableDeclarator ("self"));
+ var st = (Struct) m.parent_symbol;
+
+ // memset needs string.h
+ source_declarations.add_include ("string.h");
+ var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ czero.add_argument (new CCodeIdentifier ("self"));
+ czero.add_argument (new CCodeConstant ("0"));
+ czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (st.get_cname ())));
+ ccode.write_expression (czero);
+ }
+ }
+
+ m.body.emit (this);
- cblock.prepend_statement (cdeclaration);
+ if (current_method_inner_error) {
+ /* always separate error parameter and inner_error local variable
+ * as error may be set to NULL but we're always interested in inner errors
+ */
+ if (m.coroutine) {
+ closure_struct.add_field ("GError *", "_inner_error_");
+
+ // no initialization necessary, closure struct is zeroed
+ } else {
+ ccode.write_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
+ }
+ }
+
+ if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
+ // add dummy return if exit block is known to be unreachable to silence C compiler
+ if (m.return_block != null && m.return_block.get_predecessors ().size == 0) {
+ ccode.write_return (new CCodeIdentifier ("result"));
+ }
+ }
+
+ if (m is CreationMethod) {
+ if (current_type_symbol is Class) {
+ ccode.write_return (new CCodeIdentifier ("self"));
}
}
+
+ ccode.close ();
}
+
+ in_static_or_class_context = false;
+
bool inner_error = current_method_inner_error;
+ var method_context = emit_context;
pop_context ();
// do not declare overriding methods and interface implementations
@@ -359,13 +610,12 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
function = new CCodeFunction (m.get_real_cname ());
- m.ccodenode = function;
if (m.is_inline) {
function.modifiers |= CCodeModifiers.INLINE;
}
- var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+ cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
generate_cparameters (m, source_declarations, cparam_map, function);
@@ -385,97 +635,12 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
/* Methods imported from a plain C file don't
* have a body, e.g. Vala.Parser.parse_file () */
if (m.body != null) {
- function.block = (CCodeBlock) m.body.ccodenode;
+ function.block = method_context.ccode.get_block ();
function.block.line = function.line;
var cinit = new CCodeFragment ();
function.block.prepend_statement (cinit);
- if (m.coroutine) {
- var co_function = new CCodeFunction (m.get_real_cname () + "_co", "gboolean");
-
- // data struct to hold parameters, local variables, and the return value
- co_function.add_parameter (new CCodeFormalParameter ("data", Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data*"));
-
- co_function.modifiers |= CCodeModifiers.STATIC;
- source_declarations.add_type_member_declaration (co_function.copy ());
-
- // let gcc know that this can't happen
- current_state_switch.add_statement (new CCodeLabel ("default"));
- current_state_switch.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached"))));
-
- co_function.block = new CCodeBlock ();
- co_function.block.add_statement (current_state_switch);
-
- // coroutine body
- co_function.block.add_statement (new CCodeLabel ("_state_0"));
- co_function.block.add_statement (function.block);
-
- // epilogue
- co_function.block.add_statement (complete_async ());
-
- source_type_member_definition.append (co_function);
- }
-
- if (m.closure) {
- // add variables for parent closure blocks
- // as closures only have one parameter for the innermost closure block
- var closure_block = current_closure_block;
- int block_id = get_block_id (closure_block);
- while (true) {
- var parent_closure_block = next_closure_block (closure_block.parent_symbol);
- if (parent_closure_block == null) {
- break;
- }
- int parent_block_id = get_block_id (parent_closure_block);
-
- var parent_data = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id));
- var cdecl = new CCodeDeclaration ("Block%dData*".printf (parent_block_id));
- cdecl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id), parent_data));
-
- cinit.append (cdecl);
-
- closure_block = parent_closure_block;
- block_id = parent_block_id;
- }
-
- // add self variable for closures
- // as closures have block data parameter
- if (m.binding == MemberBinding.INSTANCE) {
- var cself = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self");
- var cdecl = new CCodeDeclaration ("%s *".printf (current_class.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
-
- cinit.append (cdecl);
- }
- } else if (m.parent_symbol is Class && !m.coroutine) {
- var cl = (Class) m.parent_symbol;
- if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
- Method base_method;
- ReferenceType base_expression_type;
- if (m.overrides) {
- base_method = m.base_method;
- base_expression_type = new ObjectType ((Class) base_method.parent_symbol);
- } else {
- base_method = m.base_interface_method;
- base_expression_type = new ObjectType ((Interface) base_method.parent_symbol);
- }
- var self_target_type = new ObjectType (cl);
- CCodeExpression cself = transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
-
- var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
-
- cinit.append (cdecl);
- } else if (m.binding == MemberBinding.INSTANCE
- && !(m is CreationMethod)) {
- var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
- if (ccheckstmt != null) {
- ccheckstmt.line = function.line;
- cinit.append (ccheckstmt);
- }
- }
- }
foreach (FormalParameter param in m.get_parameters ()) {
if (param.ellipsis) {
break;
@@ -505,36 +670,9 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
}
- if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
- var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
- var vardecl = new CCodeVariableDeclarator ("result", default_value_for_type (m.return_type, true));
- vardecl.init0 = true;
- cdecl.add_declarator (vardecl);
- cinit.append (cdecl);
-
- // add dummy return if exit block is known to be unreachable to silence C compiler
- if (m.return_block != null && m.return_block.get_predecessors ().size == 0) {
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- }
- }
-
- if (inner_error) {
- /* always separate error parameter and inner_error local variable
- * as error may be set to NULL but we're always interested in inner errors
- */
- if (m.coroutine) {
- closure_struct.add_field ("GError *", "_inner_error_");
-
- // no initialization necessary, closure struct is zeroed
- } else {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- cinit.append (cdecl);
- }
- }
if (!m.coroutine) {
- source_type_member_definition.append (function);
+ source_type_member_definition.append (method_context.ccode.get_node ());
}
if (m is CreationMethod) {
@@ -581,7 +719,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
cinit.append (cdeclaration);
if (!((CreationMethod) m).chain_up) {
- // TODO implicitly chain up to base class as in prepend_object_creation
+ // TODO implicitly chain up to base class as in add_object_creation
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
ccall.add_argument (new CCodeIdentifier ("object_type"));
cdecl.initializer = new CCodeCastExpression (ccall, cl.get_cname () + "*");
@@ -614,7 +752,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
cinit.append (cdeclaration);
if (!((CreationMethod) m).chain_up) {
- // TODO implicitly chain up to base class as in prepend_object_creation
+ // TODO implicitly chain up to base class as in add_object_creation
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
cdecl.initializer = ccall;
@@ -1027,14 +1165,13 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
return null;
}
- private void prepend_object_creation (CCodeBlock b, bool has_params) {
+ private void add_object_creation (bool has_params) {
var cl = (Class) current_type_symbol;
if (!has_params && cl.base_class != gobject_type) {
// possibly report warning or error about missing base call
}
- var cdecl = new CCodeVariableDeclarator ("self");
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
ccall.add_argument (new CCodeIdentifier ("object_type"));
if (has_params) {
@@ -1044,12 +1181,9 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
ccall.add_argument (new CCodeConstant ("0"));
ccall.add_argument (new CCodeConstant ("NULL"));
}
- cdecl.initializer = ccall;
-
- var cdeclaration = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdeclaration.add_declarator (cdecl);
- b.prepend_statement (cdeclaration);
+ ccode.write_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
}
public override void visit_creation_method (CreationMethod m) {
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index 84697a5..ced8c9c 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -142,8 +142,8 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
public override void visit_struct (Struct st) {
push_context (new EmitContext (st));
- var old_instance_finalize_fragment = instance_finalize_fragment;
- instance_finalize_fragment = new CCodeFragment ();
+ var old_instance_finalize_context = instance_finalize_context;
+ instance_finalize_context = new EmitContext ();
generate_struct_declaration (st, source_declarations);
@@ -166,7 +166,7 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
add_struct_free_function (st);
}
- instance_finalize_fragment = old_instance_finalize_fragment;
+ instance_finalize_context = old_instance_finalize_context;
pop_context ();
}
@@ -294,9 +294,6 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
}
}
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
-
function.block = cblock;
source_type_member_definition.append (function);
@@ -312,7 +309,7 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
var cblock = new CCodeBlock ();
- cblock.add_statement (instance_finalize_fragment);
+ cblock.add_statement (instance_finalize_context.ccode.get_node ());
function.block = cblock;
diff --git a/codegen/valadovaarraymodule.vala b/codegen/valadovaarraymodule.vala
index 5e3478f..fab04ce 100644
--- a/codegen/valadovaarraymodule.vala
+++ b/codegen/valadovaarraymodule.vala
@@ -38,7 +38,7 @@ public class Vala.DovaArrayModule : DovaMethodCallModule {
var name_cnode = new CCodeIdentifier (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
append_initializer_list (ce, name_cnode, expr.initializer_list, ref i);
diff --git a/codegen/valadovaassignmentmodule.vala b/codegen/valadovaassignmentmodule.vala
index dd49e86..cf1ca51 100644
--- a/codegen/valadovaassignmentmodule.vala
+++ b/codegen/valadovaassignmentmodule.vala
@@ -102,13 +102,13 @@ public class Vala.DovaAssignmentModule : DovaMemberAccessModule {
var lhs_value_type = assignment.left.value_type.copy ();
string lhs_temp_name = "_tmp%d_".printf (next_temp_var_id++);
var lhs_temp = new LocalVariable (lhs_value_type, "*" + lhs_temp_name);
- temp_vars.add (lhs_temp);
+ emit_temp_var (lhs_temp);
outer_ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (lhs_temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, lhs)));
lhs = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (lhs_temp_name)));
}
var temp_decl = get_temp_variable (assignment.left.value_type);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), rhs));
if (unref_old) {
/* unref old value */
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index 01f2b7c..66b4c36 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -299,7 +299,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
if (csource_filename != null) {
- var writer = new CCodeWriter (csource_filename);
+ var writer = new CCodeFileWriter (csource_filename);
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -330,7 +330,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// generate C header file for public API
if (context.header_filename != null) {
- var writer = new CCodeWriter (context.header_filename);
+ var writer = new CCodeFileWriter (context.header_filename);
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -379,7 +379,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (csource_filename == null) {
csource_filename = source_file.get_csource_filename ();
} else {
- var writer = new CCodeWriter (source_file.get_csource_filename ());
+ var writer = new CCodeFileWriter (source_file.get_csource_filename ());
if (!writer.open (context.version_header)) {
Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
return;
@@ -1297,6 +1297,9 @@ public class Vala.DovaBaseModule : CodeGenerator {
temp_ref_vars.clear ();
}
+ public void emit_temp_var (LocalVariable local) {
+ }
+
public void append_temp_decl (CCodeFragment cfrag, List<LocalVariable> temp_vars) {
foreach (LocalVariable local in temp_vars) {
var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
@@ -1593,7 +1596,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// assign current value to temp variable
var temp_decl = get_temp_variable (prop.property_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), (CCodeExpression) expr.inner.ccodenode));
// increment/decrement property
@@ -1685,7 +1688,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// (copy (&temp, 0, &expr, 0), temp)
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -1729,7 +1732,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
return ccall;
} else {
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -1952,7 +1955,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (arg.target_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
@@ -2008,7 +2011,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (expr.type_reference.data_type != null && expr.type_reference.data_type.get_full_name () == "Dova.Value") {
// box value
var temp_decl = get_temp_variable (expr.inner.value_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
@@ -2025,7 +2028,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
} else if (expr.inner.value_type.data_type != null && expr.inner.value_type.data_type.get_full_name () == "Dova.Value") {
// unbox value
var temp_decl = get_temp_variable (expr.type_reference, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
@@ -2068,7 +2071,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
/* (tmp = var, var = null, tmp) */
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.value_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression) expr.inner.ccodenode));
@@ -2216,7 +2219,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// treat void* special to not leak memory with void* method parameters
} else if (requires_destroy (expression_type)) {
var decl = get_temp_variable (expression_type, true, expression_type);
- temp_vars.add (decl);
+ emit_temp_var (decl);
temp_ref_vars.insert (0, decl);
cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr);
}
diff --git a/codegen/valadovamemberaccessmodule.vala b/codegen/valadovamemberaccessmodule.vala
index 2b8c621..acfccc6 100644
--- a/codegen/valadovamemberaccessmodule.vala
+++ b/codegen/valadovamemberaccessmodule.vala
@@ -71,7 +71,7 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
// instance expression has side-effects
// store in temp. variable
var temp_var = get_temp_variable (expr.inner.value_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ctemp = new CCodeIdentifier (temp_var.name);
inst = new CCodeAssignment (ctemp, pub_inst);
expr.inner.ccodenode = ctemp;
diff --git a/codegen/valadovamethodcallmodule.vala b/codegen/valadovamethodcallmodule.vala
index 40f56b4..213fc86 100644
--- a/codegen/valadovamethodcallmodule.vala
+++ b/codegen/valadovamethodcallmodule.vala
@@ -81,7 +81,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -135,7 +135,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
if (param.direction == ParameterDirection.REF) {
@@ -151,14 +151,14 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
ccomma.append_expression (ccall_expr);
} else {
ret_temp_var = get_temp_variable (itype.get_return_type ());
- temp_vars.add (ret_temp_var);
+ emit_temp_var (ret_temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr));
}
var cassign_comma = new CCodeCommaExpression ();
var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned);
- temp_vars.add (assign_temp_var);
+ emit_temp_var (assign_temp_var);
cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg)));
@@ -203,7 +203,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
if (expr.value_type is GenericType) {
ccall.add_argument (get_variable_cexpression (temp_var.name));
} else {
diff --git a/codegen/valadovavaluemodule.vala b/codegen/valadovavaluemodule.vala
index 08e2ec7..61e4af1 100644
--- a/codegen/valadovavaluemodule.vala
+++ b/codegen/valadovavaluemodule.vala
@@ -549,7 +549,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, expr);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
int i = 0;
foreach (Expression e in expr.get_expressions ()) {
@@ -583,7 +583,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, expr);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
int i = 0;
foreach (Expression e in expr.get_expressions ()) {
@@ -619,7 +619,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var key_temp_var = get_temp_variable (key_array_type, true, expr);
var key_name_cnode = get_variable_cexpression (key_temp_var.name);
- temp_vars.add (key_temp_var);
+ emit_temp_var (key_temp_var);
var value_array_type = new ArrayType (expr.map_value_type, 1, expr.source_reference);
value_array_type.inline_allocated = true;
@@ -629,7 +629,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var value_temp_var = get_temp_variable (value_array_type, true, expr);
var value_name_cnode = get_variable_cexpression (value_temp_var.name);
- temp_vars.add (value_temp_var);
+ emit_temp_var (value_temp_var);
for (int i = 0; i < length; i++) {
key_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (key_name_cnode, new CCodeConstant (i.to_string ())), (CCodeExpression) expr.get_keys ().get (i).ccodenode));
@@ -658,7 +658,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var type_temp_var = get_temp_variable (type_array_type, true, tuple);
var type_name_cnode = get_variable_cexpression (type_temp_var.name);
- temp_vars.add (type_temp_var);
+ emit_temp_var (type_temp_var);
var array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference);
array_type.inline_allocated = true;
@@ -667,7 +667,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, tuple);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var type_ce = new CCodeCommaExpression ();
var ce = new CCodeCommaExpression ();
@@ -691,7 +691,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
// tmp = expr, &tmp
var element_temp_var = get_temp_variable (element_type);
- temp_vars.add (element_temp_var);
+ emit_temp_var (element_temp_var);
ce.append_expression (new CCodeAssignment (get_variable_cexpression (element_temp_var.name), cexpr));
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (element_temp_var.name));
}
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index c8fb945..b2034cd 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -139,7 +139,7 @@ public class Vala.GAsyncModule : GSignalModule {
}
CCodeFunction generate_async_function (Method m) {
- var asyncblock = new CCodeBlock ();
+ push_context (new EmitContext (m));
// logic copied from valaccodemethodmodule
if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
@@ -156,9 +156,7 @@ public class Vala.GAsyncModule : GSignalModule {
var self_target_type = new ObjectType (type_symbol);
var cself = transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
- var cdecl = new CCodeDeclaration ("%s *".printf (type_symbol.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
- asyncblock.add_statement (cdecl);
+ ccode.write_declaration ("%s *".printf (type_symbol.get_cname ()), new CCodeVariableDeclarator ("self", cself));
}
var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
@@ -170,10 +168,8 @@ public class Vala.GAsyncModule : GSignalModule {
var data_var = new CCodeIdentifier ("_data_");
- var datadecl = new CCodeDeclaration (dataname + "*");
- datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
- asyncblock.add_statement (datadecl);
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, dataalloc)));
+ ccode.write_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
+ ccode.write_expression (new CCodeAssignment (data_var, dataalloc));
var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
@@ -201,13 +197,13 @@ public class Vala.GAsyncModule : GSignalModule {
create_result.add_argument (new CCodeIdentifier ("_user_data_"));
create_result.add_argument (new CCodeIdentifier (m.get_real_cname ()));
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), create_result)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), create_result));
var set_op_res_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_op_res_gpointer"));
set_op_res_call.add_argument (new CCodeMemberAccess.pointer (data_var, "_async_result"));
set_op_res_call.add_argument (data_var);
set_op_res_call.add_argument (new CCodeIdentifier (m.get_real_cname () + "_data_free"));
- asyncblock.add_statement (new CCodeExpressionStatement (set_op_res_call));
+ ccode.write_expression (set_op_res_call);
if (m.binding == MemberBinding.INSTANCE) {
CCodeExpression self_expr = new CCodeIdentifier ("self");
@@ -219,7 +215,7 @@ public class Vala.GAsyncModule : GSignalModule {
self_expr = refcall;
}
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "self"), self_expr)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "self"), self_expr));
}
foreach (FormalParameter param in m.get_parameters ()) {
@@ -238,34 +234,29 @@ public class Vala.GAsyncModule : GSignalModule {
cparam = get_ref_cexpression (param.variable_type, cparam, ma, param);
}
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), cparam)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), cparam));
if (param.variable_type is ArrayType) {
var array_type = (ArrayType) param.variable_type;
if (!param.no_array_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim))));
}
}
} else if (param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
if (deleg_type.delegate_symbol.has_target) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))));
if (deleg_type.value_owned) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)))));
}
}
}
}
}
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- asyncblock.add_statement (cfrag);
-
var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co"));
ccall.add_argument (data_var);
- asyncblock.add_statement (new CCodeExpressionStatement (ccall));
+ ccode.write_expression (ccall);
cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
@@ -280,7 +271,9 @@ public class Vala.GAsyncModule : GSignalModule {
asyncfunc.modifiers |= CCodeModifiers.STATIC;
}
- asyncfunc.block = asyncblock;
+ pop_context ();
+
+ asyncfunc.block = ccode.get_block ();
return asyncfunc;
}
@@ -394,20 +387,16 @@ public class Vala.GAsyncModule : GSignalModule {
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
- var finishblock = new CCodeBlock ();
+ push_context (new EmitContext (m));
var return_type = m.return_type;
if (!(return_type is VoidType) && !return_type.is_real_non_null_struct_type ()) {
- var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
- finishblock.add_statement (cdecl);
+ ccode.write_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator ("result"));
}
var data_var = new CCodeIdentifier ("_data_");
- var datadecl = new CCodeDeclaration (dataname + "*");
- datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
- finishblock.add_statement (datadecl);
+ ccode.write_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_SIMPLE_ASYNC_RESULT"));
simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
@@ -417,24 +406,25 @@ public class Vala.GAsyncModule : GSignalModule {
var propagate_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_propagate_error"));
propagate_error.add_argument (simple_async_result_cast);
propagate_error.add_argument (new CCodeIdentifier ("error"));
- var errorblock = new CCodeBlock ();
+
+ ccode.open_if (propagate_error);
if (return_type is VoidType || return_type.is_real_non_null_struct_type ()) {
- errorblock.add_statement (new CCodeReturnStatement ());
+ ccode.write_return ();
} else {
- errorblock.add_statement (new CCodeReturnStatement (default_value_for_type (return_type, false)));
+ ccode.write_return (default_value_for_type (return_type, false));
}
- finishblock.add_statement (new CCodeIfStatement (propagate_error, errorblock));
+ ccode.close ();
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_get_op_res_gpointer"));
ccall.add_argument (simple_async_result_cast);
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, ccall)));
+ ccode.write_expression (new CCodeAssignment (data_var, ccall));
foreach (FormalParameter param in m.get_parameters ()) {
if (param.direction != ParameterDirection.IN) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)))));
+ ccode.write_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name))));
if (!(param.variable_type is ValueType) || param.variable_type.nullable) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL"))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL")));
}
}
}
@@ -445,30 +435,25 @@ public class Vala.GAsyncModule : GSignalModule {
if (requires_copy (return_type)) {
cexpr = get_ref_cexpression (return_type, cexpr, null, return_type);
}
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), cexpr)));
+ ccode.write_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), cexpr));
} else if (!(return_type is VoidType)) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (data_var, "result"))));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (data_var, "result")));
if (return_type is ArrayType) {
var array_type = (ArrayType) return_type;
if (!m.no_array_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (data_var, get_array_length_cname ("result", dim)))));
+ ccode.write_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (data_var, get_array_length_cname ("result", dim))));
}
}
} else if (return_type is DelegateType && ((DelegateType) return_type).delegate_symbol.has_target) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname ("result")))));
+ ccode.write_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname ("result"))));
}
if (!(return_type is ValueType) || return_type.nullable) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "result"), new CCodeConstant ("NULL"))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "result"), new CCodeConstant ("NULL")));
}
- finishblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.write_return (new CCodeIdentifier ("result"));
}
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- finishblock.add_statement (cfrag);
-
cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
generate_cparameters (m, source_declarations, cparam_map, finishfunc, null, null, null, 2);
@@ -477,7 +462,9 @@ public class Vala.GAsyncModule : GSignalModule {
finishfunc.modifiers |= CCodeModifiers.STATIC;
}
- finishfunc.block = finishblock;
+ pop_context ();
+
+ finishfunc.block = ccode.get_block ();
return finishfunc;
}
@@ -576,68 +563,44 @@ public class Vala.GAsyncModule : GSignalModule {
return;
}
- stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.yield_expression.ccodenode);
+ ccode.write_expression ((CCodeExpression) stmt.yield_expression.ccodenode);
if (stmt.tree_can_fail && stmt.yield_expression.tree_can_fail) {
// simple case, no node breakdown necessary
- var cfrag = new CCodeFragment ();
-
- cfrag.append (stmt.ccodenode);
-
- add_simple_check (stmt.yield_expression, cfrag);
-
- stmt.ccodenode = cfrag;
+ add_simple_check (stmt.yield_expression);
}
/* free temporary objects */
- if (((List<LocalVariable>) temp_vars).size == 0) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- cfrag.append (stmt.ccodenode);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma)));
+ ccode.write_expression (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma));
}
-
- stmt.ccodenode = cfrag;
-
- temp_vars.clear ();
+
temp_ref_vars.clear ();
}
- public override CCodeStatement return_with_exception (CCodeExpression error_expr)
+ public override void return_with_exception (CCodeExpression error_expr)
{
if (!current_method.coroutine) {
- return base.return_with_exception (error_expr);
+ base.return_with_exception (error_expr);
+ return;
}
- var block = new CCodeBlock ();
-
var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_from_error"));
set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"));
set_error.add_argument (error_expr);
- block.add_statement (new CCodeExpressionStatement (set_error));
+ ccode.write_expression (set_error);
var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
free_error.add_argument (error_expr);
- block.add_statement (new CCodeExpressionStatement (free_error));
-
- var free_locals = new CCodeFragment ();
- append_local_free (current_symbol, free_locals, false);
- block.add_statement (free_locals);
+ ccode.write_expression (free_error);
- block.add_statement (complete_async ());
+ append_local_free (current_symbol, false);
- return block;
+ ccode.append (complete_async ());
}
public override void visit_return_statement (ReturnStatement stmt) {
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index dccb21b..e1c043d 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -81,60 +81,40 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
public override void visit_throw_statement (ThrowStatement stmt) {
- var cfrag = new CCodeFragment ();
-
// method will fail
current_method_inner_error = true;
- var cassign = new CCodeAssignment (get_variable_cexpression ("_inner_error_"), (CCodeExpression) stmt.error_expression.ccodenode);
- cfrag.append (new CCodeExpressionStatement (cassign));
-
- add_simple_check (stmt, cfrag, true);
-
- stmt.ccodenode = cfrag;
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), (CCodeExpression) stmt.error_expression.ccodenode));
- create_temp_decl (stmt, stmt.error_expression.temp_vars);
+ add_simple_check (stmt, true);
}
- public virtual CCodeStatement return_with_exception (CCodeExpression error_expr)
- {
+ public virtual void return_with_exception (CCodeExpression error_expr) {
var cpropagate = new CCodeFunctionCall (new CCodeIdentifier ("g_propagate_error"));
cpropagate.add_argument (new CCodeIdentifier ("error"));
cpropagate.add_argument (error_expr);
- var cerror_block = new CCodeBlock ();
- cerror_block.add_statement (new CCodeExpressionStatement (cpropagate));
+ ccode.write_expression (cpropagate);
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
if (current_method is CreationMethod) {
var cl = current_method.parent_symbol as Class;
var unref_call = get_unref_expression (new CCodeIdentifier ("self"), new ObjectType (cl), null);
- cerror_block.add_statement (new CCodeExpressionStatement (unref_call));
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+ ccode.write_expression (unref_call);
+ ccode.write_return (new CCodeConstant ("NULL"));
} else if (current_method != null && current_method.coroutine) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ ccode.write_return (new CCodeConstant ("FALSE"));
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.write_return ();
} else {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.write_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
- CCodeStatement uncaught_error_statement (CCodeExpression inner_error, CCodeBlock? block = null, bool unexpected = false) {
- var cerror_block = block;
- if (cerror_block == null) {
- cerror_block = new CCodeBlock ();
- }
-
+ void uncaught_error_statement (CCodeExpression inner_error, bool unexpected = false) {
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
ccritical.add_argument (new CCodeConstant (unexpected ? "\"file %s: line %d: unexpected error: %s (%s, %d)\"" : "\"file %s: line %d: uncaught error: %s (%s, %d)\""));
@@ -149,24 +129,19 @@ public class Vala.GErrorModule : CCodeDelegateModule {
var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, inner_error));
- var cprint_frag = new CCodeFragment ();
- cprint_frag.append (new CCodeExpressionStatement (ccritical));
- cprint_frag.append (new CCodeExpressionStatement (cclear));
-
// print critical message
- cerror_block.add_statement (cprint_frag);
+ ccode.write_expression (ccritical);
+ ccode.write_expression (cclear);
if (current_method is CreationMethod) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+ ccode.write_return (new CCodeConstant ("NULL"));
} else if (current_method != null && current_method.coroutine) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ ccode.write_return (new CCodeConstant ("FALSE"));
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.write_return ();
} else if (current_return_type != null) {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.write_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
bool in_finally_block (CodeNode node) {
@@ -181,21 +156,24 @@ public class Vala.GErrorModule : CCodeDelegateModule {
return false;
}
- public override void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
+ public override void add_simple_check (CodeNode node, bool always_fails = false) {
current_method_inner_error = true;
var inner_error = get_variable_cexpression ("_inner_error_");
- CCodeStatement cerror_handler = null;
+ if (always_fails) {
+ // inner_error is always set, avoid unnecessary if statement
+ // eliminates C warnings
+ } else {
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL"));
+ ccode.open_if (ccond);
+ }
if (current_try != null) {
// surrounding try found
- var cerror_block = new CCodeBlock ();
// free local variables
- var free_frag = new CCodeFragment ();
- append_error_free (current_symbol, free_frag, current_try);
- cerror_block.add_statement (free_frag);
+ append_error_free (current_symbol, current_try);
var error_types = new ArrayList<DataType> ();
foreach (DataType node_error_type in node.get_error_types ()) {
@@ -218,18 +196,13 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
handled_error_types.clear ();
- // go to catch clause if error domain matches
- var cgoto_stmt = new CCodeGotoStatement (clause.clabel_name);
-
if (clause.error_type.equals (gerror_type)) {
// general catch clause, this should be the last one
has_general_catch_clause = true;
- cerror_block.add_statement (cgoto_stmt);
+ ccode.write_goto (clause.clabel_name);
break;
} else {
var catch_type = clause.error_type as ErrorType;
- var cgoto_block = new CCodeBlock ();
- cgoto_block.add_statement (cgoto_stmt);
if (catch_type.error_code != null) {
/* catch clause specifies a specific error code */
@@ -238,15 +211,19 @@ public class Vala.GErrorModule : CCodeDelegateModule {
error_match.add_argument (new CCodeIdentifier (catch_type.data_type.get_upper_case_cname ()));
error_match.add_argument (new CCodeIdentifier (catch_type.error_code.get_cname ()));
- cerror_block.add_statement (new CCodeIfStatement (error_match, cgoto_block));
+ ccode.open_if (error_match);
} else {
/* catch clause specifies a full error domain */
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY,
new CCodeMemberAccess.pointer (inner_error, "domain"), new CCodeIdentifier
(clause.error_type.data_type.get_upper_case_cname ()));
- cerror_block.add_statement (new CCodeIfStatement (ccond, cgoto_block));
+ ccode.open_if (ccond);
}
+
+ // go to catch clause if error domain matches
+ ccode.write_goto (clause.clabel_name);
+ ccode.close ();
}
}
}
@@ -258,16 +235,14 @@ public class Vala.GErrorModule : CCodeDelegateModule {
} else if (error_types.size > 0) {
// go to finally clause if no catch clause matches
// and there are still unhandled error types
- cerror_block.add_statement (new CCodeGotoStatement ("__finally%d".printf (current_try_id)));
+ ccode.write_goto ("__finally%d".printf (current_try_id));
} else if (in_finally_block (node)) {
// do not check unexpected errors happening within finally blocks
// as jump out of finally block is not supported
} else {
// should never happen with correct bindings
- uncaught_error_statement (inner_error, cerror_block, true);
+ uncaught_error_statement (inner_error, true);
}
-
- cerror_handler = cerror_block;
} else if (current_method != null && current_method.get_error_types ().size > 0) {
// current method can fail, propagate error
CCodeBinaryExpression ccond = null;
@@ -289,26 +264,22 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
}
- if (ccond == null) {
- cerror_handler = return_with_exception (inner_error);
+ if (ccond != null) {
+ ccode.open_if (ccond);
+ return_with_exception (inner_error);
+
+ ccode.add_else ();
+ uncaught_error_statement (inner_error);
+ ccode.close ();
} else {
- var cerror_block = new CCodeBlock ();
- cerror_block.add_statement (new CCodeIfStatement (ccond,
- return_with_exception (inner_error),
- uncaught_error_statement (inner_error)));
- cerror_handler = cerror_block;
+ return_with_exception (inner_error);
}
} else {
- cerror_handler = uncaught_error_statement (inner_error);
+ uncaught_error_statement (inner_error);
}
- if (always_fails) {
- // inner_error is always set, avoid unnecessary if statement
- // eliminates C warnings
- cfrag.append (cerror_handler);
- } else {
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL"));
- cfrag.append (new CCodeIfStatement (ccond, cerror_handler));
+ if (!always_fails) {
+ ccode.close ();
}
}
@@ -327,7 +298,11 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
if (stmt.finally_body != null) {
+ var old_ccode = ccode;
+ emit_context.ccode = new CCodeBuilder ();
stmt.finally_body.emit (this);
+ stmt.finally_body.ccodenode = emit_context.ccode.get_node ();
+ emit_context.ccode = old_ccode;
}
is_in_catch = false;
@@ -335,6 +310,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
is_in_catch = true;
foreach (CatchClause clause in stmt.get_catch_clauses ()) {
+ ccode.write_goto ("__finally%d".printf (this_try_id));
clause.emit (this);
}
@@ -342,24 +318,14 @@ public class Vala.GErrorModule : CCodeDelegateModule {
current_try_id = old_try_id;
is_in_catch = old_is_in_catch;
- var cfrag = new CCodeFragment ();
- cfrag.append (stmt.body.ccodenode);
-
- foreach (CatchClause clause in stmt.get_catch_clauses ()) {
- cfrag.append (new CCodeGotoStatement ("__finally%d".printf (this_try_id)));
- cfrag.append (clause.ccodenode);
- }
-
- cfrag.append (new CCodeLabel ("__finally%d".printf (this_try_id)));
+ ccode.add_label ("__finally%d".printf (this_try_id));
if (stmt.finally_body != null) {
- cfrag.append (stmt.finally_body.ccodenode);
+ ccode.append (stmt.finally_body.ccodenode);
}
// check for errors not handled by this try statement
// may be handled by outer try statements or propagated
- add_simple_check (stmt, cfrag, !stmt.after_try_block_reachable);
-
- stmt.ccodenode = cfrag;
+ add_simple_check (stmt, !stmt.after_try_block_reachable);
}
public override void visit_catch_clause (CatchClause clause) {
@@ -370,12 +336,9 @@ public class Vala.GErrorModule : CCodeDelegateModule {
generate_error_domain_declaration (error_type.error_domain, source_declarations);
}
- clause.body.emit (this);
-
- var cfrag = new CCodeFragment ();
- cfrag.append (new CCodeLabel (clause.clabel_name));
+ ccode.add_label (clause.clabel_name);
- var cblock = new CCodeBlock ();
+ ccode.write_begin_block ();
string variable_name;
if (clause.variable_name != null) {
@@ -384,31 +347,27 @@ public class Vala.GErrorModule : CCodeDelegateModule {
variable_name = "__err";
}
- if (current_method != null && current_method.coroutine) {
- closure_struct.add_field ("GError *", variable_name);
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (variable_name), get_variable_cexpression ("_inner_error_"))));
- } else {
- if (clause.variable_name != null) {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, get_variable_cexpression ("_inner_error_")));
- cblock.add_statement (cdecl);
+ if (clause.variable_name != null) {
+ if (current_method != null && current_method.coroutine) {
+ closure_struct.add_field ("GError *", variable_name);
} else {
- // error object is not used within catch statement, clear it
- var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
- cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
- cblock.add_statement (new CCodeExpressionStatement (cclear));
+ ccode.write_declaration ("GError *", new CCodeVariableDeclarator (variable_name));
}
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression (variable_name), get_variable_cexpression ("_inner_error_")));
+ } else {
+ // error object is not used within catch statement, clear it
+ var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
+ cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
+ ccode.write_expression (cclear);
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL"))));
+ ccode.write_expression (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL")));
- cblock.add_statement (clause.body.ccodenode);
-
- cfrag.append (cblock);
+ clause.body.emit (this);
- clause.ccodenode = cfrag;
+ ccode.write_end_block ();
}
- public override void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public override void append_local_free (Symbol sym, bool stop_at_loop = false) {
var finally_block = (Block) null;
if (sym.parent_node is TryStatement) {
finally_block = (sym.parent_node as TryStatement).finally_body;
@@ -417,10 +376,10 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
if (finally_block != null) {
- cfrag.append (finally_block.ccodenode);
+ ccode.append (finally_block.ccodenode);
}
- base.append_local_free (sym, cfrag, stop_at_loop);
+ base.append_local_free (sym, stop_at_loop);
}
}
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index 59ef5ee..34e01d8 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -42,7 +42,7 @@ public class Vala.GObjectModule : GTypeModule {
}
}
- public override void generate_class_init (Class cl, CCodeBlock init_block) {
+ public override void generate_class_init (Class cl) {
if (!cl.is_subtype_of (gobject_type)) {
return;
}
@@ -51,24 +51,24 @@ public class Vala.GObjectModule : GTypeModule {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccall.add_argument (new CCodeIdentifier ("klass"));
if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null)))));
}
if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null)))));
}
/* set constructor */
if (cl.constructor != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null)))));
}
/* set finalize function */
if (cl.get_fields ().size > 0 || cl.destructor != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null))))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null)))));
}
/* create type, dup_func, and destroy_func properties for generic types */
@@ -90,7 +90,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.write_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
@@ -106,7 +106,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeConstant ("\"dup func\""));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.write_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
@@ -122,7 +122,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeConstant ("\"destroy func\""));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.write_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
}
@@ -134,7 +134,7 @@ public class Vala.GObjectModule : GTypeModule {
}
if (prop.comment != null) {
- init_block.add_statement (new CCodeComment (prop.comment.content));
+ ccode.append (new CCodeComment (prop.comment.content));
}
if (prop.overrides || prop.base_interface_property != null) {
@@ -143,14 +143,14 @@ public class Vala.GObjectModule : GTypeModule {
cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
cinst.add_argument (prop.get_canonical_cconstant ());
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.write_expression (cinst);
} else {
var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
cinst.add_argument (ccall);
cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
cinst.add_argument (get_param_spec (prop));
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.write_expression (cinst);
}
}
}
@@ -536,12 +536,10 @@ public class Vala.GObjectModule : GTypeModule {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
*/
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- base_init_fragment.append (cdecl);
+ base_init_context.ccode.write_declaration ("GError *", new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
}
- base_init_fragment.append (c.body.ccodenode);
+ base_init_context.ccode.append (c.body.ccodenode);
} else if (c.binding == MemberBinding.STATIC) {
// static class constructor
// add to class_init
@@ -556,12 +554,10 @@ public class Vala.GObjectModule : GTypeModule {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
*/
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- class_init_fragment.append (cdecl);
+ class_init_context.ccode.write_declaration ("GError *", new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
}
- class_init_fragment.append (c.body.ccodenode);
+ class_init_context.ccode.append (c.body.ccodenode);
} else {
Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
}
@@ -789,7 +785,7 @@ public class Vala.GObjectModule : GTypeModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type, false, expr, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), (CCodeExpression) expr.ccodenode));
var is_floating_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_is_floating"));
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index e36f5f2..89fbb11 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -649,7 +649,7 @@ public class Vala.GSignalModule : GObjectModule {
// get signal id
ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (uint_type);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
var decl_type = (TypeSymbol) sig.parent_symbol;
@@ -661,7 +661,7 @@ public class Vala.GSignalModule : GObjectModule {
parse_call.add_argument (new CCodeConstant ("FALSE"));
} else {
detail_temp_decl = get_temp_variable (gquark_type);
- temp_vars.add (detail_temp_decl);
+ emit_temp_var (detail_temp_decl);
parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
parse_call.add_argument (new CCodeConstant ("TRUE"));
}
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index c989a39..e799257 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -496,12 +496,12 @@ public class Vala.GTypeModule : GErrorModule {
var old_param_spec_struct = param_spec_struct;
var old_prop_enum = prop_enum;
- var old_class_init_fragment = class_init_fragment;
- var old_base_init_fragment = base_init_fragment;
- var old_class_finalize_fragment = class_finalize_fragment;
- var old_base_finalize_fragment = base_finalize_fragment;
- var old_instance_init_fragment = instance_init_fragment;
- var old_instance_finalize_fragment = instance_finalize_fragment;
+ var old_class_init_context = class_init_context;
+ var old_base_init_context = base_init_context;
+ var old_class_finalize_context = class_finalize_context;
+ var old_base_finalize_context = base_finalize_context;
+ var old_instance_init_context = instance_init_context;
+ var old_instance_finalize_context = instance_finalize_context;
bool is_gtypeinstance = !cl.is_compact;
bool is_fundamental = is_gtypeinstance && cl.base_class == null;
@@ -514,12 +514,12 @@ public class Vala.GTypeModule : GErrorModule {
prop_enum = new CCodeEnum ();
prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
- class_init_fragment = new CCodeFragment ();
- base_init_fragment = new CCodeFragment ();
- class_finalize_fragment = new CCodeFragment ();
- base_finalize_fragment = new CCodeFragment ();
- instance_init_fragment = new CCodeFragment ();
- instance_finalize_fragment = new CCodeFragment ();
+ class_init_context = new EmitContext (cl);
+ base_init_context = new EmitContext (cl);
+ class_finalize_context = new EmitContext (cl);
+ base_finalize_context = new EmitContext (cl);
+ instance_init_context = new EmitContext (cl);
+ instance_finalize_context = new EmitContext (cl);
generate_class_struct_declaration (cl, source_declarations);
@@ -532,6 +532,19 @@ public class Vala.GTypeModule : GErrorModule {
generate_class_struct_declaration (cl, internal_header_declarations);
}
+ if (is_gtypeinstance) {
+ begin_class_init_function (cl);
+ begin_instance_init_function (cl);
+
+ if (!cl.is_compact && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
+ begin_finalize_function (cl);
+ }
+ } else {
+ if (cl.base_class == null) {
+ begin_instance_init_function (cl);
+ }
+ }
+
cl.accept_children (this);
if (is_gtypeinstance) {
@@ -557,7 +570,7 @@ public class Vala.GTypeModule : GErrorModule {
add_g_value_take_function (cl);
var ref_count = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count"), new CCodeConstant ("1"));
- instance_init_fragment.append (new CCodeExpressionStatement (ref_count));
+ instance_init_context.ccode.write_expression (ref_count);
}
@@ -666,7 +679,7 @@ public class Vala.GTypeModule : GErrorModule {
cblock.add_statement (cl.destructor.ccodenode);
}
- cblock.add_statement (instance_finalize_fragment);
+ cblock.add_statement (instance_finalize_context.ccode.get_node ());
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
@@ -681,12 +694,12 @@ public class Vala.GTypeModule : GErrorModule {
param_spec_struct = old_param_spec_struct;
prop_enum = old_prop_enum;
- class_init_fragment = old_class_init_fragment;
- base_init_fragment = old_base_init_fragment;
- class_finalize_fragment = old_class_finalize_fragment;
- base_finalize_fragment = old_base_finalize_fragment;
- instance_init_fragment = old_instance_init_fragment;
- instance_finalize_fragment = old_instance_finalize_fragment;
+ class_init_context = old_class_init_context;
+ base_init_context = old_base_init_context;
+ class_finalize_context = old_class_finalize_context;
+ base_finalize_context = old_base_finalize_context;
+ instance_init_context = old_instance_init_context;
+ instance_finalize_context = old_instance_finalize_context;
pop_context ();
}
@@ -1186,25 +1199,23 @@ public class Vala.GTypeModule : GErrorModule {
ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
ccall.add_argument (new CCodeIdentifier ("priv"));
block.add_statement (new CCodeExpressionStatement (ccall));
- base_finalize_fragment.append (block);
+ base_finalize_context.ccode.append (block);
}
- init_block.add_statement (base_init_fragment);
+ init_block.add_statement (base_init_context.ccode.get_node ());
source_type_member_definition.append (base_init);
}
- public virtual void generate_class_init (Class cl, CCodeBlock init_block) {
+ public virtual void generate_class_init (Class cl) {
}
- private void add_class_init_function (Class cl) {
- var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
- class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
- class_init.modifiers = CCodeModifiers.STATIC;
+ private void begin_class_init_function (Class cl) {
+ push_context (class_init_context);
+
+ var parameters = ccode.parameters (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+ ccode.open_function ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void", parameters, CCodeModifiers.STATIC);
- var init_block = new CCodeBlock ();
- class_init.block = init_block;
-
CCodeFunctionCall ccall;
/* save pointer to parent class */
@@ -1214,10 +1225,11 @@ public class Vala.GTypeModule : GErrorModule {
parent_decl.add_declarator (parent_var_decl);
parent_decl.modifiers = CCodeModifiers.STATIC;
source_declarations.add_type_member_declaration (parent_decl);
+
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
ccall.add_argument (new CCodeIdentifier ("klass"));
var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
- init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+ ccode.write_expression (parent_assignment);
if (!cl.is_compact && !cl.is_subtype_of (gobject_type) && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
@@ -1230,7 +1242,7 @@ public class Vala.GTypeModule : GErrorModule {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname (null))));
ccall.add_argument (new CCodeIdentifier ("klass"));
var finalize_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "finalize"), new CCodeIdentifier (cl.get_lower_case_cprefix () + "finalize"));
- init_block.add_statement (new CCodeExpressionStatement (finalize_assignment));
+ ccode.write_expression (finalize_assignment);
}
/* add struct for private fields */
@@ -1238,7 +1250,7 @@ public class Vala.GTypeModule : GErrorModule {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
ccall.add_argument (new CCodeIdentifier ("klass"));
ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
- init_block.add_statement (new CCodeExpressionStatement (ccall));
+ ccode.write_expression (ccall);
}
/* connect overridden methods */
@@ -1253,10 +1265,10 @@ public class Vala.GTypeModule : GErrorModule {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ()))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ())));
if (m.coroutine) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.get_finish_vfunc_name ()), new CCodeIdentifier (m.get_finish_real_cname ()))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.get_finish_vfunc_name ()), new CCodeIdentifier (m.get_finish_real_cname ())));
}
}
}
@@ -1268,7 +1280,7 @@ public class Vala.GTypeModule : GErrorModule {
}
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, sig.default_handler.vfunc_name), new CCodeIdentifier (sig.default_handler.get_real_cname ()))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, sig.default_handler.vfunc_name), new CCodeIdentifier (sig.default_handler.get_real_cname ())));
}
/* connect overridden properties */
@@ -1283,30 +1295,35 @@ public class Vala.GTypeModule : GErrorModule {
if (prop.get_accessor != null) {
string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname)));
}
if (prop.set_accessor != null) {
string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname)));
}
}
- generate_class_init (cl, init_block);
+ generate_class_init (cl);
if (!cl.is_compact) {
/* create signals */
foreach (Signal sig in cl.get_signals ()) {
if (sig.comment != null) {
- init_block.add_statement (new CCodeComment (sig.comment.content));
+ ccode.append (new CCodeComment (sig.comment.content));
}
- init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, cl)));
+ ccode.write_expression (get_signal_creation (sig, cl));
}
}
- init_block.add_statement (register_dbus_info (cl));
- init_block.add_statement (class_init_fragment);
+ register_dbus_info (cl);
+
+ pop_context ();
+ }
+
+ private void add_class_init_function (Class cl) {
+ class_init_context.ccode.close ();
- source_type_member_definition.append (class_init);
+ source_type_member_definition.append (class_init_context.ccode.get_node ());
}
private void add_interface_init_function (Class cl, Interface iface) {
@@ -1520,29 +1537,35 @@ public class Vala.GTypeModule : GErrorModule {
return new CCodeCastExpression (cfunc, cast);
}
- private void add_instance_init_function (Class cl) {
- var instance_init = new CCodeFunction ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void");
- instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
- instance_init.modifiers = CCodeModifiers.STATIC;
-
+ private void begin_instance_init_function (Class cl) {
+ push_context (instance_init_context);
+
+ var parameters = ccode.parameters (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
+ ccode.open_function ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void", parameters, CCodeModifiers.STATIC);
+
+ var decl = new CCodeBuilder ();
+ decl.write_function_declaration ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void", parameters, CCodeModifiers.STATIC);
+ source_declarations.add_type_member_declaration (decl.get_node ());
+
if (cl.is_compact) {
// Add declaration, since the instance_init function is explicitly called
// by the creation methods
- source_declarations.add_type_member_declaration (instance_init.copy ());
+ //source_declarations.add_type_member_declaration (instance_init.copy ());
}
- var init_block = new CCodeBlock ();
- instance_init.block = init_block;
-
if (!cl.is_compact && (cl.has_private_fields || cl.get_type_parameters ().size > 0)) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
ccall.add_argument (new CCodeIdentifier ("self"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
+ ccode.write_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall));
}
-
- init_block.add_statement (instance_init_fragment);
- source_type_member_definition.append (instance_init);
+ pop_context ();
+ }
+
+ private void add_instance_init_function (Class cl) {
+ instance_init_context.ccode.close ();
+
+ source_type_member_definition.append (instance_init_context.ccode.get_node ());
}
private void add_class_finalize_function (Class cl) {
@@ -1558,7 +1581,7 @@ public class Vala.GTypeModule : GErrorModule {
cblock.add_statement (cl.class_destructor.ccodenode);
}
- cblock.add_statement (class_finalize_fragment);
+ cblock.add_statement (class_finalize_context.ccode.get_node ());
function.block = cblock;
source_type_member_definition.append (function);
@@ -1577,54 +1600,57 @@ public class Vala.GTypeModule : GErrorModule {
cblock.add_statement (cl.class_destructor.ccodenode);
}
- cblock.add_statement (base_finalize_fragment);
+ cblock.add_statement (base_finalize_context.ccode.get_node ());
function.block = cblock;
source_type_member_definition.append (function);
}
- private void add_finalize_function (Class cl) {
- var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
- function.modifiers = CCodeModifiers.STATIC;
+ private void begin_finalize_function (Class cl) {
+ push_context (instance_finalize_context);
var fundamental_class = cl;
while (fundamental_class.base_class != null) {
fundamental_class = fundamental_class.base_class;
}
- function.add_parameter (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
-
- source_declarations.add_type_member_declaration (function.copy ());
-
+ var parameters = ccode.parameters (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
+ ccode.open_function ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void", parameters, CCodeModifiers.STATIC);
- var cblock = new CCodeBlock ();
+ var decl = new CCodeBuilder ();
+ decl.write_function_declaration ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void", parameters, CCodeModifiers.STATIC);
+ source_declarations.add_type_member_declaration (decl.get_node ());
CCodeFunctionCall ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
- var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
-
- cblock.add_statement (cdecl);
+ ccode.write_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.write_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
if (cl.destructor != null) {
- cblock.add_statement (cl.destructor.ccodenode);
+ cl.destructor.body.emit (this);
}
- cblock.add_statement (instance_finalize_fragment);
+ pop_context ();
+ }
+
+ private void add_finalize_function (Class cl) {
+ var fundamental_class = cl;
+ while (fundamental_class.base_class != null) {
+ fundamental_class = fundamental_class.base_class;
+ }
// chain up to finalize function of the base class
if (cl.base_class != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname ())));
ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
+ var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
ccall.add_argument (new CCodeIdentifier ("obj"));
- cblock.add_statement (new CCodeExpressionStatement (ccall));
+ instance_finalize_context.ccode.write_expression (ccall);
}
+ instance_finalize_context.ccode.close ();
- function.block = cblock;
-
- source_type_member_definition.append (function);
+ source_type_member_definition.append (instance_finalize_context.ccode.get_node ());
}
public override CCodeFunctionCall get_param_spec (Property prop) {
@@ -1667,7 +1693,7 @@ public class Vala.GTypeModule : GErrorModule {
}
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant (prop.property_type.data_type.get_default_value ()));
}
@@ -1678,7 +1704,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT"));
cspec.add_argument (new CCodeConstant ("G_MAXINT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1687,7 +1713,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0U"));
}
@@ -1696,7 +1722,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT64"));
cspec.add_argument (new CCodeConstant ("G_MAXINT64"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1705,7 +1731,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT64"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0U"));
}
@@ -1714,7 +1740,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MINLONG"));
cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0L"));
}
@@ -1723,14 +1749,14 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0UL"));
}
} else if (st.get_type_id () == "G_TYPE_BOOLEAN") {
cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("FALSE"));
}
@@ -1739,7 +1765,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT8"));
cspec.add_argument (new CCodeConstant ("G_MAXINT8"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1748,7 +1774,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT8"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1757,7 +1783,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0.0F"));
}
@@ -1766,14 +1792,14 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0.0"));
}
} else if (st.get_type_id () == "G_TYPE_GTYPE") {
cspec.call = new CCodeIdentifier ("g_param_spec_gtype");
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("G_TYPE_NONE"));
}
@@ -2043,7 +2069,7 @@ public class Vala.GTypeModule : GErrorModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (new CType ("GEnumValue*"), false, expr, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var class_ref = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_ref"));
class_ref.add_argument (new CCodeIdentifier (ma.inner.value_type.get_type_id ()));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]