}
} else if (b.parent_symbol is ForeachStatement) {
var stmt = (ForeachStatement) b.parent_symbol;
- if (!stmt.use_iterator && stmt.element_variable.captured) {
+ if (stmt.element_variable.captured) {
ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_local_cname (stmt.element_variable)), get_variable_cexpression (get_local_cname (stmt.element_variable)));
}
}
var block = local.parent_symbol;
if (block != null) {
var stmt = block.parent_symbol as ForeachStatement;
- if (stmt != null && !stmt.use_iterator && stmt.element_variable == local) {
+ if (stmt != null && stmt.element_variable == local) {
return true;
}
}
ccode.close ();
}
- public override void visit_foreach_statement (ForeachStatement stmt) {
- ccode.open_block ();
-
- var collection_backup = stmt.collection_variable;
- var collection_type = collection_backup.variable_type;
-
- var array_type = collection_type as ArrayType;
- if (array_type != null) {
- // avoid assignment issues
- array_type.inline_allocated = false;
- array_type.fixed_length = false;
- }
-
- visit_local_variable (collection_backup);
- ccode.add_assignment (get_variable_cexpression (get_local_cname (collection_backup)), get_cvalue (stmt.collection));
-
- if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
- // exception handling
- add_simple_check (stmt.collection);
- }
-
- if (stmt.collection.value_type is ArrayType) {
- array_type = (ArrayType) stmt.collection.value_type;
-
- var array_len = get_array_length_cexpression (stmt.collection);
-
- // store array length for use by _vala_array_free
- ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_local_cname (collection_backup), 1)), array_len);
-
- var iterator_variable = new LocalVariable (array_type.length_type.copy (), stmt.variable_name + "_it");
- visit_local_variable (iterator_variable);
- var it_name = get_local_cname (iterator_variable);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
-
- ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")),
- ccond,
- new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
-
- CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (get_local_cname (collection_backup)), get_variable_cexpression (it_name));
-
- var element_type = array_type.element_type.copy ();
- element_type.value_owned = false;
- element_expr = get_cvalue_ (transform_value (new GLibValue (element_type, element_expr, true), stmt.type_reference, stmt));
-
- visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
-
- // set array length for stacked arrays
- if (stmt.type_reference is ArrayType) {
- var inner_array_type = (ArrayType) stmt.type_reference;
- for (int dim = 1; dim <= inner_array_type.rank; dim++) {
- ccode.add_assignment (get_variable_cexpression (get_array_length_cname (get_local_cname (stmt.element_variable), dim)), new CCodeConstant ("-1"));
- }
- }
-
- stmt.body.emit (this);
-
- ccode.close ();
- } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
- // iterating over a GList or GSList
-
- var iterator_variable = new LocalVariable (collection_type.copy (), stmt.variable_name + "_it");
- visit_local_variable (iterator_variable);
- var it_name = get_local_cname (iterator_variable);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
-
- ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (get_local_cname (collection_backup))),
- ccond,
- new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
-
- CCodeExpression element_expr = new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "data");
-
- if (collection_type.get_type_arguments ().size != 1) {
- Report.error (stmt.source_reference, "internal error: missing generic type argument");
- stmt.error = true;
- return;
- }
-
- var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
- element_data_type.value_owned = false;
- element_expr = convert_from_generic_pointer (element_expr, element_data_type);
- element_expr = get_cvalue_ (transform_value (new GLibValue (element_data_type, element_expr), stmt.type_reference, stmt));
-
- visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
-
- stmt.body.emit (this);
-
- ccode.close ();
- } else if (stmt.collection.value_type.compatible (new ObjectType (gvaluearray_type))) {
- // iterating over a GValueArray
-
- var iterator_variable = new LocalVariable (uint_type.copy (), "%s_index".printf (stmt.variable_name));
- visit_local_variable (iterator_variable);
- var arr_index = get_variable_cname (get_local_cname (iterator_variable));
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (get_local_cname (collection_backup)), "n_values"));
-
- ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
- ccond,
- new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
-
- var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth"));
- get_item.add_argument (get_variable_cexpression (get_local_cname (collection_backup)));
- get_item.add_argument (get_variable_cexpression (arr_index));
-
- CCodeExpression element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_item);
-
- if (stmt.type_reference.value_owned) {
- element_expr = get_cvalue_ (copy_value (new GLibValue (stmt.type_reference, element_expr), new StructValueType (gvalue_type)));
- }
-
- visit_local_variable (stmt.element_variable);
- ccode.add_assignment (get_variable_cexpression (get_local_cname (stmt.element_variable)), element_expr);
-
- stmt.body.emit (this);
-
- ccode.close ();
- }
-
- foreach (LocalVariable local in stmt.get_local_variables ()) {
- if (requires_destroy (local.variable_type)) {
- ccode.add_expression (destroy_local (local));
- }
- }
-
- ccode.close ();
- }
-
public override void visit_break_statement (BreakStatement stmt) {
append_local_free (current_symbol, true);
end_replace_statement ();
}
+ public override void visit_foreach_statement (ForeachStatement stmt) {
+ begin_replace_statement (stmt);
+
+ stmt.body.remove_local_variable (stmt.element_variable);
+ stmt.element_variable.checked = false;
+ var decl = new DeclarationStatement (stmt.element_variable, stmt.element_variable.source_reference);
+
+ switch (stmt.foreach_iteration) {
+ case ForeachIteration.ARRAY:
+ var array_type = (ArrayType) stmt.collection.value_type.copy ();
+ array_type.fixed_length = false;
+ array_type.inline_allocated = false;
+ string collection;
+ string length;
+ // multidimensonal array
+ if (array_type.rank > 1) {
+ length = @"$(stmt.collection).length[0]";
+ var dim = 1;
+ while (dim < array_type.rank) {
+ length += @" * $(stmt.collection).length[$dim]";
+ dim++;
+ }
+ collection = b.add_temp_declaration (new ArrayType (array_type.element_type, 1, null), expression (@"($(array_type.element_type)[]) ($(stmt.collection))"));
+ } else {
+ collection = b.add_temp_declaration (array_type, stmt.collection);
+ length = @"$collection.length";
+ }
+ var i = b.add_temp_declaration (array_type.length_type, expression ("0"));
+ b.open_for (null, expression (@"$i < $length"), expression (@"$i++"));
+ stmt.element_variable.initializer = expression (@"$collection[$i]");
+ break;
+ case ForeachIteration.GVALUE_ARRAY:
+ // GValueArray
+ var collection = b.add_temp_declaration (null, expression (@"$(stmt.collection).values"));
+ var i = b.add_temp_declaration (null, expression ("0"));
+ b.open_for (null, expression (@"$i < $collection.length"), expression (@"$i++"));
+ stmt.element_variable.initializer = expression (@"$collection[$i]");
+ break;
+ case ForeachIteration.GLIST:
+ // GList or GSList
+ var collection = b.add_temp_declaration (stmt.collection.value_type, stmt.collection);
+ var iter = b.add_temp_declaration (copy_type (stmt.collection.value_type, false, true), expression (collection));
+ b.open_for (null, expression (@"$iter != null"), expression (@"$iter = ((!) $iter).next"));
+ stmt.element_variable.initializer = expression (@"((!) $iter).data");
+ break;
+ case ForeachIteration.INDEX:
+ // get() + size
+ var collection = b.add_temp_declaration (stmt.collection.value_type, stmt.collection);
+ var size = b.add_temp_declaration (null, expression (@"$collection.size"));
+ var i = b.add_temp_declaration (null, expression ("0"));
+ b.open_for (null, expression (@"$i < $size"), expression (@"$i++"));
+ stmt.element_variable.initializer = expression (@"$collection.get ($i)");
+ break;
+ case ForeachIteration.NEXT_VALUE:
+ // iterator + next_value()
+ var collection = b.add_temp_declaration (stmt.collection.value_type, stmt.collection);
+ var iterator = b.add_temp_declaration (null, expression (@"$collection.iterator ()"));
+ var temp = b.add_temp_declaration (copy_type (stmt.type_reference, null, true));
+ b.open_while (expression (@"($temp = $iterator.next_value ()) != null"));
+ stmt.element_variable.initializer = expression (@"(!) $temp");
+ break;
+ case ForeachIteration.NEXT_GET:
+ // iterator + next() + get()
+ var collection = b.add_temp_declaration (stmt.collection.value_type, stmt.collection);
+ var iterator = b.add_temp_declaration (null, expression (@"$collection.iterator ()"));
+ b.open_while (expression (@"$iterator.next ()"));
+ stmt.element_variable.initializer = expression (@"$iterator.get ()");
+ break;
+ default:
+ assert_not_reached ();
+ }
+
+ stmt.body.insert_statement (0, decl);
+ b.add_statement (stmt.body);
+ b.close ();
+
+ stmt.body.checked = false;
+ end_replace_statement ();
+ }
+
public override void visit_expression (Expression expr) {
if (expr in context.analyzer.replaced_nodes) {
return;
checked = true;
- var insert_block = context.analyzer.get_insert_block (this);
+ var insert_block = context.analyzer.get_current_block (this);
if (left is Tuple && operator == AssignmentOperator.SIMPLE && parent_node is ExpressionStatement) {
var tuple = (Tuple) left;
checked = true;
- var insert_block = context.analyzer.get_insert_block (this);
+ var insert_block = context.analyzer.get_current_block (this);
// some expressions are not in a block,
// for example, expressions in method contracts
Statement insert_statement;
Block insert_block;
ArrayList<Statement> statement_stack = new ArrayList<Statement> ();
- ArrayList<CodeNode> check_nodes = new ArrayList<CodeNode> ();
+ ArrayList<CodeNode> decl_nodes = new ArrayList<CodeNode> ();
public CodeBuilder (CodeContext context, Statement insert_statement, SourceReference source_reference) {
- current_block = new Block (source_reference);
- insert_block = context.analyzer.get_insert_block (insert_statement);
this.source_reference = source_reference;
- var statement_block = context.analyzer.get_current_block (insert_statement);
- statement_block.insert_before (insert_statement, current_block);
- insert_statement = current_block;
- check_nodes.add (current_block);
+ current_block = new Block (source_reference);
+ insert_block = context.analyzer.get_current_block (insert_statement);
+ insert_block.insert_before (insert_statement, current_block);
+ this.insert_statement = current_block;
}
public CodeBuilder.for_subroutine (Subroutine m) {
}
public void check (CodeTransformer transformer) {
- foreach (var node in check_nodes) {
+ foreach (var node in decl_nodes) {
transformer.check (node);
}
+ transformer.check (current_block);
}
public void open_block () {
var local = new LocalVariable (type, CodeNode.get_temp_name (), initializer, source_reference);
var stmt = new DeclarationStatement (local, source_reference);
insert_block.insert_before (insert_statement, stmt);
- check_nodes.insert (0, stmt);
+ decl_nodes.add (stmt);
return local.name;
}
* Represents a foreach statement in the source code. Foreach statements iterate
* over the elements of a collection.
*/
-public class Vala.ForeachStatement : Block {
+public class Vala.ForeachStatement : CodeNode, Statement {
/**
* Specifies the element type.
*/
}
}
- public bool use_iterator { get; private set; }
-
/**
- * Specifies the declarator for the generated element variable.
+ * Specifies the approach used for the iteration.
*/
- public LocalVariable element_variable { get; set; }
+ public ForeachIteration foreach_iteration { get; private set; }
/**
- * Specifies the declarator for the generated collection variable.
- */
- public LocalVariable collection_variable { get; set; }
-
- /**
- * Specifies the declarator for the generated iterator variable.
+ * Specifies the declarator for the generated element variable.
*/
- public LocalVariable iterator_variable { get; set; }
+ public LocalVariable element_variable { get; set; }
private Expression _collection;
private Block _body;
* @return newly created foreach statement
*/
public ForeachStatement (DataType? type_reference, string variable_name, Expression collection, Block body, SourceReference source_reference) {
- base (source_reference);
this.variable_name = variable_name;
this.collection = collection;
this.body = body;
this.type_reference = type_reference;
+ this.source_reference = source_reference;
}
public override void accept (CodeVisitor visitor) {
- if (use_iterator) {
- base.accept (visitor);
- return;
- }
-
visitor.visit_foreach_statement (this);
}
public override void accept_children (CodeVisitor visitor) {
- if (use_iterator) {
- base.accept_children (visitor);
- return;
- }
-
collection.accept (visitor);
visitor.visit_end_full_expression (collection);
checked = true;
- owner = context.analyzer.get_current_symbol (parent_node).scope;
-
// analyze collection expression first, used for type inference
if (!collection.check (context)) {
// ignore inner error
// can't use inline-allocated array for temporary variable
array_type.inline_allocated = false;
- return check_without_iterator (context, collection_type, array_type.element_type);
- } else if (context.profile == Profile.GOBJECT && (collection_type.compatible (context.analyzer.glist_type) || collection_type.compatible (context.analyzer.gslist_type))) {
+ foreach_iteration = ForeachIteration.ARRAY;
+ error = !analyze_element_type (array_type.element_type, false);
+ } else if (context.profile == Profile.GOBJECT && collection_type.compatible (context.analyzer.glist_type) || collection_type.compatible (context.analyzer.gslist_type)) {
if (collection_type.get_type_arguments ().size != 1) {
error = true;
Report.error (collection.source_reference, "missing type argument for collection");
return false;
}
- return check_without_iterator (context, collection_type, collection_type.get_type_arguments ().get (0));
+ foreach_iteration = ForeachIteration.GLIST;
+ error = !analyze_element_type (collection_type.get_type_arguments ().get (0), false);
} else if (context.profile == Profile.GOBJECT && collection_type.compatible (context.analyzer.gvaluearray_type)) {
- return check_without_iterator (context, collection_type, context.analyzer.gvalue_type);
+ foreach_iteration = ForeachIteration.GVALUE_ARRAY;
+ error = !analyze_element_type (context.analyzer.gvalue_type, false);
} else {
- return check_with_iterator (context, collection_type);
+ error = !check_with_iterator (context, collection_type);
+ }
+
+ element_variable = new LocalVariable (type_reference, variable_name, null, source_reference);
+ element_variable.checked = true;
+ element_variable.active = true;
+ body.add_local_variable (element_variable);
+ if (!body.check (context)) {
+ error = true;
}
+ element_variable.active = false;
+
+ return !error;
}
bool check_with_index (CodeContext context, DataType collection_type) {
if (get_method.get_parameters ().size != 1) {
return false;
}
- var size_property = collection_type.get_member ("size") as Property;
- if (size_property == null) {
+ var element_type = get_method.return_type.get_actual_type (collection.value_type, null, this);
+ if (element_type is VoidType) {
+ Report.error (collection.source_reference, "`%s' must return an element".printf (get_method.get_full_name ()));
+ error = true;
return false;
}
- add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_list".printf (variable_name), collection, source_reference), source_reference));
- add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_size".printf (variable_name), new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "size", source_reference), source_reference), source_reference));
- add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_index".printf (variable_name), new UnaryExpression (UnaryOperator.MINUS, new IntegerLiteral ("1", source_reference), source_reference), source_reference), source_reference));
- var next = new UnaryExpression (UnaryOperator.INCREMENT, new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference), source_reference);
- var conditional = new BinaryExpression (BinaryOperator.LESS_THAN, next, new MemberAccess.simple ("_%s_size".printf (variable_name), source_reference), source_reference);
- var loop = new WhileStatement (conditional, body, source_reference);
- add_statement (loop);
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
+ return false;
+ }
- var get_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "get", source_reference), source_reference);
- get_call.add_argument (new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference));
- body.insert_statement (0, new DeclarationStatement (new LocalVariable (type_reference, variable_name, get_call, source_reference), source_reference));
+ var size_property = collection_type.get_member ("size") as Property;
+ if (size_property == null) {
+ return false;
+ }
- checked = false;
- return base.check (context);
+ foreach_iteration = ForeachIteration.INDEX;
+ return true;
}
bool check_with_iterator (CodeContext context, DataType collection_type) {
- use_iterator = true;
-
if (check_with_index (context, collection_type)) {
return true;
}
return false;
}
- var iterator_call = new MethodCall (new MemberAccess (collection, "iterator", source_reference), source_reference);
- add_statement (new DeclarationStatement (new LocalVariable (iterator_type, "_%s_it".printf (variable_name), iterator_call, source_reference), source_reference));
-
var next_value_method = iterator_type.get_member ("next_value") as Method;
var next_method = iterator_type.get_member ("next") as Method;
if (next_value_method != null) {
return false;
}
- if (!analyze_element_type (element_type)) {
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
return false;
}
- add_statement (new DeclarationStatement (new LocalVariable (type_reference, variable_name, null, source_reference), source_reference));
-
- var next_value_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_it".printf (variable_name), source_reference), "next_value", source_reference), source_reference);
- var assignment = new Assignment (new MemberAccess (null, variable_name, source_reference), next_value_call, AssignmentOperator.SIMPLE, source_reference);
- var conditional = new BinaryExpression (BinaryOperator.INEQUALITY, assignment, new NullLiteral (source_reference), source_reference);
- var loop = new WhileStatement (conditional, body, source_reference);
- add_statement (loop);
+ foreach_iteration = ForeachIteration.NEXT_VALUE;
} else if (next_method != null) {
if (next_method.get_parameters ().size != 0) {
Report.error (collection.source_reference, "`%s' must not have any parameters".printf (next_method.get_full_name ()));
return false;
}
- if (!analyze_element_type (element_type)) {
+ if (!analyze_element_type (element_type, element_type.value_owned)) {
return false;
}
- var next_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_it".printf (variable_name), source_reference), "next", source_reference), source_reference);
- var loop = new WhileStatement (next_call, body, source_reference);
- add_statement (loop);
-
- var get_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_it".printf (variable_name), source_reference), "get", source_reference), source_reference);
- body.insert_statement (0, new DeclarationStatement (new LocalVariable (type_reference, variable_name, get_call, source_reference), source_reference));
- } else {
- Report.error (collection.source_reference, "`%s' does not have a `next_value' or `next' method".printf (iterator_type.to_string ()));
- error = true;
- return false;
+ foreach_iteration = ForeachIteration.NEXT_GET;
}
- checked = false;
- return base.check (context);
+ return true;
}
- bool analyze_element_type (DataType element_type) {
+ bool analyze_element_type (DataType element_type, bool get_owned) {
// analyze element type
if (type_reference == null) {
// var type
error = true;
Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_type.to_string (), type_reference.to_string ()));
return false;
- } else if (element_type.is_disposable () && element_type.value_owned && !type_reference.value_owned) {
+ } else if (get_owned && element_type.is_disposable () && element_type.value_owned && !type_reference.value_owned) {
error = true;
Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
return false;
return true;
}
- bool check_without_iterator (CodeContext context, DataType collection_type, DataType element_type) {
- // analyze element type
- if (type_reference == null) {
- // var type
- type_reference = element_type.copy ();
- } else if (!element_type.compatible (type_reference)) {
- error = true;
- Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_type.to_string (), type_reference.to_string ()));
- return false;
- }
-
- element_variable = new LocalVariable (type_reference, variable_name, null, source_reference);
-
- body.add_local_variable (element_variable);
- element_variable.active = true;
- element_variable.checked = true;
-
- // call add_local_variable to check for shadowed variable
- add_local_variable (element_variable);
- remove_local_variable (element_variable);
-
- body.check (context);
-
- foreach (LocalVariable local in get_local_variables ()) {
- local.active = false;
- }
-
- collection_variable = new LocalVariable (collection_type.copy (), "%s_collection".printf (variable_name));
-
- add_local_variable (collection_variable);
- collection_variable.active = true;
-
- return !error;
- }
-
public override void get_error_types (Collection<DataType> collection, SourceReference? source_reference = null) {
if (source_reference == null) {
source_reference = this.source_reference;
}
public override void emit (CodeGenerator codegen) {
- if (use_iterator) {
- base.emit (codegen);
- return;
- }
-
collection.emit (codegen);
codegen.visit_end_full_expression (collection);
- element_variable.active = true;
- collection_variable.active = true;
- if (iterator_variable != null) {
- iterator_variable.active = true;
- }
-
codegen.visit_foreach_statement (this);
}
collection.add (element_variable);
}
}
+
+public enum Vala.ForeachIteration {
+ NONE,
+ ARRAY,
+ GVALUE_ARRAY,
+ GLIST,
+ INDEX,
+ NEXT_VALUE,
+ NEXT_GET
+}
var local = new LocalVariable (value_type.copy (), get_temp_name (), null, source_reference);
var decl = new DeclarationStatement (local, source_reference);
- insert_statement (context.analyzer.get_insert_block (this), decl);
+ insert_statement (context.analyzer.get_current_block (this), decl);
var temp_access = SemanticAnalyzer.create_temp_access (local, target_type);
// don't set initializer earlier as this changes parent_node and parent_statement
// otherwise there will be scoping issues in the generated code
var block = context.analyzer.get_current_block (this);
block.remove_local_variable (local);
- context.analyzer.get_insert_block (this).add_local_variable (local);
+ context.analyzer.get_current_block (this).add_local_variable (local);
old_parent_node.replace_expression (this, temp_access);
temp_access.check (context);
return (Block) node;
}
- public unowned Block? get_insert_block (CodeNode node) {
- unowned Block? block = get_current_block (node);
- if (block is ForeachStatement) {
- block = block.parent_symbol as Block;
- }
- return block;
- }
-
// check whether type is at least as accessible as the specified symbol
public bool is_type_accessible (Symbol sym, DataType type) {
return type.is_accessible (sym);