Commit 2d4a4a26 authored by Jürg Billeter's avatar Jürg Billeter

Rework header file generation

Generate single C header file for public API, do not use header
files for internal API. Fixes bug 471244, bug 571037, bug 572536,
and bug 575629.
parent 807fc30d
......@@ -693,12 +693,20 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
assignment.ccodenode = ccall;
}
public override void generate_parameter (FormalParameter param, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
if (!(param.parameter_type is ArrayType)) {
base.generate_parameter (param, cparam_map, carg_map);
base.generate_parameter (param, decl_space, cparam_map, carg_map);
return;
}
string ctypename = param.parameter_type.get_cname ();
if (param.direction != ParameterDirection.IN) {
ctypename += "*";
}
param.ccodenode = new CCodeFormalParameter (param.name, ctypename);
var array_type = (ArrayType) param.parameter_type;
cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
......
......@@ -38,6 +38,18 @@ internal class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
var prop = (Property) assignment.left.symbol_reference;
if (!(prop is DynamicProperty)) {
generate_property_accessor_declaration (prop.set_accessor, source_declarations);
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 (prop.set_accessor.construction && current_type_symbol is Class && current_class.is_subtype_of (gobject_type) && in_creation_method) {
return head.get_construct_property_assignment (prop.get_canonical_cconstant (), prop.property_type, (CCodeExpression) assignment.right.ccodenode);
} else {
......
This diff is collapsed.
......@@ -23,14 +23,39 @@
using Gee;
class Vala.CCodeDeclarationSpace {
Set<string> declarations = new HashSet<string> (str_hash, str_equal);
Set<string> includes = new HashSet<string> (str_hash, str_equal);
internal CCodeFragment begin = new CCodeFragment ();
internal CCodeFragment include_directives = new CCodeFragment ();
internal CCodeFragment type_declaration = new CCodeFragment ();
internal CCodeFragment type_definition = new CCodeFragment ();
internal CCodeFragment type_member_declaration = new CCodeFragment ();
internal CCodeFragment constant_declaration = new CCodeFragment ();
public bool add_declaration (string name) {
if (name in declarations) {
return true;
}
declarations.add (name);
return false;
}
public bool add_symbol_declaration (Symbol sym, string name) {
if (add_declaration (name)) {
return true;
}
if (sym.external_package) {
// add appropriate include file
foreach (string header_filename in sym.get_cheader_filenames ()) {
add_include (header_filename);
}
// declaration complete
return true;
} else {
// require declaration
return false;
}
}
public void add_include (string filename, bool local = false) {
if (!(filename in includes)) {
include_directives.append (new CCodeIncludeDirective (filename, local));
......@@ -38,10 +63,6 @@ class Vala.CCodeDeclarationSpace {
}
}
public void add_begin (CCodeNode node) {
begin.append (node);
}
public void add_type_declaration (CCodeNode node) {
type_declaration.append (node);
}
......
......@@ -32,11 +32,15 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
base (codegen, next);
}
public override void visit_delegate (Delegate d) {
d.accept_children (codegen);
public override void generate_delegate_declaration (Delegate d, CCodeDeclarationSpace decl_space) {
if (decl_space.add_symbol_declaration (d, d.get_cname ())) {
return;
}
var cfundecl = new CCodeFunctionDeclarator (d.get_cname ());
foreach (FormalParameter param in d.get_parameters ()) {
generate_parameter (param, decl_space, new HashMap<int,CCodeFormalParameter> (), null);
cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
// handle array parameters
......@@ -74,17 +78,16 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
var ctypedef = new CCodeTypeDefinition (d.return_type.get_cname (), cfundecl);
if (!d.is_internal_symbol ()) {
if (d.source_reference != null && d.source_reference.comment != null) {
header_declarations.add_type_declaration (new CCodeComment (d.source_reference.comment));
}
header_declarations.add_type_declaration (ctypedef);
} else {
if (d.source_reference != null && d.source_reference.comment != null) {
source_declarations.add_type_declaration (new CCodeComment (d.source_reference.comment));
}
source_declarations.add_type_declaration (ctypedef);
if (d.source_reference != null && d.source_reference.comment != null) {
decl_space.add_type_declaration (new CCodeComment (d.source_reference.comment));
}
decl_space.add_type_declaration (ctypedef);
}
public override void visit_delegate (Delegate d) {
d.accept_children (codegen);
generate_delegate_declaration (d, source_declarations);
}
public override string get_delegate_target_cname (string delegate_cname) {
......@@ -238,26 +241,7 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
var d_params = d.get_parameters ();
foreach (FormalParameter param in d_params) {
// ensure that C code node has been generated
param.accept (codegen);
cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
// handle array parameters
if (!param.no_array_length && param.parameter_type is ArrayType) {
var array_type = (ArrayType) param.parameter_type;
var length_ctype = "int";
if (param.direction != ParameterDirection.IN) {
length_ctype = "int*";
}
for (int dim = 1; dim <= array_type.rank; dim++) {
var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype);
cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
}
}
generate_parameter (param, source_declarations, cparam_map, null);
}
if (!d.no_array_length && d.return_type is ArrayType) {
// return array length if appropriate
......@@ -387,12 +371,20 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
return wrapper_name;
}
public override void generate_parameter (FormalParameter param, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
public override void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
if (!(param.parameter_type is DelegateType || param.parameter_type is MethodType)) {
base.generate_parameter (param, cparam_map, carg_map);
base.generate_parameter (param, decl_space, cparam_map, carg_map);
return;
}
string ctypename = param.parameter_type.get_cname ();
if (param.direction != ParameterDirection.IN) {
ctypename += "*";
}
param.ccodenode = new CCodeFormalParameter (param.name, ctypename);
cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
if (carg_map != null) {
carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name));
......@@ -401,6 +393,9 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
if (param.parameter_type is DelegateType) {
var deleg_type = (DelegateType) param.parameter_type;
var d = deleg_type.delegate_symbol;
generate_delegate_declaration (d, decl_space);
if (d.has_target) {
var cparam = new CCodeFormalParameter (get_delegate_target_cname (param.name), "void*");
cparam_map.set (get_param_pos (param.cdelegate_target_parameter_position), cparam);
......
......@@ -76,18 +76,10 @@ public class Vala.CCodeGenerator : CodeGenerator {
head.visit_enum (en);
}
public override void visit_enum_value (EnumValue ev) {
head.visit_enum_value (ev);
}
public override void visit_error_domain (ErrorDomain edomain) {
head.visit_error_domain (edomain);
}
public override void visit_error_code (ErrorCode ecode) {
head.visit_error_code (ecode);
}
public override void visit_delegate (Delegate d) {
head.visit_delegate (d);
}
......
......@@ -45,7 +45,19 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (expr.symbol_reference is Method) {
var m = (Method) expr.symbol_reference;
if (!(m is DynamicMethod || m is ArrayMoveMethod || m is ArrayResizeMethod)) {
generate_method_declaration (m, source_declarations);
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;
......@@ -103,6 +115,9 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (is_gtypeinstance && f.access == SymbolAccessibility.PRIVATE) {
inst = new CCodeMemberAccess.pointer (pub_inst, "priv");
} else {
if (cl != null) {
generate_class_struct_declaration (cl, source_declarations);
}
inst = pub_inst;
}
if (instance_target_type.data_type.is_reference_type () || (expr.inner != null && expr.inner.value_type is PointerType)) {
......@@ -149,6 +164,8 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
} else if (expr.symbol_reference is Constant) {
var c = (Constant) expr.symbol_reference;
generate_constant_declaration (c, source_declarations);
string fn = c.get_full_name ();
if (fn == "GLib.Log.FILE") {
string s = Path.get_basename (expr.source_reference.file.filename);
......@@ -168,6 +185,18 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
} else if (expr.symbol_reference is Property) {
var prop = (Property) expr.symbol_reference;
if (!(prop is DynamicProperty)) {
generate_property_accessor_declaration (prop.get_accessor, source_declarations);
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;
......
......@@ -60,6 +60,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
// constructor
var cl = (Class) ((ObjectType) itype).type_symbol;
m = cl.default_construction_method;
generate_method_declaration (m, source_declarations);
ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
}
......
......@@ -66,10 +66,10 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
return result;
}
public virtual void generate_method_result_declaration (Method m, CCodeFunction cfunc, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
public virtual void generate_method_result_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeFunction cfunc, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
var creturn_type = m.return_type;
if (m is CreationMethod) {
var cl = current_type_symbol as Class;
var cl = m.parent_symbol as Class;
if (cl != null) {
// object creation methods return the new object in C
// in Vala they have no return type
......@@ -78,6 +78,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
cfunc.return_type = get_creturn_type (m, creturn_type.get_cname ());
generate_type_declaration (m.return_type, decl_space);
if (!m.no_array_length && m.return_type is ArrayType) {
// return array length if appropriate
var array_type = (ArrayType) m.return_type;
......@@ -140,6 +142,42 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
return complete_block;
}
public override void generate_method_declaration (Method m, CCodeDeclarationSpace decl_space) {
if (decl_space.add_symbol_declaration (m, m.get_cname ())) {
return;
}
var function = new CCodeFunction (m.get_cname ());
if (m.is_private_symbol ()) {
function.modifiers |= CCodeModifiers.STATIC;
if (m.is_inline) {
function.modifiers |= CCodeModifiers.INLINE;
}
}
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
generate_cparameters (m, decl_space, cparam_map, function, null, carg_map, new CCodeFunctionCall (new CCodeIdentifier ("fake")));
decl_space.add_type_member_declaration (function);
if (m is CreationMethod && m.parent_symbol is Class) {
// _construct function
function = new CCodeFunction (m.get_real_cname ());
if (m.is_private_symbol ()) {
function.modifiers |= CCodeModifiers.STATIC;
}
cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
generate_cparameters (m, decl_space, cparam_map, function);
decl_space.add_type_member_declaration (function);
}
}
public override void visit_method (Method m) {
var old_type_symbol = current_type_symbol;
var old_symbol = current_symbol;
......@@ -249,6 +287,16 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
variable_name_map = old_variable_name_map;
current_try = old_try;
// do not declare overriding methods and interface implementations
if (m.is_abstract || m.is_virtual
|| (m.base_method == null && m.base_interface_method == null)) {
generate_method_declaration (m, source_declarations);
if (!m.is_internal_symbol ()) {
generate_method_declaration (m, header_declarations);
}
}
function = new CCodeFunction (m.get_real_cname ());
m.ccodenode = function;
......@@ -258,30 +306,17 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
CCodeFunctionDeclarator vdeclarator = null;
if ((m.is_abstract || m.is_virtual) && !m.coroutine) {
var vdecl = new CCodeDeclaration (get_creturn_type (m, creturn_type.get_cname ()));
vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name);
vdecl.add_declarator (vdeclarator);
type_struct.add_declaration (vdecl);
}
generate_cparameters (m, cparam_map, function, vdeclarator);
bool visible = !m.is_internal_symbol ();
generate_cparameters (m, source_declarations, cparam_map, function);
// generate *_real_* functions for virtual methods
// also generate them for abstract methods of classes to prevent faulty subclassing
if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) {
if (visible && m.base_method == null && m.base_interface_method == null) {
/* public methods need function declaration in
* header file except virtual/overridden methods */
header_declarations.add_type_member_declaration (function.copy ());
} else {
/* declare all other functions in source file to
* avoid dependency on order within source file */
if (m.base_method != null || m.base_interface_method != null) {
// declare *_real_* function
function.modifiers |= CCodeModifiers.STATIC;
source_declarations.add_type_member_declaration (function.copy ());
} else if (m.is_private_symbol ()) {
function.modifiers |= CCodeModifiers.STATIC;
}
/* Methods imported from a plain C file don't
......@@ -583,14 +618,43 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
}
public virtual void generate_parameter (FormalParameter param, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
public virtual void generate_parameter (FormalParameter param, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression>? carg_map) {
if (!param.ellipsis) {
string ctypename = param.parameter_type.get_cname ();
generate_type_declaration (param.parameter_type, decl_space);
// pass non-simple structs always by reference
if (param.parameter_type.data_type is Struct) {
var st = (Struct) param.parameter_type.data_type;
generate_struct_declaration (st, decl_space);
if (!st.is_simple_type () && param.direction == ParameterDirection.IN) {
if (st.use_const) {
ctypename = "const " + ctypename;
}
if (!param.parameter_type.nullable) {
ctypename += "*";
}
}
}
if (param.direction != ParameterDirection.IN) {
ctypename += "*";
}
param.ccodenode = new CCodeFormalParameter (param.name, ctypename);
} else {
param.ccodenode = new CCodeFormalParameter.with_ellipsis ();
}
cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
if (carg_map != null) {
if (carg_map != null && !param.ellipsis) {
carg_map.set (get_param_pos (param.cparameter_position), new CCodeIdentifier (param.name));
}
}
public override void generate_cparameters (Method m, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
public override void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
if (m.parent_symbol is Class && m is CreationMethod) {
var cl = (Class) m.parent_symbol;
if (!cl.is_compact && vcall == null) {
......@@ -611,6 +675,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
assert_not_reached ();
}
generate_type_declaration (this_type, decl_space);
CCodeFormalParameter instance_param = null;
if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) {
var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol);
......@@ -637,7 +703,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
if (is_gtypeinstance_creation_method (m)) {
// memory management for generic types
int type_param_index = 0;
foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
var cl = (Class) m.parent_symbol;
foreach (TypeParameter type_param in cl.get_type_parameters ()) {
cparam_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeFormalParameter ("%s_type".printf (type_param.name.down ()), "GType"));
cparam_map.set (get_param_pos (0.1 * type_param_index + 0.02), new CCodeFormalParameter ("%s_dup_func".printf (type_param.name.down ()), "GBoxedCopyFunc"));
cparam_map.set (get_param_pos (0.1 * type_param_index + 0.03), new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify"));
......@@ -663,11 +730,11 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
}
generate_parameter (param, cparam_map, carg_map);
generate_parameter (param, source_declarations, cparam_map, carg_map);
}
if ((direction & 2) != 0) {
generate_method_result_declaration (m, func, cparam_map, carg_map);
generate_method_result_declaration (m, decl_space, func, cparam_map, carg_map);
}
// append C parameters in the right order
......@@ -688,15 +755,16 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
vdeclarator.add_parameter (cparam_map.get (min_pos));
}
if (vcall != null) {
vcall.add_argument (carg_map.get (min_pos));
var arg = carg_map.get (min_pos);
if (arg != null) {
vcall.add_argument (arg);
}
}
last_pos = min_pos;
}
}
public void generate_vfunc (Method m, DataType return_type, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression> carg_map, string suffix = "", int direction = 3) {
bool visible = !m.is_internal_symbol ();
var vfunc = new CCodeFunction (m.get_cname () + suffix);
vfunc.line = function.line;
......@@ -724,7 +792,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.vfunc_name + suffix));
carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
generate_cparameters (m, cparam_map, vfunc, null, carg_map, vcall, direction);
generate_cparameters (m, source_declarations, cparam_map, vfunc, null, carg_map, vcall, direction);
CCodeStatement cstmt;
if (return_type is VoidType) {
......@@ -753,13 +821,6 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
}
if (visible) {
header_declarations.add_type_member_declaration (vfunc.copy ());
} else {
vfunc.modifiers |= CCodeModifiers.STATIC;
source_declarations.add_type_member_declaration (vfunc.copy ());
}
vfunc.block = vblock;
if (m.is_abstract && m.source_reference != null && m.source_reference.comment != null) {
......@@ -838,6 +899,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
var cdecl = new CCodeVariableDeclarator ("self");
if (chain_up) {
generate_method_declaration (cm, source_declarations);
var ccall = new CCodeFunctionCall (new CCodeIdentifier (cm.get_real_cname ()));
ccall.add_argument (new CCodeIdentifier ("object_type"));
cdecl.initializer = new CCodeCastExpression (ccall, "%s*".printf (cl.get_cname ()));
......@@ -861,7 +924,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
public override void visit_creation_method (CreationMethod m) {
bool visible = !m.is_internal_symbol ();
bool visible = !m.is_private_symbol ();
if (m.body != null && current_type_symbol is Class && current_class.is_subtype_of (gobject_type)) {
int n_params = 0;
......@@ -898,18 +961,17 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
var vcall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
vcall.add_argument (new CCodeIdentifier (current_class.get_type_id ()));
generate_cparameters (m, cparam_map, vfunc, null, carg_map, vcall);
generate_cparameters (m, source_declarations, cparam_map, vfunc, null, carg_map, vcall);
CCodeStatement cstmt = new CCodeReturnStatement (vcall);
cstmt.line = vfunc.line;
vblock.add_statement (cstmt);
if (visible) {
header_declarations.add_type_member_declaration (vfunc.copy ());
} else {
if (!visible) {
vfunc.modifiers |= CCodeModifiers.STATIC;
source_declarations.add_type_member_declaration (vfunc.copy ());
}
source_declarations.add_type_member_declaration (vfunc.copy ());
vfunc.block = vblock;
source_type_member_definition.append (vfunc);
......
......@@ -72,18 +72,10 @@ public abstract class Vala.CCodeModule {
next.visit_enum (en);
}
public virtual void visit_enum_value (EnumValue ev) {
next.visit_enum_value (ev);
}
public virtual void visit_error_domain (ErrorDomain edomain) {
next.visit_error_domain (edomain);
}
public virtual void visit_error_code (ErrorCode ecode) {
next.visit_error_code (ecode);
}
public virtual void visit_delegate (Delegate d) {
next.visit_delegate (d);
}
......@@ -328,10 +320,6 @@ public abstract class Vala.CCodeModule {
next.visit_assignment (a);
}
public virtual void generate_cparameters (Method m, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
next.generate_cparameters (m, cparam_map, func, vdeclarator, carg_map, vcall, direction);
}
public virtual string? get_custom_creturn_type (Method m) {
return next.get_custom_creturn_type (m);
}
......
/* valaccodestructmodule.vala
*
* Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
* Copyright (C) 2006-2009 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
......@@ -28,31 +29,62 @@ internal class Vala.CCodeStructModule : CCodeBaseModule {
base (codegen, next);
}
public override void visit_struct (Struct st) {
var old_type_symbol = current_type_symbol;
var old_instance_struct = instance_struct;
var old_instance_finalize_fragment = instance_finalize_fragment;
current_type_symbol = st;
instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
instance_finalize_fragment = new CCodeFragment ();
CCodeDeclarationSpace decl_space;
if (st.access != SymbolAccessibility.PRIVATE) {
decl_space = header_declarations;
} else {
decl_space = source_declarations;
public override void generate_struct_declaration (Struct st, CCodeDeclarationSpace decl_space) {
if (decl_space.add_symbol_declaration (st, st.get_cname ())) {
return;
}
if (st.access == SymbolAccessibility.PRIVATE
|| st.source_reference.file.cycle == null) {
// no file dependency cycle for private symbols
decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
var instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
foreach (Field f in st.get_fields ()) {
string field_ctype = f.field_type.get_cname ();
if (f.is_volatile) {
field_ctype = "volatile " + field_ctype;
}
if (f.binding == MemberBinding.INSTANCE) {
instance_struct.add_field (field_ctype, f.get_cname ());
if (f.field_type is ArrayType && !f.no_array_length) {
// create fields to store array dimensions
var array_type = (ArrayType) f.field_type;
var len_type = int_type.copy ();
for (int dim = 1; dim <= array_type.rank; dim++) {
instance_struct.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
}
if (array_type.rank == 1 && f.is_internal_symbol ()) {
instance_struct.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
}
} else if (f.field_type is DelegateType) {
var delegate_type = (DelegateType) f.field_type;
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
instance_struct.add_field ("gpointer", get_delegate_target_cname (f.name));
}
}
}
}
decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
if (st.source_reference.comment != null) {
decl_space.add_type_definition (new CCodeComment (st.source_reference.comment));
}
decl_space.add_type_definition (instance_struct);
}
public override void visit_struct (Struct st) {
var old_type_symbol = current_type_symbol;
var old_instance_finalize_fragment = instance_finalize_fragment;
current_type_symbol = st;
instance_finalize_fragment = new CCodeFragment ();
generate_struct_declaration (st, source_declarations);
if (!st.is_internal_symbol ()) {
generate_struct_declaration (st, header_declarations);
}
st.accept_children (codegen);
......@@ -65,7 +97,6 @@ internal class Vala.CCodeStructModule : CCodeBaseModule {
add_struct_free_function (st);
current_type_symbol = old_type_symbol;
instance_struct = old_instance_struct;
instance_finalize_fragment = old_instance_finalize_fragment;
}
......@@ -77,11 +108,7 @@ internal class Vala.CCodeStructModule : CCodeBaseModule {
function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));