+2006-07-14 Jürg Billeter <j@bitron.ch>
+
+ * vala/valacodecontext.vala: ignore file-internal dependencies
+ * vala/valasemanticanalyzer.vala: mark string literals as non-null, add
+ some implicit casts
+ * vala/valamemorymanager.vala: only check for leaks with reference
+ types, manage memory in field initializers
+ * vala/valacodegenerator.vala: add non-null parameter typechecks for
+ structs, simplify ref expression if expression is known to be non-null
+ * vapi/glib-2.0.vala: unichar, string, String, and Path enhancements,
+ add Base64 and Dir
+
2006-07-10 Jürg Billeter <j@bitron.ch>
* vala/parser.y: adapt to changes in InvocationExpression,
private SourceFile find_cycle_head (SourceFile! file) {
foreach (SourceFile dep in file.header_internal_full_dependencies) {
+ if (dep == file) {
+ /* ignore file-internal dependencies */
+ continue;
+ }
+
foreach (SourceFile cycle_file in file.cycle.files) {
if (dep == cycle_file) {
return find_cycle_head (dep);
private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
var ccheck = new CCodeFunctionCall ();
- var ctype_check = new CCodeFunctionCall (call = new CCodeIdentifier (name = t.get_upper_case_cname ("IS_")));
- ctype_check.add_argument (new CCodeIdentifier (name = var_name));
-
- ref CCodeExpression cexpr = ctype_check;
- if (!non_null) {
- var cnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = new CCodeIdentifier (name = var_name), right = new CCodeConstant (name = "NULL"));
-
- cexpr = new CCodeBinaryExpression (operator = CCodeBinaryOperator.OR, left = cnull, right = ctype_check);
+ if (t is Class || t is Interface) {
+ var ctype_check = new CCodeFunctionCall (call = new CCodeIdentifier (name = t.get_upper_case_cname ("IS_")));
+ ctype_check.add_argument (new CCodeIdentifier (name = var_name));
+
+ ref CCodeExpression cexpr = ctype_check;
+ if (!non_null) {
+ var cnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = new CCodeIdentifier (name = var_name), right = new CCodeConstant (name = "NULL"));
+
+ cexpr = new CCodeBinaryExpression (operator = CCodeBinaryOperator.OR, left = cnull, right = ctype_check);
+ }
+ ccheck.add_argument (cexpr);
+ } else if (!non_null) {
+ return null;
+ } else {
+ var cnonnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.INEQUALITY, left = new CCodeIdentifier (name = var_name), right = new CCodeConstant (name = "NULL"));
+ ccheck.add_argument (cnonnull);
}
- ccheck.add_argument (cexpr);
if (ret_type == null) {
/* void function */
}
foreach (FormalParameter param in m.get_parameters ()) {
var t = param.type_reference.type;
- if (t != null && (t is Class || t is Interface) && !param.type_reference.is_out) {
- cinit.append (create_method_type_check_statement (m, t, param.type_reference.non_null, param.name));
+ if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
+ var type_check = create_method_type_check_statement (m, t, param.type_reference.non_null, param.name);
+ if (type_check != null) {
+ cinit.append (type_check);
+ }
}
}
foreach (VariableDeclarator decl in temp_vars) {
var cdecl = new CCodeDeclaration (type_name = decl.type_reference.get_cname (true));
- cdecl.add_declarator (new CCodeVariableDeclarator (name = decl.name));
+ var vardecl = new CCodeVariableDeclarator (name = decl.name);
+ cdecl.add_declarator (vardecl);
+
+ if (decl.type_reference.type != null && decl.type_reference.type.is_reference_type ()) {
+ vardecl.initializer = new CCodeConstant (name = "NULL");
+ }
cfrag.append (cdecl);
}
* can be simplified to
* ref (expr)
* if static type of expr is non-null
- *
- * can be simplified to
- * (expr == NULL ? expr : ref (expr))
- * if expr.ccodenode is CCodeSimpleName or CCodeMemberAccess
*/
- var decl = get_temp_variable_declarator (expr.static_type);
- temp_vars.prepend (decl);
-
- var ctemp = new CCodeIdentifier (name = decl.name);
-
- var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = ctemp, right = new CCodeConstant (name = "NULL"));
-
string ref_function;
if (expr.static_type.type.is_reference_counting ()) {
ref_function = expr.static_type.type.get_ref_function ();
}
var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = ref_function));
- ccall.add_argument (ctemp);
-
- var ccomma = new CCodeCommaExpression ();
- ccomma.append_expression (new CCodeAssignment (left = ctemp, right = expr.ccodenode));
- ccomma.append_expression (new CCodeConditionalExpression (condition = cisnull, true_expression = ctemp, false_expression = ccall));
- return ccomma;
+ if (expr.static_type.non_null) {
+ ccall.add_argument ((CCodeExpression) expr.ccodenode);
+
+ return ccall;
+ } else {
+ var decl = get_temp_variable_declarator (expr.static_type);
+ temp_vars.prepend (decl);
+
+ var ctemp = new CCodeIdentifier (name = decl.name);
+
+ var cisnull = new CCodeBinaryExpression (operator = CCodeBinaryOperator.EQUALITY, left = ctemp, right = new CCodeConstant (name = "NULL"));
+
+ ccall.add_argument (ctemp);
+
+ var ccomma = new CCodeCommaExpression ();
+ ccomma.append_expression (new CCodeAssignment (left = ctemp, right = expr.ccodenode));
+ ccomma.append_expression (new CCodeConditionalExpression (condition = cisnull, true_expression = ctemp, false_expression = ccall));
+
+ return ccomma;
+ }
}
private void visit_expression (Expression! expr) {
private void visit_possibly_leaked_expression (Expression! expr) {
if (expr.static_type != null &&
+ (expr.static_type.type != null &&
+ expr.static_type.type.is_reference_type ()) &&
expr.static_type.is_ref) {
/* mark reference as leaked */
expr.ref_leaked = true;
}
}
+ public override void visit_field (Field! f) {
+ if (f.initializer != null) {
+ if (f.type_reference.is_lvalue_ref) {
+ visit_possibly_missing_copy_expression (f.initializer);
+ } else {
+ visit_possibly_leaked_expression (f.initializer);
+ }
+ }
+ }
+
public override void visit_begin_method (Method! m) {
current_symbol = m.symbol;
}
}
public override void visit_string_literal (StringLiteral! expr) {
- expr.static_type = string_type;
+ expr.static_type = string_type.copy ();
+ expr.static_type.non_null = true;
}
public override void visit_null_literal (NullLiteral! expr) {
return true;
}
+ /* int may be implicitly casted to ulong */
+ if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ return true;
+ }
+
+ /* uint may be implicitly casted to long */
+ if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("long").node) {
+ return true;
+ }
+
+ /* uint may be implicitly casted to ulong */
+ if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ return true;
+ }
+
/* int may be implicitly casted to uint */
if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("uint").node) {
return true;
}
+ /* uint may be implicitly casted to int */
+ if (expression_type.type == root_symbol.lookup ("uint").node && expected_type.type == root_symbol.lookup ("int").node) {
+ return true;
+ }
+
+ /* long may be implicitly casted to ulong */
+ if (expression_type.type == root_symbol.lookup ("long").node && expected_type.type == root_symbol.lookup ("ulong").node) {
+ return true;
+ }
+
+ /* ulong may be implicitly casted to long */
+ if (expression_type.type == root_symbol.lookup ("ulong").node && expected_type.type == root_symbol.lookup ("long").node) {
+ return true;
+ }
+
/* int may be implicitly casted to double */
if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("double").node) {
return true;
public struct unichar {
[CCode (cname = "g_unichar_isalnum")]
public bool isalnum ();
+ [CCode (cname = "g_unichar_isdigit")]
+ public bool isdigit ();
[CCode (cname = "g_unichar_isupper")]
public bool isupper ();
+ [CCode (cname = "g_unichar_isxdigit")]
+ public bool isxdigit ();
[CCode (cname = "g_unichar_toupper")]
public unichar toupper ();
[CCode (cname = "g_unichar_tolower")]
public unichar tolower ();
+ [CCode (cname = "g_unichar_digit_value")]
+ public int digit_value ();
+ [CCode (cname = "g_unichar_xdigit_value")]
+ public int xdigit_value ();
}
[ReferenceType (dup_function = "g_strdup", free_function = "g_free", type_id = "G_TYPE_STRING", ref_function = "g_strdup")]
[CCode (cname = "char", cheader_filename = "string.h,glib.h", type_id = "G_TYPE_STRING", marshaller_type_name = "STRING")]
public struct string {
+ [CCode (cname = "g_strstr")]
+ public string str (string! needle);
+ [CCode (cname = "g_str_has_prefix")]
+ public bool has_prefix (string! prefix);
[CCode (cname = "g_str_has_suffix")]
- public bool has_suffix (string suffix);
+ public bool has_suffix (string! suffix);
[CCode (cname = "g_strdup_printf")]
public ref string printf (...);
[CCode (cname = "g_strconcat")]
public ref string concat (string string2, ...);
[CCode (cname = "g_strndup")]
- public ref string ndup (uint n); /* FIXME: only UTF-8 */
+ public ref string ndup (ulong n); /* FIXME: only UTF-8 */
[CCode (cname = "g_strcompress")]
public ref string compress ();
[CCode (cname = "g_strsplit")]
[CCode (cname = "g_utf8_prev_char")]
public string prev_char ();
[CCode (cname = "g_utf8_strlen")]
- public long len (int max = -1);
+ public long len (long max = -1);
[CCode (cname = "g_utf8_strchr")]
- public string chr (int len, unichar c);
+ public string chr (long len, unichar c);
+ [CCode (cname = "g_utf8_validate")]
+ public bool validate (long max_len = -1, out string end = null);
[CCode (cname = "g_utf8_strup")]
- public ref string up (int len = -1);
+ public ref string up (long len = -1);
+ [CCode (cname = "g_utf8_casefold")]
+ public ref string casefold (long len = -1);
[CCode (cname = "g_utf8_collate")]
public int collate (string str2);
+
+ [CCode (cname = "atoi")]
+ public int to_int ();
}
[Import ()]
public static void assert (bool expr);
public static void assert_not_reached ();
+ public static ref string convert (string! str, long len, string! to_codeset, string! from_codeset, ref int bytes_read, ref int bytes_written, out Error error);
+
+ public struct Base64 {
+ public static int encode_step (string! _in, int len, bool break_lines, string _out, ref int state, ref int save);
+ public static int encode_close (bool break_lines, string _out, ref int state, ref int save);
+ public static ref string encode (string! data, int len);
+ public static int decode_step (string! _in, int len, ref int state, ref uint save);
+ public static ref string decode (string! text, ref ulong out_len);
+ }
+
public struct Path {
public static ref string get_basename (string file_name);
+ public static ref string get_dirname (string file_name);
[CCode (cname = "g_build_filename")]
public static ref string build_filename (string first_element, ...);
}
[CCode (cname = "fclose")]
public void close ();
+ public static bool get_contents (string! filename, out string contents, ref long length, out Error error);
+ public static bool set_contents (string! filename, string contents, long length, out Error error);
public static bool test (string filename, FileTest test);
public static int open_tmp (string tmpl, out string name_used, out Error error);
+ public static ref string read_link (string filename, out Error error);
[CCode (cname = "g_rename")]
public static int rename (string oldfilename, string newfilename);
public static int unlink (string filename);
}
+ [ReferenceType (free_function = "g_dir_close")]
+ public struct Dir {
+ public static ref Dir open (string filename, uint _flags, out Error error);
+ public string read_name ();
+
+ [CCode (cname = "g_mkdir")]
+ public static int create (string pathname, int mode);
+ [CCode (cname = "g_mkdir_with_parents")]
+ public static int create_with_parents (string pathname, int mode);
+ }
+
[ReferenceType (free_function = "g_mapped_file_free")]
public struct MappedFile {
public static ref MappedFile new (string filename, bool writable, out Error error);
[ReturnsModifiedPointer ()]
public void remove_link (List<G> llink);
[ReturnsModifiedPointer ()]
+ public void delete_link (List<G> link_);
+ [ReturnsModifiedPointer ()]
public void remove_all (G data);
public void free ();
[ReferenceType (free_function = "g_string_free")]
public struct String {
- public static ref String new (string init);
- public String append (string val);
+ public static ref String! new (string init = "");
+ public static ref String! sized_new (ulong dfl_size);
+ public String assign (string! rval);
+ public String append (string! val);
public String append_c (char c);
public String append_unichar (unichar wc);
+ public String append_len (string! val, long len);
+ public String insert (long pos, string! val);
public String erase (long pos, long len);
public string str;