~ubuntu-branches/ubuntu/dapper/fpc/dapper

« back to all changes in this revision

Viewing changes to compiler/nobj.pas

  • Committer: Bazaar Package Importer
  • Author(s): Carlos Laviola
  • Date: 2005-05-30 11:59:10 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050530115910-x5pbzm4qqta4i94h
Tags: 2.0.0-2
debian/fp-compiler.postinst.in: forgot to reapply the patch that
correctly creates the slave link to pc(1).  (Closes: #310907)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
{
2
 
    $Id: nobj.pas,v 1.69 2004/03/31 21:01:01 florian Exp $
 
2
    $Id: nobj.pas,v 1.93 2005/05/05 21:09:10 florian Exp $
3
3
    Copyright (c) 1998-2002 by Florian Klaempfl
4
4
 
5
5
    Routines for the code generation of data structures
28
28
interface
29
29
 
30
30
    uses
31
 
{$ifdef Delphi}
32
 
       dmisc,
33
 
{$endif}
34
31
       cutils,cclasses,
35
32
       globtype,
36
 
       symdef,
37
 
       aasmbase,aasmtai,
38
 
       cpuinfo
 
33
       symdef,symsym,
 
34
       aasmbase,aasmtai
39
35
       ;
40
36
 
41
37
    type
50
46
      tprocdefcoll = record
51
47
         data    : tprocdef;
52
48
         hidden  : boolean;
 
49
         visible : boolean;
53
50
         next    : pprocdefcoll;
54
51
      end;
55
52
 
56
 
      psymcoll = ^tsymcoll;
57
 
      tsymcoll = record
58
 
         speedvalue : cardinal;
59
 
         name : pstring;
60
 
         data : pprocdefcoll;
61
 
         next : psymcoll;
 
53
      pvmtentry = ^tvmtentry;
 
54
      tvmtentry = record
 
55
         speedvalue   : cardinal;
 
56
         name         : pstring;
 
57
         firstprocdef : pprocdefcoll;
 
58
         next         : pvmtentry;
62
59
      end;
63
60
 
64
61
      tclassheader=class
65
62
      private
66
63
        _Class : tobjectdef;
67
 
        count  : integer;
68
64
      private
69
65
        { message tables }
70
66
        root : pprocdeftree;
71
67
        procedure disposeprocdeftree(p : pprocdeftree);
72
68
        procedure insertmsgint(p : tnamedindexitem;arg:pointer);
73
69
        procedure insertmsgstr(p : tnamedindexitem;arg:pointer);
74
 
        procedure insertint(p : pprocdeftree;var at : pprocdeftree);
75
 
        procedure insertstr(p : pprocdeftree;var at : pprocdeftree);
 
70
        procedure insertint(p : pprocdeftree;var at : pprocdeftree;var count:longint);
 
71
        procedure insertstr(p : pprocdeftree;var at : pprocdeftree;var count:longint);
76
72
        procedure writenames(p : pprocdeftree);
77
73
        procedure writeintentry(p : pprocdeftree);
78
74
        procedure writestrentry(p : pprocdeftree);
85
81
{$endif}
86
82
      private
87
83
        { published methods }
88
 
        procedure do_count(p : tnamedindexitem;arg:pointer);
89
 
        procedure genpubmethodtableentry(p : tnamedindexitem;arg:pointer);
 
84
        procedure do_count_published_methods(p : tnamedindexitem;arg:pointer);
 
85
        procedure do_gen_published_methods(p : tnamedindexitem;arg:pointer);
90
86
      private
91
87
        { vmt }
92
 
        wurzel : psymcoll;
93
 
        nextvirtnumber : integer;
 
88
        firstvmtentry      : pvmtentry;
 
89
        nextvirtnumber     : integer;
94
90
        has_constructor,
95
91
        has_virtual_method : boolean;
 
92
        procedure newdefentry(vmtentry:pvmtentry;pd:tprocdef;is_visible:boolean);
 
93
        function  newvmtentry(sym:tprocsym):pvmtentry;
96
94
        procedure eachsym(sym : tnamedindexitem;arg:pointer);
97
95
        procedure disposevmttree;
98
96
        procedure writevirtualmethods(List:TAAsmoutput);
99
97
      private
100
98
        { interface tables }
101
99
        function  gintfgetvtbllabelname(intfindex: integer): string;
102
 
        procedure gintfcreatevtbl(intfindex: integer; rawdata,rawcode: TAAsmoutput);
 
100
        procedure gintfcreatevtbl(intfindex: integer; rawdata: TAAsmoutput);
103
101
        procedure gintfgenentry(intfindex, contintfindex: integer; rawdata: TAAsmoutput);
104
 
        procedure gintfoptimizevtbls(implvtbl : plongintarray);
 
102
        procedure gintfoptimizevtbls;
105
103
        procedure gintfwritedata;
106
104
        function  gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef;
107
105
        procedure gintfdoonintf(intf: tobjectdef; intfindex: longint);
108
106
        procedure gintfwalkdowninterface(intf: tobjectdef; intfindex: longint);
109
 
      protected
110
 
        { adjusts the self value with ioffset when casting a interface
111
 
          to a class
112
 
        }
113
 
        procedure adjustselfvalue(procdef: tprocdef;ioffset: aword);virtual;
114
 
        { generates the wrapper for a call to a method via an interface }
115
 
        procedure cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract;
116
107
      public
117
108
        constructor create(c:tobjectdef);
118
109
        destructor destroy;override;
133
124
        procedure writeinterfaceids;
134
125
      end;
135
126
 
136
 
      tclassheaderclass=class of tclassheader;
137
 
 
138
 
    var
139
 
      cclassheader : tclassheaderclass;
140
 
 
141
127
 
142
128
implementation
143
129
 
144
130
    uses
145
 
{$ifdef delphi}
146
 
       sysutils,
147
 
{$else}
148
131
       strings,
149
 
{$endif}
150
 
       globals,verbose,
151
 
       symtable,symconst,symtype,symsym,defcmp,paramgr,
 
132
       globals,verbose,systems,
 
133
       symtable,symconst,symtype,defcmp
152
134
{$ifdef GDB}
153
 
       gdb,
 
135
       ,gdb
154
136
{$endif GDB}
155
 
       aasmcpu,
156
 
       cpubase,cgbase,
157
 
       cgutils,cgobj
158
137
       ;
159
138
 
160
139
 
189
168
      end;
190
169
 
191
170
 
192
 
    procedure tclassheader.insertint(p : pprocdeftree;var at : pprocdeftree);
 
171
    procedure tclassheader.insertint(p : pprocdeftree;var at : pprocdeftree;var count:longint);
193
172
 
194
173
      begin
195
174
         if at=nil then
200
179
         else
201
180
           begin
202
181
              if p^.data.messageinf.i<at^.data.messageinf.i then
203
 
                insertint(p,at^.l)
 
182
                insertint(p,at^.l,count)
204
183
              else if p^.data.messageinf.i>at^.data.messageinf.i then
205
 
                insertint(p,at^.r)
 
184
                insertint(p,at^.r,count)
206
185
              else
207
186
                Message1(parser_e_duplicate_message_label,tostr(p^.data.messageinf.i));
208
187
           end;
209
188
      end;
210
189
 
211
 
    procedure tclassheader.insertstr(p : pprocdeftree;var at : pprocdeftree);
 
190
    procedure tclassheader.insertstr(p : pprocdeftree;var at : pprocdeftree;var count:longint);
212
191
 
213
192
      var
214
193
         i : integer;
223
202
           begin
224
203
              i:=strcomp(p^.data.messageinf.str,at^.data.messageinf.str);
225
204
              if i<0 then
226
 
                insertstr(p,at^.l)
 
205
                insertstr(p,at^.l,count)
227
206
              else if i>0 then
228
 
                insertstr(p,at^.r)
 
207
                insertstr(p,at^.r,count)
229
208
              else
230
209
                Message1(parser_e_duplicate_message_label,strpas(p^.data.messageinf.str));
231
210
           end;
249
228
                    pt^.data:=def;
250
229
                    pt^.l:=nil;
251
230
                    pt^.r:=nil;
252
 
                    insertint(pt,root);
 
231
                    insertint(pt,root,plongint(arg)^);
253
232
                  end;
254
233
              end;
255
234
      end;
272
251
                    pt^.data:=def;
273
252
                    pt^.l:=nil;
274
253
                    pt^.r:=nil;
275
 
                    insertstr(pt,root);
 
254
                    insertstr(pt,root,plongint(arg)^);
276
255
                  end;
277
256
              end;
278
257
      end;
285
264
         objectlibrary.getdatalabel(p^.nl);
286
265
         if assigned(p^.l) then
287
266
           writenames(p^.l);
288
 
         datasegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
267
         datasegment.concat(cai_align.create(const_align(sizeof(aint))));
289
268
         dataSegment.concat(Tai_label.Create(p^.nl));
290
269
         len:=strlen(p^.data.messageinf.str);
291
270
         datasegment.concat(tai_const.create_8bit(len));
303
282
           writestrentry(p^.l);
304
283
 
305
284
         { write name label }
306
 
         dataSegment.concat(Tai_const_symbol.Create(p^.nl));
307
 
         dataSegment.concat(Tai_const_symbol.Createname(p^.data.mangledname,AT_FUNCTION,0));
 
285
         dataSegment.concat(Tai_const.Create_sym(p^.nl));
 
286
         dataSegment.concat(Tai_const.Createname(p^.data.mangledname,AT_FUNCTION,0));
308
287
 
309
288
         if assigned(p^.r) then
310
289
           writestrentry(p^.r);
314
293
    function tclassheader.genstrmsgtab : tasmlabel;
315
294
      var
316
295
         r : tasmlabel;
 
296
         count : longint;
317
297
      begin
318
298
         root:=nil;
319
299
         count:=0;
320
300
         { insert all message handlers into a tree, sorted by name }
321
 
         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgstr,nil);
 
301
         _class.symtable.foreach(@insertmsgstr,@count);
322
302
 
323
303
         { write all names }
324
304
         if assigned(root) then
326
306
 
327
307
         { now start writing of the message string table }
328
308
         objectlibrary.getdatalabel(r);
329
 
         datasegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
309
         datasegment.concat(cai_align.create(const_align(sizeof(aint))));
330
310
         dataSegment.concat(Tai_label.Create(r));
331
311
         genstrmsgtab:=r;
332
312
         dataSegment.concat(Tai_const.Create_32bit(count));
345
325
 
346
326
         { write name label }
347
327
         dataSegment.concat(Tai_const.Create_32bit(p^.data.messageinf.i));
348
 
         dataSegment.concat(Tai_const_symbol.Createname(p^.data.mangledname,AT_FUNCTION,0));
 
328
         dataSegment.concat(Tai_const.Createname(p^.data.mangledname,AT_FUNCTION,0));
349
329
 
350
330
         if assigned(p^.r) then
351
331
           writeintentry(p^.r);
355
335
    function tclassheader.genintmsgtab : tasmlabel;
356
336
      var
357
337
         r : tasmlabel;
 
338
         count : longint;
358
339
      begin
359
340
         root:=nil;
360
341
         count:=0;
361
342
         { insert all message handlers into a tree, sorted by name }
362
 
         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgint,nil);
 
343
         _class.symtable.foreach(@insertmsgint,@count);
363
344
 
364
345
         { now start writing of the message string table }
365
346
         objectlibrary.getdatalabel(r);
366
 
         datasegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
347
         datasegment.concat(cai_align.create(const_align(sizeof(aint))));
367
348
         dataSegment.concat(Tai_label.Create(r));
368
349
         genintmsgtab:=r;
369
350
         dataSegment.concat(Tai_const.Create_32bit(count));
435
416
         count:=0;
436
417
         gendmt:=nil;
437
418
         { insert all message handlers into a tree, sorted by number }
438
 
         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertdmtentry);
 
419
         _class.symtable.foreach(insertdmtentry);
439
420
 
440
421
         if count>0 then
441
422
           begin
442
423
              objectlibrary.getdatalabel(r);
443
424
              gendmt:=r;
444
 
              datasegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
425
              datasegment.concat(cai_align.create(const_align(sizeof(aint))));
445
426
              dataSegment.concat(Tai_label.Create(r));
446
427
              { entries for caching }
447
428
              dataSegment.concat(Tai_const.Create_ptr(0));
463
444
        Published Methods
464
445
**************************************}
465
446
 
466
 
    procedure tclassheader.do_count(p : tnamedindexitem;arg:pointer);
467
 
 
468
 
      begin
469
 
         if (tsym(p).typ=procsym) and (sp_published in tsym(p).symoptions) then
470
 
           inc(count);
471
 
      end;
472
 
 
473
 
    procedure tclassheader.genpubmethodtableentry(p : tnamedindexitem;arg:pointer);
474
 
 
475
 
      var
476
 
         hp : tprocdef;
477
 
         l : tasmlabel;
478
 
 
479
 
      begin
480
 
         if (tsym(p).typ=procsym) and (sp_published in tsym(p).symoptions) then
481
 
           begin
482
 
              if Tprocsym(p).procdef_count>1 then
483
 
                internalerror(1209992);
484
 
              hp:=tprocsym(p).first_procdef;
485
 
              objectlibrary.getdatalabel(l);
486
 
 
487
 
              consts.concat(tai_align.create(const_align(POINTER_SIZE)));
488
 
              Consts.concat(Tai_label.Create(l));
489
 
              Consts.concat(Tai_const.Create_8bit(length(p.name)));
490
 
              Consts.concat(Tai_string.Create(p.name));
491
 
 
492
 
              dataSegment.concat(Tai_const_symbol.Create(l));
493
 
              dataSegment.concat(Tai_const_symbol.Createname(hp.mangledname,AT_FUNCTION,0));
494
 
           end;
495
 
      end;
 
447
    procedure tclassheader.do_count_published_methods(p : tnamedindexitem;arg:pointer);
 
448
      var
 
449
        i : longint;
 
450
        pd : tprocdef;
 
451
      begin
 
452
         if (tsym(p).typ=procsym) then
 
453
           begin
 
454
             for i:=1 to tprocsym(p).procdef_count do
 
455
               begin
 
456
                 pd:=tprocsym(p).procdef[i];
 
457
                 if (pd.procsym=tsym(p)) and
 
458
                    (sp_published in pd.symoptions) then
 
459
                   inc(plongint(arg)^);
 
460
                end;
 
461
           end;
 
462
      end;
 
463
 
 
464
 
 
465
    procedure tclassheader.do_gen_published_methods(p : tnamedindexitem;arg:pointer);
 
466
      var
 
467
        i  : longint;
 
468
        l  : tasmlabel;
 
469
        pd : tprocdef;
 
470
      begin
 
471
         if (tsym(p).typ=procsym) then
 
472
           begin
 
473
             for i:=1 to tprocsym(p).procdef_count do
 
474
               begin
 
475
                 pd:=tprocsym(p).procdef[i];
 
476
                 if (pd.procsym=tsym(p)) and
 
477
                    (sp_published in pd.symoptions) then
 
478
                   begin
 
479
                     objectlibrary.getdatalabel(l);
 
480
 
 
481
                     consts.concat(cai_align.create(const_align(sizeof(aint))));
 
482
                     Consts.concat(Tai_label.Create(l));
 
483
                     Consts.concat(Tai_const.Create_8bit(length(tsym(p).realname)));
 
484
                     Consts.concat(Tai_string.Create(tsym(p).realname));
 
485
 
 
486
                     dataSegment.concat(Tai_const.Create_sym(l));
 
487
                     if po_abstractmethod in pd.procoptions then
 
488
                       dataSegment.concat(Tai_const.Create_sym(nil))
 
489
                     else
 
490
                       dataSegment.concat(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0));
 
491
                   end;
 
492
                end;
 
493
           end;
 
494
      end;
 
495
 
496
496
 
497
497
    function tclassheader.genpublishedmethodstable : tasmlabel;
498
498
 
499
499
      var
500
500
         l : tasmlabel;
 
501
         count : longint;
501
502
 
502
503
      begin
503
504
         count:=0;
504
 
         _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}do_count,nil);
 
505
         _class.symtable.foreach(@do_count_published_methods,@count);
505
506
         if count>0 then
506
507
           begin
507
508
              objectlibrary.getdatalabel(l);
508
 
              datasegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
509
              datasegment.concat(cai_align.create(const_align(sizeof(aint))));
509
510
              dataSegment.concat(Tai_label.Create(l));
510
511
              dataSegment.concat(Tai_const.Create_32bit(count));
511
 
              _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}genpubmethodtableentry,nil);
 
512
              _class.symtable.foreach(@do_gen_published_methods,nil);
512
513
              genpublishedmethodstable:=l;
513
514
           end
514
515
         else
520
521
               VMT
521
522
**************************************}
522
523
 
 
524
 
 
525
    procedure tclassheader.newdefentry(vmtentry:pvmtentry;pd:tprocdef;is_visible:boolean);
 
526
      var
 
527
        procdefcoll : pprocdefcoll;
 
528
      begin
 
529
        if (_class=pd._class) then
 
530
          begin
 
531
            { new entry is needed, override was not possible }
 
532
            if (po_overridingmethod in pd.procoptions) then
 
533
              MessagePos1(pd.fileinfo,parser_e_nothing_to_be_overridden,pd.fullprocname(false));
 
534
 
 
535
            { check that all methods have overload directive }
 
536
            if not(m_fpc in aktmodeswitches) then
 
537
              begin
 
538
                procdefcoll:=vmtentry^.firstprocdef;
 
539
                while assigned(procdefcoll) do
 
540
                  begin
 
541
                    if (procdefcoll^.data._class=pd._class) and
 
542
                       ((po_overload in pd.procoptions)<>(po_overload in procdefcoll^.data.procoptions)) then
 
543
                      begin
 
544
                        MessagePos1(pd.fileinfo,parser_e_no_overload_for_all_procs,pd.procsym.realname);
 
545
                        { recover }
 
546
                        include(procdefcoll^.data.procoptions,po_overload);
 
547
                        include(pd.procoptions,po_overload);
 
548
                      end;
 
549
                    procdefcoll:=procdefcoll^.next;
 
550
                  end;
 
551
              end;
 
552
          end;
 
553
 
 
554
        { generate new entry }
 
555
        new(procdefcoll);
 
556
        procdefcoll^.data:=pd;
 
557
        procdefcoll^.hidden:=false;
 
558
        procdefcoll^.visible:=is_visible;
 
559
        procdefcoll^.next:=vmtentry^.firstprocdef;
 
560
        vmtentry^.firstprocdef:=procdefcoll;
 
561
 
 
562
        { give virtual method a number }
 
563
        if (po_virtualmethod in pd.procoptions) then
 
564
          begin
 
565
             pd.extnumber:=nextvirtnumber;
 
566
             inc(nextvirtnumber);
 
567
             has_virtual_method:=true;
 
568
          end;
 
569
 
 
570
        if (pd.proctypeoption=potype_constructor) then
 
571
          has_constructor:=true;
 
572
      end;
 
573
 
 
574
 
 
575
    function tclassheader.newvmtentry(sym:tprocsym):pvmtentry;
 
576
      begin
 
577
        { generate new vmtentry }
 
578
        new(result);
 
579
        result^.speedvalue:=sym.speedvalue;
 
580
        result^.name:=stringdup(sym.name);
 
581
        result^.next:=firstvmtentry;
 
582
        result^.firstprocdef:=nil;
 
583
        firstvmtentry:=result;
 
584
      end;
 
585
 
 
586
 
523
587
    procedure tclassheader.eachsym(sym : tnamedindexitem;arg:pointer);
524
 
 
525
 
      var
526
 
         procdefcoll : pprocdefcoll;
527
 
         symcoll : psymcoll;
528
 
         _name : string;
529
 
         _speed : cardinal;
530
 
 
531
 
      procedure newdefentry(pd:tprocdef);
532
 
        begin
533
 
           new(procdefcoll);
534
 
           procdefcoll^.data:=pd;
535
 
           procdefcoll^.hidden:=false;
536
 
           procdefcoll^.next:=symcoll^.data;
537
 
           symcoll^.data:=procdefcoll;
538
 
 
539
 
           { if it's a virtual method }
540
 
           if (po_virtualmethod in pd.procoptions) then
541
 
             begin
542
 
                { then it gets a number ... }
543
 
                pd.extnumber:=nextvirtnumber;
544
 
                { and we inc the number }
545
 
                inc(nextvirtnumber);
546
 
                has_virtual_method:=true;
547
 
             end;
548
 
 
549
 
           if (pd.proctypeoption=potype_constructor) then
550
 
             has_constructor:=true;
551
 
 
552
 
           { check, if a method should be overridden }
553
 
           if (pd._class=_class) and
554
 
              (po_overridingmethod in pd.procoptions) then
555
 
             MessagePos1(pd.fileinfo,parser_e_nothing_to_be_overridden,pd.fullprocname(false));
556
 
        end;
557
 
 
558
 
      { creates a new entry in the procsym list }
559
 
      procedure newentry;
560
 
 
561
 
        var i:cardinal;
562
 
 
563
 
        begin
564
 
           { if not, generate a new symbol item }
565
 
           new(symcoll);
566
 
           symcoll^.speedvalue:=sym.speedvalue;
567
 
           symcoll^.name:=stringdup(sym.name);
568
 
           symcoll^.next:=wurzel;
569
 
           symcoll^.data:=nil;
570
 
           wurzel:=symcoll;
571
 
 
572
 
           { inserts all definitions }
573
 
           for i:=1 to Tprocsym(sym).procdef_count do
574
 
              newdefentry(Tprocsym(sym).procdef[i]);
575
 
        end;
576
 
 
 
588
      const
 
589
        po_comp = [po_classmethod,po_virtualmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint,
 
590
                   po_exports,po_varargs,po_explicitparaloc,po_nostackframe];
577
591
      label
578
592
         handlenextdef;
579
593
      var
582
596
         is_visible,
583
597
         hasoverloads,
584
598
         pdoverload : boolean;
 
599
         procdefcoll : pprocdefcoll;
 
600
         vmtentry : pvmtentry;
 
601
         _name : string;
 
602
         _speed : cardinal;
585
603
      begin
586
 
         { put only sub routines into the VMT, and routines
587
 
           that are visible to the current class. Skip private
588
 
           methods in other classes }
589
 
         if (tsym(sym).typ=procsym) then
590
 
           begin
591
 
              { is this symbol visible from the class that we are
592
 
                generating. This will be used to hide the other procdefs.
593
 
                When the symbol is not visible we don't hide the other
594
 
                procdefs, because they can be reused in the next class.
595
 
                The check to skip the invisible methods that are in the
596
 
                list is futher down in the code }
597
 
              is_visible:=tprocsym(sym).is_visible_for_object(_class);
598
 
              { check the current list of symbols }
599
 
              _name:=sym.name;
600
 
              _speed:=sym.speedvalue;
601
 
              symcoll:=wurzel;
602
 
              while assigned(symcoll) do
603
 
               begin
604
 
                 { does the symbol already exist in the list? First
605
 
                   compare speedvalue before doing the string compare to
606
 
                   speed it up a little }
607
 
                 if (_speed=symcoll^.speedvalue) and
608
 
                    (_name=symcoll^.name^) then
 
604
        if (tsym(sym).typ<>procsym) then
 
605
          exit;
 
606
 
 
607
        { check the current list of symbols }
 
608
        _name:=sym.name;
 
609
        _speed:=sym.speedvalue;
 
610
        vmtentry:=firstvmtentry;
 
611
        while assigned(vmtentry) do
 
612
         begin
 
613
           { does the symbol already exist in the list? First
 
614
             compare speedvalue before doing the string compare to
 
615
             speed it up a little }
 
616
           if (_speed=vmtentry^.speedvalue) and
 
617
              (_name=vmtentry^.name^) then
 
618
            begin
 
619
              hasoverloads:=(Tprocsym(sym).procdef_count>1);
 
620
              { walk through all defs of the symbol }
 
621
              for i:=1 to Tprocsym(sym).procdef_count do
 
622
                begin
 
623
                 pd:=Tprocsym(sym).procdef[i];
 
624
 
 
625
                 { is this procdef visible from the class that we are
 
626
                   generating. This will be used to hide the other procdefs.
 
627
                   When the symbol is not visible we don't hide the other
 
628
                   procdefs, because they can be reused in the next class.
 
629
                   The check to skip the invisible methods that are in the
 
630
                   list is futher down in the code }
 
631
                 is_visible:=pd.is_visible_for_object(_class);
 
632
 
 
633
                 if pd.procsym=sym then
609
634
                  begin
610
 
                    hasoverloads:=(Tprocsym(sym).procdef_count>1);
611
 
                    { walk through all defs of the symbol }
612
 
                    for i:=1 to Tprocsym(sym).procdef_count do
 
635
                    pdoverload:=(po_overload in pd.procoptions);
 
636
 
 
637
                    { compare with all stored definitions }
 
638
                    procdefcoll:=vmtentry^.firstprocdef;
 
639
                    while assigned(procdefcoll) do
613
640
                      begin
614
 
                       pd:=Tprocsym(sym).procdef[i];
615
 
                       if pd.procsym=sym then
616
 
                        begin
617
 
                          pdoverload:=(po_overload in pd.procoptions);
618
 
 
619
 
                          { compare with all stored definitions }
620
 
                          procdefcoll:=symcoll^.data;
621
 
                          while assigned(procdefcoll) do
622
 
                            begin
623
 
                               { compare only if the definition is not hidden }
624
 
                               if not procdefcoll^.hidden then
625
 
                                begin
626
 
                                  { check that all methods have overload directive }
627
 
                                  if not(m_fpc in aktmodeswitches) and
628
 
                                     (_class=pd._class) and
629
 
                                     (procdefcoll^.data._class=pd._class) and
630
 
                                     ((po_overload in pd.procoptions)<>(po_overload in procdefcoll^.data.procoptions)) then
631
 
                                    begin
632
 
                                      MessagePos1(pd.fileinfo,parser_e_no_overload_for_all_procs,pd.procsym.realname);
633
 
                                      { recover }
634
 
                                      include(procdefcoll^.data.procoptions,po_overload);
 
641
                         { compare only if the definition is not hidden }
 
642
                         if not procdefcoll^.hidden then
 
643
                          begin
 
644
                            { check if one of the two methods has virtual }
 
645
                            if (po_virtualmethod in procdefcoll^.data.procoptions) or
 
646
                               (po_virtualmethod in pd.procoptions) then
 
647
                             begin
 
648
                               { if the current definition has no virtual then hide the
 
649
                                 old virtual if the new definition has the same arguments or
 
650
                                 when it has no overload directive and no overloads }
 
651
                               if not(po_virtualmethod in pd.procoptions) then
 
652
                                begin
 
653
                                  if procdefcoll^.visible and
 
654
                                     (not(pdoverload or hasoverloads) or
 
655
                                      (compare_paras(procdefcoll^.data.paras,pd.paras,cp_all,[])>=te_equal)) then
 
656
                                   begin
 
657
                                     if is_visible then
 
658
                                       procdefcoll^.hidden:=true;
 
659
                                     if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
 
660
                                       MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
 
661
                                   end;
 
662
                                end
 
663
                               { if both are virtual we check the header }
 
664
                               else if (po_virtualmethod in pd.procoptions) and
 
665
                                       (po_virtualmethod in procdefcoll^.data.procoptions) then
 
666
                                begin
 
667
                                  { new one has not override }
 
668
                                  if is_class(_class) and
 
669
                                     not(po_overridingmethod in pd.procoptions) then
 
670
                                   begin
 
671
                                     { we start a new virtual tree, hide the old }
 
672
                                     if (not(pdoverload or hasoverloads) or
 
673
                                         (compare_paras(procdefcoll^.data.paras,pd.paras,cp_all,[])>=te_equal)) and
 
674
                                        (procdefcoll^.visible) then
 
675
                                      begin
 
676
                                        if is_visible then
 
677
                                          procdefcoll^.hidden:=true;
 
678
                                        if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
 
679
                                          MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
 
680
                                      end;
 
681
                                   end
 
682
                                  { same parameters }
 
683
                                  else if (compare_paras(procdefcoll^.data.paras,pd.paras,cp_all,[])>=te_equal) then
 
684
                                   begin
 
685
                                     { overload is inherited }
 
686
                                     if (po_overload in procdefcoll^.data.procoptions) then
635
687
                                      include(pd.procoptions,po_overload);
636
 
                                    end;
637
 
 
638
 
                                  { check if one of the two methods has virtual }
639
 
                                  if (po_virtualmethod in procdefcoll^.data.procoptions) or
640
 
                                     (po_virtualmethod in pd.procoptions) then
 
688
 
 
689
                                     { inherite calling convention when it was force and the
 
690
                                       current definition has none force }
 
691
                                     if (po_hascallingconvention in procdefcoll^.data.procoptions) and
 
692
                                        not(po_hascallingconvention in pd.procoptions) then
 
693
                                       begin
 
694
                                         pd.proccalloption:=procdefcoll^.data.proccalloption;
 
695
                                         include(pd.procoptions,po_hascallingconvention);
 
696
                                       end;
 
697
 
 
698
                                     { the flags have to match except abstract and override }
 
699
                                     { only if both are virtual !!  }
 
700
                                     if (procdefcoll^.data.proccalloption<>pd.proccalloption) or
 
701
                                        (procdefcoll^.data.proctypeoption<>pd.proctypeoption) or
 
702
                                        ((procdefcoll^.data.procoptions*po_comp)<>(pd.procoptions*po_comp)) then
 
703
                                        begin
 
704
                                          MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,pd.fullprocname(false));
 
705
                                          tprocsym(procdefcoll^.data.procsym).write_parameter_lists(pd);
 
706
                                        end;
 
707
 
 
708
                                     { error, if the return types aren't equal }
 
709
                                     if not(equal_defs(procdefcoll^.data.rettype.def,pd.rettype.def)) and
 
710
                                        not((procdefcoll^.data.rettype.def.deftype=objectdef) and
 
711
                                         (pd.rettype.def.deftype=objectdef) and
 
712
                                         is_class(procdefcoll^.data.rettype.def) and
 
713
                                         is_class(pd.rettype.def) and
 
714
                                         (tobjectdef(pd.rettype.def).is_related(
 
715
                                             tobjectdef(procdefcoll^.data.rettype.def)))) then
 
716
                                       Message2(parser_e_overridden_methods_not_same_ret,pd.fullprocname(false),
 
717
                                                procdefcoll^.data.fullprocname(false));
 
718
 
 
719
                                     { check if the method to override is visible, check is only needed
 
720
                                       for the current parsed class. Parent classes are already validated and
 
721
                                       need to include all virtual methods including the ones not visible in the
 
722
                                       current class }
 
723
                                     if (_class=pd._class) and
 
724
                                        (po_overridingmethod in pd.procoptions) and
 
725
                                        (not procdefcoll^.visible) then
 
726
                                       MessagePos1(pd.fileinfo,parser_e_nothing_to_be_overridden,pd.fullprocname(false));
 
727
 
 
728
                                     { override old virtual method in VMT }
 
729
                                     pd.extnumber:=procdefcoll^.data.extnumber;
 
730
                                     procdefcoll^.data:=pd;
 
731
                                     if is_visible then
 
732
                                       procdefcoll^.visible:=true;
 
733
 
 
734
                                     goto handlenextdef;
 
735
                                   end
 
736
                                  { different parameters }
 
737
                                  else
641
738
                                   begin
642
 
                                     { if the current definition has no virtual then hide the
643
 
                                       old virtual if the new definition has the same arguments or
644
 
                                       when it has no overload directive and no overloads }
645
 
                                     if not(po_virtualmethod in pd.procoptions) then
646
 
                                      begin
647
 
                                        if tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class) and
648
 
                                           (not(pdoverload or hasoverloads) or
649
 
                                            (compare_paras(procdefcoll^.data.para,pd.para,cp_all,[])>=te_equal)) then
650
 
                                         begin
651
 
                                           if is_visible then
652
 
                                             procdefcoll^.hidden:=true;
653
 
                                           if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
654
 
                                             MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
655
 
                                         end;
656
 
                                      end
657
 
                                     { if both are virtual we check the header }
658
 
                                     else if (po_virtualmethod in pd.procoptions) and
659
 
                                             (po_virtualmethod in procdefcoll^.data.procoptions) then
660
 
                                      begin
661
 
                                        { new one has not override }
662
 
                                        if is_class(_class) and
663
 
                                           not(po_overridingmethod in pd.procoptions) then
664
 
                                         begin
665
 
                                           { we start a new virtual tree, hide the old }
666
 
                                           if (not(pdoverload or hasoverloads) or
667
 
                                               (compare_paras(procdefcoll^.data.para,pd.para,cp_all,[])>=te_equal)) and
668
 
                                              (tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class)) then
669
 
                                            begin
670
 
                                              if is_visible then
671
 
                                                procdefcoll^.hidden:=true;
672
 
                                              if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
673
 
                                                MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
674
 
                                            end;
675
 
                                         end
676
 
                                        { check if the method to override is visible }
677
 
                                        else if (po_overridingmethod in pd.procoptions) and
678
 
                                                (not tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class)) then
679
 
                                         begin
680
 
                                           { do nothing, the error will follow when adding the entry }
681
 
                                         end
682
 
                                        { same parameters }
683
 
                                        else if (compare_paras(procdefcoll^.data.para,pd.para,cp_all,[])>=te_equal) then
684
 
                                         begin
685
 
                                           { overload is inherited }
686
 
                                           if (po_overload in procdefcoll^.data.procoptions) then
687
 
                                            include(pd.procoptions,po_overload);
688
 
 
689
 
                                           { inherite calling convention when it was force and the
690
 
                                             current definition has none force }
691
 
                                           if (po_hascallingconvention in procdefcoll^.data.procoptions) and
692
 
                                              not(po_hascallingconvention in pd.procoptions) then
693
 
                                             begin
694
 
                                               pd.proccalloption:=procdefcoll^.data.proccalloption;
695
 
                                               include(pd.procoptions,po_hascallingconvention);
696
 
                                             end;
697
 
 
698
 
                                           { the flags have to match except abstract and override }
699
 
                                           { only if both are virtual !!  }
700
 
                                           if (procdefcoll^.data.proccalloption<>pd.proccalloption) or
701
 
                                               (procdefcoll^.data.proctypeoption<>pd.proctypeoption) or
702
 
                                               ((procdefcoll^.data.procoptions-
703
 
                                                   [po_abstractmethod,po_overridingmethod,po_assembler,po_overload,po_public,po_reintroduce])<>
704
 
                                                (pd.procoptions-[po_abstractmethod,po_overridingmethod,po_assembler,po_overload,po_public,po_reintroduce])) then
705
 
                                              begin
706
 
                                                MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,pd.fullprocname(false));
707
 
                                                tprocsym(procdefcoll^.data.procsym).write_parameter_lists(pd);
708
 
                                              end;
709
 
 
710
 
                                           { error, if the return types aren't equal }
711
 
                                           if not(equal_defs(procdefcoll^.data.rettype.def,pd.rettype.def)) and
712
 
                                              not((procdefcoll^.data.rettype.def.deftype=objectdef) and
713
 
                                               (pd.rettype.def.deftype=objectdef) and
714
 
                                               is_class(procdefcoll^.data.rettype.def) and
715
 
                                               is_class(pd.rettype.def) and
716
 
                                               (tobjectdef(pd.rettype.def).is_related(
717
 
                                                   tobjectdef(procdefcoll^.data.rettype.def)))) then
718
 
                                             Message2(parser_e_overridden_methods_not_same_ret,pd.fullprocname(false),
719
 
                                                      procdefcoll^.data.fullprocname(false));
720
 
 
721
 
                                           { now set the number }
722
 
                                           pd.extnumber:=procdefcoll^.data.extnumber;
723
 
                                           { and exchange }
724
 
                                           procdefcoll^.data:=pd;
725
 
                                           goto handlenextdef;
726
 
                                         end
727
 
                                        { different parameters }
728
 
                                        else
729
 
                                         begin
730
 
                                           { when we got an override directive then can search futher for
731
 
                                             the procedure to override.
732
 
                                             If we are starting a new virtual tree then hide the old tree }
733
 
                                           if not(po_overridingmethod in pd.procoptions) and
734
 
                                              not pdoverload then
735
 
                                            begin
736
 
                                              if is_visible then
737
 
                                                procdefcoll^.hidden:=true;
738
 
                                              if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
739
 
                                                MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
740
 
                                            end;
741
 
                                         end;
742
 
                                      end
743
 
                                     else
744
 
                                      begin
745
 
                                        { the new definition is virtual and the old static, we hide the old one
746
 
                                          if the new defintion has not the overload directive }
747
 
                                        if is_visible and
748
 
                                           ((not(pdoverload or hasoverloads)) or
749
 
                                            (compare_paras(procdefcoll^.data.para,pd.para,cp_all,[])>=te_equal)) then
 
739
                                     { when we got an override directive then can search futher for
 
740
                                       the procedure to override.
 
741
                                       If we are starting a new virtual tree then hide the old tree }
 
742
                                     if not(po_overridingmethod in pd.procoptions) and
 
743
                                        not pdoverload then
 
744
                                      begin
 
745
                                        if is_visible then
750
746
                                          procdefcoll^.hidden:=true;
 
747
                                        if (_class=pd._class) and not(po_reintroduce in pd.procoptions) then
 
748
                                          MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname(false));
751
749
                                      end;
752
 
                                   end
753
 
                                  else
754
 
                                   begin
755
 
                                     { both are static, we hide the old one if the new defintion
756
 
                                       has not the overload directive }
757
 
                                     if is_visible and
758
 
                                        ((not pdoverload) or
759
 
                                         (compare_paras(procdefcoll^.data.para,pd.para,cp_all,[])>=te_equal)) then
760
 
                                       procdefcoll^.hidden:=true;
761
750
                                   end;
762
 
                                end; { not hidden }
763
 
                               procdefcoll:=procdefcoll^.next;
764
 
                            end;
 
751
                                end
 
752
                               else
 
753
                                begin
 
754
                                  { the new definition is virtual and the old static, we hide the old one
 
755
                                    if the new defintion has not the overload directive }
 
756
                                  if is_visible and
 
757
                                     ((not(pdoverload or hasoverloads)) or
 
758
                                      (compare_paras(procdefcoll^.data.paras,pd.paras,cp_all,[])>=te_equal)) then
 
759
                                    procdefcoll^.hidden:=true;
 
760
                                end;
 
761
                             end
 
762
                            else
 
763
                             begin
 
764
                               { both are static, we hide the old one if the new defintion
 
765
                                 has not the overload directive }
 
766
                               if is_visible and
 
767
                                  ((not pdoverload) or
 
768
                                   (compare_paras(procdefcoll^.data.paras,pd.paras,cp_all,[])>=te_equal)) then
 
769
                                 procdefcoll^.hidden:=true;
 
770
                             end;
 
771
                          end; { not hidden }
 
772
                         procdefcoll:=procdefcoll^.next;
 
773
                      end;
765
774
 
766
 
                          { if it isn't saved in the list we create a new entry }
767
 
                          newdefentry(pd);
768
 
                        end;
769
 
                     handlenextdef:
770
 
                     end;
771
 
                    exit;
 
775
                    { if it isn't saved in the list we create a new entry }
 
776
                    newdefentry(vmtentry,pd,is_visible);
772
777
                  end;
773
 
                 symcoll:=symcoll^.next;
 
778
                  handlenextdef:
774
779
               end;
775
 
             newentry;
776
 
           end;
777
 
      end;
778
 
 
779
 
     procedure tclassheader.disposevmttree;
780
 
 
781
 
       var
782
 
          symcoll : psymcoll;
783
 
          procdefcoll : pprocdefcoll;
784
 
 
785
 
       begin
786
 
          { disposes the above generated tree }
787
 
          symcoll:=wurzel;
788
 
          while assigned(symcoll) do
789
 
            begin
790
 
               wurzel:=symcoll^.next;
791
 
               stringdispose(symcoll^.name);
792
 
               procdefcoll:=symcoll^.data;
793
 
               while assigned(procdefcoll) do
794
 
                 begin
795
 
                    symcoll^.data:=procdefcoll^.next;
796
 
                    dispose(procdefcoll);
797
 
                    procdefcoll:=symcoll^.data;
798
 
                 end;
799
 
               dispose(symcoll);
800
 
               symcoll:=wurzel;
 
780
              exit;
801
781
            end;
802
 
       end;
 
782
           vmtentry:=vmtentry^.next;
 
783
         end;
 
784
 
 
785
        { Generate new procsym entry in vmt }
 
786
        vmtentry:=newvmtentry(tprocsym(sym));
 
787
 
 
788
        { Add procdefs }
 
789
        for i:=1 to Tprocsym(sym).procdef_count do
 
790
          begin
 
791
            pd:=Tprocsym(sym).procdef[i];
 
792
            newdefentry(vmtentry,pd,pd.is_visible_for_object(_class));
 
793
          end;
 
794
      end;
 
795
 
 
796
 
 
797
    procedure tclassheader.disposevmttree;
 
798
      var
 
799
        vmtentry : pvmtentry;
 
800
        procdefcoll : pprocdefcoll;
 
801
      begin
 
802
        { disposes the above generated tree }
 
803
        vmtentry:=firstvmtentry;
 
804
        while assigned(vmtentry) do
 
805
          begin
 
806
            firstvmtentry:=vmtentry^.next;
 
807
            stringdispose(vmtentry^.name);
 
808
            procdefcoll:=vmtentry^.firstprocdef;
 
809
            while assigned(procdefcoll) do
 
810
              begin
 
811
                vmtentry^.firstprocdef:=procdefcoll^.next;
 
812
                dispose(procdefcoll);
 
813
                procdefcoll:=vmtentry^.firstprocdef;
 
814
              end;
 
815
            dispose(vmtentry);
 
816
            vmtentry:=firstvmtentry;
 
817
          end;
 
818
      end;
803
819
 
804
820
 
805
821
    procedure tclassheader.genvmt;
812
828
             do_genvmt(p.childof);
813
829
 
814
830
           { walk through all public syms }
815
 
           p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym,nil);
 
831
           p.symtable.foreach(@eachsym,nil);
816
832
        end;
817
833
 
818
834
      begin
819
 
         wurzel:=nil;
 
835
         firstvmtentry:=nil;
820
836
         nextvirtnumber:=0;
821
837
 
822
838
         has_constructor:=false;
843
859
      end;
844
860
 
845
861
 
846
 
    procedure tclassheader.gintfcreatevtbl(intfindex: integer; rawdata,rawcode: TAAsmoutput);
 
862
    procedure tclassheader.gintfcreatevtbl(intfindex: integer; rawdata: TAAsmoutput);
847
863
      var
848
864
        implintf: timplementedinterfaces;
849
865
        curintf: tobjectdef;
853
869
      begin
854
870
        implintf:=_class.implementedinterfaces;
855
871
        curintf:=implintf.interfaces(intfindex);
856
 
        rawdata.concat(tai_align.create(const_align(POINTER_SIZE)));
857
 
        if (cs_create_smart in aktmoduleswitches) then
 
872
        rawdata.concat(cai_align.create(const_align(sizeof(aint))));
 
873
        if maybe_smartlink_symbol then
858
874
         rawdata.concat(Tai_symbol.Createname_global(gintfgetvtbllabelname(intfindex),AT_DATA ,0))
859
875
        else
860
876
         rawdata.concat(Tai_symbol.Createname(gintfgetvtbllabelname(intfindex),AT_DATA,0));
864
880
            tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+curintf.objname^+'_$_'+
865
881
              tostr(i)+'_$_'+
866
882
              implintf.implprocs(intfindex,i).mangledname);
867
 
            { create wrapper code }
868
 
            cgintfwrapper(rawcode,implintf.implprocs(intfindex,i),tmps,implintf.ioffsets(intfindex)^);
869
883
            { create reference }
870
 
            rawdata.concat(Tai_const_symbol.Createname(tmps,AT_FUNCTION,0));
 
884
            rawdata.concat(Tai_const.Createname(tmps,AT_FUNCTION,0));
871
885
          end;
872
886
      end;
873
887
 
886
900
          begin
887
901
            { label for GUID }
888
902
            objectlibrary.getdatalabel(tmplabel);
889
 
            rawdata.concat(tai_align.create(const_align(pointer_size)));
 
903
            rawdata.concat(cai_align.create(const_align(sizeof(aint))));
890
904
            rawdata.concat(Tai_label.Create(tmplabel));
891
905
            rawdata.concat(Tai_const.Create_32bit(longint(curintf.iidguid^.D1)));
892
906
            rawdata.concat(Tai_const.Create_16bit(curintf.iidguid^.D2));
893
907
            rawdata.concat(Tai_const.Create_16bit(curintf.iidguid^.D3));
894
908
            for i:=Low(curintf.iidguid^.D4) to High(curintf.iidguid^.D4) do
895
909
              rawdata.concat(Tai_const.Create_8bit(curintf.iidguid^.D4[i]));
896
 
            dataSegment.concat(Tai_const_symbol.Create(tmplabel));
 
910
            dataSegment.concat(Tai_const.Create_sym(tmplabel));
897
911
          end
898
912
        else
899
913
          begin
900
914
            { nil for Corba interfaces }
901
 
            dataSegment.concat(Tai_const.Create_ptr(0)); { nil }
 
915
            dataSegment.concat(Tai_const.Create_sym(nil));
902
916
          end;
903
917
        { VTable }
904
 
        dataSegment.concat(Tai_const_symbol.Createname(gintfgetvtbllabelname(contintfindex),AT_DATA,0));
 
918
        dataSegment.concat(Tai_const.Createname(gintfgetvtbllabelname(contintfindex),AT_DATA,0));
905
919
        { IOffset field }
906
 
        dataSegment.concat(Tai_const.Create_32bit(implintf.ioffsets(contintfindex)^));
 
920
        dataSegment.concat(Tai_const.Create_32bit(implintf.ioffsets(contintfindex)));
907
921
        { IIDStr }
908
922
        objectlibrary.getdatalabel(tmplabel);
909
 
        rawdata.concat(tai_align.create(const_align(pointer_size)));
 
923
        rawdata.concat(cai_align.create(const_align(sizeof(aint))));
910
924
        rawdata.concat(Tai_label.Create(tmplabel));
911
925
        rawdata.concat(Tai_const.Create_8bit(length(curintf.iidstr^)));
912
926
        if curintf.objecttype=odt_interfacecom then
913
927
          rawdata.concat(Tai_string.Create(upper(curintf.iidstr^)))
914
928
        else
915
929
          rawdata.concat(Tai_string.Create(curintf.iidstr^));
916
 
        dataSegment.concat(Tai_const_symbol.Create(tmplabel));
 
930
        dataSegment.concat(Tai_const.Create_sym(tmplabel));
917
931
      end;
918
932
 
919
933
 
920
 
    procedure tclassheader.gintfoptimizevtbls(implvtbl : plongintarray);
 
934
    procedure tclassheader.gintfoptimizevtbls;
921
935
      type
922
936
        tcompintfentry = record
923
937
          weight: longint;
924
938
          compintf: longint;
925
939
        end;
926
940
        { Max 1000 interface in the class header interfaces it's enough imho }
927
 
        tcompintfs = packed array[1..1000] of tcompintfentry;
 
941
        tcompintfs = array[1..1000] of tcompintfentry;
928
942
        pcompintfs = ^tcompintfs;
929
 
        tequals    = packed array[1..1000] of longint;
 
943
        tequals    = array[1..1000] of longint;
930
944
        pequals    = ^tequals;
 
945
        timpls    = array[1..1000] of longint;
 
946
        pimpls    = ^timpls;
931
947
      var
932
948
        max: longint;
933
949
        equals: pequals;
934
950
        compats: pcompintfs;
935
 
        i: longint;
936
 
        j: longint;
937
 
        w: longint;
 
951
        impls: pimpls;
 
952
        w,i,j,k: longint;
938
953
        cij: boolean;
939
954
        cji: boolean;
940
955
      begin
943
958
          Internalerror(200006135);
944
959
        getmem(compats,sizeof(tcompintfentry)*max);
945
960
        getmem(equals,sizeof(longint)*max);
 
961
        getmem(impls,sizeof(longint)*max);
946
962
        fillchar(compats^,sizeof(tcompintfentry)*max,0);
947
963
        fillchar(equals^,sizeof(longint)*max,0);
 
964
        fillchar(impls^,sizeof(longint)*max,0);
948
965
        { ismergepossible is a containing relation
949
966
          meaning of ismergepossible(a,b,w) =
950
967
          if implementorfunction map of a is contained implementorfunction map of b
983
1000
                  end;
984
1001
              end;
985
1002
          end;
986
 
        for i:=1 to max do
987
 
          begin
988
 
            if compats^[i].compintf<>0 then
989
 
              implvtbl[i]:=compats^[i].compintf
990
 
            else if equals^[i]<>0 then
991
 
              implvtbl[i]:=equals^[i]
992
 
            else
993
 
              implvtbl[i]:=i;
994
 
          end;
995
 
        freemem(compats,sizeof(tcompintfentry)*max);
996
 
        freemem(equals,sizeof(longint)*max);
 
1003
        { Reset, no replacements by default }
 
1004
        for i:=1 to max do
 
1005
          impls^[i]:=i;
 
1006
        { Replace vtbls when equal or compat, repeat
 
1007
          until there are no replacements possible anymore. This is
 
1008
          needed for the cases like:
 
1009
            First loop: 2->3, 3->1
 
1010
            Second loop: 2->1 (because 3 was replaced with 1)
 
1011
        }
 
1012
        repeat
 
1013
          k:=0;
 
1014
          for i:=1 to max do
 
1015
            begin
 
1016
              if compats^[impls^[i]].compintf<>0 then
 
1017
                impls^[i]:=compats^[impls^[i]].compintf
 
1018
              else if equals^[impls^[i]]<>0 then
 
1019
                impls^[i]:=equals^[impls^[i]]
 
1020
              else
 
1021
                inc(k);
 
1022
            end;
 
1023
        until k=max;
 
1024
        { Update the implindex }
 
1025
        for i:=1 to max do
 
1026
          _class.implementedinterfaces.setimplindex(i,impls^[i]);
 
1027
        freemem(compats);
 
1028
        freemem(equals);
 
1029
        freemem(impls);
997
1030
      end;
998
1031
 
999
1032
 
1000
1033
    procedure tclassheader.gintfwritedata;
1001
1034
      var
1002
 
        rawdata,rawcode: taasmoutput;
1003
 
        impintfindexes: plongintarray;
1004
 
        max: longint;
1005
 
        i: longint;
 
1035
        rawdata: taasmoutput;
 
1036
        max,i,j : smallint;
1006
1037
      begin
1007
1038
        max:=_class.implementedinterfaces.count;
1008
 
        getmem(impintfindexes,(max+1)*sizeof(longint));
1009
 
 
1010
 
        gintfoptimizevtbls(impintfindexes);
1011
1039
 
1012
1040
        rawdata:=TAAsmOutput.Create;
1013
 
        rawcode:=TAAsmOutput.Create;
1014
1041
        dataSegment.concat(Tai_const.Create_16bit(max));
1015
1042
        { Two pass, one for allocation and vtbl creation }
1016
1043
        for i:=1 to max do
1017
1044
          begin
1018
 
            if impintfindexes[i]=i then { if implement itself }
 
1045
            if _class.implementedinterfaces.implindex(i)=i then { if implement itself }
1019
1046
              begin
1020
1047
                { allocate a pointer in the object memory }
1021
1048
                with tobjectsymtable(_class.symtable) do
1022
1049
                  begin
1023
 
                    datasize:=align(datasize,min(POINTER_SIZE,fieldalignment));
1024
 
                    _class.implementedinterfaces.ioffsets(i)^:=datasize;
1025
 
                    inc(datasize,POINTER_SIZE);
 
1050
                    datasize:=align(datasize,min(sizeof(aint),fieldalignment));
 
1051
                    _class.implementedinterfaces.setioffsets(i,datasize);
 
1052
                    inc(datasize,sizeof(aint));
1026
1053
                  end;
1027
1054
                { write vtbl }
1028
 
                gintfcreatevtbl(i,rawdata,rawcode);
 
1055
                gintfcreatevtbl(i,rawdata);
1029
1056
              end;
1030
1057
          end;
1031
1058
        { second pass: for fill interfacetable and remained ioffsets }
1032
1059
        for i:=1 to max do
1033
1060
          begin
1034
 
            if i<>impintfindexes[i] then { why execute x:=x ? }
1035
 
              with _class.implementedinterfaces do
1036
 
                ioffsets(i)^:=ioffsets(impintfindexes[i])^;
1037
 
            gintfgenentry(i,impintfindexes[i],rawdata);
 
1061
            j:=_class.implementedinterfaces.implindex(i);
 
1062
            if j<>i then
 
1063
              _class.implementedinterfaces.setioffsets(i,_class.implementedinterfaces.ioffsets(j));
 
1064
            gintfgenentry(i,j,rawdata);
1038
1065
          end;
1039
1066
        dataSegment.concatlist(rawdata);
1040
1067
        rawdata.free;
1041
 
        codeSegment.concatlist(rawcode);
1042
 
        rawcode.free;
1043
 
        freemem(impintfindexes,(max+1)*sizeof(longint));
1044
1068
      end;
1045
1069
 
1046
1070
 
1047
1071
    function tclassheader.gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef;
 
1072
      const
 
1073
        po_comp = [po_classmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint,
 
1074
                   po_exports,po_varargs,po_explicitparaloc,po_nostackframe];
1048
1075
      var
1049
1076
        sym: tsym;
1050
1077
        implprocdef : Tprocdef;
1067
1094
            for i:=1 to tprocsym(sym).procdef_count do
1068
1095
              begin
1069
1096
                implprocdef:=tprocsym(sym).procdef[i];
1070
 
                if (compare_paras(proc.para,implprocdef.para,cp_none,[])>=te_equal) and
1071
 
                   (proc.proccalloption=implprocdef.proccalloption) then
 
1097
                if (compare_paras(proc.paras,implprocdef.paras,cp_none,[])>=te_equal) and
 
1098
                   (proc.proccalloption=implprocdef.proccalloption) and
 
1099
                   (proc.proctypeoption=implprocdef.proctypeoption) and
 
1100
                   ((proc.procoptions*po_comp)=((implprocdef.procoptions+[po_virtualmethod])*po_comp)) then
1072
1101
                  begin
1073
1102
                    gintfgetcprocdef:=implprocdef;
1074
1103
                    exit;
1081
1110
    procedure tclassheader.gintfdoonintf(intf: tobjectdef; intfindex: longint);
1082
1111
      var
1083
1112
        def: tdef;
1084
 
        procname: string; { for error }
1085
1113
        mappedname: string;
1086
1114
        nextexist: pointer;
1087
1115
        implprocdef: tprocdef;
1091
1119
          begin
1092
1120
            if def.deftype=procdef then
1093
1121
              begin
1094
 
                procname:='';
1095
1122
                implprocdef:=nil;
1096
1123
                nextexist:=nil;
1097
1124
                repeat
1098
1125
                  mappedname:=_class.implementedinterfaces.getmappings(intfindex,tprocdef(def).procsym.name,nextexist);
1099
 
                  if procname='' then
1100
 
                    procname:=tprocdef(def).procsym.name;
1101
 
                    //mappedname; { for error messages }
1102
1126
                  if mappedname<>'' then
1103
1127
                    implprocdef:=gintfgetcprocdef(tprocdef(def),mappedname);
1104
1128
                until assigned(implprocdef) or not assigned(nextexist);
1105
1129
                if not assigned(implprocdef) then
1106
1130
                  implprocdef:=gintfgetcprocdef(tprocdef(def),tprocdef(def).procsym.name);
1107
 
                if procname='' then
1108
 
                  procname:=tprocdef(def).procsym.name;
1109
1131
                if assigned(implprocdef) then
1110
1132
                  _class.implementedinterfaces.addimplproc(intfindex,implprocdef)
1111
1133
                else
1139
1161
        { 2. step calc required fieldcount and their offsets in the object memory map
1140
1162
             and write data }
1141
1163
        objectlibrary.getdatalabel(intftable);
1142
 
        dataSegment.concat(tai_align.create(const_align(POINTER_SIZE)));
 
1164
        dataSegment.concat(cai_align.create(const_align(sizeof(aint))));
1143
1165
        dataSegment.concat(Tai_label.Create(intftable));
 
1166
        { Optimize interface tables to reuse wrappers }
 
1167
        gintfoptimizevtbls;
 
1168
        { Write interface tables }
1144
1169
        gintfwritedata;
1145
 
        _class.implementedinterfaces.clearimplprocs; { release temporary information }
1146
1170
        genintftable:=intftable;
1147
1171
      end;
1148
1172
 
1150
1174
  { Write interface identifiers to the data section }
1151
1175
  procedure tclassheader.writeinterfaceids;
1152
1176
    var
1153
 
      i: longint;
 
1177
      i : longint;
 
1178
      s : string;
1154
1179
    begin
1155
1180
      if assigned(_class.iidguid) then
1156
1181
        begin
1157
 
          if (cs_create_smart in aktmoduleswitches) then
1158
 
            dataSegment.concat(Tai_cut.Create);
1159
 
          dataSegment.concat(Tai_symbol.Createname_global(make_mangledname('IID',_class.owner,_class.objname^),AT_DATA,0));
1160
 
          dataSegment.concat(Tai_const.Create_32bit(_class.iidguid^.D1));
 
1182
          s:=make_mangledname('IID',_class.owner,_class.objname^);
 
1183
          maybe_new_object_file(dataSegment);
 
1184
          new_section(dataSegment,sec_rodata,s,const_align(sizeof(aint)));
 
1185
          dataSegment.concat(Tai_symbol.Createname_global(s,AT_DATA,0));
 
1186
          dataSegment.concat(Tai_const.Create_32bit(longint(_class.iidguid^.D1)));
1161
1187
          dataSegment.concat(Tai_const.Create_16bit(_class.iidguid^.D2));
1162
1188
          dataSegment.concat(Tai_const.Create_16bit(_class.iidguid^.D3));
1163
1189
          for i:=Low(_class.iidguid^.D4) to High(_class.iidguid^.D4) do
1164
1190
            dataSegment.concat(Tai_const.Create_8bit(_class.iidguid^.D4[i]));
1165
1191
        end;
1166
 
      if (cs_create_smart in aktmoduleswitches) then
1167
 
        dataSegment.concat(Tai_cut.Create);
1168
 
      dataSegment.concat(Tai_symbol.Createname_global(make_mangledname('IIDSTR',_class.owner,_class.objname^),AT_DATA,0));
 
1192
      maybe_new_object_file(dataSegment);
 
1193
      s:=make_mangledname('IIDSTR',_class.owner,_class.objname^);
 
1194
      new_section(dataSegment,sec_rodata,s,0);
 
1195
      dataSegment.concat(Tai_symbol.Createname_global(s,AT_DATA,0));
1169
1196
      dataSegment.concat(Tai_const.Create_8bit(length(_class.iidstr^)));
1170
1197
      dataSegment.concat(Tai_string.Create(_class.iidstr^));
1171
1198
    end;
1173
1200
 
1174
1201
    procedure tclassheader.writevirtualmethods(List:TAAsmoutput);
1175
1202
      var
1176
 
         symcoll : psymcoll;
 
1203
         vmtentry : pvmtentry;
1177
1204
         procdefcoll : pprocdefcoll;
1178
1205
         i : longint;
1179
1206
      begin
1181
1208
         { the method                                             }
1182
1209
         for i:=0 to nextvirtnumber-1 do
1183
1210
           begin
1184
 
              symcoll:=wurzel;
1185
 
 
1186
1211
              { walk trough all symbols }
1187
 
              while assigned(symcoll) do
 
1212
              vmtentry:=firstvmtentry;
 
1213
              while assigned(vmtentry) do
1188
1214
                begin
1189
 
 
1190
1215
                   { walk trough all methods }
1191
 
                   procdefcoll:=symcoll^.data;
 
1216
                   procdefcoll:=vmtentry^.firstprocdef;
1192
1217
                   while assigned(procdefcoll) do
1193
1218
                     begin
1194
1219
                        { writes the addresses to the VMT }
1201
1226
                                  { class abstract and it's not allow to      }
1202
1227
                                  { generates an instance                     }
1203
1228
                                  if (po_abstractmethod in procdefcoll^.data.procoptions) then
1204
 
                                    List.concat(Tai_const_symbol.Createname('FPC_ABSTRACTERROR',AT_FUNCTION,0))
 
1229
                                    List.concat(Tai_const.Createname('FPC_ABSTRACTERROR',AT_FUNCTION,0))
1205
1230
                                  else
1206
 
                                    List.concat(Tai_const_symbol.createname(procdefcoll^.data.mangledname,AT_FUNCTION,0));
 
1231
                                    List.concat(Tai_const.createname(procdefcoll^.data.mangledname,AT_FUNCTION,0));
1207
1232
                               end;
1208
1233
                          end;
1209
1234
                        procdefcoll:=procdefcoll^.next;
1210
1235
                     end;
1211
 
                   symcoll:=symcoll^.next;
 
1236
                   vmtentry:=vmtentry^.next;
1212
1237
                end;
1213
1238
           end;
1214
1239
      end;
1229
1254
         dmtlabel:=gendmt;
1230
1255
{$endif WITHDMT}
1231
1256
 
1232
 
         if (cs_create_smart in aktmoduleswitches) then
1233
 
           dataSegment.concat(Tai_cut.Create);
1234
 
 
1235
1257
         { write tables for classes, this must be done before the actual
1236
1258
           class is written, because we need the labels defined }
1237
1259
         if is_class(_class) then
1238
1260
          begin
 
1261
            objectlibrary.getdatalabel(classnamelabel);
 
1262
            maybe_new_object_file(dataSegment);
 
1263
            new_section(dataSegment,sec_rodata,classnamelabel.name,const_align(sizeof(aint)));
 
1264
 
1239
1265
            { interface table }
1240
1266
            if _class.implementedinterfaces.count>0 then
1241
 
             begin
1242
 
               if (cs_create_smart in aktmoduleswitches) then
1243
 
                codeSegment.concat(Tai_cut.Create);
1244
 
               interfacetable:=genintftable;
1245
 
             end;
 
1267
              interfacetable:=genintftable;
1246
1268
 
1247
1269
            methodnametable:=genpublishedmethodstable;
1248
1270
            fieldtablelabel:=_class.generate_field_table;
1249
1271
            { write class name }
1250
 
            objectlibrary.getdatalabel(classnamelabel);
1251
 
            dataSegment.concat(tai_align.create(const_align(POINTER_SIZE)));
1252
1272
            dataSegment.concat(Tai_label.Create(classnamelabel));
1253
1273
            dataSegment.concat(Tai_const.Create_8bit(length(_class.objrealname^)));
1254
1274
            dataSegment.concat(Tai_string.Create(_class.objrealname^));
1261
1281
          end;
1262
1282
 
1263
1283
        { write debug info }
 
1284
        maybe_new_object_file(dataSegment);
 
1285
        new_section(dataSegment,sec_rodata,_class.vmt_mangledname,const_align(sizeof(aint)));
1264
1286
{$ifdef GDB}
1265
1287
        if (cs_debuginfo in aktmoduleswitches) then
1266
1288
         begin
1270
1292
               tstoreddef(vmttype.def).numberstring+'",'+tostr(N_STSYM)+',0,0,'+_class.vmt_mangledname)));
1271
1293
         end;
1272
1294
{$endif GDB}
1273
 
         dataSegment.concat(tai_align.create(const_align(POINTER_SIZE)));
1274
1295
         dataSegment.concat(Tai_symbol.Createname_global(_class.vmt_mangledname,AT_DATA,0));
1275
1296
 
1276
1297
         { determine the size with symtable.datasize, because }
1277
1298
         { size gives back 4 for classes                    }
1278
 
         dataSegment.concat(Tai_const.Create_32bit(tobjectsymtable(_class.symtable).datasize));
1279
 
         dataSegment.concat(Tai_const.Create_32bit(Cardinal(-tobjectsymtable(_class.symtable).datasize)));
 
1299
         dataSegment.concat(Tai_const.Create(ait_const_ptr,tobjectsymtable(_class.symtable).datasize));
 
1300
         dataSegment.concat(Tai_const.Create(ait_const_ptr,-int64(tobjectsymtable(_class.symtable).datasize)));
1280
1301
{$ifdef WITHDMT}
1281
1302
         if _class.classtype=ct_object then
1282
1303
           begin
1292
1313
         { it is not written for parents that don't have any vmt !! }
1293
1314
         if assigned(_class.childof) and
1294
1315
            (oo_has_vmt in _class.childof.objectoptions) then
1295
 
           dataSegment.concat(Tai_const_symbol.Createname(_class.childof.vmt_mangledname,AT_DATA,0))
 
1316
           dataSegment.concat(Tai_const.Createname(_class.childof.vmt_mangledname,AT_DATA,0))
1296
1317
         else
1297
 
           dataSegment.concat(Tai_const.Create_ptr(0));
 
1318
           dataSegment.concat(Tai_const.Create_sym(nil));
1298
1319
 
1299
1320
         { write extended info for classes, for the order see rtl/inc/objpash.inc }
1300
1321
         if is_class(_class) then
1301
1322
          begin
1302
1323
            { pointer to class name string }
1303
 
            dataSegment.concat(Tai_const_symbol.Create(classnamelabel));
1304
 
            { pointer to dynamic table }
 
1324
            dataSegment.concat(Tai_const.Create_sym(classnamelabel));
 
1325
            { pointer to dynamic table or nil }
1305
1326
            if (oo_has_msgint in _class.objectoptions) then
1306
 
              dataSegment.concat(Tai_const_symbol.Create(intmessagetable))
1307
 
            else
1308
 
              dataSegment.concat(Tai_const.Create_ptr(0));
1309
 
            { pointer to method table }
1310
 
            if assigned(methodnametable) then
1311
 
              dataSegment.concat(Tai_const_symbol.Create(methodnametable))
1312
 
            else
1313
 
              dataSegment.concat(Tai_const.Create_ptr(0));
 
1327
              dataSegment.concat(Tai_const.Create_sym(intmessagetable))
 
1328
            else
 
1329
              dataSegment.concat(Tai_const.Create_sym(nil));
 
1330
            { pointer to method table or nil }
 
1331
            dataSegment.concat(Tai_const.Create_sym(methodnametable));
1314
1332
            { pointer to field table }
1315
 
            dataSegment.concat(Tai_const_symbol.Create(fieldtablelabel));
 
1333
            dataSegment.concat(Tai_const.Create_sym(fieldtablelabel));
1316
1334
            { pointer to type info of published section }
1317
1335
            if (oo_can_have_published in _class.objectoptions) then
1318
 
              dataSegment.concat(Tai_const_symbol.Create(_class.get_rtti_label(fullrtti)))
 
1336
              dataSegment.concat(Tai_const.Create_sym(_class.get_rtti_label(fullrtti)))
1319
1337
            else
1320
 
              dataSegment.concat(Tai_const.Create_ptr(0));
 
1338
              dataSegment.concat(Tai_const.Create_sym(nil));
1321
1339
            { inittable for con-/destruction }
1322
1340
            if _class.members_need_inittable then
1323
 
              dataSegment.concat(Tai_const_symbol.Create(_class.get_rtti_label(initrtti)))
 
1341
              dataSegment.concat(Tai_const.Create_sym(_class.get_rtti_label(initrtti)))
1324
1342
            else
1325
 
              dataSegment.concat(Tai_const.Create_ptr(0));
 
1343
              dataSegment.concat(Tai_const.Create_sym(nil));
1326
1344
            { auto table }
1327
 
            dataSegment.concat(Tai_const.Create_ptr(0));
 
1345
            dataSegment.concat(Tai_const.Create_sym(nil));
1328
1346
            { interface table }
1329
1347
            if _class.implementedinterfaces.count>0 then
1330
 
              dataSegment.concat(Tai_const_symbol.Create(interfacetable))
 
1348
              dataSegment.concat(Tai_const.Create_sym(interfacetable))
1331
1349
            else
1332
 
              dataSegment.concat(Tai_const.Create_ptr(0));
 
1350
              dataSegment.concat(Tai_const.Create_sym(nil));
1333
1351
            { table for string messages }
1334
1352
            if (oo_has_msgstr in _class.objectoptions) then
1335
 
              dataSegment.concat(Tai_const_symbol.Create(strmessagetable))
 
1353
              dataSegment.concat(Tai_const.Create_sym(strmessagetable))
1336
1354
            else
1337
 
              dataSegment.concat(Tai_const.Create_ptr(0));
 
1355
              dataSegment.concat(Tai_const.Create_sym(nil));
1338
1356
          end;
1339
1357
         { write virtual methods }
1340
1358
         writevirtualmethods(dataSegment);
 
1359
         datasegment.concat(Tai_const.create(ait_const_ptr,0));
1341
1360
         { write the size of the VMT }
1342
1361
         dataSegment.concat(Tai_symbol_end.Createname(_class.vmt_mangledname));
1343
1362
      end;
1344
1363
 
1345
1364
 
1346
 
  procedure tclassheader.adjustselfvalue(procdef: tprocdef;ioffset: aword);
1347
 
    var
1348
 
      hsym : tsym;
1349
 
      href : treference;
1350
 
      locpara : tparalocation;
1351
 
    begin
1352
 
      { calculate the parameter info for the procdef }
1353
 
      if not procdef.has_paraloc_info then
1354
 
        begin
1355
 
          procdef.requiredargarea:=paramanager.create_paraloc_info(procdef,callerside);
1356
 
          procdef.has_paraloc_info:=true;
1357
 
        end;
1358
 
      hsym:=tsym(procdef.parast.search('self'));
1359
 
      if not(assigned(hsym) and
1360
 
             (hsym.typ=varsym) and
1361
 
             assigned(tvarsym(hsym).paraitem)) then
1362
 
        internalerror(200305251);
1363
 
      locpara:=tvarsym(hsym).paraitem.paraloc[callerside];
1364
 
      case locpara.loc of
1365
 
        LOC_REGISTER:
1366
 
          cg.a_op_const_reg(exprasmlist,OP_SUB,locpara.size,ioffset,locpara.register);
1367
 
        LOC_REFERENCE:
1368
 
          begin
1369
 
             { offset in the wrapper needs to be adjusted for the stored
1370
 
               return address }
1371
 
             reference_reset_base(href,locpara.reference.index,locpara.reference.offset+POINTER_SIZE);
1372
 
             cg.a_op_const_ref(exprasmlist,OP_SUB,locpara.size,ioffset,href);
1373
 
          end
1374
 
        else
1375
 
          internalerror(200309189);
1376
 
      end;
1377
 
    end;
1378
 
 
1379
 
 
1380
 
initialization
1381
 
  cclassheader:=tclassheader;
1382
1365
end.
1383
1366
{
1384
1367
  $Log: nobj.pas,v $
1385
 
  Revision 1.69  2004/03/31 21:01:01  florian
1386
 
    * vtbls are now properly aligned
1387
 
 
1388
 
  Revision 1.68  2004/03/18 11:43:57  olle
1389
 
    * change AT_FUNCTION to AT_DATA where appropriate
1390
 
 
1391
 
  Revision 1.67  2004/03/08 22:07:46  peter
1392
 
    * stabs updates to write stabs for def for all implictly used
1393
 
      units
1394
 
 
1395
 
  Revision 1.66  2004/03/04 17:23:50  peter
1396
 
    * fix compare of parameters, they need to match exact
1397
 
 
1398
 
  Revision 1.65  2004/03/02 00:36:33  olle
1399
 
    * big transformation of Tai_[const_]Symbol.Create[data]name*
1400
 
 
1401
 
  Revision 1.64  2004/02/27 10:21:05  florian
1402
 
    * top_symbol killed
1403
 
    + refaddr to treference added
1404
 
    + refsymbol to treference added
1405
 
    * top_local stuff moved to an extra record to save memory
1406
 
    + aint introduced
1407
 
    * tppufile.get/putint64/aint implemented
1408
 
 
1409
 
  Revision 1.63  2004/02/26 16:16:38  peter
1410
 
    * tai_const.create_ptr added
1411
 
 
1412
 
  Revision 1.62  2004/02/19 17:07:42  florian
1413
 
    * fixed arg. area calculation
1414
 
 
1415
 
  Revision 1.61  2004/02/13 15:41:24  peter
1416
 
    * overload directive checking for methods is now done
1417
 
      when the vmt is generated
1418
 
 
1419
 
  Revision 1.60  2004/02/08 23:30:43  florian
1420
 
    * web bug 2942 fixed: reintroduce isn't necessary in methods of child classes of course
1421
 
 
1422
 
  Revision 1.59  2004/01/28 20:30:18  peter
1423
 
    * record alignment splitted in fieldalignment and recordalignment,
1424
 
      the latter is used when this record is inserted in another record.
1425
 
 
1426
 
  Revision 1.58  2004/01/21 14:22:00  florian
1427
 
    + reintroduce implemented
1428
 
 
1429
 
  Revision 1.57  2003/12/08 22:34:24  peter
1430
 
    * tai_const.create_32bit changed to cardinal
1431
 
 
1432
 
  Revision 1.56  2003/11/28 17:24:22  peter
1433
 
    * reversed offset calculation for caller side so it works
1434
 
      correctly for interfaces
1435
 
 
1436
 
  Revision 1.55  2003/10/30 16:23:13  peter
1437
 
    * don't search for overloads in parents for constructors
1438
 
 
1439
 
  Revision 1.54  2003/10/29 19:48:50  peter
1440
 
    * renamed mangeldname_prefix to make_mangledname and made it more
1441
 
      generic
1442
 
    * make_mangledname is now also used for internal threadvar/resstring
1443
 
      lists
1444
 
    * Add P$ in front of program modulename to prevent duplicated symbols
1445
 
      at assembler level, because the main program can have the same name
1446
 
      as a unit, see webtbs/tw1251b
1447
 
 
1448
 
  Revision 1.53  2003/10/13 14:05:12  peter
1449
 
    * removed is_visible_for_proc
1450
 
    * search also for class overloads when finding interface
1451
 
      implementations
1452
 
 
1453
 
  Revision 1.52  2003/10/10 17:48:13  peter
1454
 
    * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
1455
 
    * tregisteralloctor renamed to trgobj
1456
 
    * removed rgobj from a lot of units
1457
 
    * moved location_* and reference_* to cgobj
1458
 
    * first things for mmx register allocation
1459
 
 
1460
 
  Revision 1.51  2003/10/07 21:14:32  peter
1461
 
    * compare_paras() has a parameter to ignore hidden parameters
1462
 
    * cross unit overload searching ignores hidden parameters when
1463
 
      comparing parameter lists. Now function(string):string is
1464
 
      not overriden with procedure(string) which has the same visible
1465
 
      parameter list
1466
 
 
1467
 
  Revision 1.50  2003/10/07 20:44:22  peter
1468
 
    * inherited forced calling convention
1469
 
    * show hints when forward doesn't match
1470
 
 
1471
 
  Revision 1.49  2003/10/01 20:34:49  peter
1472
 
    * procinfo unit contains tprocinfo
1473
 
    * cginfo renamed to cgbase
1474
 
    * moved cgmessage to verbose
1475
 
    * fixed ppc and sparc compiles
1476
 
 
1477
 
  Revision 1.48  2003/09/23 17:56:05  peter
1478
 
    * locals and paras are allocated in the code generation
1479
 
    * tvarsym.localloc contains the location of para/local when
1480
 
      generating code for the current procedure
1481
 
 
1482
 
  Revision 1.47  2003/08/21 14:47:41  peter
1483
 
    * remove convert_registers
1484
 
 
1485
 
  Revision 1.46  2003/08/20 09:07:00  daniel
1486
 
    * New register coding now mandatory, some more convert_registers calls
1487
 
      removed.
1488
 
 
1489
 
  Revision 1.45  2003/08/10 17:25:23  peter
1490
 
    * fixed some reported bugs
1491
 
 
1492
 
  Revision 1.44  2003/06/01 21:38:06  peter
1493
 
    * getregisterfpu size parameter added
1494
 
    * op_const_reg size parameter added
1495
 
    * sparc updates
1496
 
 
1497
 
  Revision 1.43  2003/05/23 14:27:35  peter
1498
 
    * remove some unit dependencies
1499
 
    * current_procinfo changes to store more info
1500
 
 
1501
 
  Revision 1.42  2003/04/25 20:59:33  peter
1502
 
    * removed funcretn,funcretsym, function result is now in varsym
1503
 
      and aliases for result and function name are added using absolutesym
1504
 
    * vs_hidden parameter for funcret passed in parameter
1505
 
    * vs_hidden fixes
1506
 
    * writenode changed to printnode and released from extdebug
1507
 
    * -vp option added to generate a tree.log with the nodetree
1508
 
    * nicer printnode for statements, callnode
1509
 
 
1510
 
  Revision 1.41  2003/04/23 10:11:22  peter
1511
 
    * range check error for GUID fixed
1512
 
 
1513
 
  Revision 1.40  2003/01/13 14:54:34  daniel
1514
 
    * Further work to convert codegenerator register convention;
1515
 
      internalerror bug fixed.
1516
 
 
1517
 
  Revision 1.39  2003/01/09 21:52:37  peter
1518
 
    * merged some verbosity options.
1519
 
    * V_LineInfo is a verbosity flag to include line info
1520
 
 
1521
 
  Revision 1.38  2002/11/25 17:43:20  peter
1522
 
    * splitted defbase in defutil,symutil,defcmp
1523
 
    * merged isconvertable and is_equal into compare_defs(_ext)
1524
 
    * made operator search faster by walking the list only once
1525
 
 
1526
 
  Revision 1.37  2002/11/17 16:31:56  carl
1527
 
    * memory optimization (3-4%) : cleanup of tai fields,
1528
 
       cleanup of tdef and tsym fields.
1529
 
    * make it work for m68k
1530
 
 
1531
 
  Revision 1.36  2002/11/15 01:58:52  peter
1532
 
    * merged changes from 1.0.7 up to 04-11
1533
 
      - -V option for generating bug report tracing
1534
 
      - more tracing for option parsing
1535
 
      - errors for cdecl and high()
1536
 
      - win32 import stabs
1537
 
      - win32 records<=8 are returned in eax:edx (turned off by default)
1538
 
      - heaptrc update
1539
 
      - more info for temp management in .s file with EXTDEBUG
1540
 
 
1541
 
  Revision 1.35  2002/11/09 16:19:43  carl
1542
 
    - remove superfluous data in classname
1543
 
 
1544
 
  Revision 1.34  2002/11/09 15:35:35  carl
1545
 
    * major alignment updates for objects/class tables
1546
 
 
1547
 
  Revision 1.33  2002/10/20 15:33:36  peter
1548
 
    * having overloads is the same as overload directive for hiding of
1549
 
      parent methods. This is required becuase it can be possible that a
1550
 
      method will then hide a method in the parent that an overloaded
1551
 
      method requires. See webbug tw2185
1552
 
 
1553
 
  Revision 1.32  2002/10/19 15:09:24  peter
1554
 
    + tobjectdef.members_need_inittable that is used to generate only the
1555
 
      inittable when it is really used. This saves a lot of useless calls
1556
 
      to fpc_finalize when destroying classes
1557
 
 
1558
 
  Revision 1.31  2002/10/15 19:00:42  peter
1559
 
    * small tweak to use speedvalue before comparing strings
1560
 
 
1561
 
  Revision 1.30  2002/10/06 16:40:25  florian
1562
 
    * interface wrapper name mangling improved
1563
 
 
1564
 
  Revision 1.29  2002/10/05 12:43:25  carl
1565
 
    * fixes for Delphi 6 compilation
1566
 
     (warning : Some features do not work under Delphi)
1567
 
 
1568
 
  Revision 1.28  2002/09/16 14:11:13  peter
1569
 
    * add argument to equal_paras() to support default values or not
1570
 
 
1571
 
  Revision 1.27  2002/09/03 16:26:26  daniel
1572
 
    * Make Tprocdef.defs protected
1573
 
 
1574
 
  Revision 1.26  2002/09/03 15:44:44  peter
1575
 
    * fixed private methods hiding public virtual methods
1576
 
 
1577
 
  Revision 1.25  2002/08/11 14:32:27  peter
1578
 
    * renamed current_library to objectlibrary
1579
 
 
1580
 
  Revision 1.24  2002/08/11 13:24:12  peter
1581
 
    * saving of asmsymbols in ppu supported
1582
 
    * asmsymbollist global is removed and moved into a new class
1583
 
      tasmlibrarydata that will hold the info of a .a file which
1584
 
      corresponds with a single module. Added librarydata to tmodule
1585
 
      to keep the library info stored for the module. In the future the
1586
 
      objectfiles will also be stored to the tasmlibrarydata class
1587
 
    * all getlabel/newasmsymbol and friends are moved to the new class
1588
 
 
1589
 
  Revision 1.23  2002/08/09 07:33:01  florian
1590
 
    * a couple of interface related fixes
1591
 
 
1592
 
  Revision 1.22  2002/07/20 11:57:55  florian
1593
 
    * types.pas renamed to defbase.pas because D6 contains a types
1594
 
      unit so this would conflicts if D6 programms are compiled
1595
 
    + Willamette/SSE2 instructions to assembler added
1596
 
 
1597
 
  Revision 1.21  2002/07/01 18:46:23  peter
1598
 
    * internal linker
1599
 
    * reorganized aasm layer
1600
 
 
1601
 
  Revision 1.20  2002/05/18 13:34:10  peter
1602
 
    * readded missing revisions
1603
 
 
1604
 
  Revision 1.19  2002/05/16 19:46:39  carl
1605
 
  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
1606
 
  + try to fix temp allocation (still in ifdef)
1607
 
  + generic constructor calls
1608
 
  + start of tassembler / tmodulebase class cleanup
1609
 
 
1610
 
  Revision 1.17  2002/05/12 16:53:08  peter
1611
 
    * moved entry and exitcode to ncgutil and cgobj
1612
 
    * foreach gets extra argument for passing local data to the
1613
 
      iterator function
1614
 
    * -CR checks also class typecasts at runtime by changing them
1615
 
      into as
1616
 
    * fixed compiler to cycle with the -CR option
1617
 
    * fixed stabs with elf writer, finally the global variables can
1618
 
      be watched
1619
 
    * removed a lot of routines from cga unit and replaced them by
1620
 
      calls to cgobj
1621
 
    * u32bit-s32bit updates for and,or,xor nodes. When one element is
1622
 
      u32bit then the other is typecasted also to u32bit without giving
1623
 
      a rangecheck warning/error.
1624
 
    * fixed pascal calling method with reversing also the high tree in
1625
 
      the parast, detected by tcalcst3 test
1626
 
 
1627
 
  Revision 1.16  2002/04/20 21:32:24  carl
1628
 
  + generic FPC_CHECKPOINTER
1629
 
  + first parameter offset in stack now portable
1630
 
  * rename some constants
1631
 
  + move some cpu stuff to other units
1632
 
  - remove unused constents
1633
 
  * fix stacksize for some targets
1634
 
  * fix generic size problems which depend now on EXTEND_SIZE constant
1635
 
 
1636
 
  Revision 1.15  2002/04/19 15:46:01  peter
1637
 
    * mangledname rewrite, tprocdef.mangledname is now created dynamicly
1638
 
      in most cases and not written to the ppu
1639
 
    * add mangeledname_prefix() routine to generate the prefix of
1640
 
      manglednames depending on the current procedure, object and module
1641
 
    * removed static procprefix since the mangledname is now build only
1642
 
      on demand from tprocdef.mangledname
1643
 
 
1644
 
  Revision 1.14  2002/04/15 18:59:07  carl
1645
 
  + target_info.size_of_pointer -> pointer_Size
1646
 
 
1647
 
  Revision 1.13  2002/02/11 18:51:35  peter
1648
 
    * fixed vmt generation for private procedures that were skipped after
1649
 
      my previous changes
 
1368
  Revision 1.93  2005/05/05 21:09:10  florian
 
1369
    * write nil into the method table for abstract methods
 
1370
 
 
1371
  Revision 1.92  2005/03/17 09:08:54  michael
 
1372
  + Patch from peter to fix overload directive cheking in delphi mode
 
1373
 
 
1374
  Revision 1.91  2005/02/14 17:13:06  peter
 
1375
    * truncate log
 
1376
 
 
1377
  Revision 1.90  2005/02/10 22:08:03  peter
 
1378
    * remove obsolete code
 
1379
 
 
1380
  Revision 1.89  2005/02/02 02:19:42  karoly
 
1381
    * removed debug writelns from florian's previous commit
 
1382
 
 
1383
  Revision 1.88  2005/02/01 23:18:54  florian
 
1384
    * fixed:
 
1385
      r1 = record
 
1386
        p : procedure stdcall;
 
1387
        i : longint;
 
1388
      end;
 
1389
 
 
1390
  Revision 1.87  2005/01/24 22:08:32  peter
 
1391
    * interface wrapper generation moved to cgobj
 
1392
    * generate interface wrappers after the module is parsed
 
1393
 
 
1394
  Revision 1.86  2005/01/10 20:41:55  peter
 
1395
    * write realname for published methods
 
1396
 
 
1397
  Revision 1.85  2005/01/09 15:05:29  peter
 
1398
    * fix interface vtbl optimization
 
1399
    * replace ugly pointer construct of ioffset()
1650
1400
 
1651
1401
}