valaccodestructmodule.vala \
valaclassregisterfunction.vala \
valactype.vala \
- valadovaarraymodule.vala \
- valadovaassignmentmodule.vala \
- valadovabasemodule.vala \
- valadovacontrolflowmodule.vala \
- valadovadelegatemodule.vala \
- valadovaerrormodule.vala \
- valadovamemberaccessmodule.vala \
- valadovamethodcallmodule.vala \
- valadovamethodmodule.vala \
- valadovaobjectmodule.vala \
- valadovastructmodule.vala \
- valadovavaluemodule.vala \
valaenumregisterfunction.vala \
valagasyncmodule.vala \
valagdbusclientmodule.vala \
}
} else if (node is ObjectType) {
var type = (ObjectType) node;
- if (CodeContext.get ().profile == Profile.DOVA) {
- if (type.type_symbol.get_full_name () == "string") {
- return "string_t";
- }
- }
string cname;
if (!type.value_owned) {
if (type.inline_allocated) {
return cname;
} else {
- if (CodeContext.get ().profile == Profile.DOVA) {
- return "DovaArray";
- } else {
- return "%s*".printf (cname);
- }
+ return "%s*".printf (cname);
}
} else if (node is DelegateType) {
var type = (DelegateType) node;
- if (CodeContext.get ().profile == Profile.DOVA) {
- return "%s*".printf (CCodeBaseModule.get_ccode_name (type.delegate_symbol));
- } else {
- return CCodeBaseModule.get_ccode_name (type.delegate_symbol);
- }
+ return CCodeBaseModule.get_ccode_name (type.delegate_symbol);
} else if (node is ErrorType) {
return "GError*";
} else if (node is GenericType) {
if (base_st != null) {
return CCodeBaseModule.get_ccode_default_value (base_st);
}
-
- if (CodeContext.get ().profile == Profile.DOVA) {
- if (st.is_boolean_type ()) {
- return "false";
- } else if (st.is_integer_type () || st.is_floating_type ()) {
- return "0";
- }
- }
}
return "";
}
string infix = "construct";
- if (CodeContext.get ().profile == Profile.DOVA) {
- infix = "init";
- }
-
if (m.name == ".new") {
return "%s%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix);
} else {
+++ /dev/null
-/* valadovaarraymodule.vala
- *
- * Copyright (C) 2006-2011 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.DovaArrayModule : DovaMethodCallModule {
- void append_initializer_list (CCodeExpression name_cnode, InitializerList initializer_list, ref int i) {
- foreach (Expression e in initializer_list.get_initializers ()) {
- ccode.add_assignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e));
- i++;
- }
- }
-
- public override void visit_array_creation_expression (ArrayCreationExpression expr) {
- var array_type = expr.target_type as ArrayType;
- if (array_type != null && array_type.fixed_length) {
- // no heap allocation for fixed-length arrays
-
- var temp_var = get_temp_variable (array_type, true, expr);
- var name_cnode = new CCodeIdentifier (temp_var.name);
- int i = 0;
-
- emit_temp_var (temp_var);
-
- append_initializer_list (name_cnode, expr.initializer_list, ref i);
-
- set_cvalue (expr, name_cnode);
-
- return;
- }
-
- generate_method_declaration ((Method) array_struct.scope.lookup ("create"), cfile);
-
- var array_new = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_create"));
- array_new.add_argument (get_type_id_expression (expr.element_type));
-
- // length of new array
- array_new.add_argument (get_cvalue (expr.get_sizes ().get (0)));
-
- var temp_var = get_temp_variable (expr.value_type, true, expr);
- var name_cnode = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- ccode.add_assignment (name_cnode, array_new);
-
- set_cvalue (expr, name_cnode);
- }
-
- public override void visit_element_access (ElementAccess expr) {
- List<Expression> indices = expr.get_indices ();
-
- var ccontainer = get_cvalue (expr.container);
- var cindex = get_cvalue (indices[0]);
-
- // access to element in an array
- set_cvalue (expr, new CCodeElementAccess (ccontainer, cindex));
- }
-
- public override void visit_slice_expression (SliceExpression expr) {
- var ccontainer = get_cvalue (expr.container);
- var cstart = get_cvalue (expr.start);
- var cstop = get_cvalue (expr.stop);
-
- var array_type = (ArrayType) expr.container.value_type;
-
- var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
- array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (new CCodeMemberAccess (ccontainer, "data"), get_ccode_name (array_type.element_type) + "*"), cstart));
- array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, cstop, cstart));
-
- set_cvalue (expr, array);
- }
-}
+++ /dev/null
-/* valadovaassignmentmodule.vala
- *
- * Copyright (C) 2006-2011 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>
- */
-
-/**
- * The link between an assignment and generated code.
- */
-public class Vala.DovaAssignmentModule : DovaMemberAccessModule {
- CCodeExpression? emit_simple_assignment (Assignment assignment) {
- CCodeExpression rhs = get_cvalue (assignment.right);
- CCodeExpression lhs = (CCodeExpression) get_ccodenode (assignment.left);
-
- bool unref_old = requires_destroy (assignment.left.value_type);
-
- if (unref_old) {
- if (!is_pure_ccode_expression (lhs)) {
- /* Assign lhs to temp var to avoid repeating side effect */
- 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);
- emit_temp_var (lhs_temp);
- ccode.add_assignment (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);
- emit_temp_var (temp_decl);
- ccode.add_assignment (get_variable_cexpression (temp_decl.name), rhs);
- if (unref_old) {
- /* unref old value */
- ccode.add_expression (get_unref_expression (lhs, assignment.left.value_type, assignment.left));
- }
-
- rhs = get_variable_cexpression (temp_decl.name);
- }
-
- var cop = CCodeAssignmentOperator.SIMPLE;
- if (assignment.operator == AssignmentOperator.BITWISE_OR) {
- cop = CCodeAssignmentOperator.BITWISE_OR;
- } else if (assignment.operator == AssignmentOperator.BITWISE_AND) {
- cop = CCodeAssignmentOperator.BITWISE_AND;
- } else if (assignment.operator == AssignmentOperator.BITWISE_XOR) {
- cop = CCodeAssignmentOperator.BITWISE_XOR;
- } else if (assignment.operator == AssignmentOperator.ADD) {
- cop = CCodeAssignmentOperator.ADD;
- } else if (assignment.operator == AssignmentOperator.SUB) {
- cop = CCodeAssignmentOperator.SUB;
- } else if (assignment.operator == AssignmentOperator.MUL) {
- cop = CCodeAssignmentOperator.MUL;
- } else if (assignment.operator == AssignmentOperator.DIV) {
- cop = CCodeAssignmentOperator.DIV;
- } else if (assignment.operator == AssignmentOperator.PERCENT) {
- cop = CCodeAssignmentOperator.PERCENT;
- } else if (assignment.operator == AssignmentOperator.SHIFT_LEFT) {
- cop = CCodeAssignmentOperator.SHIFT_LEFT;
- } else if (assignment.operator == AssignmentOperator.SHIFT_RIGHT) {
- cop = CCodeAssignmentOperator.SHIFT_RIGHT;
- }
-
- CCodeExpression codenode = new CCodeAssignment (lhs, rhs, cop);
-
- ccode.add_expression (codenode);
-
- if (assignment.parent_node is ExpressionStatement) {
- return null;
- } else {
- return lhs;
- }
- }
-
- CCodeExpression? emit_fixed_length_array_assignment (Assignment assignment, ArrayType array_type) {
- CCodeExpression rhs = get_cvalue (assignment.right);
- CCodeExpression lhs = (CCodeExpression) get_ccodenode (assignment.left);
-
- // it is necessary to use memcpy for fixed-length (stack-allocated) arrays
- // simple assignments do not work in C
- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
- var size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call);
- var ccopy = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
- ccopy.add_argument (lhs);
- ccopy.add_argument (rhs);
- ccopy.add_argument (size);
-
- ccode.add_expression (ccopy);
-
- if (assignment.parent_node is ExpressionStatement) {
- return null;
- } else {
- return lhs;
- }
- }
-
- public override void visit_assignment (Assignment assignment) {
- if (assignment.left.error || assignment.right.error) {
- assignment.error = true;
- return;
- }
-
- if (assignment.left.symbol_reference is Property) {
- var ma = assignment.left as MemberAccess;
- var prop = (Property) assignment.left.symbol_reference;
-
- store_property (prop, ma.inner, assignment.right.target_value);
-
- set_cvalue (assignment, get_ccodenode (assignment.right));
- } else {
- var array_type = assignment.left.value_type as ArrayType;
- if (array_type != null && array_type.fixed_length) {
- set_cvalue (assignment, emit_fixed_length_array_assignment (assignment, array_type));
- } else {
- set_cvalue (assignment, emit_simple_assignment (assignment));
- }
- }
- }
-
- public virtual void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) {
- if (!initializer && requires_destroy (variable.variable_type)) {
- /* unref old value */
- ccode.add_expression (destroy_value (lvalue));
- }
-
- ccode.add_assignment (get_cvalue_ (lvalue), get_cvalue_ (value));
- }
-
- public override void store_local (LocalVariable local, TargetValue value, bool initializer) {
- store_variable (local, get_local_cvalue (local), value, initializer);
- }
-
- public override void store_parameter (Parameter param, TargetValue value) {
- store_variable (param, get_parameter_cvalue (param), value, false);
- }
-
- public override void store_field (Field field, TargetValue? instance, TargetValue value) {
- store_variable (field, get_field_cvalue (field, instance), value, false);
- }
-}
+++ /dev/null
-/* valadovabasemodule.vala
- *
- * Copyright (C) 2006-2011 Jürg Billeter
- * Copyright (C) 2006-2008 Raffaele Sandrini
- *
- * 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>
- * Raffaele Sandrini <raffaele@sandrini.ch>
- */
-
-/**
- * Code visitor generating C Code.
- */
-public abstract class Vala.DovaBaseModule : CodeGenerator {
- public class EmitContext {
- public Symbol? current_symbol;
- public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
- public TryStatement current_try;
- public CCodeFunction ccode;
- public ArrayList<CCodeFunction> ccode_stack = new ArrayList<CCodeFunction> ();
- public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
- public int next_temp_var_id;
- public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
-
- public EmitContext (Symbol? symbol = null) {
- current_symbol = symbol;
- }
-
- public void push_symbol (Symbol symbol) {
- symbol_stack.add (current_symbol);
- current_symbol = symbol;
- }
-
- public void pop_symbol () {
- current_symbol = symbol_stack[symbol_stack.size - 1];
- symbol_stack.remove_at (symbol_stack.size - 1);
- }
- }
-
- public CodeContext context { get; set; }
-
- public Symbol root_symbol;
-
- public EmitContext emit_context = new EmitContext ();
-
- List<EmitContext> emit_context_stack = new ArrayList<EmitContext> ();
-
- public Symbol current_symbol { get { return emit_context.current_symbol; } }
-
- public TryStatement current_try {
- get { return emit_context.current_try; }
- set { emit_context.current_try = value; }
- }
-
- public TypeSymbol? current_type_symbol {
- get {
- var sym = current_symbol;
- while (sym != null) {
- if (sym is TypeSymbol) {
- return (TypeSymbol) sym;
- }
- sym = sym.parent_symbol;
- }
- return null;
- }
- }
-
- public Class? current_class {
- get { return current_type_symbol as Class; }
- }
-
- public Method? current_method {
- get {
- var sym = current_symbol;
- while (sym is Block) {
- sym = sym.parent_symbol;
- }
- return sym as Method;
- }
- }
-
- public PropertyAccessor? current_property_accessor {
- get {
- var sym = current_symbol;
- while (sym is Block) {
- sym = sym.parent_symbol;
- }
- return sym as PropertyAccessor;
- }
- }
-
- public DataType? current_return_type {
- get {
- var m = current_method;
- if (m != null) {
- return m.return_type;
- }
-
- var acc = current_property_accessor;
- if (acc != null) {
- if (acc.readable) {
- return acc.value_type;
- } else {
- return void_type;
- }
- }
-
- return null;
- }
- }
-
- public Block? current_closure_block {
- get {
- return next_closure_block (current_symbol);
- }
- }
-
- public unowned Block? next_closure_block (Symbol sym) {
- unowned Block block = null;
- while (true) {
- block = sym as Block;
- if (!(sym is Block || sym is Method)) {
- // no closure block
- break;
- }
- if (block != null && block.captured) {
- // closure block found
- break;
- }
- sym = sym.parent_symbol;
- }
- return block;
- }
-
- public CCodeFile header_file;
- public CCodeFile cfile;
-
- string? csource_filename;
-
- public CCodeFunction ccode { get { return emit_context.ccode; } }
-
- /* temporary variables that own their content */
- public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
- /* (constant) hash table with all reserved identifiers in the generated code */
- Set<string> reserved_identifiers;
-
- public List<Field> static_fields = new ArrayList<Field> ();
-
- public int next_temp_var_id {
- get { return emit_context.next_temp_var_id; }
- set { emit_context.next_temp_var_id = value; }
- }
-
- public int next_wrapper_id = 0;
- public bool in_creation_method { get { return current_method is CreationMethod; } }
- int next_block_id = 0;
- Map<Block,int> block_map = new HashMap<Block,int> ();
-
- public DataType void_type = new VoidType ();
- public DataType bool_type;
- public DataType char_type;
- public DataType int_type;
- public DataType uint_type;
- public DataType string_type;
- public Class object_class;
- public Class type_class;
- public Class value_class;
- public Class string_class;
- public Struct array_struct;
- public Class delegate_class;
- public Class error_class;
-
- Set<Symbol> generated_external_symbols;
-
- public Map<string,string> variable_name_map { get { return emit_context.variable_name_map; } }
-
- public DovaBaseModule () {
- reserved_identifiers = new HashSet<string> (str_hash, str_equal);
-
- // C99 keywords
- reserved_identifiers.add ("_Bool");
- reserved_identifiers.add ("_Complex");
- reserved_identifiers.add ("_Imaginary");
- reserved_identifiers.add ("auto");
- reserved_identifiers.add ("break");
- reserved_identifiers.add ("case");
- reserved_identifiers.add ("char");
- reserved_identifiers.add ("const");
- reserved_identifiers.add ("continue");
- reserved_identifiers.add ("default");
- reserved_identifiers.add ("do");
- reserved_identifiers.add ("double");
- reserved_identifiers.add ("else");
- reserved_identifiers.add ("enum");
- reserved_identifiers.add ("extern");
- reserved_identifiers.add ("float");
- reserved_identifiers.add ("for");
- reserved_identifiers.add ("goto");
- reserved_identifiers.add ("if");
- reserved_identifiers.add ("inline");
- reserved_identifiers.add ("int");
- reserved_identifiers.add ("long");
- reserved_identifiers.add ("register");
- reserved_identifiers.add ("restrict");
- reserved_identifiers.add ("return");
- reserved_identifiers.add ("short");
- reserved_identifiers.add ("signed");
- reserved_identifiers.add ("sizeof");
- reserved_identifiers.add ("static");
- reserved_identifiers.add ("struct");
- reserved_identifiers.add ("switch");
- reserved_identifiers.add ("typedef");
- reserved_identifiers.add ("union");
- reserved_identifiers.add ("unsigned");
- reserved_identifiers.add ("void");
- reserved_identifiers.add ("volatile");
- reserved_identifiers.add ("while");
-
- // reserved for Vala naming conventions
- reserved_identifiers.add ("result");
- reserved_identifiers.add ("this");
- }
-
- public override void emit (CodeContext context) {
- this.context = context;
-
- root_symbol = context.root;
-
- bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool"));
- char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char"));
- int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int"));
- uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint"));
- string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string"));
-
- var dova_ns = (Namespace) root_symbol.scope.lookup ("Dova");
- object_class = (Class) dova_ns.scope.lookup ("Object");
- type_class = (Class) dova_ns.scope.lookup ("Type");
- value_class = (Class) dova_ns.scope.lookup ("Value");
- string_class = (Class) root_symbol.scope.lookup ("string");
- array_struct = (Struct) dova_ns.scope.lookup ("Array");
- delegate_class = (Class) dova_ns.scope.lookup ("Delegate");
- error_class = (Class) dova_ns.scope.lookup ("Error");
-
- header_file = new CCodeFile ();
- header_file.is_header = true;
-
- cfile = new CCodeFile ();
-
- if (context.nostdpkg) {
- header_file.add_include ("dova-types.h");
- cfile.add_include ("dova-types.h");
- } else {
- header_file.add_include ("dova-base.h");
- cfile.add_include ("dova-base.h");
- }
-
- generated_external_symbols = new HashSet<Symbol> ();
-
-
- /* we're only interested in non-pkg source files */
- var source_files = context.get_source_files ();
- foreach (SourceFile file in source_files) {
- if (file.file_type == SourceFileType.SOURCE) {
- file.accept (this);
- }
- }
-
- if (csource_filename != null) {
- if (!cfile.store (csource_filename, null, context.version_header, context.debug)) {
- Report.error (null, "unable to open `%s' for writing".printf (csource_filename));
- }
- }
-
- cfile = null;
-
-
- // generate C header file for public API
- if (context.header_filename != null) {
- if (!header_file.store (context.header_filename, null, context.version_header, false)) {
- Report.error (null, "unable to open `%s' for writing".printf (context.header_filename));
- }
- }
- }
-
- public void push_context (EmitContext emit_context) {
- if (this.emit_context != null) {
- emit_context_stack.add (this.emit_context);
- }
-
- this.emit_context = emit_context;
- }
-
- public void pop_context () {
- if (emit_context_stack.size > 0) {
- this.emit_context = emit_context_stack[emit_context_stack.size - 1];
- emit_context_stack.remove_at (emit_context_stack.size - 1);
- } else {
- this.emit_context = null;
- }
- }
-
- public void push_function (CCodeFunction func) {
- emit_context.ccode_stack.add (ccode);
- emit_context.ccode = func;
- }
-
- public void pop_function () {
- emit_context.ccode = emit_context.ccode_stack[emit_context.ccode_stack.size - 1];
- emit_context.ccode_stack.remove_at (emit_context.ccode_stack.size - 1);
- }
-
- public bool add_symbol_declaration (CCodeFile decl_space, Symbol sym, string name) {
- if (decl_space.add_declaration (name)) {
- return true;
- }
- if (sym.external_package || (!decl_space.is_header && CodeContext.get ().use_header && !sym.is_internal_symbol ())) {
- // add appropriate include file
- foreach (string header_filename in CCodeBaseModule.get_ccode_header_filenames (sym).split (",")) {
- decl_space.add_include (header_filename, !sym.external_package);
- }
- // declaration complete
- return true;
- } else {
- // require declaration
- return false;
- }
- }
-
- public override void visit_source_file (SourceFile source_file) {
- if (csource_filename == null) {
- csource_filename = source_file.get_csource_filename ();
- } else {
- var writer = new CCodeWriter (source_file.get_csource_filename ());
- if (!writer.open (context.version_header)) {
- Report.error (null, "unable to open `%s' for writing".printf (writer.filename));
- return;
- }
- writer.close ();
- }
-
- source_file.accept_children (this);
-
- if (context.report.get_errors () > 0) {
- return;
- }
- }
-
- public void generate_enum_declaration (Enum en, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, en, get_ccode_name (en))) {
- return;
- }
-
- var cenum = new CCodeEnum (get_ccode_name (en));
-
- foreach (EnumValue ev in en.get_values ()) {
- if (ev.value == null) {
- cenum.add_value (new CCodeEnumValue (get_ccode_name (ev)));
- } else {
- ev.value.emit (this);
- cenum.add_value (new CCodeEnumValue (get_ccode_name (ev), get_cvalue (ev.value)));
- }
- }
-
- decl_space.add_type_definition (cenum);
- decl_space.add_type_definition (new CCodeNewline ());
- }
-
- public override void visit_enum (Enum en) {
- en.accept_children (this);
-
- generate_enum_declaration (en, cfile);
-
- if (!en.is_internal_symbol ()) {
- generate_enum_declaration (en, header_file);
- }
- }
-
- public void generate_constant_declaration (Constant c, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, c, get_ccode_name (c))) {
- return;
- }
-
- if (!c.external) {
- c.value.emit (this);
-
- if (c.value is InitializerList) {
- var cdecl = new CCodeDeclaration (get_ccode_const_name (c.type_reference));
- var arr = "";
- if (c.type_reference is ArrayType) {
- arr = "[]";
- }
- cdecl.add_declarator (new CCodeVariableDeclarator ("%s%s".printf (get_ccode_name (c), arr), get_cvalue (c.value)));
- cdecl.modifiers = CCodeModifiers.STATIC;
-
- decl_space.add_constant_declaration (cdecl);
- } else {
- var cdefine = new CCodeMacroReplacement.with_expression (get_ccode_name (c), get_cvalue (c.value));
- decl_space.add_type_member_declaration (cdefine);
- }
- }
- }
-
- public override void visit_constant (Constant c) {
- generate_constant_declaration (c, cfile);
-
- if (!c.is_internal_symbol ()) {
- generate_constant_declaration (c, header_file);
- }
- }
-
- public void generate_field_declaration (Field f, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, f, get_ccode_name (f))) {
- return;
- }
-
- generate_type_declaration (f.variable_type, decl_space);
-
- string field_ctype = get_ccode_name (f.variable_type);
- if (f.is_volatile) {
- field_ctype = "volatile " + field_ctype;
- }
-
- var cdecl = new CCodeDeclaration (field_ctype);
- cdecl.add_declarator (new CCodeVariableDeclarator (get_ccode_name (f)));
- if (f.is_internal_symbol ()) {
- cdecl.modifiers = CCodeModifiers.STATIC;
- } else {
- cdecl.modifiers = CCodeModifiers.EXTERN;
- }
-
- if (f.get_attribute ("ThreadLocal") != null) {
- cdecl.modifiers |= CCodeModifiers.THREAD_LOCAL;
- }
-
- decl_space.add_type_member_declaration (cdecl);
- }
-
- public override void visit_field (Field f) {
- if (f.binding == MemberBinding.STATIC) {
- generate_field_declaration (f, cfile);
-
- if (!f.is_internal_symbol ()) {
- generate_field_declaration (f, header_file);
- }
-
- var var_decl = new CCodeVariableDeclarator (get_ccode_name (f));
- var_decl.initializer = default_value_for_type (f.variable_type, true);
-
- if (f.initializer != null) {
- static_fields.add (f);
- }
-
- string field_ctype = get_ccode_name (f.variable_type);
- if (f.is_volatile) {
- field_ctype = "volatile " + field_ctype;
- }
-
- var var_def = new CCodeDeclaration (field_ctype);
- var_def.add_declarator (var_decl);
- if (!f.is_internal_symbol ()) {
- var_def.modifiers = CCodeModifiers.EXTERN;
- } else {
- var_def.modifiers = CCodeModifiers.STATIC;
- }
-
- if (f.get_attribute ("ThreadLocal") != null) {
- var_def.modifiers |= CCodeModifiers.THREAD_LOCAL;
- }
-
- cfile.add_type_member_declaration (var_def);
- }
- }
-
- public bool is_constant_ccode_expression (CCodeExpression cexpr) {
- if (cexpr is CCodeConstant) {
- return true;
- } else if (cexpr is CCodeCastExpression) {
- var ccast = (CCodeCastExpression) cexpr;
- return is_constant_ccode_expression (ccast.inner);
- } else if (cexpr is CCodeBinaryExpression) {
- var cbinary = (CCodeBinaryExpression) cexpr;
- return is_constant_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right);
- }
-
- var cparenthesized = (cexpr as CCodeParenthesizedExpression);
- return (null != cparenthesized && is_constant_ccode_expression (cparenthesized.inner));
- }
-
- /**
- * Returns whether the passed cexpr is a pure expression, i.e. an
- * expression without side-effects.
- */
- public bool is_pure_ccode_expression (CCodeExpression cexpr) {
- if (cexpr is CCodeConstant || cexpr is CCodeIdentifier) {
- return true;
- } else if (cexpr is CCodeBinaryExpression) {
- var cbinary = (CCodeBinaryExpression) cexpr;
- return is_pure_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right);
- } else if (cexpr is CCodeUnaryExpression) {
- var cunary = (CCodeUnaryExpression) cexpr;
- switch (cunary.operator) {
- case CCodeUnaryOperator.PREFIX_INCREMENT:
- case CCodeUnaryOperator.PREFIX_DECREMENT:
- case CCodeUnaryOperator.POSTFIX_INCREMENT:
- case CCodeUnaryOperator.POSTFIX_DECREMENT:
- return false;
- default:
- return is_pure_ccode_expression (cunary.inner);
- }
- } else if (cexpr is CCodeMemberAccess) {
- var cma = (CCodeMemberAccess) cexpr;
- return is_pure_ccode_expression (cma.inner);
- } else if (cexpr is CCodeElementAccess) {
- var cea = (CCodeElementAccess) cexpr;
- return is_pure_ccode_expression (cea.container) && is_pure_ccode_expression (cea.index);
- } else if (cexpr is CCodeCastExpression) {
- var ccast = (CCodeCastExpression) cexpr;
- return is_pure_ccode_expression (ccast.inner);
- } else if (cexpr is CCodeParenthesizedExpression) {
- var cparenthesized = (CCodeParenthesizedExpression) cexpr;
- return is_pure_ccode_expression (cparenthesized.inner);
- }
-
- return false;
- }
-
- public override void visit_formal_parameter (Parameter p) {
- }
-
- public override void visit_property (Property prop) {
- if (prop.get_accessor != null) {
- prop.get_accessor.accept (this);
- }
- if (prop.set_accessor != null) {
- prop.set_accessor.accept (this);
- }
- }
-
- public void generate_type_declaration (DataType type, CCodeFile decl_space) {
- if (type is ObjectType) {
- var object_type = (ObjectType) type;
- if (object_type.type_symbol is Class) {
- generate_class_declaration ((Class) object_type.type_symbol, decl_space);
- } else if (object_type.type_symbol is Interface) {
- generate_interface_declaration ((Interface) object_type.type_symbol, decl_space);
- }
- } else if (type is DelegateType) {
- var deleg_type = (DelegateType) type;
- var d = deleg_type.delegate_symbol;
- generate_delegate_declaration (d, decl_space);
- } else if (type.data_type is Enum) {
- var en = (Enum) type.data_type;
- generate_enum_declaration (en, decl_space);
- } else if (type is ValueType) {
- var value_type = (ValueType) type;
- generate_struct_declaration ((Struct) value_type.type_symbol, decl_space);
- } else if (type is ArrayType) {
- var array_type = (ArrayType) type;
- generate_struct_declaration (array_struct, decl_space);
- generate_type_declaration (array_type.element_type, decl_space);
- } else if (type is PointerType) {
- var pointer_type = (PointerType) type;
- generate_type_declaration (pointer_type.base_type, decl_space);
- }
-
- foreach (DataType type_arg in type.get_type_arguments ()) {
- generate_type_declaration (type_arg, decl_space);
- }
- }
-
- public virtual void generate_struct_declaration (Struct st, CCodeFile decl_space) {
- }
-
- public virtual void generate_delegate_declaration (Delegate d, CCodeFile decl_space) {
- }
-
- public virtual void generate_cparameters (Method m, CCodeFile decl_space, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, CCodeFunctionCall? vcall = null) {
- }
-
- public virtual void generate_property_accessor_declaration (PropertyAccessor acc, CCodeFile decl_space) {
- }
-
- public int get_block_id (Block b) {
- int result = block_map[b];
- if (result == 0) {
- result = ++next_block_id;
- block_map[b] = result;
- }
- return result;
- }
-
- void capture_parameter (Parameter param, CCodeStruct data, int block_id, CCodeBlock free_block) {
- generate_type_declaration (param.variable_type, cfile);
-
- var param_type = param.variable_type.copy ();
- param_type.value_owned = true;
- data.add_field (get_ccode_name (param_type), get_variable_cname (param.name));
-
- // create copy if necessary as captured variables may need to be kept alive
- CCodeExpression cparam = get_variable_cexpression (param.name);
- if (requires_copy (param_type) && !param.variable_type.value_owned) {
- var ma = new MemberAccess.simple (param.name);
- ma.symbol_reference = param;
- ma.value_type = param.variable_type.copy ();
- // directly access parameters in ref expressions
- param.captured = false;
- cparam = get_ref_cexpression (param.variable_type, cparam, ma, param);
- param.captured = true;
- }
-
- ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam);
-
- if (requires_destroy (param_type)) {
- var ma = new MemberAccess.simple (param.name);
- ma.symbol_reference = param;
- ma.value_type = param_type.copy ();
- free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (param.name)), param.variable_type, ma)));
- }
- }
-
- public override void visit_block (Block b) {
- emit_context.push_symbol (b);
-
- var local_vars = b.get_local_variables ();
-
- if (b.parent_node is Block || b.parent_node is SwitchStatement) {
- ccode.open_block ();
- }
-
- if (b.captured) {
- var parent_block = next_closure_block (b.parent_symbol);
-
- int block_id = get_block_id (b);
- string struct_name = "Block%dData".printf (block_id);
-
- var free_block = new CCodeBlock ();
-
- var data = new CCodeStruct ("_" + struct_name);
- data.add_field ("DovaType*", "type");
- data.add_field ("int32_t", "_ref_count_");
- if (parent_block != null) {
- int parent_block_id = get_block_id (parent_block);
-
- data.add_field ("Block%dData *".printf (parent_block_id), "_data%d_".printf (parent_block_id));
-
- var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
- unref_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)));
- free_block.add_statement (new CCodeExpressionStatement (unref_call));
- } else if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) ||
- (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) {
- data.add_field ("%s *".printf (get_ccode_name (current_class)), "this");
-
- var ma = new MemberAccess.simple ("this");
- ma.symbol_reference = current_class;
- free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "this"), new ObjectType (current_class), ma)));
- }
- foreach (var local in local_vars) {
- if (local.captured) {
- generate_type_declaration (local.variable_type, cfile);
-
- data.add_field (get_ccode_name (local.variable_type), get_variable_cname (local.name) + get_ccode_declarator_suffix (local.variable_type));
- }
- }
- // free in reverse order
- for (int i = local_vars.size - 1; i >= 0; i--) {
- var local = local_vars[i];
- if (local.captured) {
- if (requires_destroy (local.variable_type)) {
- var ma = new MemberAccess.simple (local.name);
- ma.symbol_reference = local;
- ma.value_type = local.variable_type.copy ();
- free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (local.name)), local.variable_type, ma)));
- }
- }
- }
-
- var data_alloc = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc"));
- data_alloc.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_type_get".printf (block_id))));
-
- var data_decl = new CCodeDeclaration (struct_name + "*");
- data_decl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc));
- ccode.add_statement (data_decl);
-
- if (parent_block != null) {
- int parent_block_id = get_block_id (parent_block);
-
- var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_ref"));
- ref_call.add_argument (get_variable_cexpression ("_data%d_".printf (parent_block_id)));
-
- ccode.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)));
- } else if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) ||
- (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 (new CCodeIdentifier ("this"));
-
- ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "this"), ref_call)));
- }
-
- if (b.parent_symbol is Method) {
- var m = (Method) b.parent_symbol;
-
- // 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, block_id, free_block);
- }
- }
- } 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, block_id, free_block);
- }
- }
-
- var typedef = new CCodeTypeDefinition ("struct _" + struct_name, new CCodeVariableDeclarator (struct_name));
- cfile.add_type_declaration (typedef);
- cfile.add_type_definition (data);
-
- var data_free = new CCodeFunctionCall (new CCodeIdentifier ("free"));
- data_free.add_argument (new CCodeIdentifier ("_data%d_".printf (block_id)));
- free_block.add_statement (new CCodeExpressionStatement (data_free));
-
- // create type_get/finalize functions
- var type_get_fun = new CCodeFunction ("block%d_data_type_get".printf (block_id), "DovaType*");
- type_get_fun.modifiers = CCodeModifiers.STATIC;
- cfile.add_function_declaration (type_get_fun);
- type_get_fun.block = new CCodeBlock ();
-
- var cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_block%d_data_object_offset".printf (block_id), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_block%d_data_type_offset".printf (block_id), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- cdecl = new CCodeDeclaration ("DovaType *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("block%d_data_type".printf (block_id), new CCodeConstant ("NULL")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- var type_init_block = new CCodeBlock ();
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc"));
- alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("dova_object_type_get")));
- alloc_call.add_argument (new CCodeConstant ("sizeof (%s)".printf (struct_name)));
- alloc_call.add_argument (new CCodeConstant ("0"));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("block%d_data_type".printf (block_id))));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_block%d_data_object_offset".printf (block_id))));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_block%d_data_type_offset".printf (block_id))));
- type_init_block.add_statement (new CCodeExpressionStatement (alloc_call));
- var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_type_init"));
- type_init_call.add_argument (new CCodeIdentifier ("block%d_data_type".printf (block_id)));
- type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
- type_get_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("block%d_data_type".printf (block_id))), type_init_block));
- type_get_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("block%d_data_type".printf (block_id))));
-
- cfile.add_function (type_get_fun);
-
- var unref_fun = new CCodeFunction ("block%d_data_finalize".printf (block_id), "void");
- unref_fun.add_parameter (new CCodeParameter ("_data%d_".printf (block_id), struct_name + "*"));
- unref_fun.modifiers = CCodeModifiers.STATIC;
- cfile.add_function_declaration (unref_fun);
- unref_fun.block = free_block;
-
- cfile.add_function (unref_fun);
- }
-
- 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];
- if (!local.floating && !local.captured && requires_destroy (local.variable_type)) {
- var ma = new MemberAccess.simple (local.name);
- ma.symbol_reference = local;
- ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
- }
- }
-
- if (b.parent_symbol is Method) {
- var m = (Method) b.parent_symbol;
- foreach (Parameter param in m.get_parameters ()) {
- if (!param.captured && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
- var ma = new MemberAccess.simple (param.name);
- ma.symbol_reference = param;
- ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
- }
- }
- }
-
- if (b.captured) {
- int block_id = get_block_id (b);
-
- var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
- data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- ccode.add_statement (new CCodeExpressionStatement (data_unref));
- }
-
- if (b.parent_node is Block || b.parent_node is SwitchStatement) {
- ccode.close ();
- }
-
- emit_context.pop_symbol ();
- }
-
- public override void visit_declaration_statement (DeclarationStatement stmt) {
- stmt.declaration.accept (this);
- }
-
- public CCodeExpression get_variable_cexpression (string name) {
- return new CCodeIdentifier (get_variable_cname (name));
- }
-
- public string get_variable_cname (string name) {
- if (name[0] == '.') {
- // compiler-internal variable
- if (!variable_name_map.contains (name)) {
- variable_name_map.set (name, "_tmp%d_".printf (next_temp_var_id));
- next_temp_var_id++;
- }
- return variable_name_map.get (name);
- } else if (reserved_identifiers.contains (name)) {
- return "_%s_".printf (name);
- } else {
- return name;
- }
- }
-
- public override void visit_local_variable (LocalVariable local) {
- if (local.initializer != null) {
- local.initializer.emit (this);
-
- visit_end_full_expression (local.initializer);
- }
-
- generate_type_declaration (local.variable_type, cfile);
-
- CCodeExpression rhs = null;
- if (local.initializer != null && get_cvalue (local.initializer) != null) {
- rhs = get_cvalue (local.initializer);
- }
-
- if (local.captured) {
- if (local.initializer != null) {
- ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs);
- }
- } else {
- var cvar = new CCodeVariableDeclarator (get_variable_cname (local.name), rhs, get_ccode_declarator_suffix (local.variable_type));
-
- var cdecl = new CCodeDeclaration (get_ccode_name (local.variable_type));
- cdecl.add_declarator (cvar);
- ccode.add_statement (cdecl);
-
- // try to initialize uninitialized variables
- // initialization not necessary for variables stored in closure
- if (cvar.initializer == null) {
- cvar.initializer = default_value_for_type (local.variable_type, true);
- cvar.init0 = true;
- }
- }
-
- if (local.initializer != null && local.initializer.tree_can_fail) {
- add_simple_check (local.initializer);
- }
-
- local.active = true;
- }
-
- public override void visit_initializer_list (InitializerList list) {
- if (list.target_type.data_type is Struct) {
- /* initializer is used as struct initializer */
- var st = (Struct) list.target_type.data_type;
-
- var clist = new CCodeInitializerList ();
-
- var field_it = st.get_fields ().iterator ();
- foreach (Expression expr in list.get_initializers ()) {
- Field field = null;
- while (field == null) {
- field_it.next ();
- field = field_it.get ();
- if (field.binding != MemberBinding.INSTANCE) {
- // we only initialize instance fields
- field = null;
- }
- }
-
- var cexpr = get_cvalue (expr);
-
- string ctype = field.get_ctype ();
- if (ctype != null) {
- cexpr = new CCodeCastExpression (cexpr, ctype);
- }
-
- clist.append (cexpr);
- }
-
- set_cvalue (list, clist);
- } else {
- var clist = new CCodeInitializerList ();
- foreach (Expression expr in list.get_initializers ()) {
- clist.append (get_cvalue (expr));
- }
- set_cvalue (list, clist);
- }
- }
-
- public override LocalVariable create_local (DataType type) {
- var result = get_temp_variable (type, type.value_owned);
- emit_temp_var (result);
- return result;
- }
-
- public LocalVariable get_temp_variable (DataType type, bool value_owned = true, CodeNode? node_reference = null) {
- var var_type = type.copy ();
- var_type.value_owned = value_owned;
- var local = new LocalVariable (var_type, "_tmp%d_".printf (next_temp_var_id));
-
- if (node_reference != null) {
- local.source_reference = node_reference.source_reference;
- }
-
- next_temp_var_id++;
-
- return local;
- }
-
- bool is_in_generic_type (DataType type) {
- if (type.type_parameter.parent_symbol is TypeSymbol
- && (current_method == null || current_method.binding == MemberBinding.INSTANCE)) {
- return true;
- } else {
- return false;
- }
- }
-
- public CCodeExpression get_type_private_from_type (ObjectTypeSymbol type_symbol, CCodeExpression type_expression) {
- if (type_symbol is Class) {
- // class
- return new CCodeCastExpression (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (type_expression, "char *"), new CCodeIdentifier ("_%s_type_offset".printf (CCodeBaseModule.get_ccode_lower_case_name (type_symbol)))), "%sTypePrivate *".printf (get_ccode_name (type_symbol)));
- } else {
- // interface
- var get_interface = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_interface"));
- get_interface.add_argument (type_expression);
- get_interface.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (type_symbol))));
- return new CCodeCastExpression (get_interface, "%sTypePrivate *".printf (CCodeBaseModule.get_ccode_name (type_symbol)));
- }
- }
-
- public CCodeExpression get_type_id_expression (DataType type, bool is_chainup = false) {
- if (type is GenericType) {
- string var_name = "%s_type".printf (type.type_parameter.name.down ());
- if (is_in_generic_type (type) && !is_chainup) {
- return new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), var_name);
- } else {
- return new CCodeIdentifier (var_name);
- }
- } else {
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (CCodeBaseModule.get_ccode_lower_case_name (type.data_type))));
- var object_type_symbol = type.data_type as ObjectTypeSymbol;
- if (object_type_symbol != null) {
- for (int i = 0; i < object_type_symbol.get_type_parameters ().size; i++) {
- if (type.get_type_arguments ().size == 0) {
- ccall.add_argument (new CCodeConstant ("NULL"));
- } else {
- ccall.add_argument (get_type_id_expression (type.get_type_arguments ().get (i)));
- }
- }
- }
- return ccall;
- }
- }
-
- public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference, bool is_chainup = false) {
- if (type.data_type != null) {
- string dup_function = "";
- if (is_reference_counting (type.data_type)) {
- dup_function = get_ccode_ref_function (type.data_type);
- } else if (type is ValueType) {
- dup_function = get_ccode_dup_function (type.data_type);
- if (dup_function == null) {
- dup_function = "";
- }
- }
-
- return new CCodeIdentifier (dup_function);
- } else if (type.type_parameter != null) {
- return null;
- } else if (type is ArrayType) {
- return new CCodeIdentifier ("dova_object_ref");
- } else if (type is DelegateType) {
- return new CCodeIdentifier ("dova_object_ref");
- } else if (type is PointerType) {
- var pointer_type = (PointerType) type;
- return get_dup_func_expression (pointer_type.base_type, source_reference);
- } else {
- return new CCodeConstant ("NULL");
- }
- }
-
- public CCodeExpression? get_destroy_func_expression (DataType type, bool is_chainup = false) {
- if (type.data_type != null) {
- string unref_function;
- if (type is ReferenceType) {
- if (is_reference_counting (type.data_type)) {
- unref_function = get_ccode_unref_function ((ObjectTypeSymbol) type.data_type);
- } else {
- unref_function = get_ccode_free_function (type.data_type);
- }
- } else {
- if (type.nullable) {
- unref_function = get_ccode_free_function (type.data_type);
- if (unref_function == null) {
- unref_function = "free";
- }
- } else {
- var st = (Struct) type.data_type;
- unref_function = get_ccode_copy_function (st);
- }
- }
- if (unref_function == null) {
- return new CCodeConstant ("NULL");
- }
- return new CCodeIdentifier (unref_function);
- } else if (type.type_parameter != null && current_type_symbol is Class) {
- // FIXME ask type for dup/ref function
- return new CCodeIdentifier ("dova_object_unref");
- } else if (type is ArrayType) {
- return new CCodeIdentifier ("dova_object_unref");
- } else if (type is DelegateType) {
- return new CCodeIdentifier ("dova_object_unref");
- } else if (type is PointerType) {
- return new CCodeIdentifier ("free");
- } else {
- return new CCodeConstant ("NULL");
- }
- }
-
- public CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression? expr = null) {
- return destroy_value (new DovaValue (type, cvar));
- }
-
- public CCodeExpression destroy_value (TargetValue value) {
- var type = value.value_type;
- var cvar = get_cvalue_ (value);
-
- var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
-
- if (type is ValueType && !type.nullable) {
- // normal value type, no null check
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar));
- ccall.add_argument (new CCodeConstant ("0"));
- ccall.add_argument (new CCodeConstant ("NULL"));
- ccall.add_argument (new CCodeConstant ("0"));
-
- return ccall;
- }
-
- /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
-
- /* can be simplified to
- * foo = (unref (foo), NULL)
- * if foo is of static type non-null
- */
-
- var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL"));
- if (type.type_parameter != null) {
- if (!(current_type_symbol is Class) || current_class.is_compact) {
- return new CCodeConstant ("NULL");
- }
-
- // unref functions are optional for type parameters
- var cunrefisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_destroy_func_expression (type), new CCodeConstant ("NULL"));
- cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cunrefisnull);
- }
-
- ccall.add_argument (cvar);
-
- /* set freed references to NULL to prevent further use */
- var ccomma = new CCodeCommaExpression ();
-
- ccomma.append_expression (ccall);
- ccomma.append_expression (new CCodeConstant ("NULL"));
-
- var cassign = new CCodeAssignment (cvar, ccomma);
-
- return new CCodeConditionalExpression (cisnull, new CCodeConstant ("NULL"), cassign);
- }
-
- public override void visit_end_full_expression (Expression expr) {
- /* expr is a full expression, i.e. an initializer, the
- * expression in an expression statement, the controlling
- * expression in if, while, for, or foreach statements
- *
- * we unref temporary variables at the end of a full
- * expression
- */
-
- if (((List<LocalVariable>) temp_ref_vars).size == 0) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var expr_type = expr.value_type;
- if (expr.target_type != null) {
- expr_type = expr.target_type;
- }
-
- var full_expr_var = get_temp_variable (expr_type, true, expr);
- emit_temp_var (full_expr_var);
-
- var expr_list = new CCodeCommaExpression ();
- expr_list.append_expression (new CCodeAssignment (get_variable_cexpression (full_expr_var.name), get_cvalue (expr)));
-
- foreach (LocalVariable local in temp_ref_vars) {
- var ma = new MemberAccess.simple (local.name);
- ma.symbol_reference = local;
- expr_list.append_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
- }
-
- expr_list.append_expression (get_variable_cexpression (full_expr_var.name));
-
- set_cvalue (expr, expr_list);
-
- temp_ref_vars.clear ();
- }
-
- public void emit_temp_var (LocalVariable local) {
- var cdecl = new CCodeDeclaration (get_ccode_name (local.variable_type));
-
- var vardecl = new CCodeVariableDeclarator (local.name, null, get_ccode_declarator_suffix (local.variable_type));
- 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.variable_type is GenericType) {
- var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- value_size.add_argument (get_type_id_expression (local.variable_type));
-
- var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
- alloca_call.add_argument (value_size);
-
- var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- memset_call.add_argument (alloca_call);
- memset_call.add_argument (new CCodeConstant ("0"));
- memset_call.add_argument (value_size);
-
- vardecl.initializer = memset_call;
- vardecl.init0 = true;
- } else if (!local.variable_type.nullable &&
- (st != null && st.get_fields ().size > 0) ||
- array_type != null) {
- // 0-initialize struct with struct initializer { 0 }
- // necessary as they will be passed by reference
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
-
- vardecl.initializer = clist;
- vardecl.init0 = true;
- } else if (local.variable_type.is_reference_type_or_type_parameter () ||
- local.variable_type.nullable) {
- vardecl.initializer = new CCodeConstant ("NULL");
- vardecl.init0 = true;
- }
-
- ccode.add_statement (cdecl);
- }
-
- public override void visit_expression_statement (ExpressionStatement stmt) {
- if (stmt.expression.error) {
- stmt.error = true;
- return;
- }
-
- if (get_cvalue (stmt.expression) != null) {
- ccode.add_expression (get_cvalue (stmt.expression));
- }
- /* free temporary objects and handle errors */
-
- 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 ();
- ccode.add_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);
- }
-
- temp_ref_vars.clear ();
- }
-
- public virtual void append_local_free (Symbol sym, bool stop_at_loop = false, CodeNode? stop_at = null) {
- var b = (Block) sym;
-
- var local_vars = b.get_local_variables ();
- // free in reverse order
- for (int i = local_vars.size - 1; i >= 0; i--) {
- var local = local_vars[i];
- if (local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
- var ma = new MemberAccess.simple (local.name);
- ma.symbol_reference = local;
- ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
- }
- }
-
- if (b.captured) {
- int block_id = get_block_id (b);
-
- var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
- data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- ccode.add_expression (data_unref);
- }
-
- if (stop_at_loop) {
- if (b.parent_node is Loop ||
- b.parent_node is ForeachStatement ||
- b.parent_node is SwitchStatement) {
- return;
- }
- }
-
- if (b.parent_node == stop_at) {
- return;
- }
-
- if (sym.parent_symbol is Block) {
- append_local_free (sym.parent_symbol, stop_at_loop, stop_at);
- } else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol);
- }
- }
-
- private void append_param_free (Method m) {
- foreach (Parameter param in m.get_parameters ()) {
- if (requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
- var ma = new MemberAccess.simple (param.name);
- ma.symbol_reference = param;
- ccode.add_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
- }
- }
- }
-
- public override void visit_return_statement (ReturnStatement stmt) {
- // free local variables
- append_local_free (current_symbol);
-
- ccode.add_return ((current_return_type is VoidType) ? null : new CCodeIdentifier ("result"));
- }
-
- public override void visit_delete_statement (DeleteStatement stmt) {
- var pointer_type = stmt.expression.value_type as PointerType;
- var array_type = stmt.expression.value_type as ArrayType;
-
- if (pointer_type != null) {
- DataType type = pointer_type;
- if (pointer_type.base_type.data_type != null && pointer_type.base_type.data_type.is_reference_type ()) {
- type = pointer_type.base_type;
- }
-
- var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
- ccall.add_argument (get_cvalue (stmt.expression));
- ccode.add_expression (ccall);
- } else if (array_type != null) {
- // TODO free elements
- var free_call = new CCodeFunctionCall (new CCodeIdentifier ("free"));
- free_call.add_argument (new CCodeMemberAccess (get_cvalue (stmt.expression), "data"));
- ccode.add_expression (free_call);
-
- ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "data"), new CCodeConstant ("NULL"));
- ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "length"), new CCodeConstant ("0"));
- } else {
- assert_not_reached ();
- }
- }
-
- public override void visit_expression (Expression expr) {
- if (get_cvalue (expr) != null && !expr.lvalue) {
- // memory management, implicit casts, and boxing/unboxing
- set_cvalue (expr, transform_expression (get_cvalue (expr), expr.value_type, expr.target_type, expr));
- }
- }
-
- public override void visit_boolean_literal (BooleanLiteral expr) {
- set_cvalue (expr, new CCodeConstant (expr.value ? "true" : "false"));
- }
-
- public override void visit_character_literal (CharacterLiteral expr) {
- if (expr.get_char () >= 0x20 && expr.get_char () < 0x80) {
- set_cvalue (expr, new CCodeConstant (expr.value));
- } else {
- set_cvalue (expr, new CCodeConstant ("%uU".printf (expr.get_char ())));
- }
- }
-
- public override void visit_integer_literal (IntegerLiteral expr) {
- set_cvalue (expr, new CCodeConstant (expr.value));
- }
-
- public override void visit_real_literal (RealLiteral expr) {
- string c_literal = expr.value;
- if (c_literal.has_suffix ("d") || c_literal.has_suffix ("D")) {
- // there is no suffix for double in C
- c_literal = c_literal.substring (0, c_literal.length - 1);
- }
- if (!("." in c_literal || "e" in c_literal || "E" in c_literal)) {
- // C requires period or exponent part for floating constants
- if ("f" in c_literal || "F" in c_literal) {
- c_literal = c_literal.substring (0, c_literal.length - 1) + ".f";
- } else {
- c_literal += ".";
- }
- }
- set_cvalue (expr, new CCodeConstant (c_literal));
- }
-
- public override void visit_string_literal (StringLiteral expr) {
- // FIXME handle escaped characters in scanner/parser and escape them here again for C
- var cliteral = new CCodeConstant ("\"\\0\" " + expr.value);
-
- var cbinary = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, cliteral, new CCodeConstant ("1"));
- set_cvalue (expr, new CCodeCastExpression (cbinary, "string_t"));
- }
-
- public override void visit_null_literal (NullLiteral expr) {
- set_cvalue (expr, new CCodeConstant ("NULL"));
- }
-
- public override void visit_base_access (BaseAccess expr) {
- generate_type_declaration (expr.value_type, cfile);
- set_cvalue (expr, new CCodeCastExpression (new CCodeIdentifier ("this"), get_ccode_name (expr.value_type)));
- }
-
- public override void visit_postfix_expression (PostfixExpression expr) {
- MemberAccess ma = find_property_access (expr.inner);
- if (ma != null) {
- // property postfix expression
- var prop = (Property) ma.symbol_reference;
-
- // assign current value to temp variable
- var temp_decl = get_temp_variable (prop.property_type, true, expr);
- emit_temp_var (temp_decl);
- ccode.add_assignment (get_variable_cexpression (temp_decl.name), get_cvalue (expr.inner));
-
- // increment/decrement property
- var op = expr.increment ? CCodeBinaryOperator.PLUS : CCodeBinaryOperator.MINUS;
- var cexpr = new CCodeBinaryExpression (op, get_variable_cexpression (temp_decl.name), new CCodeConstant ("1"));
- store_property (prop, ma.inner, new DovaValue (expr.value_type, cexpr));
-
- // return previous value
- set_cvalue (expr, new CCodeIdentifier (temp_decl.name));
- return;
- }
-
- var op = expr.increment ? CCodeUnaryOperator.POSTFIX_INCREMENT : CCodeUnaryOperator.POSTFIX_DECREMENT;
-
- set_cvalue (expr, new CCodeUnaryExpression (op, get_cvalue (expr.inner)));
- }
-
- private MemberAccess? find_property_access (Expression expr) {
- if (!(expr is MemberAccess)) {
- return null;
- }
-
- var ma = (MemberAccess) expr;
- if (ma.symbol_reference is Property) {
- return ma;
- }
-
- return null;
- }
-
- public bool requires_copy (DataType type) {
- if (!type.is_disposable ()) {
- return false;
- }
-
- var cl = type.data_type as Class;
- if (cl != null && is_reference_counting (cl)
- && get_ccode_ref_function (cl) == "") {
- // empty ref_function => no ref necessary
- return false;
- }
-
- if (type.type_parameter != null) {
- return false;
- }
-
- return true;
- }
-
- public bool requires_destroy (DataType type) {
- if (!type.is_disposable ()) {
- return false;
- }
-
- var array_type = type as ArrayType;
- if (array_type != null && array_type.inline_allocated) {
- return requires_destroy (array_type.element_type);
- }
-
- var cl = type.data_type as Class;
- if (cl != null && is_reference_counting (cl)
- && get_ccode_unref_function (cl) == "") {
- // empty unref_function => no unref necessary
- return false;
- }
-
- if (type.type_parameter != null) {
- return false;
- }
-
- return true;
- }
-
- bool is_ref_function_void (DataType type) {
- var cl = type.data_type as Class;
- if (cl != null && get_ccode_ref_function_void (cl)) {
- return true;
- } else {
- return false;
- }
- }
-
- public virtual CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
- if (expression_type is ValueType && !expression_type.nullable) {
- // normal value type, no null check
- // (copy (&temp, 0, &expr, 0), temp)
-
- var decl = get_temp_variable (expression_type, false, node);
- emit_temp_var (decl);
-
- var ctemp = get_variable_cexpression (decl.name);
-
- var vt = (ValueType) expression_type;
- var st = (Struct) vt.type_symbol;
- var copy_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_copy_function (st)));
- copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
- copy_call.add_argument (new CCodeConstant ("0"));
- copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr));
- copy_call.add_argument (new CCodeConstant ("0"));
-
- var ccomma = new CCodeCommaExpression ();
-
- ccomma.append_expression (copy_call);
- ccomma.append_expression (ctemp);
-
- return ccomma;
- }
-
- /* (temp = expr, temp == NULL ? NULL : ref (temp))
- *
- * can be simplified to
- * ref (expr)
- * if static type of expr is non-null
- */
-
- var dupexpr = get_dup_func_expression (expression_type, node.source_reference);
-
- if (dupexpr == null) {
- node.error = true;
- return null;
- }
-
- var ccall = new CCodeFunctionCall (dupexpr);
-
- if (expr != null && expr.is_non_null ()
- && !is_ref_function_void (expression_type)) {
- // expression is non-null
- ccall.add_argument (get_cvalue (expr));
-
- return ccall;
- } else {
- var decl = get_temp_variable (expression_type, false, node);
- emit_temp_var (decl);
-
- var ctemp = get_variable_cexpression (decl.name);
-
- var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
- if (expression_type.type_parameter != null) {
- // dup functions are optional for type parameters
- var cdupisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_dup_func_expression (expression_type, node.source_reference), new CCodeConstant ("NULL"));
- cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cdupisnull);
- }
-
- ccall.add_argument (ctemp);
-
- var ccomma = new CCodeCommaExpression ();
- ccomma.append_expression (new CCodeAssignment (ctemp, cexpr));
-
- var cifnull = new CCodeConstant ("NULL");
- ccomma.append_expression (new CCodeConditionalExpression (cisnull, cifnull, ccall));
-
- // repeat temp variable at the end of the comma expression
- // if the ref function returns void
- if (is_ref_function_void (expression_type)) {
- ccomma.append_expression (ctemp);
- }
-
- return ccomma;
- }
- }
-
- public virtual void generate_class_declaration (Class cl, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl))) {
- return;
- }
- }
-
- public virtual void generate_interface_declaration (Interface iface, CCodeFile decl_space) {
- }
-
- public virtual void generate_method_declaration (Method m, CCodeFile decl_space) {
- }
-
- public void add_generic_type_arguments (CCodeFunctionCall ccall, List<DataType> type_args, CodeNode expr, bool is_chainup = false) {
- foreach (var type_arg in type_args) {
- ccall.add_argument (get_type_id_expression (type_arg, is_chainup));
- }
- }
-
- public override void visit_object_creation_expression (ObjectCreationExpression expr) {
- CCodeExpression instance = null;
- CCodeExpression creation_expr = null;
-
- var st = expr.type_reference.data_type as Struct;
-
- bool struct_by_ref = false;
- if (st != null && !st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type ()) {
- struct_by_ref = true;
- }
-
- if (struct_by_ref || expr.get_object_initializer ().size > 0) {
- // value-type initialization or object creation expression with object initializer
- var temp_decl = get_temp_variable (expr.type_reference, false, expr);
- emit_temp_var (temp_decl);
-
- instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
- }
-
- if (expr.symbol_reference == null) {
- // no creation method
- if (expr.type_reference.data_type is Struct) {
- var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
- creation_call.add_argument (new CCodeConstant ("0"));
- creation_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (expr.type_reference))));
-
- creation_expr = creation_call;
- }
- } else if (expr.symbol_reference is Method) {
- // use creation method
- var m = (Method) expr.symbol_reference;
- var params = m.get_parameters ();
- CCodeFunctionCall creation_call;
-
- generate_method_declaration (m, cfile);
-
- var cl = expr.type_reference.data_type as Class;
-
- if (!CCodeBaseModule.get_ccode_has_new_function (m)) {
- // use construct function directly
- creation_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m)));
- creation_call.add_argument (new CCodeIdentifier (CCodeBaseModule.get_ccode_type_id (cl)));
- } else {
- creation_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (m)));
- }
-
- if (struct_by_ref && !(get_ccode_instance_pos (m) < 0)) {
- creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
- }
-
- generate_type_declaration (expr.type_reference, cfile);
-
- if (cl != null && !cl.is_compact) {
- add_generic_type_arguments (creation_call, expr.type_reference.get_type_arguments (), expr);
- }
-
- bool ellipsis = false;
-
- int i = 1;
- Iterator<Parameter> params_it = params.iterator ();
- foreach (Expression arg in expr.get_argument_list ()) {
- CCodeExpression cexpr = get_cvalue (arg);
- Parameter param = null;
- if (params_it.next ()) {
- param = params_it.get ();
- ellipsis = param.ellipsis;
- if (!ellipsis) {
- cexpr = handle_struct_argument (param, arg, cexpr);
- }
- }
-
- creation_call.add_argument (cexpr);
-
- i++;
- }
- while (params_it.next ()) {
- var param = params_it.get ();
-
- if (param.ellipsis) {
- ellipsis = true;
- break;
- }
-
- if (param.initializer == null) {
- Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
- return;
- }
-
- /* evaluate default expression here as the code
- * generator might not have visited the formal
- * parameter yet */
- param.initializer.emit (this);
-
- creation_call.add_argument (get_cvalue (param.initializer));
- i++;
- }
-
- if (struct_by_ref && get_ccode_instance_pos (m) < 0) {
- // instance parameter is at the end in a struct creation method
- creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
- }
-
- if (ellipsis) {
- /* ensure variable argument list ends with NULL
- * except when using printf-style arguments */
- if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "") {
- creation_call.add_argument (new CCodeConstant (get_ccode_sentinel (m)));
- }
- }
-
- creation_expr = creation_call;
-
- // cast the return value of the creation method back to the intended type if
- // it requested a special C return type
- if (get_custom_creturn_type (m) != null) {
- creation_expr = new CCodeCastExpression (creation_expr, get_ccode_name (expr.type_reference));
- }
- } else {
- assert (false);
- }
-
- if (instance != null) {
- if (expr.type_reference.data_type is Struct) {
- ccode.add_expression (creation_expr);
- } else {
- ccode.add_assignment (instance, creation_expr);
- }
-
- foreach (MemberInitializer init in expr.get_object_initializer ()) {
- if (init.symbol_reference is Field) {
- var f = (Field) init.symbol_reference;
- var instance_target_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
- var typed_inst = transform_expression (instance, expr.type_reference, instance_target_type);
- CCodeExpression lhs;
- if (expr.type_reference.data_type is Struct) {
- lhs = new CCodeMemberAccess (typed_inst, get_ccode_name (f));
- } else {
- lhs = new CCodeMemberAccess.pointer (typed_inst, get_ccode_name (f));
- }
- ccode.add_assignment (lhs, get_cvalue (init.initializer));
- } else if (init.symbol_reference is Property) {
- var inst_ma = new MemberAccess.simple ("new");
- inst_ma.value_type = expr.type_reference;
- set_cvalue (inst_ma, instance);
- store_property ((Property) init.symbol_reference, inst_ma, init.initializer.target_value);
- }
- }
-
- creation_expr = instance;
- }
-
- if (creation_expr != null) {
- var temp_var = get_temp_variable (expr.value_type);
- var temp_ref = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- ccode.add_assignment (temp_ref, creation_expr);
- set_cvalue (expr, temp_ref);
- }
- }
-
- public CCodeExpression? handle_struct_argument (Parameter param, Expression arg, CCodeExpression? cexpr) {
- if (arg.formal_target_type is GenericType && !(arg.target_type is GenericType)) {
- // we already use a reference for arguments of ref and out parameters
- if (param.direction == ParameterDirection.IN) {
- var unary = cexpr as CCodeUnaryExpression;
- if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
- // *expr => expr
- return unary.inner;
- } else if (cexpr is CCodeIdentifier || cexpr is CCodeMemberAccess) {
- return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
- } else {
- // if cexpr is e.g. a function call, we can't take the address of the expression
- // (tmp = expr, &tmp)
- var ccomma = new CCodeCommaExpression ();
-
- var temp_var = get_temp_variable (arg.target_type);
- 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)));
-
- return ccomma;
- }
- }
- }
-
- return cexpr;
- }
-
- public override void visit_sizeof_expression (SizeofExpression expr) {
- var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- csizeof.add_argument (new CCodeIdentifier (get_ccode_name (expr.type_reference)));
- set_cvalue (expr, csizeof);
- }
-
- public override void visit_typeof_expression (TypeofExpression expr) {
- set_cvalue (expr, get_type_id_expression (expr.type_reference));
- }
-
- public override void visit_unary_expression (UnaryExpression expr) {
- CCodeUnaryOperator op;
- if (expr.operator == UnaryOperator.PLUS) {
- op = CCodeUnaryOperator.PLUS;
- } else if (expr.operator == UnaryOperator.MINUS) {
- op = CCodeUnaryOperator.MINUS;
- } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
- op = CCodeUnaryOperator.LOGICAL_NEGATION;
- } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
- op = CCodeUnaryOperator.BITWISE_COMPLEMENT;
- } else if (expr.operator == UnaryOperator.INCREMENT) {
- op = CCodeUnaryOperator.PREFIX_INCREMENT;
- } else if (expr.operator == UnaryOperator.DECREMENT) {
- op = CCodeUnaryOperator.PREFIX_DECREMENT;
- } else if (expr.operator == UnaryOperator.REF) {
- op = CCodeUnaryOperator.ADDRESS_OF;
- } else if (expr.operator == UnaryOperator.OUT) {
- op = CCodeUnaryOperator.ADDRESS_OF;
- } else {
- assert_not_reached ();
- }
- set_cvalue (expr, new CCodeUnaryExpression (op, get_cvalue (expr.inner)));
- }
-
- public override void visit_cast_expression (CastExpression expr) {
- if (expr.is_silent_cast) {
- if (expr.inner.value_type is ObjectType) {
- var ccomma = new CCodeCommaExpression ();
- var temp_decl = get_temp_variable (expr.inner.value_type, true, expr);
-
- emit_temp_var (temp_decl);
-
- var ctemp = get_variable_cexpression (temp_decl.name);
- var cinit = new CCodeAssignment (ctemp, get_cvalue (expr.inner));
- var ccheck = create_type_check (ctemp, expr.type_reference);
- var ccast = new CCodeCastExpression (ctemp, get_ccode_name (expr.type_reference));
- var cnull = new CCodeConstant ("NULL");
-
- ccomma.append_expression (cinit);
- ccomma.append_expression (new CCodeConditionalExpression (ccheck, ccast, cnull));
-
- set_cvalue (expr, ccomma);
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "Operation not supported for this type");
- }
- return;
- }
-
- 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);
- emit_temp_var (temp_decl);
- var cvar = get_variable_cexpression (temp_decl.name);
-
- var ccomma = new CCodeCommaExpression ();
- ccomma.append_expression (new CCodeAssignment (cvar, get_cvalue (expr.inner)));
-
- var to_any = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_to_any"));
- to_any.add_argument (get_type_id_expression (expr.inner.value_type));
- to_any.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar));
- to_any.add_argument (new CCodeConstant ("0"));
- ccomma.append_expression (to_any);
-
- set_cvalue (expr, ccomma);
- return;
- } 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);
- emit_temp_var (temp_decl);
- var cvar = get_variable_cexpression (temp_decl.name);
-
- var ccomma = new CCodeCommaExpression ();
-
- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (expr.type_reference)));
-
- var to_any = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_from_any"));
- to_any.add_argument (get_type_id_expression (expr.type_reference));
- to_any.add_argument (get_cvalue (expr.inner));
- to_any.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar));
- to_any.add_argument (new CCodeConstant ("0"));
- ccomma.append_expression (to_any);
-
- ccomma.append_expression (cvar);
-
- set_cvalue (expr, ccomma);
- return;
- }
-
- if (expr.inner.value_type is ArrayType && expr.type_reference is PointerType) {
- var array_type = (ArrayType) expr.inner.value_type;
- if (!array_type.fixed_length) {
- set_cvalue (expr, new CCodeMemberAccess (get_cvalue (expr.inner), "data"));
- return;
- }
- }
-
- generate_type_declaration (expr.type_reference, cfile);
-
- if (expr.inner.value_type is GenericType && !(expr.type_reference is GenericType)) {
- // generic types use an extra pointer, dereference that pointer
- set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeCastExpression (get_cvalue (expr.inner), get_ccode_name (expr.type_reference) + "*")));
- } else {
- set_cvalue (expr, new CCodeCastExpression (get_cvalue (expr.inner), get_ccode_name (expr.type_reference)));
- }
- }
-
- public override void visit_pointer_indirection (PointerIndirection expr) {
- set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_cvalue (expr.inner)));
- }
-
- public override void visit_addressof_expression (AddressofExpression expr) {
- set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue (expr.inner)));
- }
-
- public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) {
- /* (tmp = var, var = null, tmp) */
- var ccomma = new CCodeCommaExpression ();
- var temp_decl = get_temp_variable (expr.value_type, true, expr);
- emit_temp_var (temp_decl);
- var cvar = get_variable_cexpression (temp_decl.name);
-
- ccomma.append_expression (new CCodeAssignment (cvar, get_cvalue (expr.inner)));
- ccomma.append_expression (new CCodeAssignment (get_cvalue (expr.inner), new CCodeConstant ("NULL")));
- ccomma.append_expression (cvar);
- set_cvalue (expr, ccomma);
- }
-
- public override void visit_binary_expression (BinaryExpression expr) {
- var cleft = get_cvalue (expr.left);
- var cright = get_cvalue (expr.right);
-
- CCodeBinaryOperator op;
- if (expr.operator == BinaryOperator.PLUS) {
- op = CCodeBinaryOperator.PLUS;
- } else if (expr.operator == BinaryOperator.MINUS) {
- op = CCodeBinaryOperator.MINUS;
- } else if (expr.operator == BinaryOperator.MUL) {
- op = CCodeBinaryOperator.MUL;
- } else if (expr.operator == BinaryOperator.DIV) {
- op = CCodeBinaryOperator.DIV;
- } else if (expr.operator == BinaryOperator.MOD) {
- op = CCodeBinaryOperator.MOD;
- } else if (expr.operator == BinaryOperator.SHIFT_LEFT) {
- op = CCodeBinaryOperator.SHIFT_LEFT;
- } else if (expr.operator == BinaryOperator.SHIFT_RIGHT) {
- op = CCodeBinaryOperator.SHIFT_RIGHT;
- } else if (expr.operator == BinaryOperator.LESS_THAN) {
- op = CCodeBinaryOperator.LESS_THAN;
- } else if (expr.operator == BinaryOperator.GREATER_THAN) {
- op = CCodeBinaryOperator.GREATER_THAN;
- } else if (expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL) {
- op = CCodeBinaryOperator.LESS_THAN_OR_EQUAL;
- } else if (expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
- op = CCodeBinaryOperator.GREATER_THAN_OR_EQUAL;
- } else if (expr.operator == BinaryOperator.EQUALITY) {
- op = CCodeBinaryOperator.EQUALITY;
- } else if (expr.operator == BinaryOperator.INEQUALITY) {
- op = CCodeBinaryOperator.INEQUALITY;
- } else if (expr.operator == BinaryOperator.BITWISE_AND) {
- op = CCodeBinaryOperator.BITWISE_AND;
- } else if (expr.operator == BinaryOperator.BITWISE_OR) {
- op = CCodeBinaryOperator.BITWISE_OR;
- } else if (expr.operator == BinaryOperator.BITWISE_XOR) {
- op = CCodeBinaryOperator.BITWISE_XOR;
- } else if (expr.operator == BinaryOperator.AND) {
- op = CCodeBinaryOperator.AND;
- } else if (expr.operator == BinaryOperator.OR) {
- op = CCodeBinaryOperator.OR;
- } else if (expr.operator == BinaryOperator.IN) {
- set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeBinaryExpression (CCodeBinaryOperator.BITWISE_AND, cright, cleft), cleft));
- return;
- } else {
- assert_not_reached ();
- }
-
- if (expr.operator == BinaryOperator.EQUALITY ||
- expr.operator == BinaryOperator.INEQUALITY) {
- var left_type_as_struct = expr.left.value_type.data_type as Struct;
- var right_type_as_struct = expr.right.value_type.data_type as Struct;
-
- if (expr.left.value_type.data_type is Class && !((Class) expr.left.value_type.data_type).is_compact &&
- expr.right.value_type.data_type is Class && !((Class) expr.right.value_type.data_type).is_compact) {
- var left_cl = (Class) expr.left.value_type.data_type;
- var right_cl = (Class) expr.right.value_type.data_type;
-
- if (left_cl != right_cl) {
- if (left_cl.is_subtype_of (right_cl)) {
- cleft = generate_instance_cast (cleft, right_cl);
- } else if (right_cl.is_subtype_of (left_cl)) {
- cright = generate_instance_cast (cright, left_cl);
- }
- }
- } else if (left_type_as_struct != null && right_type_as_struct != null) {
- // FIXME generate and use compare/equal function for real structs
- if (expr.left.value_type.nullable && expr.right.value_type.nullable) {
- // FIXME also compare contents, not just address
- } else if (expr.left.value_type.nullable) {
- // FIXME check left value is not null
- cleft = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cleft);
- } else if (expr.right.value_type.nullable) {
- // FIXME check right value is not null
- cright = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cright);
- }
- }
- }
-
- set_cvalue (expr, new CCodeBinaryExpression (op, cleft, cright));
- }
-
- CCodeExpression? create_type_check (CCodeNode ccodenode, DataType type) {
- var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a"));
- ccheck.add_argument ((CCodeExpression) ccodenode);
- ccheck.add_argument (get_type_id_expression (type));
- return ccheck;
- }
-
- public override void visit_type_check (TypeCheck expr) {
- generate_type_declaration (expr.type_reference, cfile);
-
- set_cvalue (expr, create_type_check (get_cvalue (expr.expression), expr.type_reference));
- if (get_cvalue (expr) is CCodeInvalidExpression) {
- Report.error (expr.source_reference, "type check expressions not supported for compact classes, structs, and enums");
- }
- }
-
- public override void visit_lambda_expression (LambdaExpression l) {
- l.accept_children (this);
-
- set_cvalue (l, new CCodeIdentifier (get_ccode_name (l.method)));
- }
-
- // manage memory and implicit casts
- public CCodeExpression transform_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
- var cexpr = source_cexpr;
- if (expression_type == null) {
- return cexpr;
- }
-
-
- if (expression_type.value_owned
- && (target_type == null || !target_type.value_owned)) {
- // value leaked, destroy it
- var pointer_type = target_type as PointerType;
- if (pointer_type != null && !(pointer_type.base_type is VoidType)) {
- // manual memory management for non-void pointers
- // 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);
- emit_temp_var (decl);
- temp_ref_vars.insert (0, decl);
- cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr);
- }
- }
-
- if (target_type == null) {
- // value will be destroyed, no need for implicit casts
- return cexpr;
- }
-
- cexpr = get_implicit_cast_expression (cexpr, expression_type, target_type, expr);
-
- if (target_type.value_owned && !expression_type.value_owned) {
- // need to copy value
- if (requires_copy (target_type) && !(expression_type is NullType)) {
- CodeNode node = expr;
- if (node == null) {
- node = expression_type;
- }
- cexpr = get_ref_cexpression (target_type, cexpr, expr, node);
- }
- }
-
- return cexpr;
- }
-
- public virtual CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
- var cexpr = source_cexpr;
-
- if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) {
- // same type, no cast required
- return cexpr;
- }
-
- if (expression_type is NullType) {
- if (target_type is ArrayType) {
- var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
- array.add_argument (new CCodeConstant ("NULL"));
- array.add_argument (new CCodeConstant ("0"));
- return array;
- }
-
- // null literal, no cast required when not converting to generic type pointer
- return cexpr;
- }
-
- if (expression_type is ArrayType && target_type is PointerType) {
- var array_type = (ArrayType) expression_type;
- if (!array_type.inline_allocated) {
- return new CCodeMemberAccess (cexpr, "data");
- }
- }
-
- if (expression_type is ArrayType && target_type is ArrayType) {
- var source_array_type = (ArrayType) expression_type;
- var target_array_type = (ArrayType) target_type;
- if (source_array_type.inline_allocated && !target_array_type.inline_allocated) {
- var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array"));
- array.add_argument (cexpr);
-
- var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- csizeof.add_argument (cexpr);
- var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- csizeofelement.add_argument (new CCodeElementAccess (cexpr, new CCodeConstant ("0")));
- array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement));
-
- return array;
- }
- }
-
- generate_type_declaration (target_type, cfile);
-
- if (target_type is DelegateType && expression_type is MethodType) {
- var deleg_type = (DelegateType) target_type;
- var method_type = (MethodType) expression_type;
- CCodeExpression delegate_target;
- if (expr is LambdaExpression) {
- var lambda = (LambdaExpression) expr;
- if (lambda.method.closure) {
- int block_id = get_block_id (current_closure_block);
- delegate_target = get_variable_cexpression ("_data%d_".printf (block_id));
- } else if (get_this_type () != null) {
- delegate_target = new CCodeIdentifier ("this");
- } else {
- delegate_target = new CCodeConstant ("NULL");
- }
- } else {
- if (method_type.method_symbol.binding == MemberBinding.INSTANCE) {
- var ma = (MemberAccess) expr;
- delegate_target = (CCodeExpression) get_ccodenode (ma.inner);
- } else {
- delegate_target = new CCodeConstant ("NULL");
- }
- }
-
- var d = deleg_type.delegate_symbol;
-
- string wrapper_name = "_wrapper%d_".printf (next_wrapper_id++);
- var wrapper = new CCodeFunction (wrapper_name);
- wrapper.modifiers = CCodeModifiers.STATIC;
- var call = new CCodeFunctionCall (source_cexpr);
-
- if (method_type.method_symbol.binding == MemberBinding.INSTANCE) {
- wrapper.add_parameter (new CCodeParameter ("this", "void *"));
- call.add_argument (new CCodeIdentifier ("this"));
- }
-
- var method_param_iter = method_type.method_symbol.get_parameters ().iterator ();
- foreach (Parameter param in d.get_parameters ()) {
- method_param_iter.next ();
- var method_param = method_param_iter.get ();
- string ctype = get_ccode_name (param.variable_type);
- if (param.variable_type is GenericType && !(method_param.variable_type is GenericType)) {
- ctype = get_ccode_name (method_param.variable_type) + "*";
- call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)));
- } else if (!(param.variable_type is GenericType) && method_param.variable_type is GenericType) {
- call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
- } else {
- call.add_argument (new CCodeIdentifier (param.name));
- }
-
- wrapper.add_parameter (new CCodeParameter (param.name, ctype));
- }
-
- wrapper.block = new CCodeBlock ();
- if (d.return_type is VoidType) {
- wrapper.block.add_statement (new CCodeExpressionStatement (call));
- } else {
- var method_return_type = method_type.method_symbol.return_type;
- if (d.return_type is GenericType && !(method_return_type is GenericType)) {
- wrapper.add_parameter (new CCodeParameter ("result", get_ccode_name (method_return_type) + "*"));
- wrapper.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), call)));
- } else if (!(d.return_type is GenericType) && method_return_type is GenericType) {
- wrapper.return_type = get_ccode_name (d.return_type);
- var cdecl = new CCodeDeclaration (get_ccode_name (d.return_type));
- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
- call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
- wrapper.block.add_statement (new CCodeExpressionStatement (call));
- wrapper.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- } else if (d.return_type is GenericType) {
- wrapper.add_parameter (new CCodeParameter ("result", "void *"));
- wrapper.block.add_statement (new CCodeExpressionStatement (call));
- } else {
- wrapper.return_type = get_ccode_name (d.return_type);
- wrapper.block.add_statement (new CCodeReturnStatement (call));
- }
- }
-
- cfile.add_function (wrapper);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_new".printf (get_ccode_lower_case_name (deleg_type.delegate_symbol))));
- ccall.add_argument (delegate_target);
- ccall.add_argument (new CCodeIdentifier (wrapper_name));
- return ccall;
- }
-
- var cl = target_type.data_type as Class;
- var iface = target_type.data_type as Interface;
- if (context.checking && (iface != null || (cl != null && !cl.is_compact))) {
- // checked cast for strict subtypes of GTypeInstance
- return generate_instance_cast (cexpr, target_type.data_type);
- } else if (target_type.data_type != null && get_ccode_name (expression_type) != get_ccode_name (target_type)) {
- var st = target_type.data_type as Struct;
- if (target_type.data_type.is_reference_type () || (st != null && st.is_simple_type ())) {
- // don't cast non-simple structs
- return new CCodeCastExpression (cexpr, get_ccode_name (target_type));
- } else {
- return cexpr;
- }
- } else {
- return cexpr;
- }
- }
-
- public void store_property (Property prop, Expression? instance, TargetValue value) {
- string set_func;
-
- var base_property = prop;
- if (prop.base_property != null) {
- base_property = prop.base_property;
- } else if (prop.base_interface_property != null) {
- base_property = prop.base_interface_property;
- }
-
- generate_property_accessor_declaration (base_property.set_accessor, cfile);
- set_func = get_ccode_name (base_property.set_accessor);
-
- if (!prop.external && prop.external_package) {
- // internal VAPI properties
- // only add them once per source file
- if (add_generated_external_symbol (prop)) {
- visit_property (prop);
- }
- }
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
-
- if (prop.binding == MemberBinding.INSTANCE) {
- /* target instance is first argument */
- ccall.add_argument ((CCodeExpression) get_ccodenode (instance));
- }
-
- ccall.add_argument (get_cvalue_ (value));
-
- ccode.add_expression (ccall);
- }
-
- public bool add_generated_external_symbol (Symbol external_symbol) {
- return generated_external_symbols.add (external_symbol);
- }
-
- public static DataType get_data_type_for_symbol (TypeSymbol sym) {
- DataType type = null;
-
- if (sym is Class) {
- type = new ObjectType ((Class) sym);
- } else if (sym is Interface) {
- type = new ObjectType ((Interface) sym);
- } else if (sym is Struct) {
- var st = (Struct) sym;
- if (st.is_boolean_type ()) {
- type = new BooleanType (st);
- } else if (st.is_integer_type ()) {
- type = new IntegerType (st);
- } else if (st.is_floating_type ()) {
- type = new FloatingType (st);
- } else {
- type = new StructValueType (st);
- }
- } else if (sym is Enum) {
- type = new EnumValueType ((Enum) sym);
- } else {
- Report.error (null, "internal error: `%s' is not a supported type".printf (sym.get_full_name ()));
- return new InvalidType ();
- }
-
- return type;
- }
-
- public CCodeExpression? default_value_for_type (DataType type, bool initializer_expression) {
- var st = type.data_type as Struct;
- var array_type = type as ArrayType;
- if (type is GenericType) {
- var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- value_size.add_argument (get_type_id_expression (type));
-
- var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
- alloca_call.add_argument (value_size);
-
- var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- memset_call.add_argument (alloca_call);
- memset_call.add_argument (new CCodeConstant ("0"));
- memset_call.add_argument (value_size);
-
- return memset_call;
- } else if (initializer_expression && !type.nullable &&
- ((st != null && st.get_fields ().size > 0) ||
- array_type != null)) {
- // 0-initialize struct with struct initializer { 0 }
- // only allowed as initializer expression in C
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
- return clist;
- } else if ((type.data_type != null && type.data_type.is_reference_type ())
- || type.nullable
- || type is PointerType || type is DelegateType) {
- return new CCodeConstant ("NULL");
- } else if (type.data_type != null && get_ccode_default_value (type.data_type) != "") {
- return new CCodeConstant (get_ccode_default_value (type.data_type));
- }
- return null;
- }
-
- public CCodeExpression? get_ccodenode (Expression node) {
- if (get_cvalue (node) == null) {
- node.emit (this);
- }
- return get_cvalue (node);
- }
-
- public string get_ccode_name (CodeNode node) {
- return CCodeBaseModule.get_ccode_name (node);
- }
-
- public string get_ccode_const_name (CodeNode node) {
- return CCodeBaseModule.get_ccode_const_name (node);
- }
-
- public string get_ccode_copy_function (TypeSymbol node) {
- return CCodeBaseModule.get_ccode_copy_function (node);
- }
-
- public string get_ccode_dup_function (TypeSymbol node) {
- return CCodeBaseModule.get_ccode_dup_function (node);
- }
-
- public string get_ccode_ref_function (TypeSymbol node) {
- return CCodeBaseModule.get_ccode_ref_function (node);
- }
-
- public string get_ccode_unref_function (ObjectTypeSymbol node) {
- return CCodeBaseModule.get_ccode_unref_function (node);
- }
-
- public string get_ccode_free_function (TypeSymbol node) {
- return CCodeBaseModule.get_ccode_free_function (node);
- }
-
- public bool is_reference_counting (TypeSymbol node) {
- return CCodeBaseModule.is_reference_counting (node);
- }
-
- public bool get_ccode_ref_function_void (Class node) {
- return CCodeBaseModule.get_ccode_ref_function_void (node);
- }
-
- public string get_ccode_default_value (TypeSymbol node) {
- return CCodeBaseModule.get_ccode_default_value (node);
- }
-
- public string get_ccode_real_name (Method node) {
- return CCodeBaseModule.get_ccode_real_name (node);
- }
-
- public string get_ccode_lower_case_name (CodeNode node, string? infix = null) {
- return CCodeBaseModule.get_ccode_lower_case_name (node, infix);
- }
-
- public string get_ccode_upper_case_name (Symbol node, string? infix = null) {
- return CCodeBaseModule.get_ccode_upper_case_name (node, infix);
- }
-
- public string get_ccode_lower_case_prefix (Symbol node) {
- return CCodeBaseModule.get_ccode_lower_case_prefix (node);
- }
-
- public double get_ccode_instance_pos (CodeNode node) {
- return CCodeBaseModule.get_ccode_instance_pos (node);
- }
-
- public string get_ccode_vfunc_name (Method node) {
- return CCodeBaseModule.get_ccode_vfunc_name (node);
- }
-
- public string get_ccode_sentinel (Method m) {
- return CCodeBaseModule.get_ccode_sentinel (m);
- }
-
- public string get_ccode_declarator_suffix (DataType type) {
- return CCodeBaseModule.get_ccode_declarator_suffix (type);
- }
-
- public DataType? get_this_type () {
- if (current_method != null && current_method.binding == MemberBinding.INSTANCE) {
- return current_method.this_parameter.variable_type;
- } else if (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE) {
- return current_property_accessor.prop.this_parameter.variable_type;
- }
- return null;
- }
-
- public CCodeExpression generate_instance_cast (CCodeExpression expr, TypeSymbol type) {
- return new CCodeCastExpression (expr, get_ccode_name (type) + "*");
- }
-
- public virtual string? get_custom_creturn_type (Method m) {
- return null;
- }
-
- public virtual bool method_has_wrapper (Method method) {
- return false;
- }
-
- public virtual void add_simple_check (CodeNode node, bool always_fails = false) {
- }
-
- public CCodeExpression? get_cvalue (Expression expr) {
- if (expr.target_value == null) {
- return null;
- }
- var dova_value = (DovaValue) expr.target_value;
- return dova_value.cvalue;
- }
-
- public CCodeExpression? get_cvalue_ (TargetValue value) {
- var dova_value = (DovaValue) value;
- return dova_value.cvalue;
- }
-
- public void set_cvalue (Expression expr, CCodeExpression? cvalue) {
- var dova_value = (DovaValue) expr.target_value;
- if (dova_value == null) {
- dova_value = new DovaValue (expr.value_type);
- expr.target_value = dova_value;
- }
- dova_value.cvalue = cvalue;
- }
-}
-
-public class Vala.DovaValue : TargetValue {
- public CCodeExpression cvalue;
-
- public DovaValue (DataType? value_type = null, CCodeExpression? cvalue = null) {
- base (value_type);
- this.cvalue = cvalue;
- }
-}
+++ /dev/null
-/* valadovacontrolflowmodule.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>
- */
-
-public abstract class Vala.DovaControlFlowModule : DovaMethodModule {
- public override void visit_if_statement (IfStatement stmt) {
- ccode.open_if (get_cvalue (stmt.condition));
-
- stmt.true_statement.emit (this);
-
- if (stmt.false_statement != null) {
- ccode.add_else ();
- stmt.false_statement.emit (this);
- }
-
- ccode.close ();
- }
-
- public override void visit_switch_statement (SwitchStatement stmt) {
- ccode.open_switch (get_cvalue (stmt.expression));
-
- foreach (SwitchSection section in stmt.get_sections ()) {
- if (section.has_default_label ()) {
- ccode.add_default ();
- }
- section.emit (this);
- }
-
- ccode.close ();
- }
-
- public override void visit_switch_label (SwitchLabel label) {
- if (label.expression != null) {
- label.expression.emit (this);
-
- visit_end_full_expression (label.expression);
-
- ccode.add_case (get_cvalue (label.expression));
- }
- }
-
- public override void visit_loop (Loop stmt) {
- ccode.open_while (new CCodeConstant ("true"));
-
- stmt.body.emit (this);
-
- ccode.close ();
- }
-
- public override void visit_break_statement (BreakStatement stmt) {
- append_local_free (current_symbol, true);
-
- ccode.add_break ();
- }
-
- public override void visit_continue_statement (ContinueStatement stmt) {
- append_local_free (current_symbol, true);
-
- ccode.add_continue ();
- }
-}
-
+++ /dev/null
-/* valadovadelegatemodule.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>
- * Raffaele Sandrini <raffaele@sandrini.ch>
- */
-
-/**
- * The link between a delegate and generated code.
- */
-public class Vala.DovaDelegateModule : DovaValueModule {
- public override void generate_delegate_declaration (Delegate d, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, d, get_ccode_name (d))) {
- return;
- }
-
- decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (d)), new CCodeVariableDeclarator (get_ccode_name (d))));
-
- generate_class_declaration (type_class, decl_space);
- generate_method_declaration ((Method) object_class.scope.lookup ("ref"), decl_space);
- generate_method_declaration ((Method) object_class.scope.lookup ("unref"), decl_space);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (d)), "DovaType *");
- if (d.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
- decl_space.add_function_declaration (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (d)));
- if (d.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- decl_space.add_function_declaration (type_init_fun);
-
- generate_type_declaration (d.return_type, decl_space);
-
- var function = generate_new_function (d, decl_space);
- function.block = null;
- decl_space.add_function_declaration (function);
-
- function = generate_invoke_function (d, decl_space);
- function.block = null;
- decl_space.add_function_declaration (function);
- }
-
- CCodeFunction generate_new_function (Delegate d, CCodeFile decl_space) {
- var function = new CCodeFunction ("%s_new".printf (get_ccode_lower_case_name (d)), "%s*".printf (get_ccode_name (d)));
- if (d.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- function.add_parameter (new CCodeParameter ("target", "DovaObject *"));
- function.add_parameter (new CCodeParameter ("(*method) (void)", "void"));
-
- function.block = new CCodeBlock ();
-
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc"));
- alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (d)))));
-
- var cdecl = new CCodeDeclaration ("%s*".printf (get_ccode_name (d)));
- cdecl.add_declarator (new CCodeVariableDeclarator ("this", alloc_call));
- function.block.add_statement (cdecl);
-
- var init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_init"));
- init_call.add_argument (new CCodeIdentifier ("this"));
- init_call.add_argument (new CCodeIdentifier ("target"));
- function.block.add_statement (new CCodeExpressionStatement (init_call));
-
- var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (d))));
- priv.add_argument (new CCodeIdentifier ("this"));
- var assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (priv, "method"), new CCodeIdentifier ("method"));
- function.block.add_statement (new CCodeExpressionStatement (assignment));
-
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this")));
-
- return function;
- }
-
- CCodeFunction generate_invoke_function (Delegate d, CCodeFile decl_space) {
- var function = new CCodeFunction ("%s_invoke".printf (get_ccode_lower_case_name (d)));
-
- if (d.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- function.add_parameter (new CCodeParameter ("this", "%s*".printf (get_ccode_name (d))));
-
- string param_list = "";
-
- foreach (Parameter param in d.get_parameters ()) {
- generate_type_declaration (param.variable_type, decl_space);
-
- function.add_parameter (new CCodeParameter (param.name, get_ccode_name (param.variable_type)));
-
- if (param_list != "") {
- param_list += ", ";
- }
- param_list += get_ccode_name (param.variable_type);
- }
-
- if (d.return_type is GenericType) {
- function.add_parameter (new CCodeParameter ("result", "void *"));
-
- if (param_list != "") {
- param_list += ", ";
- }
- param_list += "void *";
- } else {
- function.return_type = get_ccode_name (d.return_type);
- }
-
- function.block = new CCodeBlock ();
-
- var get_target = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_get_target"));
- get_target.add_argument (new CCodeIdentifier ("this"));
-
- var cdecl = new CCodeDeclaration ("DovaObject*");
- cdecl.add_declarator (new CCodeVariableDeclarator ("target", get_target));
- function.block.add_statement (cdecl);
-
- var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (d))));
- priv.add_argument (new CCodeIdentifier ("this"));
-
- string instance_param_list = "(DovaObject *";
- if (param_list != "") {
- instance_param_list += ",";
- instance_param_list += param_list;
- }
- instance_param_list += ")";
-
- var instance_block = new CCodeBlock ();
- var instance_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, instance_param_list)));
-
- instance_call.add_argument (new CCodeIdentifier ("target"));
-
- string static_param_list = "(";
- if (param_list != "") {
- static_param_list += param_list;
- } else {
- static_param_list += "void";
- }
- static_param_list += ")";
-
- var static_block = new CCodeBlock ();
- var static_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, static_param_list)));
-
- foreach (Parameter param in d.get_parameters ()) {
- instance_call.add_argument (new CCodeIdentifier (param.name));
- static_call.add_argument (new CCodeIdentifier (param.name));
- }
-
- if (d.return_type is VoidType) {
- instance_block.add_statement (new CCodeExpressionStatement (instance_call));
- static_block.add_statement (new CCodeExpressionStatement (static_call));
- } else if (d.return_type is GenericType) {
- instance_call.add_argument (new CCodeIdentifier ("result"));
- static_call.add_argument (new CCodeIdentifier ("result"));
- instance_block.add_statement (new CCodeExpressionStatement (instance_call));
- static_block.add_statement (new CCodeExpressionStatement (static_call));
- } else {
- instance_block.add_statement (new CCodeReturnStatement (instance_call));
- static_block.add_statement (new CCodeReturnStatement (static_call));
- }
-
- function.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("target"), instance_block, static_block));
-
- return function;
- }
-
- public override void visit_delegate (Delegate d) {
- d.accept_children (this);
-
- generate_delegate_declaration (d, cfile);
-
- if (!d.is_internal_symbol ()) {
- generate_delegate_declaration (d, header_file);
- }
-
- generate_type_get_function (d, delegate_class);
-
- var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (get_ccode_name (d)));
-
- instance_priv_struct.add_field ("void", "(*method) (void)");
-
- cfile.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (get_ccode_name (d)))));
- cfile.add_type_definition (instance_priv_struct);
-
- string macro = "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (d), get_ccode_lower_case_name (d));
- cfile.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (d, null)), macro));
-
- var cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (d)), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_type_offset".printf (get_ccode_lower_case_name (d)), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- cfile.add_function (generate_new_function (d, cfile));
- cfile.add_function (generate_invoke_function (d, cfile));
- }
-}
+++ /dev/null
-/* valadovaerrormodule.vala
- *
- * Copyright (C) 2008-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>
- * Thijs Vermeir <thijsvermeir@gmail.com>
- */
-
-public class Vala.DovaErrorModule : DovaDelegateModule {
- private int current_try_id = 0;
- private int next_try_id = 0;
- private bool is_in_catch = false;
-
- public override void visit_throw_statement (ThrowStatement stmt) {
- ccode.add_assignment (new CCodeIdentifier ("dova_error"), get_cvalue (stmt.error_expression));
-
- add_simple_check (stmt, true);
- }
-
- public void return_with_exception () {
- // propagate error
- // nothing to do
-
- // free local variables
- append_local_free (current_symbol, false);
-
- if (current_method is CreationMethod && current_method.parent_symbol is Class) {
- var cl = current_method.parent_symbol as Class;
- var unref_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_unref_function (cl)));
- unref_call.add_argument (new CCodeIdentifier ("this"));
- ccode.add_expression (unref_call);
- ccode.add_return ();
- } else if (current_return_type is VoidType) {
- ccode.add_return ();
- } else {
- ccode.add_return (default_value_for_type (current_return_type, false));
- }
- }
-
- void uncaught_error_statement () {
- // free local variables
- append_local_free (current_symbol, false);
-
- // TODO log uncaught error as critical warning
-
- if (current_method is CreationMethod) {
- ccode.add_return ();
- } else if (current_return_type is VoidType) {
- ccode.add_return ();
- } else if (current_return_type != null) {
- ccode.add_return (default_value_for_type (current_return_type, false));
- }
- }
-
- bool in_finally_block (CodeNode node) {
- var current_node = node;
- while (current_node != null) {
- var try_stmt = current_node.parent_node as TryStatement;
- if (try_stmt != null && try_stmt.finally_body == current_node) {
- return true;
- }
- current_node = current_node.parent_node;
- }
- return false;
- }
-
- public override void add_simple_check (CodeNode node, bool always_fails = false) {
- if (always_fails) {
- // inner_error is always set, avoid unnecessary if statement
- // eliminates C warnings
- } else {
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"));
- ccode.open_if (ccond);
- }
-
- if (current_try != null) {
- // surrounding try found
-
- // free local variables
- append_local_free (current_symbol, false, current_try);
-
- var error_types = new ArrayList<DataType> ();
- foreach (DataType node_error_type in node.get_error_types ()) {
- error_types.add (node_error_type);
- }
-
- bool has_general_catch_clause = false;
-
- if (!is_in_catch) {
- var handled_error_types = new ArrayList<DataType> ();
- foreach (CatchClause clause in current_try.get_catch_clauses ()) {
- // keep track of unhandled error types
- foreach (DataType node_error_type in error_types) {
- if (clause.error_type == null || node_error_type.compatible (clause.error_type)) {
- handled_error_types.add (node_error_type);
- }
- }
- foreach (DataType handled_error_type in handled_error_types) {
- error_types.remove (handled_error_type);
- }
- handled_error_types.clear ();
-
- if (clause.error_type.equals (new ObjectType (error_class))) {
- // general catch clause, this should be the last one
- has_general_catch_clause = true;
- ccode.add_goto (clause.clabel_name);
- break;
- } else {
- var catch_type = clause.error_type as ObjectType;
-
- var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a"));
- type_check.add_argument (new CCodeIdentifier ("dova_error"));
- type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (catch_type.type_symbol)))));
-
- ccode.open_if (type_check);
-
- // go to catch clause if error domain matches
- ccode.add_goto (clause.clabel_name);
- ccode.close ();
- }
- }
- }
-
- if (has_general_catch_clause) {
- // every possible error is already caught
- // as there is a general catch clause
- // no need to do anything else
- } else if (error_types.size > 0) {
- // go to finally clause if no catch clause matches
- // and there are still unhandled error types
- ccode.add_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 {
- assert_not_reached ();
- }
- } else if (current_method != null && current_method.get_error_types ().size > 0) {
- // current method can fail, propagate error
- CCodeExpression ccond = null;
-
- foreach (DataType error_type in current_method.get_error_types ()) {
- // If Dova.Error is allowed we propagate everything
- if (error_type.equals (new ObjectType (error_class))) {
- ccond = null;
- break;
- }
-
- // Check the allowed error domains to propagate
- var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a"));
- type_check.add_argument (new CCodeIdentifier ("dova_error"));
- type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (error_class)))));
- if (ccond == null) {
- ccond = type_check;
- } else {
- ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, ccond, type_check);
- }
- }
-
- if (ccond == null) {
- return_with_exception ();
- } else {
- ccode.open_if (ccond);
- return_with_exception ();
- ccode.add_else ();
- uncaught_error_statement ();
- ccode.close ();
- }
- } else {
- uncaught_error_statement ();
- }
-
- if (!always_fails) {
- ccode.close ();
- }
- }
-
- public override void visit_try_statement (TryStatement stmt) {
- int this_try_id = next_try_id++;
-
- var old_try = current_try;
- var old_try_id = current_try_id;
- var old_is_in_catch = is_in_catch;
- current_try = stmt;
- current_try_id = this_try_id;
- is_in_catch = true;
-
- foreach (CatchClause clause in stmt.get_catch_clauses ()) {
- clause.clabel_name = "__catch%d_%s".printf (this_try_id, get_ccode_lower_case_name (clause.error_type));
- }
-
- is_in_catch = false;
- stmt.body.emit (this);
- is_in_catch = true;
-
- foreach (CatchClause clause in stmt.get_catch_clauses ()) {
- ccode.add_goto ("__finally%d".printf (this_try_id));
- clause.emit (this);
- }
-
- current_try = old_try;
- current_try_id = old_try_id;
- is_in_catch = old_is_in_catch;
-
- ccode.add_label ("__finally%d".printf (this_try_id));
- if (stmt.finally_body != null) {
- stmt.finally_body.emit (this);
- }
-
- // check for errors not handled by this try statement
- // may be handled by outer try statements or propagated
- add_simple_check (stmt, !stmt.after_try_block_reachable);
- }
-
- public override void visit_catch_clause (CatchClause clause) {
- generate_type_declaration (clause.error_type, cfile);
-
- ccode.add_label (clause.clabel_name);
-
- ccode.open_block ();
-
- string variable_name;
- if (clause.variable_name != null) {
- variable_name = get_variable_cname (clause.variable_name);
- } else {
- variable_name = "__err";
- }
-
- if (clause.variable_name != null) {
- var cdecl = new CCodeDeclaration (get_ccode_name (clause.error_type));
- cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, new CCodeIdentifier ("dova_error")));
- ccode.add_statement (cdecl);
- } else {
- // error object is not used within catch statement, clear it
- var cclear = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
- cclear.add_argument (new CCodeIdentifier ("dova_error"));
- ccode.add_statement (new CCodeExpressionStatement (cclear));
- }
- ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"))));
-
- clause.body.emit (this);
-
- ccode.close ();
- }
-
- public override void append_local_free (Symbol sym, bool stop_at_loop = false, CodeNode? stop_at = null) {
- var finally_block = (Block) null;
- if (sym.parent_node is TryStatement) {
- finally_block = (sym.parent_node as TryStatement).finally_body;
- } else if (sym.parent_node is CatchClause) {
- finally_block = (sym.parent_node.parent_node as TryStatement).finally_body;
- }
-
- if (finally_block != null) {
- finally_block.emit (this);
- }
-
- base.append_local_free (sym, stop_at_loop, stop_at);
- }
-}
-
-// vim:sw=8 noet
+++ /dev/null
-/* valadovamemberaccessmodule.vala
- *
- * Copyright (C) 2006-2011 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;
-
-public abstract class Vala.DovaMemberAccessModule : DovaControlFlowModule {
- public override void visit_member_access (MemberAccess expr) {
- CCodeExpression pub_inst = null;
- DataType base_type = null;
-
- if (expr.inner != null) {
- pub_inst = get_cvalue (expr.inner);
-
- if (expr.inner.value_type != null) {
- base_type = expr.inner.value_type;
- }
- }
-
- if (expr.symbol_reference is Method) {
- var m = (Method) expr.symbol_reference;
-
- if (!(m is DynamicMethod)) {
- generate_method_declaration (m, cfile);
-
- if (!m.external && m.external_package) {
- // internal VAPI methods
- // only add them once per source file
- if (add_generated_external_symbol (m)) {
- visit_method (m);
- }
- }
- }
-
- if (expr.inner is BaseAccess) {
- if (m.base_method != null) {
- var base_class = (Class) m.base_method.parent_symbol;
-
- set_cvalue (expr, new CCodeIdentifier ("%s_base_%s".printf (get_ccode_lower_case_name (base_class, null), m.name)));
- return;
- } else if (m.base_interface_method != null) {
- var base_iface = (Interface) m.base_interface_method.parent_symbol;
-
- set_cvalue (expr, new CCodeIdentifier ("%s_base_%s".printf (get_ccode_lower_case_name (base_iface, null), m.name)));
- return;
- }
- }
-
- if (m.base_method != null) {
- if (!method_has_wrapper (m.base_method)) {
- var inst = pub_inst;
- if (expr.inner != null && !expr.inner.is_pure ()) {
- // instance expression has side-effects
- // store in temp. variable
- var temp_var = get_temp_variable (expr.inner.value_type);
- emit_temp_var (temp_var);
- var ctemp = new CCodeIdentifier (temp_var.name);
- inst = new CCodeAssignment (ctemp, pub_inst);
- set_cvalue (expr.inner, ctemp);
- }
- var base_class = (Class) m.base_method.parent_symbol;
- var vclass = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (get_ccode_upper_case_name (base_class, null))));
- vclass.add_argument (inst);
- set_cvalue (expr, new CCodeMemberAccess.pointer (vclass, m.name));
- } else {
- set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_method)));
- }
- } else if (m.base_interface_method != null) {
- set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_interface_method)));
- } else if (m is CreationMethod) {
- set_cvalue (expr, new CCodeIdentifier (get_ccode_real_name (m)));
- } else {
- set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m)));
- }
- } else if (expr.symbol_reference is ArrayLengthField) {
- var array_type = (ArrayType) expr.inner.value_type;
- if (array_type.fixed_length) {
- var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- csizeof.add_argument (pub_inst);
- var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- csizeofelement.add_argument (new CCodeElementAccess (pub_inst, new CCodeConstant ("0")));
- set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement));
- } else {
- set_cvalue (expr, new CCodeMemberAccess (pub_inst, "length"));
- }
- } else if (expr.symbol_reference is Field) {
- var f = (Field) expr.symbol_reference;
- expr.target_value = load_field (f, expr.inner != null ? expr.inner.target_value : null);
- } else if (expr.symbol_reference is EnumValue) {
- var ev = (EnumValue) expr.symbol_reference;
-
- generate_enum_declaration ((Enum) ev.parent_symbol, cfile);
-
- set_cvalue (expr, new CCodeConstant (get_ccode_name (ev)));
- } else if (expr.symbol_reference is Constant) {
- var c = (Constant) expr.symbol_reference;
-
- generate_constant_declaration (c, cfile);
-
- set_cvalue (expr, new CCodeIdentifier (get_ccode_name (c)));
- } else if (expr.symbol_reference is Property) {
- var prop = (Property) expr.symbol_reference;
-
- if (!(prop is DynamicProperty)) {
- generate_property_accessor_declaration (prop.get_accessor, cfile);
-
- if (!prop.external && prop.external_package) {
- // internal VAPI properties
- // only add them once per source file
- if (add_generated_external_symbol (prop)) {
- visit_property (prop);
- }
- }
- }
-
- if (expr.inner is BaseAccess) {
- if (prop.base_property != null) {
- var base_class = (Class) prop.base_property.parent_symbol;
- var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (get_ccode_upper_case_name (base_class, null))));
- vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class, null))));
-
- var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name)));
- ccall.add_argument (get_cvalue (expr.inner));
- set_cvalue (expr, ccall);
- return;
- } else if (prop.base_interface_property != null) {
- var base_iface = (Interface) prop.base_interface_property.parent_symbol;
- string parent_iface_var = "%s_%s_parent_iface".printf (get_ccode_lower_case_name (current_class, null), get_ccode_lower_case_name (base_iface, null));
-
- var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), "get_%s".printf (prop.name)));
- ccall.add_argument (get_cvalue (expr.inner));
- set_cvalue (expr, ccall);
- return;
- }
- }
-
- var base_property = prop;
- if (prop.base_property != null) {
- base_property = prop.base_property;
- } else if (prop.base_interface_property != null) {
- base_property = prop.base_interface_property;
- }
- string getter_cname = get_ccode_name (base_property.get_accessor);
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (getter_cname));
-
- if (prop.binding == MemberBinding.INSTANCE) {
- ccall.add_argument (pub_inst);
- }
-
- set_cvalue (expr, ccall);
- } else if (expr.symbol_reference is LocalVariable) {
- var local = (LocalVariable) expr.symbol_reference;
- expr.target_value = load_local (local);
- } else if (expr.symbol_reference is Parameter) {
- var p = (Parameter) expr.symbol_reference;
- expr.target_value = load_parameter (p);
- }
- }
-
- public TargetValue get_local_cvalue (LocalVariable local) {
- var result = new DovaValue (local.variable_type);
-
- if (local.is_result) {
- // used in postconditions
- result.cvalue = new CCodeIdentifier ("result");
- } else if (local.captured) {
- // captured variables are stored on the heap
- var block = (Block) local.parent_symbol;
- result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name));
- } else {
- result.cvalue = get_variable_cexpression (local.name);
- }
-
- return result;
- }
-
- public TargetValue get_parameter_cvalue (Parameter p) {
- var result = new DovaValue (p.variable_type);
-
- if (p.name == "this") {
- if (current_method != null && current_method.coroutine) {
- // use closure
- result.cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "this");
- } else {
- var st = current_type_symbol as Struct;
- if (st != null && !st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type () && (!st.is_simple_type () || current_method is CreationMethod)) {
- result.cvalue = new CCodeIdentifier ("(*this)");
- } else {
- result.cvalue = new CCodeIdentifier ("this");
- }
- }
- } else {
- if (p.captured) {
- // captured variables are stored on the heap
- var block = p.parent_symbol as Block;
- if (block == null) {
- block = ((Method) p.parent_symbol).body;
- }
- result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (p.name));
- } else {
- if (current_method != null && current_method.coroutine) {
- // use closure
- result.cvalue = get_variable_cexpression (p.name);
- } else {
- var type_as_struct = p.variable_type.data_type as Struct;
- if (p.direction != ParameterDirection.IN
- || (type_as_struct != null && !type_as_struct.is_simple_type () && !p.variable_type.nullable)) {
- if (p.variable_type is GenericType) {
- result.cvalue = get_variable_cexpression (p.name);
- } else {
- result.cvalue = new CCodeIdentifier ("(*%s)".printf (get_variable_cname (p.name)));
- }
- } else {
- // Property setters of non simple structs shall replace all occurences
- // of the "value" formal parameter with a dereferencing version of that
- // parameter.
- if (current_property_accessor != null &&
- current_property_accessor.writable &&
- current_property_accessor.value_parameter == p &&
- current_property_accessor.prop.property_type.is_real_struct_type ()) {
- result.cvalue = new CCodeIdentifier ("(*value)");
- } else {
- result.cvalue = get_variable_cexpression (p.name);
- }
- }
- }
- }
- }
-
- return result;
- }
-
- public TargetValue get_field_cvalue (Field f, TargetValue? instance) {
- var result = new DovaValue (f.variable_type);
-
- if (f.binding == MemberBinding.INSTANCE) {
- CCodeExpression pub_inst = null;
-
- if (instance != null) {
- pub_inst = get_cvalue_ (instance);
- }
-
- var instance_target_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
-
- var cl = instance_target_type.data_type as Class;
- bool dova_priv = false;
- if ((f.access == SymbolAccessibility.PRIVATE || f.access == SymbolAccessibility.INTERNAL)) {
- dova_priv = true;
- }
-
- CCodeExpression inst;
- if (dova_priv) {
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (cl, null))));
- priv_call.add_argument (pub_inst);
- inst = priv_call;
- } else {
- inst = pub_inst;
- }
- if (instance_target_type.data_type.is_reference_type () || (instance != null && instance.value_type is PointerType)) {
- result.cvalue = new CCodeMemberAccess.pointer (inst, get_ccode_name (f));
- } else {
- result.cvalue = new CCodeMemberAccess (inst, get_ccode_name (f));
- }
- } else {
- generate_field_declaration (f, cfile);
-
- result.cvalue = new CCodeIdentifier (get_ccode_name (f));
- }
-
- return result;
- }
-
- TargetValue load_variable (Variable variable, TargetValue value) {
- return value;
- }
-
- public override TargetValue load_local (LocalVariable local) {
- return load_variable (local, get_local_cvalue (local));
- }
-
- public override TargetValue load_parameter (Parameter param) {
- return load_variable (param, get_parameter_cvalue (param));
- }
-
- public override TargetValue load_field (Field field, TargetValue? instance) {
- return load_variable (field, get_field_cvalue (field, instance));
- }
-}
-
+++ /dev/null
-/* valadovamethodcallmodule.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>
- */
-
-public class Vala.DovaMethodCallModule : DovaAssignmentModule {
- public override void visit_method_call (MethodCall expr) {
- // the bare function call
- var ccall = new CCodeFunctionCall (get_cvalue (expr.call));
-
- Method m = null;
- Delegate deleg = null;
- List<Parameter> params;
-
- var ma = expr.call as MemberAccess;
-
- var itype = expr.call.value_type;
- params = itype.get_parameters ();
-
- if (itype is MethodType) {
- assert (ma != null);
- m = ((MethodType) itype).method_symbol;
- } else if (itype is ObjectType) {
- // constructor
- var cl = (Class) ((ObjectType) itype).type_symbol;
- m = cl.default_construction_method;
- generate_method_declaration (m, cfile);
- ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m)));
- } else if (itype is DelegateType) {
- deleg = ((DelegateType) itype).delegate_symbol;
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_invoke".printf (get_ccode_lower_case_name (deleg))));
- ccall.add_argument (get_cvalue (expr.call));
- }
-
- if (m is CreationMethod) {
- var cl = (Class) m.parent_symbol;
-
- if (cl == current_class) {
- ccall.add_argument (new CCodeIdentifier ("this"));
- } else {
- ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("this"), get_ccode_name (cl) + "*"));
- }
- } else if (m != null) {
- if (m.binding == MemberBinding.INSTANCE) {
- var instance = get_cvalue (ma.inner);
-
- if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
- var inner_ma = (MemberAccess) ma.inner;
- instance = get_cvalue (inner_ma.inner);
- }
-
- var st = m.parent_symbol as Struct;
- if (st != null && !st.is_simple_type ()) {
- // we need to pass struct instance by reference
- var unary = instance as CCodeUnaryExpression;
- if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
- // *expr => expr
- instance = unary.inner;
- } else if (instance is CCodeIdentifier || instance is CCodeMemberAccess) {
- instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
- } else {
- // if instance is e.g. a function call, we can't take the address of the expression
- // (tmp = expr, &tmp)
- var ccomma = new CCodeCommaExpression ();
-
- var temp_var = get_temp_variable (ma.inner.target_type);
- 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)));
-
- instance = ccomma;
- }
- }
-
- if (ma.inner is BaseAccess) {
- ccall.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (current_class.base_class)))));
- }
- ccall.add_argument (instance);
- }
-
- if (m.binding != MemberBinding.INSTANCE && m.parent_symbol is ObjectTypeSymbol) {
- // support static methods in generic types
- var type_symbol = (ObjectTypeSymbol) m.parent_symbol;
- if (type_symbol.get_type_parameters ().size > 0 && ma.inner is MemberAccess) {
- var type_ma = (MemberAccess) ma.inner;
- add_generic_type_arguments (ccall, type_ma.get_type_arguments (), expr);
- }
- }
- if (m.get_type_parameters ().size > 0) {
- add_generic_type_arguments (ccall, ma.get_type_arguments (), expr);
- }
- }
-
- // the complete call expression, might include casts, comma expressions, and/or assignments
- CCodeExpression ccall_expr = ccall;
-
- bool ellipsis = false;
-
- int i = 1;
- Iterator<Parameter> params_it = params.iterator ();
- foreach (Expression arg in expr.get_argument_list ()) {
- CCodeExpression cexpr = get_cvalue (arg);
-
- if (params_it.next ()) {
- var param = params_it.get ();
- ellipsis = param.params_array || param.ellipsis;
- if (!ellipsis) {
- cexpr = handle_struct_argument (param, arg, cexpr);
-
- // unref old value for non-null non-weak ref/out arguments
- // disabled for arrays for now as that requires special handling
- // (ret_tmp = call (&tmp), var1 = (assign_tmp = dup (tmp), free (var1), assign_tmp), ret_tmp)
- if (param.direction != ParameterDirection.IN && requires_destroy (arg.value_type)
- && (param.direction == ParameterDirection.OUT || !param.variable_type.value_owned)
- && !(param.variable_type is ArrayType)) {
- var unary = (UnaryExpression) arg;
-
- var ccomma = new CCodeCommaExpression ();
-
- var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
- emit_temp_var (temp_var);
- cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
-
- if (param.direction == ParameterDirection.REF) {
- var crefcomma = new CCodeCommaExpression ();
- crefcomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), get_cvalue (unary.inner)));
- crefcomma.append_expression (cexpr);
- cexpr = crefcomma;
- }
-
- // call function
- LocalVariable ret_temp_var = null;
- if (itype.get_return_type () is VoidType) {
- ccomma.append_expression (ccall_expr);
- } else {
- ret_temp_var = get_temp_variable (itype.get_return_type ());
- 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);
- 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)));
-
- // unref old value
- cassign_comma.append_expression (get_unref_expression (get_cvalue (unary.inner), arg.value_type, arg));
-
- cassign_comma.append_expression (get_variable_cexpression (assign_temp_var.name));
-
- // assign new value
- ccomma.append_expression (new CCodeAssignment (get_cvalue (unary.inner), cassign_comma));
-
- // return value
- if (!(itype.get_return_type () is VoidType)) {
- ccomma.append_expression (get_variable_cexpression (ret_temp_var.name));
- }
-
- ccall_expr = ccomma;
- }
-
- if (CCodeBaseModule.get_ccode_type (param) != null) {
- cexpr = new CCodeCastExpression (cexpr, CCodeBaseModule.get_ccode_type (param));
- }
- }
- }
-
- ccall.add_argument (cexpr);
-
- i++;
- }
- if (params_it.next ()) {
- var param = params_it.get ();
-
- /* if there are more parameters than arguments,
- * the additional parameter is an ellipsis parameter
- * otherwise there is a bug in the semantic analyzer
- */
- assert (param.params_array || param.ellipsis);
- ellipsis = true;
- }
-
- if (itype.get_return_type () is GenericType) {
- var ccomma = new CCodeCommaExpression ();
-
- var temp_var = get_temp_variable (expr.value_type);
- emit_temp_var (temp_var);
- if (expr.value_type is GenericType) {
- ccall.add_argument (get_variable_cexpression (temp_var.name));
- } else {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
- }
-
- // call function
- ccomma.append_expression (ccall_expr);
-
- ccomma.append_expression (get_variable_cexpression (temp_var.name));
-
- ccall_expr = ccomma;
- }
-
- if (expr.parent_node is ExpressionStatement) {
- ccode.add_expression (ccall_expr);
- } else {
- var temp_var = get_temp_variable (expr.value_type);
- var temp_ref = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- ccode.add_assignment (temp_ref, ccall_expr);
- set_cvalue (expr, temp_ref);
- }
- }
-}
-
+++ /dev/null
-/* valadovamethodmodule.vala
- *
- * Copyright (C) 2007-2009 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>
- */
-
-/**
- * The link between a method and generated code.
- */
-public abstract class Vala.DovaMethodModule : DovaStructModule {
- public override bool method_has_wrapper (Method method) {
- return (method.get_attribute ("NoWrapper") == null);
- }
-
- public override string? get_custom_creturn_type (Method m) {
- var attr = m.get_attribute ("CCode");
- if (attr != null) {
- string type = attr.get_string ("type");
- if (type != null) {
- return type;
- }
- }
- return null;
- }
-}
-
+++ /dev/null
-/* valadovaobjectmodule.vala
- *
- * Copyright (C) 2009-2011 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.DovaObjectModule : DovaArrayModule {
- public override void generate_class_declaration (Class cl, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl))) {
- return;
- }
-
- if (cl.base_class == null) {
- decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (cl)), new CCodeVariableDeclarator (get_ccode_name (cl))));
- } else if (cl == string_type.data_type) {
- generate_class_declaration (cl.base_class, decl_space);
- decl_space.add_type_declaration (new CCodeTypeDefinition ("const uint8_t *", new CCodeVariableDeclarator (get_ccode_name (cl))));
- } else {
- // typedef to base class instead of dummy struct to avoid warnings/casts
- generate_class_declaration (cl.base_class, decl_space);
- decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (cl.base_class), new CCodeVariableDeclarator (get_ccode_name (cl))));
- }
-
- if (cl.base_class == null) {
- var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (cl)));
- instance_struct.add_field ("DovaType *", "type");
- decl_space.add_type_definition (instance_struct);
- } else if (cl == type_class) {
- var value_copy_function = new CCodeFunction ("dova_type_value_copy");
- value_copy_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_copy_function.add_parameter (new CCodeParameter ("dest", "void *"));
- value_copy_function.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- value_copy_function.add_parameter (new CCodeParameter ("src", "void *"));
- value_copy_function.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- cfile.add_function_declaration (value_copy_function);
-
- var value_equals_function = new CCodeFunction ("dova_type_value_equals", "bool");
- value_equals_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_equals_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_equals_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_equals_function.add_parameter (new CCodeParameter ("other", "void *"));
- value_equals_function.add_parameter (new CCodeParameter ("other_index", "intptr_t"));
-
- cfile.add_function_declaration (value_equals_function);
-
- var value_hash_function = new CCodeFunction ("dova_type_value_hash", "uintptr_t");
- value_hash_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_hash_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_hash_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- cfile.add_function_declaration (value_hash_function);
- }
-
- if (cl.base_class != null) {
- // cycle Object -> any -> Type -> Object needs to be broken to get correct declaration order
- generate_class_declaration (type_class, decl_space);
- }
- generate_method_declaration ((Method) object_class.scope.lookup ("ref"), decl_space);
- generate_method_declaration ((Method) object_class.scope.lookup ("unref"), decl_space);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (cl)), "DovaType *");
- if (cl.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
- foreach (var type_param in cl.get_type_parameters ()) {
- type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- decl_space.add_function_declaration (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (cl)));
- if (cl.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- foreach (var type_param in cl.get_type_parameters ()) {
- type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- decl_space.add_function_declaration (type_init_fun);
- }
-
- void generate_virtual_method_declaration (Method m, CCodeFile decl_space, CCodeStruct type_struct) {
- if (!m.is_abstract && !m.is_virtual) {
- return;
- }
-
- // add vfunc field to the type struct
- var vdeclarator = new CCodeFunctionDeclarator (get_ccode_vfunc_name (m));
-
- generate_cparameters (m, decl_space, new CCodeFunction ("fake"), vdeclarator);
-
- var vdecl = new CCodeDeclaration (get_ccode_name (m.return_type));
- vdecl.add_declarator (vdeclarator);
- type_struct.add_declaration (vdecl);
- }
-
- bool has_instance_struct (Class cl) {
- foreach (Field f in cl.get_fields ()) {
- if (f.binding == MemberBinding.INSTANCE) {
- return true;
- }
- }
- return false;
- }
-
- bool has_type_struct (Class cl) {
- if (cl.get_type_parameters ().size > 0) {
- return true;
- }
- foreach (Method m in cl.get_methods ()) {
- if (m.is_abstract || m.is_virtual) {
- return true;
- }
- }
- foreach (Property prop in cl.get_properties ()) {
- if (prop.is_abstract || prop.is_virtual) {
- return true;
- }
- }
- return false;
- }
-
- void generate_class_private_declaration (Class cl, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl) + "Private")) {
- return;
- }
-
- var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (get_ccode_name (cl)));
- var type_priv_struct = new CCodeStruct ("_%sTypePrivate".printf (get_ccode_name (cl)));
-
- foreach (Field f in cl.get_fields ()) {
- if (f.binding == MemberBinding.INSTANCE) {
- generate_type_declaration (f.variable_type, decl_space);
-
- string field_ctype = get_ccode_name (f.variable_type);
- if (f.is_volatile) {
- field_ctype = "volatile " + field_ctype;
- }
-
- instance_priv_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type));
- }
- }
-
- if (cl.get_full_name () == "Dova.Type") {
- var vdeclarator = new CCodeFunctionDeclarator ("value_copy");
- vdeclarator.add_parameter (new CCodeParameter ("dest", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- vdeclarator.add_parameter (new CCodeParameter ("src", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- var vdecl = new CCodeDeclaration ("void");
- vdecl.add_declarator (vdeclarator);
- instance_priv_struct.add_declaration (vdecl);
-
- vdeclarator = new CCodeFunctionDeclarator ("value_equals");
- vdeclarator.add_parameter (new CCodeParameter ("value", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- vdeclarator.add_parameter (new CCodeParameter ("other", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("other_index", "intptr_t"));
-
- vdecl = new CCodeDeclaration ("bool");
- vdecl.add_declarator (vdeclarator);
- instance_priv_struct.add_declaration (vdecl);
-
- vdeclarator = new CCodeFunctionDeclarator ("value_hash");
- vdeclarator.add_parameter (new CCodeParameter ("value", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- vdecl = new CCodeDeclaration ("uintptr_t");
- vdecl.add_declarator (vdeclarator);
- instance_priv_struct.add_declaration (vdecl);
-
- vdeclarator = new CCodeFunctionDeclarator ("value_to_any");
- vdeclarator.add_parameter (new CCodeParameter ("value", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- vdecl = new CCodeDeclaration ("DovaObject *");
- vdecl.add_declarator (vdeclarator);
- instance_priv_struct.add_declaration (vdecl);
-
- vdeclarator = new CCodeFunctionDeclarator ("value_from_any");
- vdeclarator.add_parameter (new CCodeParameter ("any_", "any *"));
- vdeclarator.add_parameter (new CCodeParameter ("value", "void *"));
- vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- vdecl = new CCodeDeclaration ("void");
- vdecl.add_declarator (vdeclarator);
- instance_priv_struct.add_declaration (vdecl);
- }
-
- foreach (var type_param in cl.get_type_parameters ()) {
- var type_param_decl = new CCodeDeclaration ("DovaType *");
- type_param_decl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (type_param.name.down ())));
- type_priv_struct.add_declaration (type_param_decl);
- }
-
- foreach (Method m in cl.get_methods ()) {
- generate_virtual_method_declaration (m, decl_space, type_priv_struct);
- }
-
- foreach (Property prop in cl.get_properties ()) {
- if (!prop.is_abstract && !prop.is_virtual) {
- continue;
- }
- generate_type_declaration (prop.property_type, decl_space);
-
- var t = (ObjectTypeSymbol) prop.parent_symbol;
-
- var this_type = new ObjectType (t);
- var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type));
- var cvalueparam = new CCodeParameter ("value", get_ccode_name (prop.property_type));
-
- if (prop.get_accessor != null) {
- var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name));
- vdeclarator.add_parameter (cselfparam);
- string creturn_type = get_ccode_name (prop.property_type);
-
- var vdecl = new CCodeDeclaration (creturn_type);
- vdecl.add_declarator (vdeclarator);
- type_priv_struct.add_declaration (vdecl);
- }
- if (prop.set_accessor != null) {
- var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name));
- vdeclarator.add_parameter (cselfparam);
- vdeclarator.add_parameter (cvalueparam);
-
- var vdecl = new CCodeDeclaration ("void");
- vdecl.add_declarator (vdeclarator);
- type_priv_struct.add_declaration (vdecl);
- }
- }
-
- if (!instance_priv_struct.is_empty) {
- decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (get_ccode_name (cl)))));
- decl_space.add_type_definition (instance_priv_struct);
- }
-
- if (!type_priv_struct.is_empty) {
- decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sTypePrivate".printf (get_ccode_name (cl)))));
- decl_space.add_type_definition (type_priv_struct);
- }
-
- var cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- decl_space.add_type_member_declaration (cdecl);
-
- CCodeExpression type_offset;
-
- string macro;
- if (cl.base_class == null) {
- // offset of any class is 0
- macro = "((%sPrivate *) o)".printf (get_ccode_name (cl));
- type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)");
- } else if (cl == object_class) {
- macro = "((%sPrivate *) (((char *) o) + sizeof (anyPrivate)))".printf (get_ccode_name (cl));
- type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)");
- } else if (cl == type_class) {
- macro = "((%sPrivate *) (((char *) o) + sizeof (anyPrivate) + sizeof (DovaObjectPrivate)))".printf (get_ccode_name (cl));
- type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate) + sizeof (DovaObjectTypePrivate)");
- } else {
- macro = "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (cl), get_ccode_lower_case_name (cl));
- type_offset = new CCodeConstant ("0");
- }
- if (!instance_priv_struct.is_empty) {
- decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (cl, null)), macro));
- }
-
- cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_type_offset".printf (get_ccode_lower_case_name (cl)), type_offset));
- cdecl.modifiers = CCodeModifiers.STATIC;
- decl_space.add_type_member_declaration (cdecl);
- }
-
- CCodeFunction create_set_value_copy_function (bool decl_only = false) {
- var result = new CCodeFunction ("dova_type_set_value_copy");
- result.add_parameter (new CCodeParameter ("type", "DovaType *"));
- result.add_parameter (new CCodeParameter ("(*function) (void *dest, intptr_t dest_index, void *src, intptr_t src_index)", "void"));
- if (decl_only) {
- return result;
- }
-
- result.block = new CCodeBlock ();
-
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_copy"), new CCodeIdentifier ("function"))));
- return result;
- }
-
- public void declare_set_value_copy_function (CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_copy")) {
- return;
- }
- decl_space.add_function_declaration (create_set_value_copy_function (true));
- }
-
- CCodeFunction create_set_value_equals_function (bool decl_only = false) {
- var result = new CCodeFunction ("dova_type_set_value_equals");
- result.add_parameter (new CCodeParameter ("type", "DovaType *"));
- result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index, void *other, intptr_t other_index)", "bool"));
- if (decl_only) {
- return result;
- }
-
- result.block = new CCodeBlock ();
-
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_equals"), new CCodeIdentifier ("function"))));
- return result;
- }
-
- public void declare_set_value_equals_function (CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_equals")) {
- return;
- }
- decl_space.add_function_declaration (create_set_value_equals_function (true));
- }
-
- CCodeFunction create_set_value_hash_function (bool decl_only = false) {
- var result = new CCodeFunction ("dova_type_set_value_hash");
- result.add_parameter (new CCodeParameter ("type", "DovaType *"));
- result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index)", "uintptr_t"));
- if (decl_only) {
- return result;
- }
-
- result.block = new CCodeBlock ();
-
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_hash"), new CCodeIdentifier ("function"))));
- return result;
- }
-
- public void declare_set_value_hash_function (CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_hash")) {
- return;
- }
- decl_space.add_function_declaration (create_set_value_hash_function (true));
- }
-
- CCodeFunction create_set_value_to_any_function (bool decl_only = false) {
- var result = new CCodeFunction ("dova_type_set_value_to_any");
- result.add_parameter (new CCodeParameter ("type", "DovaType *"));
- result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index)", "DovaObject *"));
- if (decl_only) {
- return result;
- }
-
- result.block = new CCodeBlock ();
-
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_to_any"), new CCodeIdentifier ("function"))));
- return result;
- }
-
- public void declare_set_value_to_any_function (CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_to_any")) {
- return;
- }
- decl_space.add_function_declaration (create_set_value_to_any_function (true));
- }
-
- CCodeFunction create_set_value_from_any_function (bool decl_only = false) {
- var result = new CCodeFunction ("dova_type_set_value_from_any");
- result.add_parameter (new CCodeParameter ("type", "DovaType *"));
- result.add_parameter (new CCodeParameter ("(*function) (DovaObject *any, void *value, intptr_t value_index)", "void"));
- if (decl_only) {
- return result;
- }
-
- result.block = new CCodeBlock ();
-
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_from_any"), new CCodeIdentifier ("function"))));
- return result;
- }
-
- public void declare_set_value_from_any_function (CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_from_any")) {
- return;
- }
- decl_space.add_function_declaration (create_set_value_from_any_function (true));
- }
-
- public CCodeBlock generate_type_get_function (TypeSymbol cl, Class? base_class) {
- DataType? base_class_type = null;
- if (base_class != null && cl is Class) {
- foreach (DataType base_type in ((Class) cl).get_base_types ()) {
- if (base_type.data_type == base_class) {
- base_class_type = base_type;
- break;
- }
- }
- }
-
- var cdecl = new CCodeDeclaration ("DovaType *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("NULL")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (cl)), "DovaType *");
- if (cl.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
-
- var object_type_symbol = cl as ObjectTypeSymbol;
- if (object_type_symbol != null) {
- foreach (var type_param in object_type_symbol.get_type_parameters ()) {
- type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- }
-
- type_fun.block = new CCodeBlock ();
-
- var type_init_block = new CCodeBlock ();
-
- if (base_class == null) {
- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- sizeof_call.add_argument (new CCodeIdentifier ("%sPrivate".printf (get_ccode_name (cl))));
-
- var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc"));
- calloc_call.add_argument (new CCodeConstant ("1"));
- calloc_call.add_argument (new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)"));
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))), calloc_call)));
-
- var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_object_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))));
- set_size.add_argument (sizeof_call);
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_any_type_offset"), new CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)"))));
-
- set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_type_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))));
- set_size.add_argument (new CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)"));
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))), "type"), new CCodeFunctionCall (new CCodeIdentifier ("dova_type_type_get")))));
- } else {
- generate_method_declaration ((Method) object_class.scope.lookup ("alloc"), cfile);
- generate_method_declaration ((Method) type_class.scope.lookup ("alloc"), cfile);
-
- var base_type = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (base_class))));
- for (int i = 0; i < base_class.get_type_parameters ().size; i++) {
- base_type.add_argument (new CCodeConstant ("NULL"));
- }
-
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc"));
- alloc_call.add_argument (base_type);
- if (!(cl is Class) || has_instance_struct ((Class) cl)) {
- alloc_call.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (get_ccode_name (cl))));
- } else {
- alloc_call.add_argument (new CCodeConstant ("0"));
- }
- if ((!(cl is Class) || has_type_struct ((Class) cl)) && !(cl is Delegate)) {
- alloc_call.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (cl))));
- } else {
- alloc_call.add_argument (new CCodeConstant ("0"));
- }
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (cl)))));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_type_offset".printf (get_ccode_lower_case_name (cl)))));
-
- type_init_block.add_statement (new CCodeExpressionStatement (alloc_call));
- }
-
- var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (cl))));
- type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))));
-
- if (object_type_symbol != null) {
- for (int i = 0; i < object_type_symbol.get_type_parameters ().size; i++) {
- type_init_call.add_argument (new CCodeConstant ("NULL"));
- }
- }
-
- type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))), type_init_block));
-
- if (object_type_symbol != null && object_type_symbol.get_type_parameters ().size > 0) {
- // generics
- var specialized_type_get_block = new CCodeBlock ();
-
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("next_type")).get_accessor, cfile);
- generate_method_declaration ((Method) type_class.scope.lookup ("insert_type"), cfile);
-
- var first = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_next_type"));
- first.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))));
-
- cdecl = new CCodeDeclaration ("DovaType *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("result", first));
- specialized_type_get_block.add_statement (cdecl);
-
- var next = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_next_type"));
- next.add_argument (new CCodeIdentifier ("result"));
-
- var next_check = new CCodeBlock ();
- next_check.add_statement (new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeMemberAccess.pointer (get_type_private_from_type (object_type_symbol, new CCodeIdentifier ("result")), "%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ())), new CCodeIdentifier ("%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ()))), new CCodeBreakStatement ()));
- next_check.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), next)));
-
- specialized_type_get_block.add_statement (new CCodeWhileStatement (new CCodeIdentifier ("result"), next_check));
-
- var specialized_type_init_block = new CCodeBlock ();
-
- generate_method_declaration ((Method) type_class.scope.lookup ("alloc"), cfile);
-
- var base_type = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (base_class))));
- if (base_class_type != null) {
- foreach (var type_arg in base_class_type.get_type_arguments ()) {
- base_type.add_argument (get_type_id_expression (type_arg, true));
- }
- }
-
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc"));
- alloc_call.add_argument (base_type);
- if (!(cl is Class) || has_instance_struct ((Class) cl)) {
- alloc_call.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (get_ccode_name (cl))));
- } else {
- alloc_call.add_argument (new CCodeConstant ("0"));
- }
- if (!(cl is Class) || has_type_struct ((Class) cl)) {
- alloc_call.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (cl))));
- } else {
- alloc_call.add_argument (new CCodeConstant ("0"));
- }
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (cl)))));
- alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_type_offset".printf (get_ccode_lower_case_name (cl)))));
-
- specialized_type_init_block.add_statement (new CCodeExpressionStatement (alloc_call));
-
- type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (cl))));
- type_init_call.add_argument (new CCodeIdentifier ("result"));
-
- foreach (var type_param in object_type_symbol.get_type_parameters ()) {
- type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
-
- specialized_type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- var insert_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_insert_type"));
- insert_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))));
- insert_call.add_argument (new CCodeIdentifier ("result"));
- specialized_type_init_block.add_statement (new CCodeExpressionStatement (insert_call));
-
- specialized_type_get_block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("result")), specialized_type_init_block));
-
- specialized_type_get_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-
- type_fun.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ())), specialized_type_get_block));
- }
-
- type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))));
-
- cfile.add_function (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (cl)));
- if (cl.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- if (object_type_symbol != null) {
- foreach (var type_param in object_type_symbol.get_type_parameters ()) {
- type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- }
- type_init_fun.block = new CCodeBlock ();
-
- if (base_class == null || cl == object_class || cl == value_class || cl == string_class) {
- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- sizeof_call.add_argument (new CCodeIdentifier ("void *"));
-
- var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size"));
- set_size.add_argument (new CCodeIdentifier ("type"));
- set_size.add_argument (sizeof_call);
- type_init_fun.block.add_statement (new CCodeExpressionStatement (set_size));
-
- declare_set_value_copy_function (cfile);
-
- var value_copy_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_copy"));
- value_copy_call.add_argument (new CCodeIdentifier ("type"));
- value_copy_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (cl))), "void (*)(void *, intptr_t, void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_copy_call));
-
- var function = new CCodeFunction ("%s_copy".printf (get_ccode_lower_case_name (cl)), "void");
- function.modifiers = CCodeModifiers.STATIC;
- function.add_parameter (new CCodeParameter ("dest", "any **"));
- function.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- function.add_parameter (new CCodeParameter ("src", "any **"));
- function.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- function.block = new CCodeBlock ();
- var cfrag = new CCodeFragment ();
- function.block.add_statement (cfrag);
-
- var dest = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("dest"), new CCodeIdentifier ("dest_index"));
- var src = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("src"), new CCodeIdentifier ("src_index"));
-
- var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_unref".printf (get_ccode_lower_case_name (cl))));
- unref_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest));
- var unref_block = new CCodeBlock ();
- unref_block.add_statement (new CCodeExpressionStatement (unref_call));
- unref_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), new CCodeConstant ("NULL"))));
- function.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), unref_block));
-
- var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_ref".printf (get_ccode_lower_case_name (cl))));
- ref_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src));
- var ref_block = new CCodeBlock ();
- ref_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), ref_call)));
- function.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("src"), ref_block));
-
- cfile.add_function (function);
-
- {
- var value_equals_fun = new CCodeFunction ("%s_value_equals".printf (get_ccode_lower_case_name (cl)), "bool");
- value_equals_fun.modifiers = CCodeModifiers.STATIC;
- value_equals_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**"));
- value_equals_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_equals_fun.add_parameter (new CCodeParameter ("other", get_ccode_name (cl) + "**"));
- value_equals_fun.add_parameter (new CCodeParameter ("other_index", "intptr_t"));
- value_equals_fun.block = new CCodeBlock ();
- var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index"));
- var other = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("other"), new CCodeIdentifier ("other_index"));
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("any_equals"));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, other));
- value_equals_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_equals_fun);
-
- declare_set_value_equals_function (cfile);
-
- var value_equals_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_equals"));
- value_equals_call.add_argument (new CCodeIdentifier ("type"));
- value_equals_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_equals".printf (get_ccode_lower_case_name (cl))), "bool (*)(void *, intptr_t, void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_equals_call));
- }
-
- {
- var value_hash_fun = new CCodeFunction ("%s_value_hash".printf (get_ccode_lower_case_name (cl)), "uintptr_t");
- value_hash_fun.modifiers = CCodeModifiers.STATIC;
- value_hash_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**"));
- value_hash_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_hash_fun.block = new CCodeBlock ();
- var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index"));
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("any_hash"));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val));
- value_hash_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_hash_fun);
-
- declare_set_value_hash_function (cfile);
-
- var value_hash_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_hash"));
- value_hash_call.add_argument (new CCodeIdentifier ("type"));
- value_hash_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_hash".printf (get_ccode_lower_case_name (cl))), "uintptr_t (*)(void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_hash_call));
- }
-
- // generate method to box value
- var value_to_any_fun = new CCodeFunction ("%s_value_to_any".printf (get_ccode_lower_case_name (cl)), "any*");
- value_to_any_fun.modifiers = CCodeModifiers.STATIC;
- value_to_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**"));
- value_to_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_to_any_fun.block = new CCodeBlock ();
- var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index"));
- string to_any_fun = "%s_ref".printf (get_ccode_lower_case_name (cl));
- if (cl == string_class) {
- to_any_fun = "string_to_any";
- }
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (to_any_fun));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val));
- value_to_any_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_to_any_fun);
-
- declare_set_value_to_any_function (cfile);
-
- var value_to_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_to_any"));
- value_to_any_call.add_argument (new CCodeIdentifier ("type"));
- value_to_any_call.add_argument (new CCodeIdentifier ("%s_value_to_any".printf (get_ccode_lower_case_name (cl))));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_to_any_call));
-
- // generate method to unbox value
- var value_from_any_fun = new CCodeFunction ("%s_value_from_any".printf (get_ccode_lower_case_name (cl)));
- value_from_any_fun.modifiers = CCodeModifiers.STATIC;
- value_from_any_fun.add_parameter (new CCodeParameter ("any_", "any *"));
- value_from_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**"));
- value_from_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_from_any_fun.block = new CCodeBlock ();
- string from_any_fun = "%s_ref".printf (get_ccode_lower_case_name (cl));
- if (cl == string_class) {
- from_any_fun = "string_from_any";
- }
- ccall = new CCodeFunctionCall (new CCodeIdentifier (from_any_fun));
- ccall.add_argument (new CCodeIdentifier ("any_"));
- value_from_any_fun.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val), ccall)));
- value_from_any_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_from_any_fun);
-
- declare_set_value_from_any_function (cfile);
-
- var value_from_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_from_any"));
- value_from_any_call.add_argument (new CCodeIdentifier ("type"));
- value_from_any_call.add_argument (new CCodeIdentifier ("%s_value_from_any".printf (get_ccode_lower_case_name (cl))));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_from_any_call));
- } else {
- type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (base_class))));
- type_init_call.add_argument (new CCodeIdentifier ("type"));
-
- if (base_class_type != null) {
- foreach (var type_arg in base_class_type.get_type_arguments ()) {
- type_init_call.add_argument (get_type_id_expression (type_arg, true));
- }
- }
-
- type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- if (object_type_symbol != null) {
- foreach (var type_param in object_type_symbol.get_type_parameters ()) {
- type_init_fun.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_type_private_from_type (object_type_symbol, new CCodeIdentifier ("type")), "%s_type".printf (type_param.name.down ())), new CCodeIdentifier ("%s_type".printf (type_param.name.down ())))));
- }
- }
- }
-
- cfile.add_function (type_init_fun);
-
- return type_init_fun.block;
- }
-
- void add_finalize_function (Class cl) {
- var function = new CCodeFunction ("%sfinalize".printf (get_ccode_lower_case_prefix (cl)), "void");
- function.modifiers = CCodeModifiers.STATIC;
-
- function.add_parameter (new CCodeParameter ("this", get_ccode_name (cl) + "*"));
-
- push_function (function);
-
- cfile.add_function_declaration (function);
-
- if (cl.destructor != null) {
- cl.destructor.body.emit (this);
- }
-
- foreach (var f in cl.get_fields ()) {
- if (f.binding == MemberBinding.INSTANCE) {
- CCodeExpression lhs = null;
- if (f.is_internal_symbol ()) {
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (cl, null))));
- priv_call.add_argument (new CCodeIdentifier ("this"));
- lhs = new CCodeMemberAccess.pointer (priv_call, get_ccode_name (f));
- } else {
- lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), get_ccode_name (f));
- }
-
- if (requires_destroy (f.variable_type)) {
- var this_access = new MemberAccess.simple ("this");
- this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
-
- var field_st = f.parent_symbol as Struct;
- if (field_st != null && !field_st.is_simple_type ()) {
- set_cvalue (this_access, new CCodeIdentifier ("(*this)"));
- } else {
- set_cvalue (this_access, new CCodeIdentifier ("this"));
- }
-
- var ma = new MemberAccess (this_access, f.name);
- ma.symbol_reference = f;
- ccode.add_expression (get_unref_expression (lhs, f.variable_type, ma));
- }
- }
- }
-
- // chain up to finalize function of the base class
- foreach (DataType base_type in cl.get_base_types ()) {
- var object_type = (ObjectType) base_type;
- if (object_type.type_symbol is Class) {
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_base_finalize"));
- var type_get_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (object_type.type_symbol))));
- foreach (var type_arg in base_type.get_type_arguments ()) {
- type_get_call.add_argument (get_type_id_expression (type_arg, false));
- }
- ccall.add_argument (type_get_call);
- ccall.add_argument (new CCodeIdentifier ("this"));
- ccode.add_statement (new CCodeExpressionStatement (ccall));
- }
- }
-
- pop_function ();
-
- cfile.add_function (function);
- }
-
- public override void visit_class (Class cl) {
- push_context (new EmitContext (cl));
-
- generate_class_declaration (cl, cfile);
- generate_class_private_declaration (cl, cfile);
-
- if (!cl.is_internal_symbol ()) {
- generate_class_declaration (cl, header_file);
- }
-
- cl.accept_children (this);
-
- var type_init_block = generate_type_get_function (cl, cl.base_class);
-
- foreach (DataType base_type in cl.get_base_types ()) {
- var object_type = (ObjectType) base_type;
- if (object_type.type_symbol is Interface) {
- generate_interface_declaration ((Interface) object_type.type_symbol, cfile);
-
- var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (object_type.type_symbol))));
- type_init_call.add_argument (new CCodeIdentifier ("type"));
- foreach (var type_arg in base_type.get_type_arguments ()) {
- type_init_call.add_argument (get_type_id_expression (type_arg, true));
- }
- type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
- }
- }
-
- // finalizer
- if (cl.base_class != null && !cl.is_fundamental () && (cl.get_fields ().size > 0 || cl.destructor != null)) {
- add_finalize_function (cl);
-
- generate_method_declaration ((Method) object_class.scope.lookup ("finalize"), cfile);
-
- var override_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_override_finalize"));
- override_call.add_argument (new CCodeIdentifier ("type"));
- override_call.add_argument (new CCodeIdentifier ("%sfinalize".printf (get_ccode_lower_case_prefix (cl))));
- type_init_block.add_statement (new CCodeExpressionStatement (override_call));
- }
-
- foreach (Method m in cl.get_methods ()) {
- if (m.is_virtual || m.overrides) {
- var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.base_method.parent_symbol), m.name)));
- override_call.add_argument (new CCodeIdentifier ("type"));
- override_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m)));
- type_init_block.add_statement (new CCodeExpressionStatement (override_call));
- } else if (m.base_interface_method != null) {
- var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.base_interface_method.parent_symbol), m.name)));
- override_call.add_argument (new CCodeIdentifier ("type"));
- override_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m)));
- type_init_block.add_statement (new CCodeExpressionStatement (override_call));
- }
- }
-
- foreach (Property prop in cl.get_properties ()) {
- if (prop.is_virtual || prop.overrides) {
- if (prop.get_accessor != null) {
- var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_get_%s".printf (get_ccode_lower_case_prefix (prop.base_property.parent_symbol), prop.name)));
- override_call.add_argument (new CCodeIdentifier ("type"));
- override_call.add_argument (new CCodeIdentifier (get_ccode_name (prop.get_accessor)));
- type_init_block.add_statement (new CCodeExpressionStatement (override_call));
- }
- if (prop.set_accessor != null) {
- var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_set_%s".printf (get_ccode_lower_case_prefix (prop.base_property.parent_symbol), prop.name)));
- override_call.add_argument (new CCodeIdentifier ("type"));
- override_call.add_argument (new CCodeIdentifier (get_ccode_name (prop.set_accessor)));
- type_init_block.add_statement (new CCodeExpressionStatement (override_call));
- }
- }
- }
-
- if (cl == type_class) {
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE"));
- priv_call.add_argument (new CCodeIdentifier ("type"));
-
- var value_copy_function = new CCodeFunction ("dova_type_value_copy");
- value_copy_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_copy_function.add_parameter (new CCodeParameter ("dest", "void *"));
- value_copy_function.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- value_copy_function.add_parameter (new CCodeParameter ("src", "void *"));
- value_copy_function.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- value_copy_function.block = new CCodeBlock ();
-
- var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_copy"));
- ccall.add_argument (new CCodeIdentifier ("dest"));
- ccall.add_argument (new CCodeIdentifier ("dest_index"));
- ccall.add_argument (new CCodeIdentifier ("src"));
- ccall.add_argument (new CCodeIdentifier ("src_index"));
- value_copy_function.block.add_statement (new CCodeExpressionStatement (ccall));
-
- cfile.add_function (value_copy_function);
-
- declare_set_value_copy_function (cfile);
- declare_set_value_copy_function (header_file);
- cfile.add_function (create_set_value_copy_function ());
-
- var value_equals_function = new CCodeFunction ("dova_type_value_equals", "bool");
- value_equals_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_equals_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_equals_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_equals_function.add_parameter (new CCodeParameter ("other", "void *"));
- value_equals_function.add_parameter (new CCodeParameter ("other_index", "intptr_t"));
-
- value_equals_function.block = new CCodeBlock ();
-
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_equals"));
- ccall.add_argument (new CCodeIdentifier ("value"));
- ccall.add_argument (new CCodeIdentifier ("value_index"));
- ccall.add_argument (new CCodeIdentifier ("other"));
- ccall.add_argument (new CCodeIdentifier ("other_index"));
- value_equals_function.block.add_statement (new CCodeReturnStatement (ccall));
-
- cfile.add_function (value_equals_function);
-
- declare_set_value_equals_function (cfile);
- declare_set_value_equals_function (header_file);
- cfile.add_function (create_set_value_equals_function ());
-
- var value_hash_function = new CCodeFunction ("dova_type_value_hash", "uintptr_t");
- value_hash_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_hash_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_hash_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- value_hash_function.block = new CCodeBlock ();
-
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_hash"));
- ccall.add_argument (new CCodeIdentifier ("value"));
- ccall.add_argument (new CCodeIdentifier ("value_index"));
- value_hash_function.block.add_statement (new CCodeReturnStatement (ccall));
-
- cfile.add_function (value_hash_function);
-
- declare_set_value_hash_function (cfile);
- declare_set_value_hash_function (header_file);
- cfile.add_function (create_set_value_hash_function ());
-
- var value_to_any_function = new CCodeFunction ("dova_type_value_to_any", "DovaObject *");
- value_to_any_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_to_any_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_to_any_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- value_to_any_function.block = new CCodeBlock ();
-
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_to_any"));
- ccall.add_argument (new CCodeIdentifier ("value"));
- ccall.add_argument (new CCodeIdentifier ("value_index"));
- value_to_any_function.block.add_statement (new CCodeReturnStatement (ccall));
-
- cfile.add_function (value_to_any_function);
-
- declare_set_value_to_any_function (cfile);
- declare_set_value_to_any_function (header_file);
- cfile.add_function (create_set_value_to_any_function ());
-
- var value_from_any_function = new CCodeFunction ("dova_type_value_from_any", "void");
- value_from_any_function.add_parameter (new CCodeParameter ("type", "DovaType *"));
- value_from_any_function.add_parameter (new CCodeParameter ("any_", "any *"));
- value_from_any_function.add_parameter (new CCodeParameter ("value", "void *"));
- value_from_any_function.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
-
- value_from_any_function.block = new CCodeBlock ();
-
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_from_any"));
- ccall.add_argument (new CCodeIdentifier ("any_"));
- ccall.add_argument (new CCodeIdentifier ("value"));
- ccall.add_argument (new CCodeIdentifier ("value_index"));
- value_from_any_function.block.add_statement (new CCodeReturnStatement (ccall));
-
- cfile.add_function (value_from_any_function);
-
- declare_set_value_from_any_function (cfile);
- declare_set_value_from_any_function (header_file);
- cfile.add_function (create_set_value_from_any_function ());
- }
-
- pop_context ();
- }
-
- public override void visit_interface (Interface iface) {
- push_context (new EmitContext (iface));
-
- generate_interface_declaration (iface, cfile);
-
- var type_priv_struct = new CCodeStruct ("_%sTypePrivate".printf (get_ccode_name (iface)));
-
- foreach (var type_param in iface.get_type_parameters ()) {
- var type_param_decl = new CCodeDeclaration ("DovaType *");
- type_param_decl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (type_param.name.down ())));
- type_priv_struct.add_declaration (type_param_decl);
- }
-
- foreach (Method m in iface.get_methods ()) {
- generate_virtual_method_declaration (m, cfile, type_priv_struct);
- }
-
- if (!type_priv_struct.is_empty) {
- cfile.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sTypePrivate".printf (get_ccode_name (iface)))));
- cfile.add_type_definition (type_priv_struct);
- }
-
- var cdecl = new CCodeDeclaration ("DovaType *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (iface)), new CCodeConstant ("NULL")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (iface)), "DovaType *");
- if (iface.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
- foreach (var type_param in iface.get_type_parameters ()) {
- type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- type_fun.block = new CCodeBlock ();
-
- var type_init_block = new CCodeBlock ();
-
- var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc"));
- calloc_call.add_argument (new CCodeConstant ("1"));
-
- if (!type_priv_struct.is_empty) {
- calloc_call.add_argument (new CCodeConstant ("dova_type_get_type_size (dova_type_type_get ()) + sizeof (%sTypePrivate)".printf (get_ccode_name (iface))));
- } else {
- calloc_call.add_argument (new CCodeConstant ("dova_type_get_type_size (dova_type_type_get ())"));
- }
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface))), calloc_call)));
-
- // call any_type_init to set value_copy and similar functions
- var any_type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("any_type_init"));
- any_type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface))));
- type_init_block.add_statement (new CCodeExpressionStatement (any_type_init_call));
-
- var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (iface))));
- type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface))));
- foreach (var type_param in iface.get_type_parameters ()) {
- type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
- type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface)))), type_init_block));
-
- type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface)))));
-
- cfile.add_function (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (iface)));
- if (iface.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- foreach (var type_param in iface.get_type_parameters ()) {
- type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- type_init_fun.block = new CCodeBlock ();
-
- foreach (DataType base_type in iface.get_prerequisites ()) {
- var object_type = (ObjectType) base_type;
- if (object_type.type_symbol is Interface) {
- type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (object_type.type_symbol))));
- type_init_call.add_argument (new CCodeIdentifier ("type"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call));
- }
- }
-
- var vtable_alloc = new CCodeFunctionCall (new CCodeIdentifier ("calloc"));
- vtable_alloc.add_argument (new CCodeConstant ("1"));
- vtable_alloc.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (iface))));
-
- var type_get_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (iface))));
- foreach (var type_param in iface.get_type_parameters ()) {
- type_get_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
-
- if (!type_priv_struct.is_empty) {
- var add_interface_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_add_interface"));
- add_interface_call.add_argument (new CCodeIdentifier ("type"));
- add_interface_call.add_argument (type_get_call);
- add_interface_call.add_argument (vtable_alloc);
- type_init_fun.block.add_statement (new CCodeExpressionStatement (add_interface_call));
- }
-
- cfile.add_function (type_init_fun);
-
- iface.accept_children (this);
-
- pop_context ();
- }
-
- public override void generate_property_accessor_declaration (PropertyAccessor acc, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, acc.prop, get_ccode_name (acc))) {
- return;
- }
-
- var prop = (Property) acc.prop;
-
- generate_type_declaration (acc.value_type, decl_space);
-
- CCodeFunction function;
-
- if (acc.readable) {
- function = new CCodeFunction (get_ccode_name (acc), get_ccode_name (acc.value_type));
- } else {
- function = new CCodeFunction (get_ccode_name (acc), "void");
- }
-
- if (prop.binding == MemberBinding.INSTANCE) {
- DataType this_type;
- if (prop.parent_symbol is Struct) {
- var st = (Struct) prop.parent_symbol;
- this_type = SemanticAnalyzer.get_data_type_for_symbol (st);
- } else {
- var t = (ObjectTypeSymbol) prop.parent_symbol;
- this_type = new ObjectType (t);
- }
-
- generate_type_declaration (this_type, decl_space);
- var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type));
-
- function.add_parameter (cselfparam);
- }
-
- if (acc.writable) {
- var cvalueparam = new CCodeParameter ("value", get_ccode_name (acc.value_type));
- function.add_parameter (cvalueparam);
- }
-
- if (prop.is_internal_symbol () || acc.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- }
- decl_space.add_function_declaration (function);
-
- if (prop.is_abstract || prop.is_virtual) {
- string param_list = "(%s *this".printf (get_ccode_name (prop.parent_symbol));
- if (!acc.readable) {
- param_list += ", ";
- param_list += get_ccode_name (acc.value_type);
- }
- param_list += ")";
-
- var override_func = new CCodeFunction ("%soverride_%s_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), acc.readable ? "get" : "set", prop.name));
- override_func.add_parameter (new CCodeParameter ("type", "DovaType *"));
- override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), acc.readable ? get_ccode_name (acc.value_type) : "void"));
-
- decl_space.add_function_declaration (override_func);
- }
- }
-
- public override void visit_property_accessor (PropertyAccessor acc) {
- push_context (new EmitContext (acc));
-
- var prop = (Property) acc.prop;
-
- // do not declare overriding properties and interface implementations
- if (prop.is_abstract || prop.is_virtual
- || (prop.base_property == null && prop.base_interface_property == null)) {
- generate_property_accessor_declaration (acc, cfile);
-
- if (!prop.is_internal_symbol ()
- && (acc.access == SymbolAccessibility.PUBLIC
- || acc.access == SymbolAccessibility.PROTECTED)) {
- generate_property_accessor_declaration (acc, header_file);
- }
- }
-
- DataType this_type;
- if (prop.parent_symbol is Struct) {
- var st = (Struct) prop.parent_symbol;
- this_type = SemanticAnalyzer.get_data_type_for_symbol (st);
- } else {
- var t = (ObjectTypeSymbol) prop.parent_symbol;
- this_type = new ObjectType (t);
- }
- var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type));
- var cvalueparam = new CCodeParameter ("value", get_ccode_name (acc.value_type));
-
- string cname = get_ccode_name (acc);
-
- if (prop.is_abstract || prop.is_virtual) {
- CCodeFunction function;
- if (acc.readable) {
- function = new CCodeFunction (get_ccode_name (acc), get_ccode_name (current_return_type));
- } else {
- function = new CCodeFunction (get_ccode_name (acc), "void");
- }
- function.add_parameter (cselfparam);
- if (acc.writable) {
- function.add_parameter (cvalueparam);
- }
-
- if (prop.is_internal_symbol () || !(acc.readable || acc.writable) || acc.is_internal_symbol ()) {
- // accessor function should be private if the property is an internal symbol
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- push_function (function);
-
- var vcast = get_type_private_from_type ((ObjectTypeSymbol) prop.parent_symbol, get_type_from_instance (new CCodeIdentifier ("this")));
-
- if (acc.readable) {
- var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name)));
- vcall.add_argument (new CCodeIdentifier ("this"));
- ccode.add_return (vcall);
- } else {
- var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "set_%s".printf (prop.name)));
- vcall.add_argument (new CCodeIdentifier ("this"));
- vcall.add_argument (new CCodeIdentifier ("value"));
- ccode.add_expression (vcall);
- }
-
- pop_function ();
-
- cfile.add_function (function);
-
-
- string param_list = "(%s *this".printf (get_ccode_name (prop.parent_symbol));
- if (!acc.readable) {
- param_list += ", ";
- param_list += get_ccode_name (acc.value_type);
- }
- param_list += ")";
-
- var override_func = new CCodeFunction ("%soverride_%s_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), acc.readable ? "get" : "set", prop.name));
- override_func.add_parameter (new CCodeParameter ("type", "DovaType *"));
- override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), acc.readable ? get_ccode_name (acc.value_type) : "void"));
-
- push_function (override_func);
-
- vcast = get_type_private_from_type ((ObjectTypeSymbol) prop.parent_symbol, new CCodeIdentifier ("type"));
-
- ccode.add_assignment (new CCodeMemberAccess.pointer (vcast, "%s_%s".printf (acc.readable ? "get" : "set", prop.name)), new CCodeIdentifier ("function"));
-
- pop_function ();
-
- cfile.add_function (override_func);
- }
-
- if (!prop.is_abstract) {
- CCodeFunction function;
- if (acc.writable) {
- function = new CCodeFunction (cname, "void");
- } else {
- function = new CCodeFunction (cname, get_ccode_name (acc.value_type));
- }
-
- if (prop.binding == MemberBinding.INSTANCE) {
- function.add_parameter (cselfparam);
- }
- if (acc.writable) {
- function.add_parameter (cvalueparam);
- }
-
- if (prop.is_internal_symbol () || !(acc.readable || acc.writable) || acc.is_internal_symbol ()) {
- // accessor function should be private if the property is an internal symbol
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- push_function (function);
-
- acc.body.emit (this);
-
- if (acc.readable) {
- var cdecl = new CCodeDeclaration (get_ccode_name (acc.value_type));
- cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (acc.value_type, true)));
- function.block.prepend_statement (cdecl);
-
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- }
-
- cfile.add_function (function);
- }
-
- pop_context ();
- }
-
- public override void generate_interface_declaration (Interface iface, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, iface, get_ccode_name (iface))) {
- return;
- }
-
- // typedef to DovaObject instead of dummy struct to avoid warnings/casts
- generate_class_declaration (object_class, decl_space);
- decl_space.add_type_declaration (new CCodeTypeDefinition ("DovaObject", new CCodeVariableDeclarator (get_ccode_name (iface))));
-
- generate_class_declaration (type_class, decl_space);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (iface)), "DovaType *");
- if (iface.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
- foreach (var type_param in iface.get_type_parameters ()) {
- type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- decl_space.add_function_declaration (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (iface)));
- if (iface.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- foreach (var type_param in iface.get_type_parameters ()) {
- type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *"));
- }
- decl_space.add_function_declaration (type_init_fun);
- }
-
-
- public override bool method_has_wrapper (Method method) {
- return (method.get_attribute ("NoWrapper") == null);
- }
-
- public override string? get_custom_creturn_type (Method m) {
- var attr = m.get_attribute ("CCode");
- if (attr != null) {
- string type = attr.get_string ("type");
- if (type != null) {
- return type;
- }
- }
- return null;
- }
-
- public override void generate_method_declaration (Method m, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, m, get_ccode_name (m))) {
- return;
- }
-
- var function = new CCodeFunction (get_ccode_name (m));
-
- if (m.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- if (m.is_inline) {
- function.modifiers |= CCodeModifiers.INLINE;
- }
- }
-
- generate_cparameters (m, decl_space, function, null, new CCodeFunctionCall (new CCodeIdentifier ("fake")));
-
- decl_space.add_function_declaration (function);
-
- if (m.is_abstract || m.is_virtual) {
- var base_func = function.copy ();
- base_func.name = "%sbase_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name);
- base_func.insert_parameter (0, new CCodeParameter ("base_type", "DovaType *"));
- decl_space.add_function_declaration (base_func);
-
- string param_list = "(%s *this".printf (get_ccode_name (m.parent_symbol));
- foreach (var param in m.get_parameters ()) {
- param_list += ", ";
- param_list += get_ccode_name (param.variable_type);
- }
- if (m.return_type is GenericType) {
- param_list += ", void *";
- }
- param_list += ")";
-
- var override_func = new CCodeFunction ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name));
- override_func.add_parameter (new CCodeParameter ("type", "DovaType *"));
- override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type)));
- decl_space.add_function_declaration (override_func);
- }
-
- if (m is CreationMethod && m.parent_symbol is Class) {
- generate_class_declaration ((Class) m.parent_symbol, decl_space);
-
- // _init function
- function = new CCodeFunction (get_ccode_real_name (m));
-
- if (m.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- generate_cparameters (m, decl_space, function);
-
- decl_space.add_function_declaration (function);
- }
- }
-
- CCodeExpression get_type_from_instance (CCodeExpression instance_expression) {
- return new CCodeMemberAccess.pointer (new CCodeCastExpression (instance_expression, "DovaObject *"), "type");
- }
-
- public override void visit_method (Method m) {
- push_context (new EmitContext (m));
-
- foreach (Parameter param in m.get_parameters ()) {
- param.accept (this);
- }
-
- foreach (Expression precondition in m.get_preconditions ()) {
- precondition.emit (this);
- }
-
- foreach (Expression postcondition in m.get_postconditions ()) {
- postcondition.emit (this);
- }
-
-
- generate_method_declaration (m, cfile);
-
- if (!m.is_internal_symbol ()) {
- generate_method_declaration (m, header_file);
- }
-
- var function = new CCodeFunction (get_ccode_real_name (m));
-
- generate_cparameters (m, cfile, function);
-
- // generate *_real_* functions for virtual methods
- if (!m.is_abstract) {
- if (m.base_method != null || m.base_interface_method != null) {
- // declare *_real_* function
- function.modifiers |= CCodeModifiers.STATIC;
- cfile.add_function_declaration (function);
- } else if (m.is_internal_symbol ()) {
- function.modifiers |= CCodeModifiers.STATIC;
- }
-
- if (m.body != null) {
- push_function (function);
-
- if (context.module_init_method == m) {
- add_module_init ();
- }
-
- 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));
-
- ccode.add_statement (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)), "this");
- var cdecl = new CCodeDeclaration ("%s *".printf (get_ccode_name (current_class)));
- cdecl.add_declarator (new CCodeVariableDeclarator ("this", cself));
-
- ccode.add_statement (cdecl);
- }
- }
- foreach (Parameter param in m.get_parameters ()) {
- if (param.ellipsis) {
- break;
- }
-
- var t = param.variable_type.data_type;
- if (t != null && t.is_reference_type ()) {
- if (param.direction == ParameterDirection.OUT) {
- // 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, new CCodeIdentifier (param.name), new CCodeConstant ("NULL"));
- var if_statement = new CCodeIfStatement (condition, cblock);
- ccode.add_statement (if_statement);
- }
- }
- }
-
- m.body.emit (this);
-
- if (!(m.return_type is VoidType) && !(m.return_type is GenericType)) {
- var cdecl = new CCodeDeclaration (get_ccode_name (m.return_type));
- cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
- ccode.add_statement (cdecl);
-
- ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- }
-
- var st = m.parent_symbol as Struct;
- if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) {
- var cdecl = new CCodeDeclaration (get_ccode_name (st));
- cdecl.add_declarator (new CCodeVariableDeclarator ("this", new CCodeConstant ("0")));
- ccode.add_statement (cdecl);
-
- ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this")));
- }
-
- cfile.add_function (function);
- }
- }
-
- if (m.is_abstract || m.is_virtual) {
- generate_class_declaration ((Class) object_class, cfile);
-
- var vfunc = new CCodeFunction (get_ccode_name (m), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type));
- vfunc.block = new CCodeBlock ();
-
- vfunc.add_parameter (new CCodeParameter ("this", "%s *".printf (get_ccode_name (m.parent_symbol))));
- foreach (TypeParameter type_param in m.get_type_parameters ()) {
- vfunc.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*"));
- }
- foreach (Parameter param in m.get_parameters ()) {
- string ctypename = get_ccode_name (param.variable_type);
- if (param.direction != ParameterDirection.IN) {
- ctypename += "*";
- }
- vfunc.add_parameter (new CCodeParameter (param.name, ctypename));
- }
- if (m.return_type is GenericType) {
- vfunc.add_parameter (new CCodeParameter ("result", "void *"));
- }
-
- if (m.get_full_name () == "any.equals") {
- // make this null-safe
- var null_block = new CCodeBlock ();
- null_block.add_statement (new CCodeReturnStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("other"))));
- vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block));
- } else if (m.get_full_name () == "any.hash") {
- // make this null-safe
- var null_block = new CCodeBlock ();
- null_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("0")));
- vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block));
- } else if (m.get_full_name () == "any.to_string") {
- // make this null-safe
- var null_string = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring"));
- null_string.add_argument (new CCodeConstant ("\"(null)\""));
- var null_block = new CCodeBlock ();
- null_block.add_statement (new CCodeReturnStatement (null_string));
- vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block));
- }
-
- var vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, get_type_from_instance (new CCodeIdentifier ("this")));
-
- var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m)));
- vcall.add_argument (new CCodeIdentifier ("this"));
- foreach (TypeParameter type_param in m.get_type_parameters ()) {
- vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
- foreach (Parameter param in m.get_parameters ()) {
- vcall.add_argument (new CCodeIdentifier (param.name));
- }
- if (m.return_type is GenericType) {
- vcall.add_argument (new CCodeIdentifier ("result"));
- }
-
- if (m.return_type is VoidType || m.return_type is GenericType) {
- vfunc.block.add_statement (new CCodeExpressionStatement (vcall));
- } else {
- vfunc.block.add_statement (new CCodeReturnStatement (vcall));
- }
-
- cfile.add_function (vfunc);
-
-
- vfunc = new CCodeFunction ("%sbase_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type));
- vfunc.block = new CCodeBlock ();
-
- vfunc.add_parameter (new CCodeParameter ("base_type", "DovaType *"));
- vfunc.add_parameter (new CCodeParameter ("this", "%s *".printf (get_ccode_name (m.parent_symbol))));
- foreach (TypeParameter type_param in m.get_type_parameters ()) {
- vfunc.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*"));
- }
- foreach (Parameter param in m.get_parameters ()) {
- string ctypename = get_ccode_name (param.variable_type);
- if (param.direction != ParameterDirection.IN) {
- ctypename += "*";
- }
- vfunc.add_parameter (new CCodeParameter (param.name, ctypename));
- }
- if (m.return_type is GenericType) {
- vfunc.add_parameter (new CCodeParameter ("result", "void *"));
- }
-
- var base_type = new CCodeIdentifier ("base_type");
-
- vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, base_type);
-
- vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m)));
- vcall.add_argument (new CCodeIdentifier ("this"));
- foreach (TypeParameter type_param in m.get_type_parameters ()) {
- vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
- foreach (Parameter param in m.get_parameters ()) {
- vcall.add_argument (new CCodeIdentifier (param.name));
- }
- if (m.return_type is GenericType) {
- vcall.add_argument (new CCodeIdentifier ("result"));
- }
-
- if (m.return_type is VoidType || m.return_type is GenericType) {
- vfunc.block.add_statement (new CCodeExpressionStatement (vcall));
- } else {
- vfunc.block.add_statement (new CCodeReturnStatement (vcall));
- }
-
- cfile.add_function (vfunc);
-
-
- string param_list = "(%s *this".printf (get_ccode_name (m.parent_symbol));
- foreach (var param in m.get_parameters ()) {
- param_list += ", ";
- param_list += get_ccode_name (param.variable_type);
- }
- if (m.return_type is GenericType) {
- param_list += ", void *";
- }
- param_list += ")";
-
- var override_func = new CCodeFunction ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name));
- override_func.add_parameter (new CCodeParameter ("type", "DovaType *"));
- override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type)));
- override_func.block = new CCodeBlock ();
-
- vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, new CCodeIdentifier ("type"));
-
- override_func.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (vcast, m.name), new CCodeIdentifier ("function"))));
-
- cfile.add_function (override_func);
- }
-
- pop_context ();
-
- if (m.entry_point) {
- generate_type_declaration (new StructValueType (array_struct), cfile);
-
- // m is possible entry point, add appropriate startup code
- var cmain = new CCodeFunction ("main", "int");
- cmain.line = function.line;
- cmain.add_parameter (new CCodeParameter ("argc", "int"));
- cmain.add_parameter (new CCodeParameter ("argv", "char **"));
-
- push_function (cmain);
-
- var dova_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_init"));
- dova_init_call.add_argument (new CCodeIdentifier ("argc"));
- dova_init_call.add_argument (new CCodeIdentifier ("argv"));
- ccode.add_statement (new CCodeExpressionStatement (dova_init_call));
-
- add_module_init ();
-
- var cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator ("result", new CCodeConstant ("0")));
- ccode.add_statement (cdecl);
-
- var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
-
- if (m.get_parameters ().size == 1) {
- // create Dova array from C array
- // should be replaced by Dova list
- var array_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_create"));
- array_creation.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("string_type_get")));
- array_creation.add_argument (new CCodeIdentifier ("argc"));
-
- cdecl = new CCodeDeclaration ("DovaArray");
- cdecl.add_declarator (new CCodeVariableDeclarator ("args", array_creation));
- ccode.add_statement (cdecl);
-
- var array_data = new CCodeMemberAccess (new CCodeIdentifier ("args"), "data");
-
- cdecl = new CCodeDeclaration ("string_t*");
- cdecl.add_declarator (new CCodeVariableDeclarator ("args_data", array_data));
- ccode.add_statement (cdecl);
-
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator ("argi"));
- ccode.add_statement (cdecl);
-
- var string_creation = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring"));
- string_creation.add_argument (new CCodeElementAccess (new CCodeIdentifier ("argv"), new CCodeIdentifier ("argi")));
-
- var loop_block = new CCodeBlock ();
- loop_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("args_data"), new CCodeIdentifier ("argi")), string_creation)));
-
- var for_stmt = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("argi"), new CCodeIdentifier ("argc")), loop_block);
- for_stmt.add_initializer (new CCodeAssignment (new CCodeIdentifier ("argi"), new CCodeConstant ("0")));
- for_stmt.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("argi")));
- ccode.add_statement (for_stmt);
-
- main_call.add_argument (new CCodeIdentifier ("args"));
- }
-
- if (m.return_type is VoidType) {
- // method returns void, always use 0 as exit code
- var main_stmt = new CCodeExpressionStatement (main_call);
- main_stmt.line = cmain.line;
- ccode.add_statement (main_stmt);
- } else {
- var main_stmt = new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), main_call));
- main_stmt.line = cmain.line;
- ccode.add_statement (main_stmt);
- }
-
- var ret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result"));
- ret_stmt.line = cmain.line;
- ccode.add_statement (ret_stmt);
-
- pop_function ();
-
- cfile.add_function (cmain);
- }
- }
-
- public override void visit_creation_method (CreationMethod m) {
- bool visible = !m.is_internal_symbol ();
-
- visit_method (m);
-
- DataType creturn_type;
- if (current_type_symbol is Class) {
- creturn_type = new ObjectType (current_class);
- } else {
- creturn_type = new VoidType ();
- }
-
- // do not generate _new functions for creation methods of abstract classes
- if (current_type_symbol is Class && !current_class.is_abstract) {
- var vfunc = new CCodeFunction (get_ccode_name (m));
-
- var vblock = new CCodeBlock ();
-
- var cdecl = new CCodeDeclaration ("%s *".printf (get_ccode_name (current_type_symbol)));
- cdecl.add_declarator (new CCodeVariableDeclarator ("this"));
- vblock.add_statement (cdecl);
-
- var type_get = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_lower_case_name (current_class) + "_type_get"));
- foreach (var type_param in current_class.get_type_parameters ()) {
- type_get.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
-
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc"));
- alloc_call.add_argument (type_get);
- vblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("this"), new CCodeCastExpression (alloc_call, "%s *".printf (get_ccode_name (current_type_symbol))))));
-
- // allocate memory for fields of generic types
- // this is only a temporary measure until this can be allocated inline at the end of the instance
- // this also won't work for subclasses of classes that have fields of generic types
- foreach (var f in current_class.get_fields ()) {
- if (f.binding != MemberBinding.INSTANCE || !(f.variable_type is GenericType)) {
- continue;
- }
-
- var generic_type = (GenericType) f.variable_type;
- var type_get_value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- type_get_value_size.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ())));
-
- var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc"));
- calloc_call.add_argument (new CCodeConstant ("1"));
- calloc_call.add_argument (type_get_value_size);
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (current_class, null))));
- priv_call.add_argument (new CCodeIdentifier ("this"));
-
- vblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, f.name), calloc_call)));
- }
-
- var vcall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m)));
- vcall.add_argument (new CCodeIdentifier ("this"));
- vblock.add_statement (new CCodeExpressionStatement (vcall));
-
- generate_cparameters (m, cfile, vfunc, null, vcall);
- CCodeStatement cstmt = new CCodeReturnStatement (new CCodeIdentifier ("this"));
- cstmt.line = vfunc.line;
- vblock.add_statement (cstmt);
-
- if (!visible) {
- vfunc.modifiers |= CCodeModifiers.STATIC;
- }
-
- cfile.add_function_declaration (vfunc);
-
- vfunc.block = vblock;
-
- cfile.add_function (vfunc);
- }
- }
-
- private TypeSymbol? find_parent_type (Symbol sym) {
- while (sym != null) {
- if (sym is TypeSymbol) {
- return (TypeSymbol) sym;
- }
- sym = sym.parent_symbol;
- }
- return null;
- }
-
- public override void generate_cparameters (Method m, CCodeFile decl_space, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, CCodeFunctionCall? vcall = null) {
- CCodeParameter instance_param = null;
- if (m.closure) {
- var closure_block = current_closure_block;
- int block_id = get_block_id (closure_block);
- instance_param = new CCodeParameter ("_data%d_".printf (block_id), "Block%dData*".printf (block_id));
- } else if (m.parent_symbol is Class && m is CreationMethod) {
- if (vcall == null) {
- instance_param = new CCodeParameter ("this", get_ccode_name (((Class) m.parent_symbol)) + "*");
- }
- } else if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) {
- TypeSymbol parent_type = find_parent_type (m);
- var this_type = get_data_type_for_symbol (parent_type);
-
- generate_type_declaration (this_type, decl_space);
-
- if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) {
- var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol);
- instance_param = new CCodeParameter ("this", get_ccode_name (base_type));
- } else if (m.overrides) {
- var base_type = new ObjectType ((Class) m.base_method.parent_symbol);
- generate_type_declaration (base_type, decl_space);
- instance_param = new CCodeParameter ("this", get_ccode_name (base_type));
- } else {
- if (m.parent_symbol is Struct && m is CreationMethod) {
- var st = (Struct) m.parent_symbol;
- if (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ()) {
- // use return value
- } else {
- instance_param = new CCodeParameter ("*this", get_ccode_name (this_type));
- }
- } else {
- instance_param = new CCodeParameter ("this", get_ccode_name (this_type));
- }
- }
- }
- if (instance_param != null) {
- func.add_parameter (instance_param);
- if (vdeclarator != null) {
- vdeclarator.add_parameter (instance_param);
- }
- }
-
- if (m is CreationMethod) {
- generate_class_declaration ((Class) type_class, decl_space);
-
- if (m.parent_symbol is Class) {
- var cl = (Class) m.parent_symbol;
- foreach (TypeParameter type_param in cl.get_type_parameters ()) {
- var cparam = new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*");
- if (vcall != null) {
- func.add_parameter (cparam);
- }
- }
- }
- } else {
- foreach (TypeParameter type_param in m.get_type_parameters ()) {
- var cparam = new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*");
- func.add_parameter (cparam);
- if (vdeclarator != null) {
- vdeclarator.add_parameter (cparam);
- }
- if (vcall != null) {
- vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ())));
- }
- }
- }
-
- foreach (Parameter param in m.get_parameters ()) {
- CCodeParameter cparam;
- if (!param.ellipsis) {
- string ctypename = get_ccode_name (param.variable_type);
-
- generate_type_declaration (param.variable_type, decl_space);
-
- if (param.direction != ParameterDirection.IN && !(param.variable_type is GenericType)) {
- ctypename += "*";
- }
-
- cparam = new CCodeParameter (get_variable_cname (param.name), ctypename);
- } else {
- cparam = new CCodeParameter.with_ellipsis ();
- }
-
- func.add_parameter (cparam);
- if (vdeclarator != null) {
- vdeclarator.add_parameter (cparam);
- }
- if (vcall != null) {
- if (param.name != null) {
- vcall.add_argument (get_variable_cexpression (param.name));
- }
- }
- }
-
- if (m.parent_symbol is Class && m is CreationMethod && vcall != null) {
- func.return_type = get_ccode_name (((Class) m.parent_symbol)) + "*";
- } else {
- if (m.return_type is GenericType) {
- func.add_parameter (new CCodeParameter ("result", "void *"));
- if (vdeclarator != null) {
- vdeclarator.add_parameter (new CCodeParameter ("result", "void *"));
- }
- } else {
- var st = m.parent_symbol as Struct;
- if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) {
- func.return_type = get_ccode_name (st);
- } else {
- func.return_type = get_ccode_name (m.return_type);
- }
- }
-
- generate_type_declaration (m.return_type, decl_space);
- }
- }
-
- public override void visit_element_access (ElementAccess expr) {
- var array_type = expr.container.value_type as ArrayType;
- if (array_type != null) {
- // access to element in an array
-
- expr.accept_children (this);
-
- List<Expression> indices = expr.get_indices ();
- var cindex = get_cvalue (indices[0]);
-
- if (array_type.inline_allocated) {
- if (array_type.element_type is GenericType) {
- // generic array
- // calculate offset in bytes based on value size
- var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- value_size.add_argument (get_type_id_expression (array_type.element_type));
- set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (get_cvalue (expr.container), "char*"), new CCodeBinaryExpression (CCodeBinaryOperator.MUL, value_size, cindex)));
- } else {
- set_cvalue (expr, new CCodeElementAccess (get_cvalue (expr.container), cindex));
- }
- } else {
- var ccontainer = new CCodeMemberAccess (get_cvalue (expr.container), "data");
-
- if (array_type.element_type is GenericType) {
- // generic array
- // calculate offset in bytes based on value size
- var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- value_size.add_argument (get_type_id_expression (array_type.element_type));
- set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (ccontainer, "char*"), new CCodeBinaryExpression (CCodeBinaryOperator.MUL, value_size, cindex)));
- } else {
- set_cvalue (expr, new CCodeElementAccess (new CCodeCastExpression (ccontainer, "%s*".printf (get_ccode_name (array_type.element_type))), cindex));
- }
- }
-
- } else {
- base.visit_element_access (expr);
- }
- }
-
- void add_module_init () {
- foreach (var field in static_fields) {
- field.initializer.emit (this);
-
- var lhs = new CCodeIdentifier (get_ccode_name (field));
- var rhs = get_cvalue (field.initializer);
-
- ccode.add_assignment (lhs, rhs);
- }
- }
-}
+++ /dev/null
-/* valadovastructmodule.vala
- *
- * Copyright (C) 2006-2009 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;
-
-public abstract class Vala.DovaStructModule : DovaBaseModule {
- public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
- if (add_symbol_declaration (decl_space, st, get_ccode_name (st))) {
- return;
- }
-
- if (st.base_struct != null) {
- generate_struct_declaration (st.base_struct, decl_space);
-
- decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (st.base_struct), new CCodeVariableDeclarator (get_ccode_name (st))));
- return;
- }
-
- if (st.is_boolean_type ()) {
- // typedef for boolean types
- return;
- } else if (st.is_integer_type ()) {
- // typedef for integral types
- return;
- } else if (st.is_decimal_floating_type ()) {
- // typedef for decimal floating types
- return;
- } else if (st.is_floating_type ()) {
- // typedef for generic floating types
- return;
- }
-
- var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (st)));
-
- foreach (Field f in st.get_fields ()) {
- string field_ctype = get_ccode_name (f.variable_type);
- if (f.is_volatile) {
- field_ctype = "volatile " + field_ctype;
- }
-
- if (f.binding == MemberBinding.INSTANCE) {
- generate_type_declaration (f.variable_type, decl_space);
-
- instance_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type));
- }
- }
-
- decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (st)), new CCodeVariableDeclarator (get_ccode_name (st))));
-
- decl_space.add_type_definition (instance_struct);
- }
-
- public override void visit_struct (Struct st) {
- push_context (new EmitContext (st));
-
- generate_struct_declaration (st, cfile);
-
- if (!st.is_internal_symbol ()) {
- generate_struct_declaration (st, header_file);
- }
-
- st.accept_children (this);
-
- pop_context ();
- }
-}
-
+++ /dev/null
-/* valadovavaluemodule.vala
- *
- * Copyright (C) 2009-2011 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.DovaValueModule : DovaObjectModule {
- public override void visit_creation_method (CreationMethod m) {
- if (current_type_symbol is Class &&
- (current_class.base_class == null ||
- current_class.base_class.get_full_name () != "Dova.Value")) {
- base.visit_creation_method (m);
- return;
- }
-
- visit_method (m);
- }
-
- public override void generate_struct_declaration (Struct st, CCodeFile decl_space) {
- base.generate_struct_declaration (st, decl_space);
-
- if (add_symbol_declaration (decl_space, st, get_ccode_copy_function (st))) {
- return;
- }
-
- generate_class_declaration (type_class, decl_space);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (st)), "DovaType *");
- if (st.is_internal_symbol ()) {
- type_fun.modifiers = CCodeModifiers.STATIC;
- }
- decl_space.add_function_declaration (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (st)));
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- if (st.is_internal_symbol ()) {
- type_init_fun.modifiers = CCodeModifiers.STATIC;
- }
- decl_space.add_function_declaration (type_init_fun);
-
- var function = new CCodeFunction (get_ccode_copy_function (st), "void");
- if (st.is_internal_symbol ()) {
- function.modifiers = CCodeModifiers.STATIC;
- }
-
- function.add_parameter (new CCodeParameter ("dest", get_ccode_name (st) + "*"));
- function.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- function.add_parameter (new CCodeParameter ("src", get_ccode_name (st) + "*"));
- function.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- decl_space.add_function_declaration (function);
- }
-
- public override void visit_struct (Struct st) {
- base.visit_struct (st);
-
- var cdecl = new CCodeDeclaration ("intptr_t");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (st)), new CCodeConstant ("0")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- string macro = "((%s *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (st), get_ccode_lower_case_name (st));
- cfile.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (st, null)), macro));
-
-
- cdecl = new CCodeDeclaration ("DovaType *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (st)), new CCodeConstant ("NULL")));
- cdecl.modifiers = CCodeModifiers.STATIC;
- cfile.add_type_member_declaration (cdecl);
-
- var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (st)), "DovaType *");
- type_fun.block = new CCodeBlock ();
-
- var type_init_block = new CCodeBlock ();
-
- generate_method_declaration ((Method) object_class.scope.lookup ("alloc"), cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("base_type")).get_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("base_type")).set_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("object_size")).get_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("object_size")).set_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("type_size")).get_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("type_size")).set_accessor, cfile);
- generate_property_accessor_declaration (((Property) type_class.scope.lookup ("value_size")).set_accessor, cfile);
-
- generate_class_declaration ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Value"), cfile);
-
- var base_type = new CCodeFunctionCall (new CCodeIdentifier ("dova_value_type_get"));
-
- var base_type_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_type_size"));
- base_type_size.add_argument (base_type);
-
- var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc"));
- calloc_call.add_argument (new CCodeConstant ("1"));
- calloc_call.add_argument (base_type_size);
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))), calloc_call)));
-
- generate_class_declaration ((Class) object_class, cfile);
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))), "DovaObject *"), "type"), new CCodeFunctionCall (new CCodeIdentifier ("dova_type_type_get")))));
-
- var set_base_type = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_base_type"));
- set_base_type.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- set_base_type.add_argument (base_type);
- type_init_block.add_statement (new CCodeExpressionStatement (set_base_type));
-
- var base_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_object_size"));
- base_size.add_argument (base_type);
-
- type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (st))), base_size)));
-
- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
- sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (st)));
- var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_object_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- set_size.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, base_size, sizeof_call));
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- set_size.add_argument (sizeof_call);
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_type_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- set_size.add_argument (base_type_size);
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (st))));
- type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- type_init_block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- // workaround: set value_size again as it is currently overwritten by dova_object_type_init
- set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size"));
- set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))));
- set_size.add_argument (sizeof_call);
- type_init_block.add_statement (new CCodeExpressionStatement (set_size));
-
- type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))), type_init_block));
-
- type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))));
-
- cfile.add_function (type_fun);
-
- var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (st)));
- type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *"));
- type_init_fun.block = new CCodeBlock ();
-
- type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_value_type_init"));
- type_init_call.add_argument (new CCodeIdentifier ("type"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call));
-
- declare_set_value_copy_function (cfile);
-
- var value_copy_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_copy"));
- value_copy_call.add_argument (new CCodeIdentifier ("type"));
- value_copy_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st))), "void (*)(void *, intptr_t, void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_copy_call));
-
- if (st.scope.lookup ("equals") is Method) {
- var value_equals_fun = new CCodeFunction ("%s_value_equals".printf (get_ccode_lower_case_name (st)), "bool");
- value_equals_fun.modifiers = CCodeModifiers.STATIC;
- value_equals_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*"));
- value_equals_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_equals_fun.add_parameter (new CCodeParameter ("other", get_ccode_name (st) + "*"));
- value_equals_fun.add_parameter (new CCodeParameter ("other_index", "intptr_t"));
- value_equals_fun.block = new CCodeBlock ();
- var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index"));
- var other = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("other"), new CCodeIdentifier ("other_index"));
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_equals".printf (get_ccode_lower_case_name (st))));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, other));
- value_equals_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_equals_fun);
-
- declare_set_value_equals_function (cfile);
-
- var value_equals_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_equals"));
- value_equals_call.add_argument (new CCodeIdentifier ("type"));
- value_equals_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_equals".printf (get_ccode_lower_case_name (st))), "bool (*)(void *, intptr_t, void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_equals_call));
- }
-
- if (st.scope.lookup ("hash") is Method) {
- var value_hash_fun = new CCodeFunction ("%s_value_hash".printf (get_ccode_lower_case_name (st)), "uintptr_t");
- value_hash_fun.modifiers = CCodeModifiers.STATIC;
- value_hash_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*"));
- value_hash_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_hash_fun.block = new CCodeBlock ();
- var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index"));
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_hash".printf (get_ccode_lower_case_name (st))));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val));
- value_hash_fun.block.add_statement (new CCodeReturnStatement (ccall));
- cfile.add_function (value_hash_fun);
-
- declare_set_value_hash_function (cfile);
-
- var value_hash_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_hash"));
- value_hash_call.add_argument (new CCodeIdentifier ("type"));
- value_hash_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_hash".printf (get_ccode_lower_case_name (st))), "uintptr_t (*)(void *, intptr_t)"));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_hash_call));
- }
-
- // generate method to box values
- var value_to_any_fun = new CCodeFunction ("%s_value_to_any".printf (get_ccode_lower_case_name (st)), "DovaObject*");
- value_to_any_fun.modifiers = CCodeModifiers.STATIC;
- value_to_any_fun.add_parameter (new CCodeParameter ("value", "void *"));
- value_to_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_to_any_fun.block = new CCodeBlock ();
- var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc"));
- alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (st)))));
- cdecl = new CCodeDeclaration ("DovaObject *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("result", alloc_call));
- value_to_any_fun.block.add_statement (cdecl);
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (st, null))));
- priv_call.add_argument (new CCodeIdentifier ("result"));
- var copy_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st))));
- copy_call.add_argument (priv_call);
- copy_call.add_argument (new CCodeConstant ("0"));
- copy_call.add_argument (new CCodeIdentifier ("value"));
- copy_call.add_argument (new CCodeIdentifier ("value_index"));
- value_to_any_fun.block.add_statement (new CCodeExpressionStatement (copy_call));
- value_to_any_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- cfile.add_function (value_to_any_fun);
-
- declare_set_value_to_any_function (cfile);
-
- var value_to_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_to_any"));
- value_to_any_call.add_argument (new CCodeIdentifier ("type"));
- value_to_any_call.add_argument (new CCodeIdentifier ("%s_value_to_any".printf (get_ccode_lower_case_name (st))));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_to_any_call));
-
- // generate method to unbox values
- var value_from_any_fun = new CCodeFunction ("%s_value_from_any".printf (get_ccode_lower_case_name (st)));
- value_from_any_fun.modifiers = CCodeModifiers.STATIC;
- value_from_any_fun.add_parameter (new CCodeParameter ("any_", "any *"));
- value_from_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*"));
- value_from_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t"));
- value_from_any_fun.block = new CCodeBlock ();
- priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (st, null))));
- priv_call.add_argument (new CCodeIdentifier ("any_"));
- copy_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st))));
- copy_call.add_argument (new CCodeIdentifier ("value"));
- copy_call.add_argument (new CCodeIdentifier ("value_index"));
- copy_call.add_argument (priv_call);
- copy_call.add_argument (new CCodeConstant ("0"));
- value_from_any_fun.block.add_statement (new CCodeExpressionStatement (copy_call));
- cfile.add_function (value_from_any_fun);
-
- declare_set_value_from_any_function (cfile);
-
- var value_from_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_from_any"));
- value_from_any_call.add_argument (new CCodeIdentifier ("type"));
- value_from_any_call.add_argument (new CCodeIdentifier ("%s_value_from_any".printf (get_ccode_lower_case_name (st))));
- type_init_fun.block.add_statement (new CCodeExpressionStatement (value_from_any_call));
-
- cfile.add_function (type_init_fun);
-
- add_struct_copy_function (st);
- }
-
- void add_struct_copy_function (Struct st) {
- var function = new CCodeFunction (get_ccode_copy_function (st), "void");
- if (st.is_internal_symbol ()) {
- function.modifiers = CCodeModifiers.STATIC;
- }
-
- function.add_parameter (new CCodeParameter ("dest", get_ccode_name (st) + "*"));
- function.add_parameter (new CCodeParameter ("dest_index", "intptr_t"));
- function.add_parameter (new CCodeParameter ("src", get_ccode_name (st) + "*"));
- function.add_parameter (new CCodeParameter ("src_index", "intptr_t"));
-
- var cblock = new CCodeBlock ();
- var cfrag = new CCodeFragment ();
- cblock.add_statement (cfrag);
-
- var dest = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("dest"), new CCodeIdentifier ("dest_index"));
- var src = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("src"), new CCodeIdentifier ("src_index"));
-
- foreach (var f in st.get_fields ()) {
- if (f.binding == MemberBinding.INSTANCE) {
- var field = new CCodeMemberAccess.pointer (dest, f.name);
-
- var array_type = f.variable_type as ArrayType;
- if (array_type != null && array_type.fixed_length) {
- for (int i = 0; i < array_type.length; i++) {
- var element = new CCodeElementAccess (field, new CCodeConstant (i.to_string ()));
-
- if (requires_destroy (array_type.element_type)) {
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (element, array_type.element_type)));
- }
- }
- continue;
- }
-
- if (requires_destroy (f.variable_type)) {
- var this_access = new MemberAccess.simple ("this");
- this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
- set_cvalue (this_access, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest));
- var ma = new MemberAccess (this_access, f.name);
- ma.symbol_reference = f;
- ma.value_type = f.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (field, f.variable_type, ma)));
- }
- }
- }
-
- var copy_block = new CCodeBlock ();
-
- if (st.get_fields ().size == 0) {
- copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src))));
- } else {
- foreach (var f in st.get_fields ()) {
- if (f.binding == MemberBinding.INSTANCE) {
- CCodeExpression copy = new CCodeMemberAccess.pointer (src, f.name);
- var dest_field = new CCodeMemberAccess.pointer (dest, f.name);
-
- var array_type = f.variable_type as ArrayType;
- if (array_type != null && array_type.fixed_length) {
- for (int i = 0; i < array_type.length; i++) {
- CCodeExpression copy_element = new CCodeElementAccess (copy, new CCodeConstant (i.to_string ()));
- var dest_field_element = new CCodeElementAccess (dest_field, new CCodeConstant (i.to_string ()));
-
- if (requires_copy (array_type.element_type)) {
- copy_element = get_ref_cexpression (array_type.element_type, copy_element, null, f);
- }
-
- copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest_field_element, copy_element)));
- }
- continue;
- }
-
- if (requires_copy (f.variable_type)) {
- var this_access = new MemberAccess.simple ("this");
- this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
- set_cvalue (this_access, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src));
- var ma = new MemberAccess (this_access, f.name);
- ma.symbol_reference = f;
- copy = get_ref_cexpression (f.variable_type, copy, ma, f);
- }
-
- copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest_field, copy)));
- }
- }
- }
-
- cblock.add_statement (new CCodeIfStatement (new CCodeIdentifier ("src"), copy_block));
-
- function.block = cblock;
-
- cfile.add_function (function);
- }
-
- public override void visit_assignment (Assignment assignment) {
- var generic_type = assignment.left.value_type as GenericType;
- if (generic_type == null) {
- base.visit_assignment (assignment);
- return;
- }
-
- var dest = assignment.left;
- CCodeExpression cdest;
- CCodeExpression dest_index = new CCodeConstant ("0");
- var src = assignment.right;
- CCodeExpression csrc;
- CCodeExpression src_index = new CCodeConstant ("0");
-
- if (src is NullLiteral) {
- // TODO destroy dest
- set_cvalue (assignment, new CCodeConstant ("0"));
- return;
- }
-
- var dest_ea = dest as ElementAccess;
- var src_ea = src as ElementAccess;
-
- if (dest_ea != null) {
- dest = dest_ea.container;
-
- var array_type = dest.value_type as ArrayType;
- if (array_type != null && !array_type.inline_allocated) {
- cdest = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (dest), "data");
- } else {
- cdest = (CCodeExpression) get_ccodenode (dest);
- }
- dest_index = (CCodeExpression) get_ccodenode (dest_ea.get_indices ().get (0));
- } else {
- cdest = (CCodeExpression) get_ccodenode (dest);
- }
-
- if (src_ea != null) {
- src = src_ea.container;
-
- var array_type = src.value_type as ArrayType;
- if (array_type != null && !array_type.inline_allocated) {
- csrc = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (src), "data");
- } else {
- csrc = (CCodeExpression) get_ccodenode (src);
- }
- src_index = (CCodeExpression) get_ccodenode (src_ea.get_indices ().get (0));
- } else {
- csrc = (CCodeExpression) get_ccodenode (src);
- }
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_copy"));
- if (generic_type.type_parameter.parent_symbol is TypeSymbol) {
- // generic type
- ccall.add_argument (new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) generic_type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), "%s_type".printf (generic_type.type_parameter.name.down ())));
- } else {
- // generic method
- ccall.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ())));
- }
- ccall.add_argument (cdest);
- ccall.add_argument (dest_index);
- ccall.add_argument (csrc);
- ccall.add_argument (src_index);
- set_cvalue (assignment, ccall);
- }
-
- public override void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) {
- var generic_type = lvalue.value_type as GenericType;
- if (generic_type == null) {
- base.store_variable (variable, lvalue, value, initializer);
- return;
- }
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_copy"));
- if (generic_type.type_parameter.parent_symbol is TypeSymbol) {
- // generic type
- ccall.add_argument (new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) generic_type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), "%s_type".printf (generic_type.type_parameter.name.down ())));
- } else {
- // generic method
- ccall.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ())));
- }
- ccall.add_argument (get_cvalue_ (lvalue));
- ccall.add_argument (new CCodeConstant ("0"));
- ccall.add_argument (get_cvalue_ (value));
- ccall.add_argument (new CCodeConstant ("0"));
-
- ccode.add_expression (ccall);
- }
-
- public override void visit_binary_expression (BinaryExpression expr) {
- var generic_type = expr.left.value_type as GenericType;
- if (generic_type == null) {
- base.visit_binary_expression (expr);
- return;
- }
-
- CCodeExpression cleft;
- CCodeExpression left_index = new CCodeConstant ("0");
- CCodeExpression cright;
- CCodeExpression right_index = new CCodeConstant ("0");
-
- var left_ea = expr.left as ElementAccess;
- var right_ea = expr.right as ElementAccess;
-
- if (left_ea != null) {
- cleft = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (left_ea.container), "data");
- left_index = (CCodeExpression) get_ccodenode (left_ea.get_indices ().get (0));
- } else {
- cleft = (CCodeExpression) get_ccodenode (expr.left);
- }
-
- if (right_ea != null) {
- cright = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (right_ea.container), "data");
- right_index = (CCodeExpression) get_ccodenode (right_ea.get_indices ().get (0));
- } else {
- cright = (CCodeExpression) get_ccodenode (expr.right);
- }
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_equals"));
- ccall.add_argument (get_type_id_expression (generic_type));
- ccall.add_argument (cleft);
- ccall.add_argument (left_index);
- ccall.add_argument (cright);
- ccall.add_argument (right_index);
-
- if (expr.operator == BinaryOperator.EQUALITY) {
- set_cvalue (expr, ccall);
- } else {
- set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, ccall));
- }
- }
-
- public override void visit_method_call (MethodCall expr) {
- var ma = expr.call as MemberAccess;
- if (ma == null || ma.inner == null || !(ma.inner.value_type is GenericType)) {
- base.visit_method_call (expr);
- return;
- }
-
- // handle method calls on generic types
-
- expr.accept_children (this);
-
- if (ma.member_name == "hash") {
- var val = ma.inner;
- CCodeExpression cval;
- CCodeExpression val_index = new CCodeConstant ("0");
-
- var val_ea = val as ElementAccess;
- if (val_ea != null) {
- val = val_ea.container;
-
- cval = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (val), "data");
- val_index = (CCodeExpression) get_ccodenode (val_ea.get_indices ().get (0));
- } else {
- cval = (CCodeExpression) get_ccodenode (val);
- }
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_hash"));
- ccall.add_argument (get_type_id_expression (ma.inner.value_type));
- ccall.add_argument (cval);
- ccall.add_argument (val_index);
-
- set_cvalue (expr, ccall);
- }
- }
-
- public override void visit_list_literal (ListLiteral expr) {
- CCodeExpression ptr;
- int length = expr.get_expressions ().size;
-
- if (length == 0) {
- ptr = new CCodeConstant ("NULL");
- } else {
- var array_type = new ArrayType (expr.element_type, 1, expr.source_reference);
- array_type.inline_allocated = true;
- array_type.fixed_length = true;
- array_type.length = length;
-
- var temp_var = get_temp_variable (array_type, true, expr);
- var name_cnode = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- int i = 0;
- foreach (Expression e in expr.get_expressions ()) {
- ccode.add_assignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e));
- i++;
- }
-
- ptr = name_cnode;
- }
-
- var array_type = new ArrayType (expr.element_type, 1, expr.source_reference);
-
- var temp_var = get_temp_variable (array_type, true, expr);
- var name_cnode = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- var array_init = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_init"));
- array_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, name_cnode));
- array_init.add_argument (ptr);
- array_init.add_argument (new CCodeConstant (length.to_string ()));
- ccode.add_expression (array_init);
-
- var list_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_list_new"));
- list_creation.add_argument (get_type_id_expression (expr.element_type));
- list_creation.add_argument (name_cnode);
-
- set_cvalue (expr, list_creation);
- }
-
- public override void visit_set_literal (SetLiteral expr) {
- var ce = new CCodeCommaExpression ();
- int length = expr.get_expressions ().size;
-
- if (length == 0) {
- ce.append_expression (new CCodeConstant ("NULL"));
- } else {
- var array_type = new ArrayType (expr.element_type, 1, expr.source_reference);
- array_type.inline_allocated = true;
- array_type.fixed_length = true;
- array_type.length = length;
-
- var temp_var = get_temp_variable (array_type, true, expr);
- var name_cnode = get_variable_cexpression (temp_var.name);
-
- emit_temp_var (temp_var);
-
- int i = 0;
- foreach (Expression e in expr.get_expressions ()) {
- ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e)));
- i++;
- }
-
- ce.append_expression (name_cnode);
- }
-
- var set_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_set_new"));
- set_creation.add_argument (get_type_id_expression (expr.element_type));
- set_creation.add_argument (new CCodeConstant (length.to_string ()));
- set_creation.add_argument (ce);
-
- set_cvalue (expr, set_creation);
- }
-
- public override void visit_map_literal (MapLiteral expr) {
- var key_ce = new CCodeCommaExpression ();
- var value_ce = new CCodeCommaExpression ();
- int length = expr.get_keys ().size;
-
- if (length == 0) {
- key_ce.append_expression (new CCodeConstant ("NULL"));
- value_ce.append_expression (new CCodeConstant ("NULL"));
- } else {
- var key_array_type = new ArrayType (expr.map_key_type, 1, expr.source_reference);
- key_array_type.inline_allocated = true;
- key_array_type.fixed_length = true;
- key_array_type.length = length;
-
- var key_temp_var = get_temp_variable (key_array_type, true, expr);
- var key_name_cnode = get_variable_cexpression (key_temp_var.name);
-
- 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;
- value_array_type.fixed_length = true;
- value_array_type.length = length;
-
- var value_temp_var = get_temp_variable (value_array_type, true, expr);
- var value_name_cnode = get_variable_cexpression (value_temp_var.name);
-
- 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 ())), get_cvalue (expr.get_keys ().get (i))));
- value_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (value_name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (expr.get_values ().get (i))));
- }
-
- key_ce.append_expression (key_name_cnode);
- value_ce.append_expression (value_name_cnode);
- }
-
- var map_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_map_new"));
- map_creation.add_argument (get_type_id_expression (expr.map_key_type));
- map_creation.add_argument (get_type_id_expression (expr.map_value_type));
- map_creation.add_argument (new CCodeConstant (length.to_string ()));
- map_creation.add_argument (key_ce);
- map_creation.add_argument (value_ce);
-
- set_cvalue (expr, map_creation);
- }
-
- public override void visit_tuple (Tuple tuple) {
- var type_array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference);
- type_array_type.inline_allocated = true;
- type_array_type.fixed_length = true;
- type_array_type.length = tuple.get_expressions ().size;
-
- var type_temp_var = get_temp_variable (type_array_type, true, tuple);
- var type_name_cnode = get_variable_cexpression (type_temp_var.name);
- emit_temp_var (type_temp_var);
-
- var array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference);
- array_type.inline_allocated = true;
- array_type.fixed_length = true;
- array_type.length = tuple.get_expressions ().size;
-
- var temp_var = get_temp_variable (array_type, true, tuple);
- var name_cnode = get_variable_cexpression (temp_var.name);
- emit_temp_var (temp_var);
-
- var type_ce = new CCodeCommaExpression ();
- var ce = new CCodeCommaExpression ();
-
- int i = 0;
- foreach (Expression e in tuple.get_expressions ()) {
- var element_type = tuple.value_type.get_type_arguments ().get (i);
-
- type_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (type_name_cnode, new CCodeConstant (i.to_string ())), get_type_id_expression (element_type)));
-
- var cexpr = get_cvalue (e);
-
- var unary = cexpr as CCodeUnaryExpression;
- if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
- // *expr => expr
- cexpr = unary.inner;
- } else if (cexpr is CCodeIdentifier || cexpr is CCodeMemberAccess) {
- cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
- } else {
- // if cexpr is e.g. a function call, we can't take the address of the expression
- // tmp = expr, &tmp
-
- var element_temp_var = get_temp_variable (element_type);
- 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));
- }
-
- ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), cexpr));
-
- i++;
- }
-
- type_ce.append_expression (type_name_cnode);
- ce.append_expression (name_cnode);
-
- var tuple_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_tuple_new"));
- tuple_creation.add_argument (new CCodeConstant (tuple.get_expressions ().size.to_string ()));
- tuple_creation.add_argument (type_ce);
- tuple_creation.add_argument (ce);
-
- set_cvalue (tuple, tuple_creation);
- }
-}
// default profile
context.profile = Profile.GOBJECT;
context.add_define ("GOBJECT");
- } else if (profile == "dova") {
- context.profile = Profile.DOVA;
- context.add_define ("DOVA");
} else {
Report.error (null, "Unknown profile %s".printf (profile));
}
context.add_external_package ("glib-2.0");
context.add_external_package ("gobject-2.0");
}
- } else if (context.profile == Profile.DOVA) {
- if (!nostdpkg) {
- /* default package */
- context.add_external_package ("dova-core-0.1");
- }
}
if (packages != null) {
if (context.profile == Profile.GOBJECT) {
context.codegen = new GDBusServerModule ();
- } else if (context.profile == Profile.DOVA) {
- context.codegen = new DovaErrorModule ();
} else {
context.codegen = new CCodeDelegateModule ();
}
valainterfacetype.vala \
valainvalidtype.vala \
valalambdaexpression.vala \
- valalistliteral.vala \
valaliteral.vala \
valalocalvariable.vala \
valalockable.vala \
valalockstatement.vala \
valaloop.vala \
- valamapliteral.vala \
valamarkupreader.vala \
valamemberaccess.vala \
valamemberinitializer.vala \
valascanner.vala \
valascope.vala \
valasemanticanalyzer.vala \
- valasetliteral.vala \
valasignal.vala \
valasignaltype.vala \
valasizeofexpression.vala \
public override bool is_disposable () {
if (fixed_length) {
return element_type.is_disposable ();
- } else if (CodeContext.get ().profile == Profile.DOVA) {
- return false;
} else {
return base.is_disposable ();
}
&& operator == BinaryOperator.PLUS) {
// string concatenation
- if (context.profile == Profile.DOVA) {
- var concat_call = new MethodCall (new MemberAccess (left, "concat", source_reference), source_reference);
- concat_call.add_argument (right);
- concat_call.target_type = target_type;
- parent_node.replace_expression (this, concat_call);
- return concat_call.check (context);
- }
-
if (right.value_type == null || right.value_type.data_type != context.analyzer.string_type.data_type) {
error = true;
Report.error (source_reference, "Operands must be strings");
} else {
value_type.value_owned = true;
}
- } else if (context.profile == Profile.DOVA && left.value_type.data_type == context.analyzer.list_type.data_type
- && operator == BinaryOperator.PLUS) {
- // list concatenation
-
- var concat_call = new MethodCall (new MemberAccess (left, "concat", source_reference), source_reference);
- concat_call.add_argument (right);
- concat_call.target_type = target_type;
- parent_node.replace_expression (this, concat_call);
- return concat_call.check (context);
- } else if (context.profile != Profile.DOVA && left.value_type is ArrayType && operator == BinaryOperator.PLUS) {
+ } else if (left.value_type is ArrayType && operator == BinaryOperator.PLUS) {
// array concatenation
var array_type = (ArrayType) left.value_type;
}
} else if (right.value_type is PointerType) {
// pointer arithmetic: pointer - pointer
- if (context.profile == Profile.DOVA) {
- value_type = context.analyzer.long_type;
- } else {
- value_type = context.analyzer.size_t_type;
- }
+ value_type = context.analyzer.size_t_type;
}
} else {
left.target_type.nullable = false;
}
}
- if (left.value_type.compatible (context.analyzer.string_type)
- && right.value_type.compatible (context.analyzer.string_type)) {
- // string comparison
- if (context.profile == Profile.DOVA) {
- var string_ma = new MemberAccess.simple ("string", source_reference);
- string_ma.qualified = true;
- var equals_call = new MethodCall (new MemberAccess (string_ma, "equals", source_reference), source_reference);
- equals_call.add_argument (left);
- equals_call.add_argument (right);
- if (operator == BinaryOperator.EQUALITY) {
- parent_node.replace_expression (this, equals_call);
- return equals_call.check (context);
- } else {
- var not = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, equals_call, source_reference);
- parent_node.replace_expression (this, not);
- return not.check (context);
- }
- }
- }
-
value_type = context.analyzer.bool_type;
} else if (operator == BinaryOperator.BITWISE_AND
|| operator == BinaryOperator.BITWISE_OR) {
checked = true;
- if (context.profile == Profile.DOVA) {
- value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"), get_char ().to_string (), "int");
+ if (get_char () < 128) {
+ value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"));
} else {
- if (get_char () < 128) {
- value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"));
- } else {
- value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("unichar"));
- }
+ value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("unichar"));
}
return !error;
* @param f a field
*/
public override void add_field (Field f) {
- if (CodeContext.get ().profile == Profile.DOVA &&
- f.binding == MemberBinding.INSTANCE &&
- (f.access == SymbolAccessibility.PUBLIC || f.access == SymbolAccessibility.PROTECTED) &&
- name != "any" /* temporary workaround */) {
- // public/protected instance fields not supported, convert to automatic property
-
- var prop = new Property (f.name, f.variable_type.copy (), null, null, f.source_reference, comment);
- prop.access = access;
-
- var get_type = prop.property_type.copy ();
- get_type.value_owned = true;
- var set_type = prop.property_type.copy ();
- set_type.value_owned = false;
-
- prop.get_accessor = new PropertyAccessor (true, false, false, get_type, null, f.source_reference);
-
- prop.set_accessor = new PropertyAccessor (false, true, false, set_type, null, f.source_reference);
-
- f.name = "_%s".printf (f.name);
- f.access = SymbolAccessibility.PRIVATE;
- prop.field = f;
-
- add_property (prop);
- return;
- }
-
fields.add (f);
if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) {
has_private_fields = true;
m.this_parameter = new Parameter ("this", get_this_type ());
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
if (m.result_var != null) {
m.scope.remove (m.result_var.name);
}
public bool is_fundamental () {
if (!is_compact && base_class == null) {
return true;
- } else if (CodeContext.get ().profile == Profile.DOVA && base_class.base_class == null) {
- return true;
}
return false;
}
var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "GLib", null));
source_file.add_using_directive (ns_ref);
root.add_using_directive (ns_ref);
- } else if (profile == Profile.DOVA) {
- // import the Dova namespace by default (namespace of backend-specific standard library)
- var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "Dova", null));
- source_file.add_using_directive (ns_ref);
- root.add_using_directive (ns_ref);
}
add_source_file (source_file);
public virtual void visit_template (Template tmpl) {
}
- /**
- * Visit operation called for list literals.
- *
- * @param lit a list literal
- */
- public virtual void visit_list_literal (ListLiteral lit) {
- }
-
- /**
- * Visit operation called for set literals.
- *
- * @param lit a set literal
- */
- public virtual void visit_set_literal (SetLiteral lit) {
- }
-
- /**
- * Visit operation called for map literals.
- *
- * @param lit a map literal
- */
- public virtual void visit_map_literal (MapLiteral lit) {
- }
-
/**
* Visit operation called for tuples.
*
write_params (m.get_parameters ());
- if (context.profile != Profile.DOVA) {
- write_error_domains (m.get_error_types ());
- }
+ write_error_domains (m.get_error_types ());
write_code_block (m.body);
write_property_accessor_accessibility (prop.get_accessor);
- if (context.profile != Profile.DOVA && prop.get_accessor.value_type.is_disposable ()) {
+ if (prop.get_accessor.value_type.is_disposable ()) {
write_string (" owned");
}
write_property_accessor_accessibility (prop.set_accessor);
- if (context.profile != Profile.DOVA && prop.set_accessor.value_type.value_owned) {
+ if (prop.set_accessor.value_type.value_owned) {
write_string (" owned");
}
private void write_identifier (string s) {
char* id = (char*)s;
int id_length = (int)s.length;
- if (context.profile != Profile.DOVA &&
- (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER ||
- s.get_char ().isdigit ())) {
+ if (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER ||
+ s.get_char ().isdigit ()) {
stream.putc ('@');
}
write_string (s);
}
}
- if (this is ValueType && target_type.data_type != null && target_type.data_type.get_full_name () == "Dova.Value") {
- // allow implicit conversion to Dova.Value
- return true;
- }
-
if (target_type is DelegateType && this is DelegateType) {
return ((DelegateType) target_type).delegate_symbol == ((DelegateType) this).delegate_symbol;
}
return false;
}
- var container_type = container.value_type.data_type;
-
if (container is MemberAccess && container.symbol_reference is Signal) {
// signal detail access
if (get_indices ().size != 1) {
}
} else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) {
value_type = pointer_type.base_type.copy ();
- } else if (context.profile == Profile.DOVA && container_type == context.analyzer.tuple_type.data_type) {
- if (get_indices ().size != 1) {
- error = true;
- Report.error (source_reference, "Element access with more than one dimension is not supported for tuples");
- return false;
- }
- var index = get_indices ().get (0) as IntegerLiteral;
- if (index == null) {
- error = true;
- Report.error (source_reference, "Element access with non-literal index is not supported for tuples");
- return false;
- }
- int i = int.parse (index.value);
- if (container.value_type.get_type_arguments ().size == 0) {
- error = true;
- Report.error (source_reference, "Element access is not supported for untyped tuples");
- return false;
- }
- if (i < 0 || i >= container.value_type.get_type_arguments ().size) {
- error = true;
- Report.error (source_reference, "Index out of range");
- return false;
- }
-
- value_type = container.value_type.get_type_arguments ().get (i);
-
- // replace element access by call to generic get method
- var ma = new MemberAccess (container, "get", source_reference);
- ma.add_type_argument (value_type);
- var get_call = new MethodCall (ma, source_reference);
- get_call.add_argument (index);
- get_call.target_type = this.target_type;
- parent_node.replace_expression (this, get_call);
- return get_call.check (context);
} else if (container is MemberAccess && container.symbol_reference is Signal) {
index_int_type_check = false;
m.this_parameter = new Parameter ("this", new EnumValueType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
m.return_block.connect (m.exit_block);
- if (context.profile == Profile.DOVA && m.result_var != null) {
- // ensure result is defined at end of method
- var result_ma = new MemberAccess.simple ("result", m.source_reference);
- result_ma.symbol_reference = m.result_var;
- m.return_block.add_node (result_ma);
- }
if (m is Method) {
// ensure out parameters are defined at end of method
foreach (var param in ((Method) m).get_parameters ()) {
if (current_block != null) {
// end of method body reachable
- if (context.profile != Profile.DOVA && m.has_result) {
+ if (m.has_result) {
Report.error (m.source_reference, "missing return statement at end of subroutine body");
m.error = true;
}
var collection_type = collection.value_type.copy ();
collection.target_type = collection_type.copy ();
- if (context.profile != Profile.DOVA && collection_type.is_array ()) {
+ if (collection_type.is_array ()) {
var array_type = (ArrayType) collection_type;
// can't use inline-allocated array for temporary variable
}
public override Symbol? get_member (string member_name) {
- if (CodeContext.get ().profile == Profile.DOVA) {
- if (member_name == "equals") {
- return CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Object").scope.lookup ("equals");
- } else if (member_name == "hash") {
- return CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Object").scope.lookup ("hash");
- }
- }
return null;
}
}
type_suffix = "";
type_name = "int";
}
- } else if (CodeContext.get ().profile == Profile.DOVA) {
- if (u) {
- type_suffix = "UL";
- type_name = "uint64";
- } else {
- type_suffix = "L";
- type_name = "int64";
- }
} else if (l == 1) {
if (u) {
type_suffix = "UL";
}
var st = (Struct) context.analyzer.root_symbol.scope.lookup (type_name);
- // ensure attributes are already processed in case of bootstrapping dova-core
+ // ensure attributes are already processed
st.check (context);
value_type = new IntegerType (st, value, type_name);
m.this_parameter = new Parameter ("this", get_this_type ());
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
}
method.owner = context.analyzer.current_symbol.scope;
- if (!(method.return_type is VoidType) && CodeContext.get ().profile == Profile.DOVA) {
- method.result_var = new LocalVariable (method.return_type.copy (), "result", null, source_reference);
- method.result_var.is_result = true;
- }
-
var lambda_params = get_parameters ();
Iterator<Parameter> lambda_param_it = lambda_params.iterator ();
block.scope.parent_scope = method.scope;
if (method.return_type.data_type != null) {
- if (context.profile == Profile.DOVA) {
- block.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), expression_body, AssignmentOperator.SIMPLE, source_reference), source_reference));
- block.add_statement (new ReturnStatement (null, source_reference));
- } else {
- block.add_statement (new ReturnStatement (expression_body, source_reference));
- }
+ block.add_statement (new ReturnStatement (expression_body, source_reference));
} else {
block.add_statement (new ExpressionStatement (expression_body, source_reference));
}
+++ /dev/null
-/* valalistliteral.vala
- *
- * Copyright (C) 2009-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.ListLiteral : Literal {
- private List<Expression> expression_list = new ArrayList<Expression> ();
-
- public DataType element_type { get; private set; }
-
- public ListLiteral (SourceReference? source_reference = null) {
- this.source_reference = source_reference;
- }
-
- public override void accept_children (CodeVisitor visitor) {
- foreach (Expression expr in expression_list) {
- expr.accept (visitor);
- }
- }
-
- public override void accept (CodeVisitor visitor) {
- visitor.visit_list_literal (this);
-
- visitor.visit_expression (this);
- }
-
- public void add_expression (Expression expr) {
- expression_list.add (expr);
- expr.parent_node = this;
- }
-
- public List<Expression> get_expressions () {
- return expression_list;
- }
-
- public override bool is_pure () {
- return false;
- }
-
- public override void replace_expression (Expression old_node, Expression new_node) {
- for (int i = 0; i < expression_list.size; i++) {
- if (expression_list[i] == old_node) {
- expression_list[i] = new_node;
- }
- }
- }
-
- public override bool check (CodeContext context) {
- if (checked) {
- return !error;
- }
-
- checked = true;
-
- // list literals are also allowed for constant arrays,
- // however, they are currently handled by InitializerList
- // therefore transform this expression if necessary
- var array_type = target_type as ArrayType;
- if (array_type != null && array_type.inline_allocated) {
- var initializer = new InitializerList (source_reference);
- initializer.target_type = target_type;
- foreach (var expr in expression_list) {
- initializer.append (expr);
- }
-
- context.analyzer.replaced_nodes.add (this);
- parent_node.replace_expression (this, initializer);
- return initializer.check (context);
- }
-
- var list_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("List"));
- list_type.value_owned = true;
-
- bool fixed_element_type = false;
- if (target_type != null && target_type.data_type == list_type.data_type && target_type.get_type_arguments ().size == 1) {
- element_type = target_type.get_type_arguments ().get (0).copy ();
- element_type.value_owned = false;
- fixed_element_type = true;
- }
-
- for (int i = 0; i < expression_list.size; i++) {
- var expr = expression_list[i];
-
- if (fixed_element_type) {
- expr.target_type = element_type;
- }
- if (!expr.check (context)) {
- return false;
- }
-
- // expression might have been replaced in the list
- expr = expression_list[i];
-
- if (element_type == null) {
- element_type = expr.value_type.copy ();
- element_type.value_owned = false;
- }
- }
-
- if (element_type == null) {
- error = true;
- Report.error (source_reference, "cannot infer element type for list literal");
- return false;
- }
-
- element_type = element_type.copy ();
- element_type.value_owned = true;
- list_type.add_type_argument (element_type);
- value_type = list_type;
-
- return !error;
- }
-
- public override void emit (CodeGenerator codegen) {
- foreach (Expression expr in expression_list) {
- expr.emit (codegen);
- }
-
- codegen.visit_list_literal (this);
-
- codegen.visit_expression (this);
- }
-}
+++ /dev/null
-/* valamapliteral.vala
- *
- * Copyright (C) 2009-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.MapLiteral : Literal {
- private List<Expression> keys = new ArrayList<Expression> ();
- private List<Expression> values = new ArrayList<Expression> ();
-
- public DataType map_key_type { get; private set; }
- public DataType map_value_type { get; private set; }
-
- public MapLiteral (SourceReference? source_reference = null) {
- this.source_reference = source_reference;
- }
-
- public override void accept_children (CodeVisitor visitor) {
- for (int i = 0; i < keys.size; i++) {
- keys[i].accept (visitor);
- values[i].accept (visitor);
- }
- }
-
- public override void accept (CodeVisitor visitor) {
- visitor.visit_map_literal (this);
-
- visitor.visit_expression (this);
- }
-
- public void add_key (Expression expr) {
- keys.add (expr);
- expr.parent_node = this;
- }
-
- public void add_value (Expression expr) {
- values.add (expr);
- expr.parent_node = this;
- }
-
- public List<Expression> get_keys () {
- return keys;
- }
-
- public List<Expression> get_values () {
- return values;
- }
-
- public override bool is_pure () {
- return false;
- }
-
- public override void replace_expression (Expression old_node, Expression new_node) {
- for (int i = 0; i < keys.size; i++) {
- if (keys[i] == old_node) {
- keys[i] = new_node;
- }
- if (values[i] == old_node) {
- values[i] = new_node;
- }
- }
- }
-
- public override bool check (CodeContext context) {
- if (checked) {
- return !error;
- }
-
- checked = true;
-
- var map_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Map"));
- map_type.value_owned = true;
-
- bool fixed_element_type = false;
- if (target_type != null && target_type.data_type == map_type.data_type && target_type.get_type_arguments ().size == 2) {
- map_key_type = target_type.get_type_arguments ().get (0).copy ();
- map_key_type.value_owned = false;
- map_value_type = target_type.get_type_arguments ().get (1).copy ();
- map_value_type.value_owned = false;
- fixed_element_type = true;
- }
-
- for (int i = 0; i < keys.size; i++) {
- if (fixed_element_type) {
- keys[i].target_type = map_key_type;
- values[i].target_type = map_value_type;
- }
- if (!keys[i].check (context)) {
- return false;
- }
- if (!values[i].check (context)) {
- return false;
- }
- if (map_key_type == null) {
- map_key_type = keys[i].value_type.copy ();
- map_key_type.value_owned = false;
- map_value_type = values[i].value_type.copy ();
- map_value_type.value_owned = false;
- }
- }
-
- if (map_key_type == null) {
- error = true;
- Report.error (source_reference, "cannot infer key type for map literal");
- return false;
- }
-
- if (map_value_type == null) {
- error = true;
- Report.error (source_reference, "cannot infer value type for map literal");
- return false;
- }
-
- map_key_type = map_key_type.copy ();
- map_key_type.value_owned = true;
- map_value_type = map_value_type.copy ();
- map_value_type.value_owned = true;
- map_type.add_type_argument (map_key_type);
- map_type.add_type_argument (map_value_type);
- value_type = map_type;
-
- return !error;
- }
-
- public override void emit (CodeGenerator codegen) {
- for (int i = 0; i < keys.size; i++) {
- keys[i].emit (codegen);
- values[i].emit (codegen);
- }
-
- codegen.visit_map_literal (this);
-
- codegen.visit_expression (this);
- }
-}
entry_point = true;
context.entry_point = this;
- if (tree_can_fail && context.profile != Profile.DOVA) {
+ if (tree_can_fail) {
Report.error (source_reference, "\"main\" method cannot throw errors");
}
}
if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
// simple statements, no side effects after method call
} else if (!(context.analyzer.current_symbol is Block)) {
- if (context.profile != Profile.DOVA) {
- // can't handle errors in field initializers
- Report.error (source_reference, "Field initializers must not throw errors");
- }
+ // can't handle errors in field initializers
+ Report.error (source_reference, "Field initializers must not throw errors");
} else {
// store parent_node as we need to replace the expression in the old parent node later on
var old_parent_node = parent_node;
m.error = true;
return;
}
- if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
// simple statements, no side effects after method call
} else if (!(context.analyzer.current_symbol is Block)) {
- if (context.profile != Profile.DOVA) {
- // can't handle errors in field initializers
- Report.error (source_reference, "Field initializers must not throw errors");
- }
+ // can't handle errors in field initializers
+ Report.error (source_reference, "Field initializers must not throw errors");
} else {
// store parent_node as we need to replace the expression in the old parent node later on
var old_parent_node = parent_node;
return false;
}
- if (context.profile == Profile.DOVA && type_symbol.get_full_name () == "Dova.Tuple") {
- // tuples have variadic generics
- return true;
- }
-
int n_type_args = get_type_arguments ().size;
if (n_type_args > 0 && n_type_args < type_symbol.get_type_parameters ().size) {
Report.error (source_reference, "too few type arguments");
bool value_owned = owned_by_default;
if (owned_by_default) {
- if (context.profile == Profile.DOVA) {
- if (can_weak_ref && accept (TokenType.WEAK)) {
- value_owned = false;
- }
- } else if (accept (TokenType.UNOWNED)) {
+ if (accept (TokenType.UNOWNED)) {
value_owned = false;
} else if (accept (TokenType.WEAK)) {
if (!can_weak_ref && !context.deprecated) {
value_owned = false;
}
} else {
- value_owned = (context.profile != Profile.DOVA && accept (TokenType.OWNED));
+ value_owned = accept (TokenType.OWNED);
}
DataType type;
// only used for parsing, reject use as real type
invalid_array = true;
}
- } while (context.profile != Profile.DOVA && accept (TokenType.COMMA));
+ } while (accept (TokenType.COMMA));
expect (TokenType.CLOSE_BRACKET);
// arrays contain strong references by default
}
if (!owned_by_default) {
- if (context.profile != Profile.DOVA && accept (TokenType.HASH)) {
+ if (accept (TokenType.HASH)) {
if (!context.deprecated) {
Report.warning (get_last_src (), "deprecated syntax, use `owned` modifier");
}
expr = parse_literal ();
break;
case TokenType.OPEN_BRACE:
- if (context.profile == Profile.DOVA) {
- expr = parse_set_literal ();
- } else {
- expr = parse_initializer ();
- }
+ expr = parse_initializer ();
break;
case TokenType.OPEN_BRACKET:
- if (context.profile == Profile.DOVA) {
- expr = parse_list_literal ();
- } else {
- expr = parse_simple_name ();
- }
+ expr = parse_simple_name ();
break;
case TokenType.OPEN_PARENS:
expr = parse_tuple ();
expr = parse_member_access (begin, expr);
break;
case TokenType.OP_PTR:
- if (context.profile == Profile.DOVA) {
- found = false;
- } else {
- expr = parse_pointer_member_access (begin, expr);
- }
+ expr = parse_pointer_member_access (begin, expr);
break;
case TokenType.OPEN_PARENS:
expr = parse_method_call (begin, expr);
case TokenType.OPEN_BRACKET:
expr = parse_element_access (begin, expr);
break;
- case TokenType.OPEN_BRACE:
- var ma = expr as MemberAccess;
- if (context.profile == Profile.DOVA && ma != null) {
- expr = parse_object_literal (begin, ma);
- } else {
- found = false;
- }
- break;
case TokenType.OP_INC:
expr = parse_post_increment_expression (begin, expr);
break;
return expr;
}
- Expression parse_object_literal (SourceLocation begin, MemberAccess member) throws ParseError {
- member.creation_member = true;
-
- var expr = new ObjectCreationExpression (member, get_src (begin));
-
- expect (TokenType.OPEN_BRACE);
-
- do {
- var member_begin = get_location ();
- string id = parse_identifier ();
- expect (TokenType.COLON);
- var member_expr = parse_expression ();
-
- expr.add_member_initializer (new MemberInitializer (id, member_expr, get_src (member_begin)));
- } while (accept (TokenType.COMMA));
-
- expect (TokenType.CLOSE_BRACE);
-
- return expr;
- }
-
Expression parse_array_creation_expression () throws ParseError {
var begin = get_location ();
expect (TokenType.NEW);
size_specified = true;
}
size_specifier_list.add (size);
- } while (context.profile != Profile.DOVA && accept (TokenType.COMMA));
+ } while (accept (TokenType.COMMA));
expect (TokenType.CLOSE_BRACKET);
} while (accept (TokenType.OPEN_BRACKET));
InitializerList initializer = null;
- if (context.profile != Profile.DOVA && current () == TokenType.OPEN_BRACE) {
+ if (current () == TokenType.OPEN_BRACE) {
initializer = parse_initializer ();
}
var expr = new ArrayCreationExpression (element_type, size_specifier_list.size, initializer, get_src (begin));
List<MemberInitializer> parse_object_initializer () throws ParseError {
var list = new ArrayList<MemberInitializer> ();
- if (context.profile != Profile.DOVA && accept (TokenType.OPEN_BRACE)) {
+ if (accept (TokenType.OPEN_BRACE)) {
do {
list.add (parse_member_initializer ());
} while (accept (TokenType.COMMA));
}
if (!is_decl) {
- if (context.profile == Profile.DOVA && stmt is ReturnStatement) {
- // split
- // return foo;
- // into
- // result = foo;
- // return;
- var ret_stmt = (ReturnStatement) stmt;
- if (ret_stmt.return_expression != null) {
- var assignment = new Assignment (new MemberAccess.simple ("result", stmt.source_reference), ret_stmt.return_expression, AssignmentOperator.SIMPLE, stmt.source_reference);
- ret_stmt.return_expression = null;
- block.add_statement (new ExpressionStatement (assignment, stmt.source_reference));
- }
- }
block.add_statement (stmt);
}
} catch (ParseError e) {
var block = new Block (get_src (get_location ()));
var stmt = parse_embedded_statement_without_block ();
- if (context.profile == Profile.DOVA && stmt is ReturnStatement) {
- // split
- // return foo;
- // into
- // result = foo;
- // return;
- var ret_stmt = (ReturnStatement) stmt;
- if (ret_stmt.return_expression != null) {
- var assignment = new Assignment (new MemberAccess.simple ("result"), ret_stmt.return_expression);
- ret_stmt.return_expression = null;
- block.add_statement (new ExpressionStatement (assignment));
- }
- }
block.add_statement (stmt);
return block;
method.body.source_reference.end = get_current_src ().end;
- if (!context.experimental && context.profile != Profile.DOVA) {
+ if (!context.experimental) {
Report.warning (method.source_reference, "main blocks are experimental");
}
var begin = get_location ();
var access = parse_access_modifier ();
var flags = parse_member_declaration_modifiers ();
- if (context.profile == Profile.DOVA) {
- accept (TokenType.VOLATILE);
- }
var type = parse_type (true, true);
string id = parse_identifier ();
return initializer;
}
- ListLiteral parse_list_literal () throws ParseError {
- var begin = get_location ();
- expect (TokenType.OPEN_BRACKET);
- var initializer = new ListLiteral (get_src (begin));
- if (current () != TokenType.CLOSE_BRACKET) {
- do {
- var init = parse_expression ();
- initializer.add_expression (init);
- } while (accept (TokenType.COMMA));
- }
- expect (TokenType.CLOSE_BRACKET);
- return initializer;
- }
-
- Expression parse_set_literal () throws ParseError {
- var begin = get_location ();
- expect (TokenType.OPEN_BRACE);
- var set = new SetLiteral (get_src (begin));
- bool first = true;
- if (current () != TokenType.CLOSE_BRACE) {
- do {
- var expr = parse_expression ();
- if (first && accept (TokenType.COLON)) {
- // found colon after expression, it's a map
- rollback (begin);
- return parse_map_literal ();
- }
- first = false;
- set.add_expression (expr);
- } while (accept (TokenType.COMMA));
- }
- expect (TokenType.CLOSE_BRACE);
- return set;
- }
-
- Expression parse_map_literal () throws ParseError {
- var begin = get_location ();
- expect (TokenType.OPEN_BRACE);
- var map = new MapLiteral (get_src (begin));
- if (current () != TokenType.CLOSE_BRACE) {
- do {
- var key = parse_expression ();
- map.add_key (key);
- expect (TokenType.COLON);
- var value = parse_expression ();
- map.add_value (value);
- } while (accept (TokenType.COMMA));
- }
- expect (TokenType.CLOSE_BRACE);
- return map;
- }
-
void parse_method_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError {
var begin = get_location ();
var access = parse_access_modifier ();
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
- if (context.profile == Profile.DOVA) {
- var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference);
- method.add_error_type (error_type);
- if (accept (TokenType.THROWS)) {
- do {
- parse_type (true, false);
- } while (accept (TokenType.COMMA));
- Report.warning (method.source_reference, "`throws' is ignored in the Dova profile");
- }
- } else {
- if (accept (TokenType.THROWS)) {
- do {
- method.add_error_type (parse_type (true, false));
- } while (accept (TokenType.COMMA));
- }
+ if (accept (TokenType.THROWS)) {
+ do {
+ method.add_error_type (parse_type (true, false));
+ } while (accept (TokenType.COMMA));
}
while (accept (TokenType.REQUIRES)) {
expect (TokenType.OPEN_PARENS);
var type = parse_type (true, true);
bool getter_owned = false;
- if (context.profile == Profile.DOVA) {
- getter_owned = true;
- } else if (accept (TokenType.HASH)) {
+ if (accept (TokenType.HASH)) {
if (!context.deprecated) {
Report.warning (get_last_src (), "deprecated syntax, use `owned` modifier before `get'");
}
if (ModifierFlags.EXTERN in flags || scanner.source_file.file_type == SourceFileType.PACKAGE) {
prop.external = true;
}
- if (context.profile == Profile.DOVA) {
- } else {
- if (accept (TokenType.THROWS)) {
- do {
- prop.add_error_type (parse_type (true, false));
- } while (accept (TokenType.COMMA));
- Report.error (prop.source_reference, "properties throwing errors are not supported yet");
- }
+ if (accept (TokenType.THROWS)) {
+ do {
+ prop.add_error_type (parse_type (true, false));
+ } while (accept (TokenType.COMMA));
+ Report.error (prop.source_reference, "properties throwing errors are not supported yet");
}
expect (TokenType.OPEN_BRACE);
while (current () != TokenType.CLOSE_BRACE) {
var accessor_access = parse_access_modifier (SymbolAccessibility.PUBLIC);
var value_type = type.copy ();
- value_type.value_owned = (context.profile != Profile.DOVA && accept (TokenType.OWNED));
+ value_type.value_owned = accept (TokenType.OWNED);
if (accept (TokenType.GET)) {
if (prop.get_accessor != null) {
direction = ParameterDirection.REF;
}
- if (context.profile == Profile.DOVA) {
- accept (TokenType.VOLATILE);
- }
DataType type;
if (direction == ParameterDirection.IN) {
// in parameters are unowned by default
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
- if (context.profile == Profile.DOVA) {
- var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference);
- method.add_error_type (error_type);
- if (accept (TokenType.THROWS)) {
- do {
- parse_type (true, false);
- } while (accept (TokenType.COMMA));
- Report.warning (method.source_reference, "`throws' is ignored in the Dova profile");
- }
- } else {
- if (accept (TokenType.THROWS)) {
- do {
- method.add_error_type (parse_type (true, false));
- } while (accept (TokenType.COMMA));
- }
+ if (accept (TokenType.THROWS)) {
+ do {
+ method.add_error_type (parse_type (true, false));
+ } while (accept (TokenType.COMMA));
}
while (accept (TokenType.REQUIRES)) {
expect (TokenType.OPEN_PARENS);
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
- if (context.profile == Profile.DOVA) {
- var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), d.source_reference);
- d.add_error_type (error_type);
- if (accept (TokenType.THROWS)) {
- do {
- parse_type (true, false);
- } while (accept (TokenType.COMMA));
- Report.warning (d.source_reference, "`throws' is ignored in the Dova profile");
- }
- } else {
- if (accept (TokenType.THROWS)) {
- do {
- d.add_error_type (parse_type (true, false));
- } while (accept (TokenType.COMMA));
- }
+ if (accept (TokenType.THROWS)) {
+ do {
+ d.add_error_type (parse_type (true, false));
+ } while (accept (TokenType.COMMA));
}
expect (TokenType.SEMICOLON);
}
public override Symbol? get_member (string member_name) {
- if (CodeContext.get ().profile != Profile.DOVA) {
- return null;
- }
-
- Symbol base_symbol = base_type.data_type;
-
- if (base_symbol == null) {
- return null;
- }
-
- return SemanticAnalyzer.symbol_lookup_inherited (base_symbol, member_name);
+ return null;
}
public override Symbol? get_pointer_member (string member_name) {
public enum Vala.Profile {
POSIX,
- GOBJECT,
- DOVA
+ GOBJECT
}
body = new Block (source_reference);
var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference);
if (readable) {
- if (context.profile == Profile.DOVA) {
- body.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), ma, AssignmentOperator.SIMPLE, source_reference), source_reference));
- body.add_statement (new ReturnStatement (null, source_reference));
- } else {
- body.add_statement (new ReturnStatement (ma, source_reference));
- }
+ body.add_statement (new ReturnStatement (ma, source_reference));
} else {
Expression value = new MemberAccess.simple ("value", source_reference);
if (value_type.value_owned) {
}
if (body != null) {
- if (readable && context.profile == Profile.DOVA) {
- result_var = new LocalVariable (value_type.copy (), "result", null, source_reference);
- result_var.is_result = true;
-
- result_var.check (context);
- } else if (writable || construction) {
+ if (writable || construction) {
value_parameter = new Parameter ("value", value_type, source_reference);
body.scope.add (value_parameter.name, value_parameter);
}
body.check (context);
- if (context.profile != Profile.DOVA) {
- foreach (DataType body_error_type in body.get_error_types ()) {
- if (!((ErrorType) body_error_type).dynamic_error) {
- Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
- }
+ foreach (DataType body_error_type in body.get_error_types ()) {
+ if (!((ErrorType) body_error_type).dynamic_error) {
+ Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
}
}
}
checked = true;
var st = (Struct) context.analyzer.root_symbol.scope.lookup (get_type_name ());
- // ensure attributes are already processed in case of bootstrapping dova-core
+ // ensure attributes are already processed
st.check (context);
value_type = new FloatingType (st);
return false;
}
- if (context.profile == Profile.DOVA) {
- // no return expressions in Dova profile
- return !error;
- }
-
if (return_expression == null) {
if (!(context.analyzer.current_return_type is VoidType)) {
error = true;
len++;
}
type = get_identifier_or_keyword (begin, len);
- } else if (current[0] == '@' && source_file.context.profile != Profile.DOVA) {
+ } else if (current[0] == '@') {
if (current < end - 1 && current[1] == '"') {
type = TokenType.OPEN_TEMPLATE;
current += 2;
column = 1;
token_length_in_chars = 1;
} else {
- if (type == TokenType.STRING_LITERAL && source_file.context.profile == Profile.DOVA && current[0] == '$') {
- // string template
- type = TokenType.OPEN_TEMPLATE;
- current = begin;
- state_stack += State.TEMPLATE;
- break;
- }
unichar u = ((string) current).get_char_validated ((long) (end - current));
if (u != (unichar) (-1)) {
current += u.to_utf8 (null);
int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int"));
uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint"));
- if (context.profile != Profile.DOVA) {
- uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar"));
- int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8"));
- short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short"));
- ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort"));
- long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long"));
- ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong"));
- size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t"));
- ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t"));
- double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
- } else {
- long_type = int_type;
- ulong_type = uint_type;
- size_t_type = uint_type;
- ssize_t_type = int_type;
- }
+ uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar"));
+ int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8"));
+ short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short"));
+ ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort"));
+ long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long"));
+ ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong"));
+ size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t"));
+ ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t"));
+ double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar");
if (unichar_struct != null) {
gerror_type = (Class) glib_ns.scope.lookup ("Error");
regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex"));
- } else if (context.profile == Profile.DOVA) {
- var dova_ns = root_symbol.scope.lookup ("Dova");
-
- object_type = (Class) dova_ns.scope.lookup ("Object");
- type_type = new ObjectType ((Class) dova_ns.scope.lookup ("Type"));
- list_type = new ObjectType ((Class) dova_ns.scope.lookup ("List"));
- tuple_type = new ObjectType ((Class) dova_ns.scope.lookup ("Tuple"));
- error_type = new ObjectType ((Class) dova_ns.scope.lookup ("Error"));
}
current_symbol = root_symbol;
instance_type = instance_pointer_type.base_type;
}
- if (CodeContext.get ().profile == Profile.DOVA) {
- while (instance_type is ArrayType) {
- var instance_array_type = (ArrayType) instance_type;
- instance_type = new ObjectType ((Class) CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Array"));
- instance_type.add_type_argument (instance_array_type.element_type);
- }
- }
-
if (instance_type is DelegateType && ((DelegateType) instance_type).delegate_symbol == type_symbol) {
return instance_type;
} else if (instance_type.data_type == type_symbol) {
+++ /dev/null
-/* valasetliteral.vala
- *
- * Copyright (C) 2009-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.SetLiteral : Literal {
- private List<Expression> expression_list = new ArrayList<Expression> ();
-
- public DataType element_type { get; private set; }
-
- public SetLiteral (SourceReference? source_reference = null) {
- this.source_reference = source_reference;
- }
-
- public override void accept_children (CodeVisitor visitor) {
- foreach (Expression expr in expression_list) {
- expr.accept (visitor);
- }
- }
-
- public override void accept (CodeVisitor visitor) {
- visitor.visit_set_literal (this);
-
- visitor.visit_expression (this);
- }
-
- public void add_expression (Expression expr) {
- expression_list.add (expr);
- expr.parent_node = this;
- }
-
- public List<Expression> get_expressions () {
- return expression_list;
- }
-
- public override bool is_pure () {
- return false;
- }
-
- public override void replace_expression (Expression old_node, Expression new_node) {
- for (int i = 0; i < expression_list.size; i++) {
- if (expression_list[i] == old_node) {
- expression_list[i] = new_node;
- }
- }
- }
-
- public override bool check (CodeContext context) {
- if (checked) {
- return !error;
- }
-
- checked = true;
-
- var set_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Set"));
- set_type.value_owned = true;
-
- bool fixed_element_type = false;
- if (target_type != null && target_type.data_type == set_type.data_type && target_type.get_type_arguments ().size == 1) {
- element_type = target_type.get_type_arguments ().get (0).copy ();
- element_type.value_owned = false;
- fixed_element_type = true;
- }
-
- for (int i = 0; i < expression_list.size; i++) {
- var expr = expression_list[i];
-
- if (fixed_element_type) {
- expr.target_type = element_type;
- }
- if (!expr.check (context)) {
- return false;
- }
-
- // expression might have been replaced in the list
- expr = expression_list[i];
-
- if (element_type == null) {
- element_type = expr.value_type.copy ();
- element_type.value_owned = false;
- }
- }
-
- if (element_type == null) {
- error = true;
- Report.error (source_reference, "cannot infer element type for set literal");
- return false;
- }
-
- element_type = element_type.copy ();
- element_type.value_owned = true;
- set_type.add_type_argument (element_type);
- value_type = set_type;
-
- return !error;
- }
-
- public override void emit (CodeGenerator codegen) {
- foreach (Expression expr in expression_list) {
- expr.emit (codegen);
- }
-
- codegen.visit_set_literal (this);
-
- codegen.visit_expression (this);
- }
-}
m.this_parameter = new Parameter ("this", SemanticAnalyzer.get_data_type_for_symbol (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
* instances are passed by value.
*/
public bool is_simple_type () {
- if (CodeContext.get ().profile == Profile.DOVA) {
- return true;
- }
var st = base_struct;
if (st != null && st.is_simple_type ()) {
return true;
}
}
- if (context.profile == Profile.DOVA) {
- // classes derive from Object by default
- if (cl.base_class == null) {
- var any_class = (Class) root_symbol.scope.lookup ("any");
- if (cl != any_class) {
- var object_class = (Class) root_symbol.scope.lookup ("Dova").scope.lookup ("Object");
- cl.add_base_type (new ObjectType (object_class));
- cl.base_class = object_class;
- }
- }
- }
-
current_scope = current_scope.parent_scope;
}
}
}
- if (context.profile == Profile.DOVA) {
- // all interfaces require Object
- if (iface.get_prerequisites ().size == 0) {
- var object_class = (Class) root_symbol.scope.lookup ("Dova").scope.lookup ("Object");
- iface.add_prerequisite (new ObjectType (object_class));
- }
- }
-
current_scope = current_scope.parent_scope;
}
tmpl.accept_children (this);
}
- public override void visit_list_literal (ListLiteral lit) {
- lit.accept_children (this);
- }
-
- public override void visit_set_literal (SetLiteral lit) {
- lit.accept_children (this);
- }
-
- public override void visit_map_literal (MapLiteral lit) {
- lit.accept_children (this);
- }
-
public override void visit_tuple (Tuple tuple) {
tuple.accept_children (this);
}
} else {
expr = stringify (expression_list[0]);
if (expression_list.size > 1) {
- if (context.profile == Profile.DOVA) {
- // varargs concat not yet supported
- for (int i = 1; i < expression_list.size; i++) {
- expr = new BinaryExpression (BinaryOperator.PLUS, expr, stringify (expression_list[i]), source_reference);
- }
- } else {
- var concat = new MethodCall (new MemberAccess (expr, "concat", source_reference), source_reference);
- for (int i = 1; i < expression_list.size; i++) {
- concat.add_argument (stringify (expression_list[i]));
- }
- expr = concat;
+ var concat = new MethodCall (new MemberAccess (expr, "concat", source_reference), source_reference);
+ for (int i = 1; i < expression_list.size; i++) {
+ concat.add_argument (stringify (expression_list[i]));
}
+ expr = concat;
}
}
expr.target_type = target_type;
checked = true;
- if (context.profile != Profile.DOVA) {
- Report.error (source_reference, "tuples are not supported");
- error = true;
- return false;
- }
-
- value_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Tuple"));
- value_type.value_owned = true;
-
- foreach (var expr in expression_list) {
- if (!expr.check (context)) {
- return false;
- }
- value_type.add_type_argument (expr.value_type.copy ());
- }
-
- return !error;
+ Report.error (source_reference, "tuples are not supported");
+ error = true;
+ return false;
}
public override void emit (CodeGenerator codegen) {