~ubuntu-branches/ubuntu/vivid/vala/vivid

« back to all changes in this revision

Viewing changes to codegen/valadovabasemodule.vala

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2010-07-28 07:58:01 UTC
  • mfrom: (1.5.5 upstream) (7.3.14 experimental)
  • Revision ID: james.westby@ubuntu.com-20100728075801-18u9cg5hv5oety6m
Tags: 0.9.4-1
New upstream development release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
135
135
 
136
136
        public int next_temp_var_id = 0;
137
137
        public int next_wrapper_id = 0;
138
 
        public int next_string_const_id = 0;
139
138
        public bool in_creation_method { get { return current_method is CreationMethod; } }
140
 
        public bool current_method_inner_error = false;
141
139
        int next_block_id = 0;
142
140
        Map<Block,int> block_map = new HashMap<Block,int> ();
143
141
 
209
207
                reserved_identifiers.add ("while");
210
208
 
211
209
                // reserved for Vala naming conventions
212
 
                reserved_identifiers.add ("error");
213
210
                reserved_identifiers.add ("result");
214
211
                reserved_identifiers.add ("this");
215
212
        }
241
238
 
242
239
                header_declarations = new CCodeDeclarationSpace ();
243
240
 
244
 
 
245
241
                source_declarations = new CCodeDeclarationSpace ();
246
242
                module_init_fragment = new CCodeFragment ();
247
243
                source_type_member_definition = new CCodeFragment ();
248
244
 
 
245
                if (context.nostdpkg) {
 
246
                        header_declarations.add_include ("dova-types.h");
 
247
                        source_declarations.add_include ("dova-types.h");
 
248
                } else {
 
249
                        header_declarations.add_include ("dova-base.h");
 
250
                        source_declarations.add_include ("dova-base.h");
 
251
                }
 
252
 
249
253
                next_temp_var_id = 0;
250
254
                variable_name_map.clear ();
251
255
 
389
393
                }
390
394
        }
391
395
 
392
 
        public override void visit_member (Member m) {
393
 
        }
394
 
 
395
396
        public void generate_constant_declaration (Constant c, CCodeDeclarationSpace decl_space) {
396
397
                if (decl_space.add_symbol_declaration (c, c.get_cname ())) {
397
398
                        return;
400
401
                c.accept_children (codegen);
401
402
 
402
403
                if (!c.external) {
403
 
                        if (c.initializer is InitializerList) {
 
404
                        if (c.value is InitializerList) {
404
405
                                var cdecl = new CCodeDeclaration (c.type_reference.get_const_cname ());
405
406
                                var arr = "";
406
407
                                if (c.type_reference is ArrayType) {
407
408
                                        arr = "[]";
408
409
                                }
409
 
                                cdecl.add_declarator (new CCodeVariableDeclarator ("%s%s".printf (c.get_cname (), arr), (CCodeExpression) c.initializer.ccodenode));
 
410
                                cdecl.add_declarator (new CCodeVariableDeclarator ("%s%s".printf (c.get_cname (), arr), (CCodeExpression) c.value.ccodenode));
410
411
                                cdecl.modifiers = CCodeModifiers.STATIC;
411
412
 
412
413
                                decl_space.add_constant_declaration (cdecl);
413
414
                        } else {
414
 
                                var cdefine = new CCodeMacroReplacement.with_expression (c.get_cname (), (CCodeExpression) c.initializer.ccodenode);
 
415
                                var cdefine = new CCodeMacroReplacement.with_expression (c.get_cname (), (CCodeExpression) c.value.ccodenode);
415
416
                                decl_space.add_type_member_declaration (cdefine);
416
417
                        }
417
418
                }
430
431
                        return;
431
432
                }
432
433
 
433
 
                generate_type_declaration (f.field_type, decl_space);
 
434
                generate_type_declaration (f.variable_type, decl_space);
434
435
 
435
 
                string field_ctype = f.field_type.get_cname ();
 
436
                string field_ctype = f.variable_type.get_cname ();
436
437
                if (f.is_volatile) {
437
438
                        field_ctype = "volatile " + field_ctype;
438
439
                }
444
445
                } else {
445
446
                        cdecl.modifiers = CCodeModifiers.EXTERN;
446
447
                }
 
448
 
 
449
                if (f.get_attribute ("ThreadLocal") != null) {
 
450
                        cdecl.modifiers |= CCodeModifiers.THREAD_LOCAL;
 
451
                }
 
452
 
447
453
                decl_space.add_type_member_declaration (cdecl);
448
454
        }
449
455
 
454
460
 
455
461
                CCodeExpression lhs = null;
456
462
 
457
 
                string field_ctype = f.field_type.get_cname ();
 
463
                string field_ctype = f.variable_type.get_cname ();
458
464
                if (f.is_volatile) {
459
465
                        field_ctype = "volatile " + field_ctype;
460
466
                }
477
483
                                temp_vars.clear ();
478
484
                        }
479
485
 
480
 
                        if (requires_destroy (f.field_type) && instance_finalize_fragment != null) {
 
486
                        if (requires_destroy (f.variable_type) && instance_finalize_fragment != null) {
481
487
                                var this_access = new MemberAccess.simple ("this");
482
488
                                this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
483
489
 
490
496
 
491
497
                                var ma = new MemberAccess (this_access, f.name);
492
498
                                ma.symbol_reference = f;
493
 
                                instance_finalize_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.field_type, ma)));
 
499
                                instance_finalize_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.variable_type, ma)));
494
500
                        }
495
501
                } else {
496
502
                        generate_field_declaration (f, source_declarations);
502
508
                        lhs = new CCodeIdentifier (f.get_cname ());
503
509
 
504
510
                        var var_decl = new CCodeVariableDeclarator (f.get_cname ());
505
 
                        var_decl.initializer = default_value_for_type (f.field_type, true);
 
511
                        var_decl.initializer = default_value_for_type (f.variable_type, true);
506
512
 
507
513
                        if (f.initializer != null) {
508
514
                                var rhs = (CCodeExpression) f.initializer.ccodenode;
520
526
                        } else {
521
527
                                var_def.modifiers = CCodeModifiers.STATIC;
522
528
                        }
 
529
 
 
530
                        if (f.get_attribute ("ThreadLocal") != null) {
 
531
                                var_def.modifiers |= CCodeModifiers.THREAD_LOCAL;
 
532
                        }
 
533
 
523
534
                        source_declarations.add_type_member_declaration (var_def);
524
535
                }
525
536
        }
643
654
        }
644
655
 
645
656
        public override void visit_destructor (Destructor d) {
646
 
                bool old_method_inner_error = current_method_inner_error;
647
 
                current_method_inner_error = false;
648
 
 
649
657
                d.accept_children (codegen);
650
658
 
651
659
                CCodeFragment cfrag = new CCodeFragment ();
653
661
                cfrag.append (d.body.ccodenode);
654
662
 
655
663
                d.ccodenode = cfrag;
656
 
 
657
 
                current_method_inner_error = old_method_inner_error;
658
664
        }
659
665
 
660
666
        public int get_block_id (Block b) {
667
673
        }
668
674
 
669
675
        void capture_parameter (FormalParameter param, CCodeStruct data, CCodeBlock cblock, int block_id, CCodeBlock free_block) {
670
 
                generate_type_declaration (param.parameter_type, source_declarations);
 
676
                generate_type_declaration (param.variable_type, source_declarations);
671
677
 
672
 
                var param_type = param.parameter_type.copy ();
 
678
                var param_type = param.variable_type.copy ();
673
679
                param_type.value_owned = true;
674
680
                data.add_field (param_type.get_cname (), get_variable_cname (param.name));
675
681
 
676
682
                // create copy if necessary as captured variables may need to be kept alive
677
683
                CCodeExpression cparam = get_variable_cexpression (param.name);
678
 
                if (requires_copy (param_type) && !param.parameter_type.value_owned)  {
 
684
                if (requires_copy (param_type) && !param.variable_type.value_owned)  {
679
685
                        var ma = new MemberAccess.simple (param.name);
680
686
                        ma.symbol_reference = param;
681
 
                        ma.value_type = param.parameter_type.copy ();
 
687
                        ma.value_type = param.variable_type.copy ();
682
688
                        // directly access parameters in ref expressions
683
689
                        param.captured = false;
684
 
                        cparam = get_ref_cexpression (param.parameter_type, cparam, ma, param);
 
690
                        cparam = get_ref_cexpression (param.variable_type, cparam, ma, param);
685
691
                        param.captured = true;
686
692
                }
687
693
 
691
697
                        var ma = new MemberAccess.simple (param.name);
692
698
                        ma.symbol_reference = param;
693
699
                        ma.value_type = param_type.copy ();
694
 
                        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.parameter_type, ma)));
 
700
                        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)));
695
701
                }
696
702
        }
697
703
 
887
893
                if (b.parent_symbol is Method) {
888
894
                        var m = (Method) b.parent_symbol;
889
895
                        foreach (FormalParameter param in m.get_parameters ()) {
890
 
                                if (!param.captured && requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) {
 
896
                                if (!param.captured && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
891
897
                                        var ma = new MemberAccess.simple (param.name);
892
898
                                        ma.symbol_reference = param;
893
 
                                        cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.parameter_type, ma)));
 
899
                                        cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
894
900
                                }
895
901
                        }
896
902
                }
1114
1120
                        var pointer_type = (PointerType) type;
1115
1121
                        return get_dup_func_expression (pointer_type.base_type, source_reference);
1116
1122
                } else {
1117
 
                        source_declarations.add_include ("stddef.h");
1118
1123
                        return new CCodeConstant ("NULL");
1119
1124
                }
1120
1125
        }
1140
1145
                                }
1141
1146
                        }
1142
1147
                        if (unref_function == null) {
1143
 
                                source_declarations.add_include ("stddef.h");
1144
1148
                                return new CCodeConstant ("NULL");
1145
1149
                        }
1146
1150
                        return new CCodeIdentifier (unref_function);
1154
1158
                } else if (type is PointerType) {
1155
1159
                        return new CCodeIdentifier ("free");
1156
1160
                } else {
1157
 
                        source_declarations.add_include ("stddef.h");
1158
1161
                        return new CCodeConstant ("NULL");
1159
1162
                }
1160
1163
        }
1179
1182
                 * if foo is of static type non-null
1180
1183
                 */
1181
1184
 
1182
 
                source_declarations.add_include ("stddef.h");
1183
 
 
1184
1185
                var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL"));
1185
1186
                if (type.type_parameter != null) {
1186
1187
                        if (!(current_type_symbol is Class) || current_class.is_compact) {
1279
1280
                                var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
1280
1281
                                alloca_call.add_argument (value_size);
1281
1282
 
1282
 
                                // memset needs string.h
1283
 
                                source_declarations.add_include ("string.h");
1284
1283
                                var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
1285
1284
                                memset_call.add_argument (alloca_call);
1286
1285
                                memset_call.add_argument (new CCodeConstant ("0"));
1300
1299
                                vardecl.init0 = true;
1301
1300
                        } else if (local.variable_type.is_reference_type_or_type_parameter () ||
1302
1301
                               local.variable_type.nullable) {
1303
 
                                source_declarations.add_include ("stddef.h");
1304
1302
                                vardecl.initializer = new CCodeConstant ("NULL");
1305
1303
                                vardecl.init0 = true;
1306
1304
                        }
1449
1447
 
1450
1448
        private void append_param_free (Method m, CCodeFragment cfrag) {
1451
1449
                foreach (FormalParameter param in m.get_parameters ()) {
1452
 
                        if (requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) {
 
1450
                        if (requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
1453
1451
                                var ma = new MemberAccess.simple (param.name);
1454
1452
                                ma.symbol_reference = param;
1455
 
                                cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.parameter_type, ma)));
 
1453
                                cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
1456
1454
                        }
1457
1455
                }
1458
1456
        }
1501
1499
        }
1502
1500
 
1503
1501
        public override void visit_boolean_literal (BooleanLiteral expr) {
1504
 
                source_declarations.add_include ("stdbool.h");
1505
1502
                expr.ccodenode = new CCodeConstant (expr.value ? "true" : "false");
1506
1503
        }
1507
1504
 
1535
1532
        }
1536
1533
 
1537
1534
        public override void visit_string_literal (StringLiteral expr) {
1538
 
                var val = new CCodeInitializerList ();
1539
 
                val.append (new CCodeConstant ("0"));
 
1535
                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring"));
1540
1536
                // FIXME handle escaped characters in scanner/parser and escape them here again for C
1541
 
                val.append (new CCodeConstant ((expr.eval ().size ()).to_string ()));
1542
 
                val.append (new CCodeConstant (expr.value));
1543
 
 
1544
 
                var cdecl = new CCodeDeclaration ("const string");
1545
 
                cdecl.add_declarator (new CCodeVariableDeclarator ("_string%d_".printf (next_string_const_id), val));
1546
 
                cdecl.modifiers = CCodeModifiers.STATIC;
1547
 
                source_declarations.add_constant_declaration (cdecl);
1548
 
 
1549
 
                expr.ccodenode = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeConstant ("_string%d_".printf (next_string_const_id)));
1550
 
 
1551
 
                next_string_const_id++;
 
1537
                ccall.add_argument (new CCodeConstant (expr.value));
 
1538
 
 
1539
                expr.ccodenode = ccall;
1552
1540
        }
1553
1541
 
1554
1542
        public override void visit_null_literal (NullLiteral expr) {
1555
 
                source_declarations.add_include ("stddef.h");
1556
1543
                expr.ccodenode = new CCodeConstant ("NULL");
1557
1544
        }
1558
1545
 
1630
1617
                }
1631
1618
 
1632
1619
                var array_type = type as ArrayType;
1633
 
                if (array_type != null && array_type.fixed_length) {
 
1620
                if (array_type != null && array_type.inline_allocated) {
1634
1621
                        return requires_destroy (array_type.element_type);
1635
1622
                }
1636
1623
 
1711
1698
 
1712
1699
                        var ctemp = get_variable_cexpression (decl.name);
1713
1700
 
1714
 
                        source_declarations.add_include ("stddef.h");
1715
1701
                        var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
1716
1702
                        if (expression_type.type_parameter != null) {
1717
1703
                                // dup functions are optional for type parameters
1779
1765
                if (expr.symbol_reference == null) {
1780
1766
                        // no creation method
1781
1767
                        if (expr.type_reference.data_type is Struct) {
1782
 
                                // memset needs string.h
1783
 
                                source_declarations.add_include ("string.h");
1784
1768
                                var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
1785
1769
                                creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
1786
1770
                                creation_call.add_argument (new CCodeConstant ("0"));
1843
1827
                                        break;
1844
1828
                                }
1845
1829
 
1846
 
                                if (param.default_expression == null) {
 
1830
                                if (param.initializer == null) {
1847
1831
                                        Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
1848
1832
                                        return;
1849
1833
                                }
1851
1835
                                /* evaluate default expression here as the code
1852
1836
                                 * generator might not have visited the formal
1853
1837
                                 * parameter yet */
1854
 
                                param.default_expression.accept (codegen);
 
1838
                                param.initializer.accept (codegen);
1855
1839
 
1856
 
                                creation_call.add_argument ((CCodeExpression) param.default_expression.ccodenode);
 
1840
                                creation_call.add_argument ((CCodeExpression) param.initializer.ccodenode);
1857
1841
                                i++;
1858
1842
                        }
1859
1843
 
1862
1846
                                creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
1863
1847
                        }
1864
1848
 
1865
 
                        if (expr.tree_can_fail) {
1866
 
                                // method can fail
1867
 
                                current_method_inner_error = true;
1868
 
                                creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_inner_error_")));
1869
 
                        }
1870
 
 
1871
1849
                        if (ellipsis) {
1872
1850
                                /* ensure variable argument list ends with NULL
1873
1851
                                 * except when using printf-style arguments */
2300
2278
                        foreach (FormalParameter param in d.get_parameters ()) {
2301
2279
                                method_param_iter.next ();
2302
2280
                                var method_param = method_param_iter.get ();
2303
 
                                string ctype = param.parameter_type.get_cname ();
2304
 
                                if (param.parameter_type is GenericType && !(method_param.parameter_type is GenericType)) {
2305
 
                                        ctype = method_param.parameter_type.get_cname () + "*";
 
2281
                                string ctype = param.variable_type.get_cname ();
 
2282
                                if (param.variable_type is GenericType && !(method_param.variable_type is GenericType)) {
 
2283
                                        ctype = method_param.variable_type.get_cname () + "*";
2306
2284
                                        call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)));
2307
 
                                } else if (!(param.parameter_type is GenericType) && method_param.parameter_type is GenericType) {
 
2285
                                } else if (!(param.variable_type is GenericType) && method_param.variable_type is GenericType) {
2308
2286
                                        call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
2309
2287
                                } else {
2310
2288
                                        call.add_argument (new CCodeIdentifier (param.name));
2425
2403
        }
2426
2404
 
2427
2405
        public CCodeExpression? default_value_for_type (DataType type, bool initializer_expression) {
2428
 
                source_declarations.add_include ("stddef.h");
2429
 
 
2430
2406
                var st = type.data_type as Struct;
2431
2407
                var array_type = type as ArrayType;
2432
2408
                if (type is GenericType) {
2436
2412
                        var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
2437
2413
                        alloca_call.add_argument (value_size);
2438
2414
 
2439
 
                        // memset needs string.h
2440
 
                        source_declarations.add_include ("string.h");
2441
2415
                        var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
2442
2416
                        memset_call.add_argument (alloca_call);
2443
2417
                        memset_call.add_argument (new CCodeConstant ("0"));
2475
2449
 
2476
2450
        public DataType? get_this_type () {
2477
2451
                if (current_method != null && current_method.binding == MemberBinding.INSTANCE) {
2478
 
                        return current_method.this_parameter.parameter_type;
 
2452
                        return current_method.this_parameter.variable_type;
2479
2453
                } else if (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE) {
2480
 
                        return current_property_accessor.prop.this_parameter.parameter_type;
 
2454
                        return current_property_accessor.prop.this_parameter.variable_type;
2481
2455
                }
2482
2456
                return null;
2483
2457
        }
2484
2458
 
2485
 
        public CCodeFunctionCall generate_instance_cast (CCodeExpression expr, TypeSymbol type) {
2486
 
                var result = new CCodeFunctionCall (new CCodeIdentifier (type.get_upper_case_cname (null)));
2487
 
                result.add_argument (expr);
2488
 
                return result;
 
2459
        public CCodeExpression generate_instance_cast (CCodeExpression expr, TypeSymbol type) {
 
2460
                return new CCodeCastExpression (expr, type.get_cname () + "*");
2489
2461
        }
2490
2462
}