3 Copyright (c) 1998-2000 by Florian Klaempfl, Daniel Mantione
5 Does the parsing of the procedures/functions
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 ****************************************************************************
28 symconst
,tokens
,symtable
;
31 pd_global
= $1; { directive must be global }
32 pd_body
= $2; { directive needs a body }
33 pd_implemen
= $4; { directive can be used implementation section }
34 pd_interface
= $8; { directive can be used interface section }
35 pd_object
= $10; { directive can be used object declaration }
36 pd_procvar
= $20; { directive can be used procvar declaration }
37 pd_notobject
= $40;{ directive can not be used object declaration }
39 procedure compile_proc_body(const proc_names
:Tstringcontainer
;
40 make_global
,parent_has_class
:boolean);
41 procedure parse_proc_head(options
:tproctypeoption
);
42 procedure parse_proc_dec
;
43 function is_proc_directive(tok
:ttoken
):boolean;
44 procedure parse_var_proc_directives(var sym
: psym
);
45 procedure parse_object_proc_directives(var sym
: pprocsym
);
47 function check_identical_proc(var p
: pprocdef
) : boolean;
53 strings
,globals
,verbose
,files
,
54 scanner
,aasm
,tree
,types
,
55 import
,gendef
,htypechk
,
84 { parser specific stuff }
85 ,pbase
,ptype
,pdecl
,pexpr
,pstatmnt
87 ,tgcpu
,convtree
,cgobj
,tgeni386
{ for the new code generator tgeni386 is only a dummy }
92 realname
:string; { contains the real name of a procedure as it's typed }
95 procedure parse_proc_head(options
:tproctypeoption
);
102 overloaded_level
:word;
103 storepos
,procstartfilepos
: tfileposinfo
;
105 { Save the position where this procedure really starts and set col to 1 which
107 procstartfilepos
:=tokenpos
;
108 { procstartfilepos.column:=1; I do not agree here !!
109 lets keep excat position PM }
111 if (options
=potype_operator
) then
113 sp
:=overloaded_names
[optoken
];
119 realname
:=orgpattern
;
124 if not(parse_only
) and
125 (lexlevel
=normal_function_level
) and
126 try_to_consume(_POINT
) then
129 tokenpos
:=procstartfilepos
;
135 realname
:=orgpattern
;
136 procstartfilepos
:=tokenpos
;
137 { qualifier is class name ? }
138 if (sym
^.typ
<>typesym
) or
139 (ptypesym(sym
)^.restype
.def
^.deftype
<>objectdef
) then
141 Message(parser_e_class_id_expected
);
147 { used to allow private syms to be seen }
148 aktobjectdef
:=pobjectdef(ptypesym(sym
)^.restype
.def
);
149 procinfo
^._class
:=pobjectdef(ptypesym(sym
)^.restype
.def
);
150 aktprocsym
:=pprocsym(procinfo
^._class
^.symtable
^.search(sp
));
152 {The procedure has been found. So it is
153 a global one. Set the flags to mark this.}
154 procinfo
^.flags
:=procinfo
^.flags
or pi_is_global
;
156 { we solve this below }
157 if not(assigned(aktprocsym
)) then
158 Message(parser_e_methode_id_expected
);
163 { check for constructor/destructor which is not allowed here }
164 if (not parse_only
) and
165 (options
in [potype_constructor
,potype_destructor
]) then
166 Message(parser_e_constructors_always_objects
);
168 tokenpos
:=procstartfilepos
;
169 aktprocsym
:=pprocsym(symtablestack
^.search(sp
));
171 if not(parse_only
) then
173 {The procedure we prepare for is in the implementation
174 part of the unit we compile. It is also possible that we
175 are compiling a program, which is also some kind of
178 We need to find out if the procedure is global. If it is
179 global, it is in the global symtable.}
180 if not assigned(aktprocsym
) and
181 (symtablestack
^.symtabletype
=staticsymtable
) then
183 {Search the procedure in the global symtable.}
184 aktprocsym
:=Pprocsym(search_a_symtable(sp
,globalsymtable
));
185 if assigned(aktprocsym
) then
187 {Check if it is a procedure.}
188 if aktprocsym
^.typ
<>procsym
then
189 DuplicateSym(aktprocsym
);
190 {The procedure has been found. So it is
191 a global one. Set the flags to mark this.}
192 procinfo
^.flags
:=procinfo
^.flags
or pi_is_global
;
198 { Create the mangledname }
199 {$ifndef UseNiceNames}
200 if assigned(procinfo
^._class
) then
202 if (pos('_$$_',procprefix
)=0) then
203 hs
:=procprefix
+'_$$_'+procinfo
^._class
^.objname
^+'_$$_'+sp
205 hs
:=procprefix
+'_$'+sp
;
209 if lexlevel
=normal_function_level
then
210 hs
:=procprefix
+'_'+sp
212 hs
:=procprefix
+'_$'+sp
;
215 if assigned(procinfo
^._class
) then
217 if (pos('_5Class_',procprefix
)=0) then
218 hs
:=procprefix
+'_5Class_'+procinfo
^._class
^.name
^+'_'+tostr(length(sp
))+sp
220 hs
:=procprefix
+'_'+tostr(length(sp
))+sp
;
224 if lexlevel
=normal_function_level
then
225 hs
:=procprefix
+'_'+tostr(length(sp
))+sp
227 hs
:=lowercase(procprefix
)+'_'+tostr(length(sp
))+sp
;
229 {$endif UseNiceNames}
231 if assigned(aktprocsym
) then
233 { Check if overloaded is a procsym, we use a different error message
234 for tp7 so it looks more compatible }
235 if aktprocsym
^.typ
<>procsym
then
237 if (m_fpc
in aktmodeswitches
) then
238 Message1(parser_e_overloaded_no_procedure
,aktprocsym
^.name
)
240 DuplicateSym(aktprocsym
);
241 { try to recover by creating a new aktprocsym }
242 tokenpos
:=procstartfilepos
;
243 aktprocsym
:=new(pprocsym
,init(sp
));
248 { create a new procsym and set the real filepos }
249 tokenpos
:=procstartfilepos
;
250 aktprocsym
:=new(pprocsym
,init(sp
));
251 { for operator we have only one definition for each overloaded
253 if (options
=potype_operator
) then
255 { the only problem is that nextoverloaded might not be in a unit
256 known for the unit itself }
258 if assigned(overloaded_operators
[optoken
]) then
259 aktprocsym
^.definition
:=overloaded_operators
[optoken
]^.definition
;
260 {$ifndef DONOTCHAINOPERATORS}
261 overloaded_operators
[optoken
]:=aktprocsym
;
262 {$endif DONOTCHAINOPERATORS}
264 symtablestack
^.insert(aktprocsym
);
268 pd
:=new(pprocdef
,init
);
269 pd
^.symtablelevel
:=symtablestack
^.symtablelevel
;
271 if assigned(procinfo
^._class
) then
272 pd
^._class
:= procinfo
^._class
;
274 { set the options from the caller (podestructor or poconstructor) }
275 pd
^.proctypeoption
:=options
;
277 { calculate the offset of the parameters }
280 { calculate frame pointer offset }
281 if lexlevel
>normal_function_level
then
283 procinfo
^.framepointer_offset
:=paramoffset
;
284 inc(paramoffset
,target_os
.size_of_pointer
);
285 { this is needed to get correct framepointer push for local
286 forward functions !! }
287 pd
^.parast
^.symtablelevel
:=lexlevel
;
290 if assigned (procinfo
^._Class
) and
291 not(procinfo
^._Class
^.is_class
) and
292 (pd
^.proctypeoption
in [potype_constructor
,potype_destructor
]) then
293 inc(paramoffset
,target_os
.size_of_pointer
);
295 { self pointer offset }
296 { self isn't pushed in nested procedure of methods }
297 if assigned(procinfo
^._class
) and (lexlevel
=normal_function_level
) then
299 procinfo
^.selfpointer_offset
:=paramoffset
;
300 if assigned(aktprocsym
^.definition
) and
301 not(po_containsself
in aktprocsym
^.definition
^.procoptions
) then
302 inc(paramoffset
,target_os
.size_of_pointer
);
305 { con/-destructor flag ? }
306 if assigned (procinfo
^._Class
) and
307 procinfo
^._class
^.is_class
and
308 (pd
^.proctypeoption
in [potype_destructor
,potype_constructor
]) then
309 inc(paramoffset
,target_os
.size_of_pointer
);
311 procinfo
^.para_offset
:=paramoffset
;
313 pd
^.parast
^.datasize
:=0;
315 pd
^.nextoverloaded
:=aktprocsym
^.definition
;
316 aktprocsym
^.definition
:=pd
;
317 { this is probably obsolete now PM }
318 aktprocsym
^.definition
^.fileinfo
:=procstartfilepos
;
319 aktprocsym
^.definition
^.setmangledname(hs
);
320 aktprocsym
^.definition
^.procsym
:=aktprocsym
;
322 if not parse_only
then
325 { we need another procprefix !!! }
326 { count, but only those in the same unit !!}
327 while assigned(pd
) and
328 (pd
^.owner
^.symtabletype
in [globalsymtable
,staticsymtable
]) do
330 { only count already implemented functions }
331 if not(pd
^.forwarddef
) then
332 inc(overloaded_level
);
333 pd
:=pd
^.nextoverloaded
;
335 if overloaded_level
>0 then
336 procprefix
:=hs
+'$'+tostr(overloaded_level
)+'$'
341 { this must also be inserted in the right symtable !! PM }
342 { otherwise we get subbtle problems with
343 definitions of args defs in staticsymtable for
344 implementation of a global method }
345 if token
=_LKLAMMER
then
346 parameter_dec(aktprocsym
^.definition
);
348 { so we only restore the symtable now }
350 if (options
=potype_operator
) then
351 overloaded_operators
[optoken
]:=aktprocsym
;
355 procedure parse_proc_dec
;
358 isclassmethod
: boolean;
361 { read class method }
368 isclassmethod
:=false;
372 parse_proc_head(potype_none
);
373 if token
<>_COLON
then
375 if not(aktprocsym
^.definition
^.forwarddef
) or
376 (m_repeat_forward
in aktmodeswitches
) then
379 consume_all_until(_SEMICOLON
);
386 single_type(aktprocsym
^.definition
^.rettype
,hs
,false);
387 aktprocsym
^.definition
^.test_if_fpu_result
;
393 parse_proc_head(potype_none
);
394 aktprocsym
^.definition
^.rettype
.def
:=voiddef
;
397 consume(_CONSTRUCTOR
);
398 parse_proc_head(potype_constructor
);
399 if assigned(procinfo
^._class
) and
400 procinfo
^._class
^.is_class
then
402 { CLASS constructors return the created instance }
403 aktprocsym
^.definition
^.rettype
.def
:=procinfo
^._class
;
407 { OBJECT constructors return a boolean }
409 { GDB doesn't like unnamed types !}
410 aktprocsym
^.definition
^.rettype
.def
:=globaldef('boolean');
412 aktprocsym
^.definition
^.rettype
.def
:=new(porddef
,init(bool8bit
,0,1));
417 consume(_DESTRUCTOR
);
418 parse_proc_head(potype_destructor
);
419 aktprocsym
^.definition
^.rettype
.def
:=voiddef
;
422 if lexlevel
>normal_function_level
then
423 Message(parser_e_no_local_operator
);
425 if not(token
in [_PLUS
..last_overloaded
]) then
426 Message(parser_e_overload_operator_failed
);
429 procinfo
^.flags
:=procinfo
^.flags
or pi_operator
;
430 parse_proc_head(potype_operator
);
434 if not(m_result
in aktmodeswitches
) then
439 opsym
:=new(pvarsym
,initdef(pattern
,voiddef
));
442 if not try_to_consume(_COLON
) then
445 aktprocsym
^.definition
^.rettype
.def
:=generrordef
;
446 consume_all_until(_SEMICOLON
);
450 single_type(aktprocsym
^.definition
^.rettype
,hs
,false);
451 aktprocsym
^.definition
^.test_if_fpu_result
;
452 if (optoken
in [_EQUAL
,_GT
,_LT
,_GTE
,_LTE
]) and
453 ((aktprocsym
^.definition
^.rettype
.def
^.deftype
<>
454 orddef
) or (porddef(aktprocsym
^.definition
^.
455 rettype
.def
)^.typ
<>bool8bit
)) then
456 Message(parser_e_comparative_operator_return_boolean
);
457 if assigned(opsym
) then
458 opsym
^.vartype
.def
:=aktprocsym
^.definition
^.rettype
.def
;
459 { We need to add the return type in the mangledname
460 to allow overloading with just different results !! (PM) }
461 aktprocsym
^.definition
^.setmangledname(
462 aktprocsym
^.definition
^.mangledname
+'$$'+hs
);
463 if (optoken
=_ASSIGNMENT
) and
464 is_equal(aktprocsym
^.definition
^.rettype
.def
,
465 pvarsym(aktprocsym
^.definition
^.parast
^.symindex
^.first
)^.vartype
.def
) then
466 message(parser_e_no_such_assignment
)
467 else if not isoperatoracceptable(aktprocsym
^.definition
,optoken
) then
468 Message(parser_e_overload_impossible
);
473 assigned(aktprocsym
) then
475 include(aktprocsym
^.definition
^.procoptions
,po_classmethod
);
477 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+[po_classmethod
];
479 { support procedure proc;stdcall export; in Delphi mode only }
480 if not((m_delphi
in aktmodeswitches
) and
481 is_proc_directive(token
)) then
487 {****************************************************************************
488 Procedure directive handlers
489 ****************************************************************************}
495 procedure pd_far(const procnames
:Tstringcontainer
);
497 Message(parser_w_proc_far_ignored
);
500 procedure pd_near(const procnames
:Tstringcontainer
);
502 Message(parser_w_proc_near_ignored
);
505 procedure pd_export(const procnames
:Tstringcontainer
);
507 if assigned(procinfo
^._class
) then
508 Message(parser_e_methods_dont_be_export
);
509 if lexlevel
<>normal_function_level
then
510 Message(parser_e_dont_nest_export
);
511 { only os/2 needs this }
512 if target_info
.target
=target_i386_os2
then
514 procnames
.insert(realname
);
515 procinfo
^.exported
:=true;
516 if cs_link_deffile
in aktglobalswitches
then
517 deffile
.AddExport(aktprocsym
^.definition
^.mangledname
);
521 procedure pd_inline(const procnames
:Tstringcontainer
);
523 if not(cs_support_inline
in aktmoduleswitches
) then
524 Message(parser_e_proc_inline_not_supported
);
527 procedure pd_forward(const procnames
:Tstringcontainer
);
529 aktprocsym
^.definition
^.forwarddef
:=true;
532 procedure pd_stdcall(const procnames
:Tstringcontainer
);
536 procedure pd_safecall(const procnames
:Tstringcontainer
);
540 procedure pd_alias(const procnames
:Tstringcontainer
);
543 procnames
.insert(get_stringconst
);
546 procedure pd_asmname(const procnames
:Tstringcontainer
);
548 aktprocsym
^.definition
^.setmangledname(target_os
.Cprefix
+pattern
);
553 { we don't need anything else }
554 aktprocsym
^.definition
^.forwarddef
:=false;
557 procedure pd_intern(const procnames
:Tstringcontainer
);
560 aktprocsym
^.definition
^.extnumber
:=get_intconst
;
563 procedure pd_interrupt(const procnames
:Tstringcontainer
);
566 Message(parser_w_proc_interrupt_ignored
);
568 if lexlevel
<>normal_function_level
then
569 Message(parser_e_dont_nest_interrupt
);
573 procedure pd_system(const procnames
:Tstringcontainer
);
575 aktprocsym
^.definition
^.setmangledname(realname
);
578 procedure pd_abstract(const procnames
:Tstringcontainer
);
580 if (po_virtualmethod
in aktprocsym
^.definition
^.procoptions
) then
582 include(aktprocsym
^.definition
^.procoptions
,po_abstractmethod
)
584 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+[po_abstractmethod
]
587 Message(parser_e_only_virtual_methods_abstract
);
588 { the method is defined }
589 aktprocsym
^.definition
^.forwarddef
:=false;
592 procedure pd_virtual(const procnames
:Tstringcontainer
);
598 if (aktprocsym
^.definition
^.proctypeoption
=potype_constructor
) and
599 not(aktprocsym
^.definition
^._class
^.is_class
) then
600 Message(parser_e_constructor_cannot_be_not_virtual
);
602 if not(aktprocsym
^.definition
^._class
^.is_class
) and
603 (token
<>_SEMICOLON
) then
605 { any type of parameter is allowed here! }
609 if is_constintnode(pt
) then
611 include(aktprocsym
^.definition
^.procoptions
,po_msgint
);
612 aktprocsym
^.definition
^.messageinf
.i
:=pt
^.value
;
615 Message(parser_e_ill_msg_expr
);
621 procedure pd_static(const procnames
:Tstringcontainer
);
623 if (cs_static_keyword
in aktmoduleswitches
) then
626 include(aktprocsym
^.symoptions
,sp_static
);
627 include(aktprocsym
^.definition
^.procoptions
,po_staticmethod
);
629 aktprocsym
^.symoptions
:=aktprocsym
^.symoptions
+[sp_static
];
630 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+[po_staticmethod
];
635 procedure pd_override(const procnames
:Tstringcontainer
);
637 if not(aktprocsym
^.definition
^._class
^.is_class
) then
638 Message(parser_e_no_object_override
);
641 procedure pd_overload(const procnames
:Tstringcontainer
);
645 procedure pd_message(const procnames
:Tstringcontainer
);
649 { check parameter type }
650 if not(po_containsself
in aktprocsym
^.definition
^.procoptions
) and
651 ((aktprocsym
^.definition
^.para
^.count
<>1) or
652 (pparaitem(aktprocsym
^.definition
^.para
^.first
)^.paratyp
<>vs_var
)) then
653 Message(parser_e_ill_msg_param
);
656 if pt
^.treetype
=stringconstn
then
659 include(aktprocsym
^.definition
^.procoptions
,po_msgstr
);
661 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+[po_msgstr
];
663 aktprocsym
^.definition
^.messageinf
.str
:=strnew(pt
^.value_str
);
666 if is_constintnode(pt
) then
669 include(aktprocsym
^.definition
^.procoptions
,po_msgint
);
671 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+[po_msgint
];
673 aktprocsym
^.definition
^.messageinf
.i
:=pt
^.value
;
676 Message(parser_e_ill_msg_expr
);
681 procedure resetvaluepara(p
:pnamedindexobject
);{$ifndef FPC}far;{$endif}
683 if psym(p
)^.typ
=varsym
then
685 if copy(name
,1,3)='val' then
686 aktprocsym
^.definition
^.parast
^.symsearch
^.rename(name
,copy(name
,4,length(name
)));
690 procedure pd_cdecl(const procnames
:Tstringcontainer
);
692 if aktprocsym
^.definition
^.deftype
<>procvardef
then
693 aktprocsym
^.definition
^.setmangledname(target_os
.Cprefix
+realname
);
694 { do not copy on local !! }
695 if (aktprocsym
^.definition
^.deftype
=procdef
) and
696 assigned(aktprocsym
^.definition
^.parast
) then
697 aktprocsym
^.definition
^.parast
^.foreach({$ifndef TP}@{$endif}resetvaluepara
);
701 procedure pd_pascal(const procnames
:Tstringcontainer
);
702 var st
,parast
: psymtable
;
705 new(st
,init(parasymtable
));
706 parast
:=aktprocsym
^.definition
^.parast
;
708 while assigned(parast
^.symindex
^.first
) and (lastps
<>psym(parast
^.symindex
^.first
)) do
710 ps
:=psym(parast
^.symindex
^.first
);
711 while assigned(ps
^.indexnext
) and (psym(ps
^.indexnext
)<>lastps
) do
712 ps
:=psym(ps
^.indexnext
);
714 { recalculate the corrected offset }
715 { the really_insert_in_data procedure
716 for parasymtable should only calculateoffset PM }
718 { reset the owner correctly }
725 procedure pd_register(const procnames
:Tstringcontainer
);
727 Message1(parser_w_proc_directive_ignored
,'REGISTER');
731 procedure pd_reintroduce(const procnames
:Tstringcontainer
);
733 Message1(parser_w_proc_directive_ignored
,'REINTRODUCE');
737 procedure pd_syscall(const procnames
:Tstringcontainer
);
739 aktprocsym
^.definition
^.forwarddef
:=false;
740 aktprocsym
^.definition
^.extnumber
:=get_intconst
;
744 procedure pd_external(const procnames
:Tstringcontainer
);
746 If import_dll=nil the procedure is assumed to be in another
747 object file. In that object file it should have the name to
748 which import_name is pointing to. Otherwise, the procedure is
749 assumed to be in the DLL to which import_dll is pointing to. In
750 that case either import_nr<>0 or import_name<>nil is true, so
751 the procedure is either imported by number or by name. (DM)
755 import_name
: string;
758 aktprocsym
^.definition
^.forwarddef
:=false;
759 { If the procedure should be imported from a DLL, a constant string follows.
760 This isn't really correct, an contant string expression follows
761 so we check if an semicolon follows, else a string constant have to
765 if not(token
=_SEMICOLON
) and not(idtoken
=_NAME
) then
767 import_dll
:=get_stringconst
;
768 if (idtoken
=_NAME
) then
771 import_name
:=get_stringconst
;
773 if (idtoken
=_INDEX
) then
775 {After the word index follows the index number in the DLL.}
777 import_nr
:=get_intconst
;
779 if (import_nr
=0) and (import_name
='') then
780 {if (aktprocsym^.definition^.options and pocdecl)<>0 then
781 import_name:=aktprocsym^.definition^.mangledname
783 Message(parser_w_empty_import_name);}
784 { this should work both for win32 and Linux !! PM }
785 import_name
:=realname
;
786 if not(current_module
^.uses_imports
) then
788 current_module
^.uses_imports
:=true;
789 importlib
^.preparelib(current_module
^.modulename
^);
791 if not(m_repeat_forward
in aktmodeswitches
) then
793 { we can only have one overloaded here ! }
794 if assigned(aktprocsym
^.definition
^.nextoverloaded
) then
795 importlib
^.importprocedure(aktprocsym
^.definition
^.nextoverloaded
^.mangledname
,
796 import_dll
,import_nr
,import_name
)
798 importlib
^.importprocedure(aktprocsym
^.mangledname
,import_dll
,import_nr
,import_name
);
801 importlib
^.importprocedure(aktprocsym
^.mangledname
,import_dll
,import_nr
,import_name
);
805 if (idtoken
=_NAME
) then
808 import_name
:=get_stringconst
;
809 aktprocsym
^.definition
^.setmangledname(import_name
);
813 { external shouldn't override the cdecl/system name }
814 if not (pocall_clearstack
in aktprocsym
^.definition
^.proccalloptions
) then
815 aktprocsym
^.definition
^.setmangledname(aktprocsym
^.name
);
831 pd_handler
=procedure(const procnames
:Tstringcontainer
);
835 handler
: pd_handler
;
836 pocall
: tproccalloptions
;
837 pooption
: tprocoptions
;
838 mutexclpocall
: tproccalloptions
;
839 mutexclpotype
: tproctypeoptions
;
840 mutexclpo
: tprocoptions
;
843 {Should contain the number of procedure directives we support.}
844 num_proc_directives
=31;
845 proc_direcdata
:array[1..num_proc_directives
] of proc_dir_rec
=
849 pd_flags
: pd_interface
+pd_object
;
850 handler
: {$ifndef TP}@{$endif}pd_abstract
;
852 pooption
: [po_abstractmethod
];
853 mutexclpocall
: [pocall_internproc
,pocall_inline
];
854 mutexclpotype
: [potype_constructor
,potype_destructor
];
855 mutexclpo
: [po_exports
,po_interrupt
,po_external
]
858 pd_flags
: pd_implemen
+pd_body
;
859 handler
: {$ifndef TP}@{$endif}pd_alias
;
862 mutexclpocall
: [pocall_inline
];
864 mutexclpo
: [po_external
]
867 pd_flags
: pd_interface
+pd_implemen
;
868 handler
: {$ifndef TP}@{$endif}pd_asmname
;
869 pocall
: [pocall_cdecl
,pocall_clearstack
];
870 pooption
: [po_external
];
871 mutexclpocall
: [pocall_internproc
];
873 mutexclpo
: [po_external
]
876 pd_flags
: pd_implemen
+pd_body
;
879 pooption
: [po_assembler
];
882 mutexclpo
: [po_external
]
885 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
886 handler
: {$ifndef TP}@{$endif}pd_cdecl
;
887 pocall
: [pocall_cdecl
,pocall_clearstack
];
888 pooption
: [po_savestdregs
];
889 mutexclpocall
: [pocall_internproc
,pocall_leftright
,pocall_inline
];
891 mutexclpo
: [po_assembler
,po_external
]
894 pd_flags
: pd_interface
+pd_object
;
895 handler
: {$ifndef TP}@{$endif}pd_virtual
;
897 pooption
: [po_virtualmethod
];
898 mutexclpocall
: [pocall_internproc
,pocall_inline
];
900 mutexclpo
: [po_exports
,po_interrupt
,po_external
]
903 pd_flags
: pd_body
+pd_global
+pd_interface
+pd_implemen
{??};
904 handler
: {$ifndef TP}@{$endif}pd_export
;
906 pooption
: [po_exports
];
907 mutexclpocall
: [pocall_internproc
,pocall_inline
];
909 mutexclpo
: [po_external
,po_interrupt
]
912 pd_flags
: pd_implemen
+pd_interface
;
913 handler
: {$ifndef TP}@{$endif}pd_external
;
915 pooption
: [po_external
];
916 mutexclpocall
: [pocall_internproc
,pocall_inline
,pocall_palmossyscall
];
918 mutexclpo
: [po_exports
,po_interrupt
,po_assembler
]
921 pd_flags
: pd_implemen
+pd_body
+pd_interface
+pd_procvar
;
922 handler
: {$ifndef TP}@{$endif}pd_far
;
925 mutexclpocall
: [pocall_internproc
,pocall_inline
];
930 pd_flags
: pd_implemen
;
931 handler
: {$ifndef TP}@{$endif}pd_forward
;
934 mutexclpocall
: [pocall_internproc
,pocall_inline
];
936 mutexclpo
: [po_external
]
939 pd_flags
: pd_implemen
+pd_body
;
940 handler
: {$ifndef TP}@{$endif}pd_inline
;
941 pocall
: [pocall_inline
];
943 mutexclpocall
: [pocall_internproc
];
944 mutexclpotype
: [potype_constructor
,potype_destructor
];
945 mutexclpo
: [po_exports
,po_external
,po_interrupt
]
948 pd_flags
: pd_implemen
+pd_body
;
949 handler
: {$ifndef TP}@{$endif}pd_intern
;
950 pocall
: [pocall_internconst
];
953 mutexclpotype
: [potype_operator
];
957 pd_flags
: pd_implemen
;
958 handler
: {$ifndef TP}@{$endif}pd_intern
;
959 pocall
: [pocall_internproc
];
961 mutexclpocall
: [pocall_inline
,pocall_clearstack
,pocall_leftright
,pocall_cdecl
];
962 mutexclpotype
: [potype_constructor
,potype_destructor
,potype_operator
];
963 mutexclpo
: [po_exports
,po_external
,po_interrupt
,po_assembler
,po_iocheck
]
966 pd_flags
: pd_implemen
+pd_body
;
967 handler
: {$ifndef TP}@{$endif}pd_interrupt
;
969 pooption
: [po_interrupt
];
970 mutexclpocall
: [pocall_internproc
,pocall_cdecl
,pocall_clearstack
,pocall_leftright
,pocall_inline
];
971 mutexclpotype
: [potype_constructor
,potype_destructor
,potype_operator
];
972 mutexclpo
: [po_external
]
975 pd_flags
: pd_implemen
+pd_body
;
978 pooption
: [po_iocheck
];
979 mutexclpocall
: [pocall_internproc
];
981 mutexclpo
: [po_external
]
984 pd_flags
: pd_interface
+pd_object
;
985 handler
: {$ifndef TP}@{$endif}pd_message
;
987 pooption
: []; { can be po_msgstr or po_msgint }
988 mutexclpocall
: [pocall_inline
,pocall_internproc
];
989 mutexclpotype
: [potype_constructor
,potype_destructor
,potype_operator
];
990 mutexclpo
: [po_interrupt
,po_external
]
993 pd_flags
: pd_implemen
+pd_body
+pd_procvar
;
994 handler
: {$ifndef TP}@{$endif}pd_near
;
997 mutexclpocall
: [pocall_internproc
];
1002 pd_flags
: pd_implemen
+pd_interface
+pd_body
;
1003 handler
: {$ifndef TP}@{$endif}pd_overload
;
1005 pooption
: [po_overload
];
1006 mutexclpocall
: [pocall_internproc
];
1011 pd_flags
: pd_interface
+pd_object
;
1012 handler
: {$ifndef TP}@{$endif}pd_override
;
1014 pooption
: [po_overridingmethod
,po_virtualmethod
];
1015 mutexclpocall
: [pocall_inline
,pocall_internproc
];
1017 mutexclpo
: [po_exports
,po_external
,po_interrupt
]
1020 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1021 handler
: {$ifndef TP}@{$endif}pd_pascal
;
1022 pocall
: [pocall_leftright
];
1024 mutexclpocall
: [pocall_leftright
,pocall_cdecl
,pocall_internproc
,
1025 pocall_stdcall
,pocall_clearstack
,pocall_inline
];
1027 mutexclpo
: [po_external
]
1030 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1032 pocall
: [pocall_clearstack
];
1034 mutexclpocall
: [pocall_inline
,pocall_internproc
];
1036 mutexclpo
: [po_assembler
,po_external
]
1039 pd_flags
: pd_implemen
+pd_body
+pd_global
+pd_notobject
;
1043 mutexclpocall
: [pocall_internproc
,pocall_inline
];
1045 mutexclpo
: [po_external
]
1048 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1049 handler
: {$ifndef TP}@{$endif}pd_register
;
1050 pocall
: [pocall_register
];
1052 mutexclpocall
: [pocall_leftright
,pocall_cdecl
,pocall_internproc
];
1054 mutexclpo
: [po_external
]
1057 pd_flags
: pd_interface
+pd_object
;
1058 handler
: {$ifndef TP}@{$endif}pd_reintroduce
;
1066 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1067 handler
: {$ifndef TP}@{$endif}pd_safecall
;
1068 pocall
: [pocall_safecall
];
1069 pooption
: [po_savestdregs
];
1070 mutexclpocall
: [pocall_leftright
,pocall_cdecl
,pocall_internproc
,pocall_inline
];
1072 mutexclpo
: [po_external
]
1074 idtok
:_SAVEREGISTERS
;
1075 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1078 pooption
: [po_saveregisters
];
1079 mutexclpocall
: [pocall_internproc
];
1081 mutexclpo
: [po_external
]
1084 pd_flags
: pd_interface
+pd_object
;
1085 handler
: {$ifndef TP}@{$endif}pd_static
;
1087 pooption
: [po_staticmethod
];
1088 mutexclpocall
: [pocall_inline
,pocall_internproc
];
1089 mutexclpotype
: [potype_constructor
,potype_destructor
];
1090 mutexclpo
: [po_external
,po_interrupt
,po_exports
]
1093 pd_flags
: pd_interface
+pd_implemen
+pd_body
+pd_procvar
;
1094 handler
: {$ifndef TP}@{$endif}pd_stdcall
;
1095 pocall
: [pocall_stdcall
];
1096 pooption
: [po_savestdregs
];
1097 mutexclpocall
: [pocall_leftright
,pocall_cdecl
,pocall_inline
,pocall_internproc
];
1099 mutexclpo
: [po_external
]
1102 pd_flags
: pd_interface
;
1103 handler
: {$ifndef TP}@{$endif}pd_syscall
;
1104 pocall
: [pocall_palmossyscall
];
1106 mutexclpocall
: [pocall_cdecl
,pocall_inline
,pocall_internproc
];
1108 mutexclpo
: [po_external
,po_assembler
,po_interrupt
,po_exports
]
1111 pd_flags
: pd_implemen
;
1112 handler
: {$ifndef TP}@{$endif}pd_system
;
1113 pocall
: [pocall_clearstack
];
1115 mutexclpocall
: [pocall_leftright
,pocall_inline
,pocall_internproc
];
1117 mutexclpo
: [po_external
,po_assembler
,po_interrupt
]
1120 pd_flags
: pd_interface
+pd_object
;
1121 handler
: {$ifndef TP}@{$endif}pd_virtual
;
1123 pooption
: [po_virtualmethod
];
1124 mutexclpocall
: [pocall_inline
,pocall_internproc
];
1126 mutexclpo
: [po_external
,po_interrupt
,po_exports
]
1131 function is_proc_directive(tok
:ttoken
):boolean;
1135 is_proc_directive
:=false;
1136 for i
:=1 to num_proc_directives
do
1137 if proc_direcdata
[i
].idtok
=idtoken
then
1139 is_proc_directive
:=true;
1145 function parse_proc_direc(const proc_names
:Tstringcontainer
;var pdflags
:word):boolean;
1147 Parse the procedure directive, returns true if a correct directive is found
1154 parse_proc_direc
:=false;
1157 for p
:=1 to num_proc_directives
do
1158 if proc_direcdata
[p
].idtok
=idtoken
then
1164 { Check if the procedure directive is known }
1167 { parsing a procvar type the name can be any
1169 if (pdflags
and (pd_procvar
or pd_object
))=0 then
1170 Message1(parser_w_unknown_proc_directive_ignored
,name
);
1174 { static needs a special treatment }
1175 if (idtoken
=_STATIC
) and not (cs_static_keyword
in aktmoduleswitches
) then
1178 { Conflicts between directives ? }
1179 if (aktprocsym
^.definition
^.proctypeoption
in proc_direcdata
[p
].mutexclpotype
) or
1180 ((aktprocsym
^.definition
^.proccalloptions
*proc_direcdata
[p
].mutexclpocall
)<>[]) or
1181 ((aktprocsym
^.definition
^.procoptions
*proc_direcdata
[p
].mutexclpo
)<>[]) then
1183 Message1(parser_e_proc_dir_conflict
,name
);
1187 { Check if the directive is only for objects }
1188 if ((proc_direcdata
[p
].pd_flags
and pd_object
)<>0) and
1189 not assigned(aktprocsym
^.definition
^._class
) then
1193 { check if method and directive not for object public }
1194 if ((proc_direcdata
[p
].pd_flags
and pd_notobject
)<>0) and
1195 assigned(aktprocsym
^.definition
^._class
) then
1200 { consume directive, and turn flag on }
1202 parse_proc_direc
:=true;
1204 { Check the pd_flags if the directive should be allowed }
1205 if ((pdflags
and pd_interface
)<>0) and
1206 ((proc_direcdata
[p
].pd_flags
and pd_interface
)=0) then
1208 Message1(parser_e_proc_dir_not_allowed_in_interface
,name
);
1211 if ((pdflags
and pd_implemen
)<>0) and
1212 ((proc_direcdata
[p
].pd_flags
and pd_implemen
)=0) then
1214 Message1(parser_e_proc_dir_not_allowed_in_implementation
,name
);
1217 if ((pdflags
and pd_procvar
)<>0) and
1218 ((proc_direcdata
[p
].pd_flags
and pd_procvar
)=0) then
1220 Message1(parser_e_proc_dir_not_allowed_in_procvar
,name
);
1224 { Return the new pd_flags }
1225 if (proc_direcdata
[p
].pd_flags
and pd_body
)=0 then
1226 pdflags
:=pdflags
and (not pd_body
);
1227 if (proc_direcdata
[p
].pd_flags
and pd_global
)<>0 then
1228 pdflags
:=pdflags
or pd_global
;
1230 { Add the correct flag }
1231 aktprocsym
^.definition
^.proccalloptions
:=aktprocsym
^.definition
^.proccalloptions
+proc_direcdata
[p
].pocall
;
1232 aktprocsym
^.definition
^.procoptions
:=aktprocsym
^.definition
^.procoptions
+proc_direcdata
[p
].pooption
;
1234 { Adjust positions of args for cdecl or stdcall }
1235 if (aktprocsym
^.definition
^.deftype
=procdef
) and
1236 (([pocall_cdecl
,pocall_stdcall
]*aktprocsym
^.definition
^.proccalloptions
)<>[]) then
1237 aktprocsym
^.definition
^.parast
^.set_alignment(target_os
.size_of_longint
);
1239 { Call the handler }
1240 if pointer({$ifndef FPC}@{$endif}proc_direcdata
[p
].handler
)<>nil then
1241 proc_direcdata
[p
].handler(proc_names
);
1244 {***************************************************************************}
1246 function check_identical_proc(var p
: pprocdef
) : boolean;
1248 Search for idendical definitions,
1249 if there is a forward, then kill this.
1251 Returns the result of the forward check.
1253 Removed from unter_dec to keep the source readable
1257 storeparast
: psymtable
;
1261 check_identical_proc
:=false;
1263 pd
:=aktprocsym
^.definition
;
1264 if assigned(pd
) then
1266 { Is there an overload/forward ? }
1267 if assigned(pd
^.nextoverloaded
) then
1269 { walk the procdef list }
1270 while (assigned(pd
)) and (assigned(pd
^.nextoverloaded
)) do
1272 hd
:=pd
^.nextoverloaded
;
1274 { check the parameters }
1275 if (not(m_repeat_forward
in aktmodeswitches
) and
1276 (aktprocsym
^.definition
^.para
^.count
=0)) or
1277 (equal_paras(aktprocsym
^.definition
^.para
,hd
^.para
,cp_none
) and
1278 { for operators equal_paras is not enough !! }
1279 ((aktprocsym
^.definition
^.proctypeoption
<>potype_operator
) or (optoken
<>_ASSIGNMENT
) or
1280 is_equal(hd
^.rettype
.def
,aktprocsym
^.definition
^.rettype
.def
))) then
1282 if not equal_paras(aktprocsym
^.definition
^.para
,hd
^.para
,cp_all
) and
1283 ((m_repeat_forward
in aktmodeswitches
) or
1284 (aktprocsym
^.definition
^.para
^.count
>0)) then
1286 MessagePos1(aktprocsym
^.definition
^.fileinfo
,parser_e_header_dont_match_forward
,
1287 aktprocsym
^.demangledName
);
1290 if hd
^.forwarddef
then
1291 { remove the forward definition but don't delete it, }
1292 { the symtable is the owner !! }
1294 { Check if the procedure type and return type are correct }
1295 if (hd
^.proctypeoption
<>aktprocsym
^.definition
^.proctypeoption
) or
1296 (not(is_equal(hd
^.rettype
.def
,aktprocsym
^.definition
^.rettype
.def
)) and
1297 (m_repeat_forward
in aktmodeswitches
)) then
1299 MessagePos1(aktprocsym
^.definition
^.fileinfo
,parser_e_header_dont_match_forward
,
1300 aktprocsym
^.demangledName
);
1303 { Check calling convention, no check for internconst,internproc which
1304 are only defined in interface or implementation }
1305 if (hd
^.proccalloptions
-[pocall_internconst
,pocall_internproc
]<>
1306 aktprocsym
^.definition
^.proccalloptions
-[pocall_internconst
,pocall_internproc
]) then
1308 { only trigger an error, becuase it doesn't hurt, for delphi check
1309 if the current implementation has no proccalloptions, then
1310 take the options from the interface }
1311 if (m_delphi
in aktmodeswitches
) then
1313 if (aktprocsym
^.definition
^.proccalloptions
=[]) then
1314 aktprocsym
^.definition
^.proccalloptions
:=hd
^.proccalloptions
1316 MessagePos(aktprocsym
^.definition
^.fileinfo
,parser_e_call_convention_dont_match_forward
);
1319 MessagePos(aktprocsym
^.definition
^.fileinfo
,parser_e_call_convention_dont_match_forward
);
1320 { set the mangledname to the interface name so it doesn't trigger
1321 the Note about different manglednames (PFV) }
1322 aktprocsym
^.definition
^.setmangledname(hd
^.mangledname
);
1324 { manglednames are equal? }
1326 if (m_repeat_forward
in aktmodeswitches
) or
1327 aktprocsym
^.definition
^.haspara
then
1329 if (hd
^.mangledname
<>aktprocsym
^.definition
^.mangledname
) then
1331 if not(po_external
in aktprocsym
^.definition
^.procoptions
) then
1332 MessagePos2(aktprocsym
^.definition
^.fileinfo
,parser_n_interface_name_diff_implementation_name
,hd
^.mangledname
,
1333 aktprocsym
^.definition
^.mangledname
);
1334 { reset the mangledname of the interface part to be sure }
1335 { this is wrong because the mangled name might have been used already !! }
1337 renameasmsymbol(hd
^.mangledname
,aktprocsym
^.definition
^.mangledname
);
1338 hd
^.setmangledname(aktprocsym
^.definition
^.mangledname
);
1339 { so we need to keep the name of interface !!
1340 No!!!! The procedure directives can change the mangledname.
1341 I fixed this by first calling check_identical_proc and then doing
1342 the proc directives, but this is not a good solution.(DM)}
1343 { this is also wrong (PM)
1344 aktprocsym^.definition^.setmangledname(hd^.mangledname);}
1348 { If mangled names are equal, therefore }
1349 { they have the same number of parameters }
1350 { Therefore we can check the name of these }
1352 if hd
^.forwarddef
and aktprocsym
^.definition
^.forwarddef
then
1354 MessagePos1(aktprocsym
^.definition
^.fileinfo
,
1355 parser_e_function_already_declared_public_forward
,aktprocsym
^.demangledName
);
1356 check_identical_proc
:=true;
1357 { Remove other forward from the list to reduce errors }
1358 pd
^.nextoverloaded
:=pd
^.nextoverloaded
^.nextoverloaded
;
1361 ad
:=psym(hd
^.parast
^.symindex
^.first
);
1362 fd
:=psym(aktprocsym
^.definition
^.parast
^.symindex
^.first
);
1363 if assigned(ad
) and assigned(fd
) then
1365 while assigned(ad
) and assigned(fd
) do
1370 MessagePos3(aktprocsym
^.definition
^.fileinfo
,parser_e_header_different_var_names
,
1371 aktprocsym
^.name
,s
,fd
^.name
);
1374 { it is impossible to have a nil pointer }
1375 { for only one parameter - since they }
1376 { have the same number of parameters. }
1377 { Left = next parameter. }
1384 { also the para_offset }
1385 hd
^.parast
^.address_fixup
:=aktprocsym
^.definition
^.parast
^.address_fixup
;
1388 { remove pd^.nextoverloaded from the list }
1389 { and add aktprocsym^.definition }
1390 pd
^.nextoverloaded
:=pd
^.nextoverloaded
^.nextoverloaded
;
1391 hd
^.nextoverloaded
:=aktprocsym
^.definition
^.nextoverloaded
;
1392 { Alert! All fields of aktprocsym^.definition that are modified
1393 by the procdir handlers must be copied here!.}
1394 hd
^.forwarddef
:=false;
1395 hd
^.hasforward
:=true;
1396 hd
^.proccalloptions
:=hd
^.proccalloptions
+ aktprocsym
^.definition
^.proccalloptions
;
1397 hd
^.procoptions
:=hd
^.procoptions
+ aktprocsym
^.definition
^.procoptions
;
1398 if aktprocsym
^.definition
^.extnumber
=-1 then
1399 aktprocsym
^.definition
^.extnumber
:=hd
^.extnumber
1401 if hd
^.extnumber
=-1 then
1402 hd
^.extnumber
:=aktprocsym
^.definition
^.extnumber
;
1403 { switch parast for warning in implementation PM }
1404 if (m_repeat_forward
in aktmodeswitches
) or
1405 aktprocsym
^.definition
^.haspara
then
1407 storeparast
:=hd
^.parast
;
1408 hd
^.parast
:=aktprocsym
^.definition
^.parast
;
1409 aktprocsym
^.definition
^.parast
:=storeparast
;
1411 if pd
=aktprocsym
^.definition
then
1415 aktprocsym
^.definition
:=hd
;
1416 check_identical_proc
:=true;
1419 { abstract methods aren't forward defined, but this }
1420 { needs another error message }
1421 if not(po_abstractmethod
in pd
^.nextoverloaded
^.procoptions
) then
1422 MessagePos(aktprocsym
^.definition
^.fileinfo
,parser_e_overloaded_have_same_parameters
)
1424 MessagePos(aktprocsym
^.definition
^.fileinfo
,parser_e_abstract_no_definition
);
1428 { check for allowing overload directive }
1429 if not(m_fpc
in aktmodeswitches
) then
1431 { overload directive turns on overloading }
1432 if ((po_overload
in aktprocsym
^.definition
^.procoptions
) or
1433 ((po_overload
in hd
^.procoptions
))) then
1435 { check if all procs have overloading, but not if the proc was
1436 already declared forward, then the check is already done }
1437 if not(hd
^.hasforward
) and
1438 (aktprocsym
^.definition
^.forwarddef
=hd
^.forwarddef
) and
1439 not((po_overload
in aktprocsym
^.definition
^.procoptions
) and
1440 ((po_overload
in hd
^.procoptions
))) then
1442 MessagePos1(aktprocsym
^.definition
^.fileinfo
,parser_e_no_overload_for_all_procs
,aktprocsym
^.name
);
1448 if not(hd
^.forwarddef
) then
1450 MessagePos(aktprocsym
^.definition
^.fileinfo
,parser_e_procedure_overloading_is_off
);
1456 { try next overloaded }
1457 pd
:=pd
^.nextoverloaded
;
1462 { there is no overloaded, so its always identical with itself }
1463 check_identical_proc
:=true;
1466 { insert opsym only in the right symtable }
1467 if ((procinfo
^.flags
and pi_operator
)<>0) and assigned(opsym
)
1468 and not parse_only
then
1470 if ret_in_param(aktprocsym
^.definition
^.rettype
.def
) then
1472 pprocdef(aktprocsym
^.definition
)^.parast
^.insert(opsym
);
1473 { this increases the data size }
1474 { correct this to get the right ret $value }
1475 dec(pprocdef(aktprocsym
^.definition
)^.parast
^.datasize
,opsym
^.getpushsize
);
1476 { this allows to read the funcretoffset }
1478 opsym
^.varspez
:=vs_var
;
1481 pprocdef(aktprocsym
^.definition
)^.localst
^.insert(opsym
);
1485 procedure compile_proc_body(const proc_names
:Tstringcontainer
;
1486 make_global
,parent_has_class
:boolean);
1488 Compile the body of a procedure
1491 oldexitlabel
,oldexit2label
: pasmlabel
;
1492 oldfaillabel
,oldquickexitlabel
:Pasmlabel
;
1493 _class
,hp
:Pobjectdef
;
1494 { switches can change inside the procedure }
1495 entryswitches
, exitswitches
: tlocalswitches
;
1496 oldaktmaxfpuregisters
,localmaxfpuregisters
: longint;
1497 { code for the subroutine as tree }
1503 { size of the local strackframe }
1505 { true when no stackframe is required }
1506 nostackframe
:boolean;
1507 { number of bytes which have to be cleared by RET }
1512 exitpos
: tfileposinfo
;
1514 { calculate the lexical level }
1517 Message(parser_e_too_much_lexlevel
);
1519 { static is also important for local procedures !! }
1520 if (po_staticmethod
in aktprocsym
^.definition
^.procoptions
) then
1521 allow_only_static
:=true
1522 else if (lexlevel
=normal_function_level
) then
1523 allow_only_static
:=false;
1526 oldexitlabel
:=aktexitlabel
;
1527 oldexit2label
:=aktexit2label
;
1528 oldquickexitlabel
:=quickexitlabel
;
1529 oldfaillabel
:=faillabel
;
1531 getlabel(aktexitlabel
);
1532 getlabel(aktexit2label
);
1533 { exit for fail in constructors }
1534 if (aktprocsym
^.definition
^.proctypeoption
=potype_constructor
) then
1536 getlabel(faillabel
);
1537 getlabel(quickexitlabel
);
1539 { reset break and continue labels }
1540 block_type
:=bt_general
;
1542 aktcontinuelabel
:=nil;
1544 { insert symtables for the class, by only if it is no nested function }
1545 if assigned(procinfo
^._class
) and not(parent_has_class
) then
1547 { insert them in the reverse order ! }
1550 _class
:=procinfo
^._class
;
1551 while _class
^.childof
<>hp
do
1552 _class
:=_class
^.childof
;
1554 _class
^.symtable
^.next
:=symtablestack
;
1555 symtablestack
:=_class
^.symtable
;
1556 until hp
=procinfo
^._class
;
1559 { insert parasymtable in symtablestack}
1560 { only if lexlevel > 1 !!! global symtable should be right after staticsymtazble
1561 for checking of same names used in interface and implementation !! }
1562 if lexlevel
>=normal_function_level
then
1564 aktprocsym
^.definition
^.parast
^.next
:=symtablestack
;
1565 symtablestack
:=aktprocsym
^.definition
^.parast
;
1566 symtablestack
^.symtablelevel
:=lexlevel
;
1568 { insert localsymtable in symtablestack}
1569 aktprocsym
^.definition
^.localst
^.next
:=symtablestack
;
1570 symtablestack
:=aktprocsym
^.definition
^.localst
;
1571 symtablestack
^.symtablelevel
:=lexlevel
;
1572 { constant symbols are inserted in this symboltable }
1573 constsymtable
:=symtablestack
;
1575 { reset the temporary memory }
1581 { no registers are used }
1585 entrypos
:=aktfilepos
;
1586 entryswitches
:=aktlocalswitches
;
1587 localmaxfpuregisters
:=aktmaxfpuregisters
;
1590 { parse the code ... }
1591 if (po_assembler
in aktprocsym
^.definition
^.procoptions
) then
1592 code
:=convtree2node(assembler_block
)
1594 code
:=convtree2node(block(current_module
^.islibrary
));
1596 { parse the code ... }
1597 if (po_assembler
in aktprocsym
^.definition
^.procoptions
) then
1598 code
:=assembler_block
1600 code
:=block(current_module
^.islibrary
);
1602 { parse the code ... }
1603 if (po_assembler
in aktprocsym
^.definition
^.procoptions
) then
1604 code
:=assembler_block
1606 code
:=block(current_module
^.islibrary
);
1609 { get a better entry point }
1610 if assigned(code
) then
1611 entrypos
:=code
^.fileinfo
;
1614 exitswitches
:=aktlocalswitches
;
1615 exitpos
:=last_endtoken_filepos
;
1617 { save current filepos }
1618 savepos
:=aktfilepos
;
1620 {When we are called to compile the body of a unit, aktprocsym should
1621 point to the unit initialization. If the unit has no initialization,
1622 aktprocsym=nil. But in that case code=nil. hus we should check for
1623 code=nil, when we use aktprocsym.}
1625 { set the framepointer to esp for assembler functions }
1626 { but only if the are no local variables }
1627 { already done in assembler_block }
1629 tg
.setfirsttemp(procinfo
^.firsttemp_offset
);
1631 setfirsttemp(procinfo
^.firsttemp_offset
);
1634 { ... and generate assembler }
1635 { but set the right switches for entry !! }
1636 aktlocalswitches
:=entryswitches
;
1637 oldaktmaxfpuregisters
:=aktmaxfpuregisters
;
1638 aktmaxfpuregisters
:=localmaxfpuregisters
;
1641 if assigned(code
) then
1644 if assigned(code
) then
1647 { set switches to status at end of procedure }
1648 aktlocalswitches
:=exitswitches
;
1650 if assigned(code
) then
1652 aktprocsym
^.definition
^.code
:=code
;
1654 { the procedure is now defined }
1655 aktprocsym
^.definition
^.forwarddef
:=false;
1659 stackframe
:=tg
.gettempsize
;
1661 stackframe
:=gettempsize
;
1664 { first generate entry code with the correct position and switches }
1665 aktfilepos
:=entrypos
;
1666 aktlocalswitches
:=entryswitches
;
1668 if assigned(code
) then
1669 cg
^.g_entrycode(procinfo
^.aktentrycode
,proc_names
,make_global
,stackframe
,parasize
,nostackframe
,false);
1671 if assigned(code
) then
1672 genentrycode(procinfo
^.aktentrycode
,proc_names
,make_global
,stackframe
,parasize
,nostackframe
,false);
1675 { FPC_POPADDRSTACK destroys all registers (JM) }
1676 if (procinfo
^.flags
and (pi_needs_implicit_finally
or pi_uses_exceptions
)) <> 0 then
1679 { now generate exit code with the correct position and switches }
1680 aktfilepos
:=exitpos
;
1681 aktlocalswitches
:=exitswitches
;
1682 if assigned(code
) then
1685 cg
^.g_exitcode(procinfo
^.aktexitcode
,parasize
,nostackframe
,false);
1687 genexitcode(procinfo
^.aktexitcode
,parasize
,nostackframe
,false);
1689 { Now we can set the used registers }
1691 aktprocsym
^.definition
^.usedregisters
:=tg
.usedinproc
;
1693 aktprocsym
^.definition
^.usedregisters
:=usedinproc
;
1696 procinfo
^.aktproccode
^.insertlist(procinfo
^.aktentrycode
);
1697 procinfo
^.aktproccode
^.concatlist(procinfo
^.aktexitcode
);
1700 if (cs_optimize
in aktglobalswitches
) and
1701 { do not optimize pure assembler procedures }
1702 ((procinfo
^.flags
and pi_is_assembler
)=0) then
1703 Optimize(procinfo
^.aktproccode
);
1706 { save local data (casetable) also in the same file }
1707 if assigned(procinfo
^.aktlocaldata
) and
1708 (not procinfo
^.aktlocaldata
^.empty
) then
1710 procinfo
^.aktproccode
^.concat(new(pai_section
,init(sec_data
)));
1711 procinfo
^.aktproccode
^.concatlist(procinfo
^.aktlocaldata
);
1712 procinfo
^.aktproccode
^.concat(new(pai_section
,init(sec_code
)));
1714 { now we can insert a cut }
1715 if (cs_create_smart
in aktmoduleswitches
) then
1716 codesegment
^.concat(new(pai_cut
,init
));
1718 { add the procedure to the codesegment }
1719 codesegment
^.concatlist(procinfo
^.aktproccode
);
1722 if assigned(code
) then
1726 { ... remove symbol tables, for the browser leave the static table }
1727 { if (cs_browser in aktmoduleswitches) and (symtablestack^.symtabletype=staticsymtable) then
1728 symtablestack^.next:=symtablestack^.next^.next
1730 if lexlevel
>=normal_function_level
then
1731 symtablestack
:=symtablestack
^.next
^.next
1733 symtablestack
:=symtablestack
^.next
;
1735 { ... check for unused symbols }
1736 { but only if there is no asm block }
1737 if assigned(code) then
1739 if (Errorcount=0) then
1741 aktprocsym^.definition^.localst^.check_forwards;
1742 aktprocsym^.definition^.localst^.checklabels;
1744 if (procinfo^.flags and pi_uses_asm)=0 then
1746 { not for unit init, becuase the var can be used in finalize,
1747 it will be done in proc_unit }
1748 if not(aktprocsym^.definition^.proctypeoption
1749 in [potype_proginit,potype_unitinit,potype_unitfinalize]) then
1750 aktprocsym^.definition^.localst^.allsymbolsused;
1751 aktprocsym^.definition^.parast^.allsymbolsused;
1755 { the local symtables can be deleted, but the parast }
1756 { doesn't, (checking definitons when calling a }
1758 { not for a inline procedure !! (PM) }
1759 { at lexlevel = 1 localst is the staticsymtable itself }
1760 { so no dispose here !! }
1761 if assigned(code) and
1762 not(cs_browser in aktmoduleswitches) and
1763 not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
1765 if lexlevel>=normal_function_level then
1766 dispose(aktprocsym^.definition^.localst,done);
1767 aktprocsym^.definition^.localst:=nil;
1771 { all registers can be used again }
1772 tg.resetusableregisters;
1773 { only now we can remove the temps }
1776 { all registers can be used again }
1777 resetusableregisters;
1778 { only now we can remove the temps }
1782 { remove code tree, if not inline procedure }
1783 if assigned(code) and not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
1785 {!!!!!!! dispose(code,done); }
1791 { remove class member symbol tables }
1792 while symtablestack^.symtabletype=objectsymtable do
1793 symtablestack:=symtablestack^.next;
1795 aktmaxfpuregisters:=oldaktmaxfpuregisters;
1797 { restore filepos, the switches are already set }
1798 aktfilepos:=savepos;
1800 aktexitlabel:=oldexitlabel;
1801 aktexit2label:=oldexit2label;
1802 quickexitlabel:=oldquickexitlabel;
1803 faillabel:=oldfaillabel;
1805 { reset to normal non static function }
1806 if (lexlevel=normal_function_level) then
1807 allow_only_static:=false;
1808 { previous lexlevel }
1813 procedure parse_proc_directives(Anames:Pstringcontainer;var pdflags:word);
1815 Parse the procedure directives. It does not matter if procedure directives
1816 are written using ;procdir; or ['procdir'] syntax.
1821 while token in [_ID,_LECKKLAMMER] do
1823 if try_to_consume(_LECKKLAMMER) then
1826 parse_proc_direc(Anames^,pdflags);
1827 until not try_to_consume(_COMMA);
1828 consume(_RECKKLAMMER);
1829 { we always expect at least '[];' }
1833 res:=parse_proc_direc(Anames^,pdflags);
1834 { A procedure directive normally followed by a semicolon, but in
1835 a const section we should stop when _EQUAL is found }
1838 if (block_type=bt_const) and
1841 { support procedure proc;stdcall export; in Delphi mode only }
1842 if not((m_delphi in aktmodeswitches) and
1843 is_proc_directive(token)) then
1844 consume(_SEMICOLON);
1851 procedure parse_var_proc_directives(var sym : psym);
1853 anames : pstringcontainer;
1856 pd : pabstractprocdef;
1859 anames:=new(pstringcontainer,init);
1860 pdflags:=pd_procvar;
1861 { we create a temporary aktprocsym to read the directives }
1862 aktprocsym:=new(pprocsym,init(sym^.name));
1865 pd:=pabstractprocdef(pvarsym(sym)^.vartype.def);
1867 pd:=pabstractprocdef(ptypedconstsym(sym)^.typedconsttype.def);
1869 pd:=pabstractprocdef(ptypesym(sym)^.restype.def);
1871 internalerror(994932432);
1873 if pd^.deftype<>procvardef then
1874 internalerror(994932433);
1875 pabstractprocdef(aktprocsym^.definition):=pd;
1876 { names should never be used anyway }
1878 parse_proc_directives(anames,pdflags);
1880 aktprocsym^.definition:=nil;
1881 dispose(aktprocsym,done);
1882 dispose(anames,done);
1886 procedure parse_object_proc_directives(var sym : pprocsym);
1888 anames : pstringcontainer;
1892 anames:=new(pstringcontainer,init);
1894 parse_proc_directives(anames,pdflags);
1896 dispose(anames,done);
1897 if (po_containsself in aktprocsym^.definition^.procoptions) and
1898 (([po_msgstr,po_msgint]*aktprocsym^.definition^.procoptions)=[]) then
1899 Message(parser_e_self_in_non_message_handler);
1902 procedure checkvaluepara(p:pnamedindexobject);{$ifndef FPC}far;{$endif}
1909 if copy(name,1,3)='val' then
1911 s:=Copy(name,4,255);
1912 if not(po_assembler in aktprocsym^.definition^.procoptions) then
1914 vs:=new(Pvarsym,initdef(s,vartype.def));
1915 vs^.fileinfo:=fileinfo;
1916 vs^.varspez:=varspez;
1917 aktprocsym^.definition^.localst^.insert(vs);
1919 include(vs^.varoptions,vo_is_local_copy);
1921 vs^.varoptions:=vs^.varoptions+[vo_is_local_copy];
1923 vs^.varstate:=vs_assigned;
1925 inc(refs); { the para was used to set the local copy ! }
1926 { warnings only on local copy ! }
1931 aktprocsym^.definition^.parast^.rename(name,s);
1938 procedure read_proc;
1940 Parses the procedure directives, then parses the procedure body, then
1941 generates the code for it
1945 oldprocsym : Pprocsym;
1946 oldprocinfo : pprocinfo;
1947 oldconstsymtable : Psymtable;
1948 oldfilepos : tfileposinfo;
1949 names : Pstringcontainer;
1951 prevdef,stdef : pprocdef;
1954 oldprocsym:=aktprocsym;
1955 oldprefix:=procprefix;
1956 oldconstsymtable:=constsymtable;
1957 oldprocinfo:=procinfo;
1958 { create a new procedure }
1960 {$ifdef fixLeaksOnError}
1961 strContStack.push(names);
1962 {$endif fixLeaksOnError}
1963 codegen_newprocedure;
1966 parent:=oldprocinfo;
1969 { standard frame pointer }
1970 framepointer:=frame_pointer;
1971 { funcret_is_valid:=false; }
1972 funcret_state:=vs_declared;
1973 { is this a nested function of a method ? }
1974 if assigned(oldprocinfo) then
1975 _class:=oldprocinfo^._class;
1980 procinfo^.sym:=aktprocsym;
1981 procinfo^.def:=aktprocsym^.definition;
1983 { set the default function options }
1986 aktprocsym^.definition^.forwarddef:=true;
1987 { set also the interface flag, for better error message when the
1988 implementation doesn't much this header }
1989 aktprocsym^.definition^.interfacedef:=true;
1990 pdflags:=pd_interface;
1995 if current_module^.in_implementation then
1996 pdflags:=pdflags or pd_implemen;
1997 if (not current_module^.is_unit) or (cs_create_smart in aktmoduleswitches) then
1998 pdflags:=pdflags or pd_global;
1999 procinfo^.exported:=false;
2000 aktprocsym^.definition^.forwarddef:=false;
2003 { parse the directives that may follow }
2005 parse_proc_directives(names,pdflags);
2008 { set aktfilepos to the beginning of the function declaration }
2009 oldfilepos:=aktfilepos;
2010 aktfilepos:=aktprocsym^.definition^.fileinfo;
2012 { search for forward declarations }
2013 if not check_identical_proc(prevdef) then
2015 { A method must be forward defined (in the object declaration) }
2016 if assigned(procinfo^._class) and (not assigned(oldprocinfo^._class)) then
2018 Message1(parser_e_header_dont_match_any_member,aktprocsym^.demangledName);
2019 aktprocsym^.write_parameter_lists(aktprocsym^.definition);
2023 { Give a better error if there is a forward def in the interface and only
2024 a single implementation }
2025 if (not aktprocsym^.definition^.forwarddef) and
2026 assigned(aktprocsym^.definition^.nextoverloaded) and
2027 aktprocsym^.definition^.nextoverloaded^.forwarddef and
2028 aktprocsym^.definition^.nextoverloaded^.interfacedef and
2029 not(assigned(aktprocsym^.definition^.nextoverloaded^.nextoverloaded)) then
2031 Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName);
2032 aktprocsym^.write_parameter_lists(aktprocsym^.definition);
2036 { check the global flag }
2037 if (procinfo^.flags and pi_is_global)<>0 then
2038 Message(parser_e_overloaded_must_be_all_global);
2043 { set return type here, becuase the aktprocsym^.definition can be
2044 changed by check_identical_proc (PFV) }
2045 procinfo^.returntype.def:=aktprocsym^.definition^.rettype.def;
2048 if (po_interrupt in aktprocsym^.definition^.procoptions) then
2050 { we push Flags and CS as long
2051 to cope with the IRETD
2052 and we save 6 register + 4 selectors }
2053 inc(procinfo^.para_offset,8+6*4+4*2);
2057 { pointer to the return value ? }
2058 if ret_in_param(procinfo^.returntype.def) then
2060 procinfo^.return_offset:=procinfo^.para_offset;
2061 inc(procinfo^.para_offset,target_os.size_of_pointer);
2063 { allows to access the parameters of main functions in nested functions }
2064 aktprocsym^.definition^.parast^.address_fixup:=procinfo^.para_offset;
2066 { when it is a value para and it needs a local copy then rename
2067 the parameter and insert a copy in the localst. This is not done
2068 for assembler procedures }
2069 if (not parse_only) and (not aktprocsym^.definition^.forwarddef) then
2070 aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}checkvaluepara);
2072 { restore file pos }
2073 aktfilepos:=oldfilepos;
2075 { compile procedure when a body is needed }
2076 if (pdflags and pd_body)<>0 then
2078 Message1(parser_p_procedure_start,aktprocsym^.demangledname);
2079 names^.insert(aktprocsym^.definition^.mangledname);
2080 { set _FAIL as keyword if constructor }
2081 if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
2082 tokeninfo^[_FAIL].keyword:=m_all;
2083 if assigned(aktprocsym^.definition^._class) then
2084 tokeninfo^[_SELF].keyword:=m_all;
2086 compile_proc_body(names^,((pdflags and pd_global)<>0),assigned(oldprocinfo^._class));
2088 { reset _FAIL as normal }
2089 if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
2090 tokeninfo^[_FAIL].keyword:=m_none;
2091 if assigned(aktprocsym^.definition^._class) and (lexlevel=main_program_level) then
2092 tokeninfo^[_SELF].keyword:=m_none;
2093 consume(_SEMICOLON);
2096 {$ifdef fixLeaksOnError}
2097 if names <> strContStack.pop then
2098 writeln('problem with strContStack in psub!');
2099 {$endif fixLeaksOnError}
2100 dispose(names,done);
2101 codegen_doneprocedure;
2102 { Restore old state }
2103 constsymtable:=oldconstsymtable;
2104 { from now on all refernece to mangledname means
2105 that the function is already used }
2106 aktprocsym^.definition^.count:=true;
2107 { restore the interface order to maintain CRC values PM }
2108 if assigned(prevdef) and assigned(aktprocsym^.definition^.nextoverloaded) then
2110 stdef:=aktprocsym^.definition;
2111 aktprocsym^.definition:=stdef^.nextoverloaded;
2112 stdef^.nextoverloaded:=prevdef^.nextoverloaded;
2113 prevdef^.nextoverloaded:=stdef;
2115 aktprocsym:=oldprocsym;
2116 procprefix:=oldprefix;
2117 procinfo:=oldprocinfo;
2125 Revision 1.1 2002/02/19 08:23:36 sasu
2128 Revision 1.1.2.10 2000/11/26 22:41:47 florian
2129 * pascal modifier in units works now
2131 Revision 1.1.2.9 2000/11/08 16:34:35 jonas
2132 * if a procedure uses exceptions (be it implicit or explicit), the
2133 usedregisters are set to all (because FPC_POPADDRSTACK doesn't save
2136 Revision 1.1.2.8 2000/10/24 22:19:41 peter
2137 * set usedregisters after writing entry and exit code
2139 Revision 1.1.2.7 2000/09/24 21:38:34 peter
2140 * calling convention checking for delphi mode fixed
2142 Revision 1.1.2.6 2000/09/10 20:10:47 peter
2143 * overload checking in implementation removed
2145 Revision 1.1.2.5 2000/08/16 18:26:00 peter
2146 * splitted namedobjectitem.next into indexnext and listnext so it
2147 can be used in both lists
2148 * don't allow "word = word" type definitions
2150 Revision 1.1.2.4 2000/08/13 12:50:20 peter
2151 * class member decl wrong then no other error after it
2152 * -vb has now also line numbering
2153 * -vb is also used for interface/implementation different decls and
2154 doesn't list the current function
2156 Revision 1.1.2.3 2000/08/08 19:18:06 peter
2157 * delphi compatibility with proc directives after func/proc without ;
2159 Revision 1.1.2.2 2000/08/06 14:14:57 peter
2160 * overload directive checks fixes
2162 Revision 1.1.2.1 2000/07/30 16:40:40 peter
2163 * overload directive support is more delphi compatible
2165 Revision 1.1 2000/07/13 06:29:55 michael
2168 Revision 1.67 2000/07/07 20:42:55 pierre
2169 * get a failure on webtbf/tbug890
2171 Revision 1.66 2000/07/06 19:04:59 peter
2172 * allow in delphi mode directives without semicolons between
2174 Revision 1.65 2000/06/25 20:13:51 florian
2175 * fixed a problem with forward declarations in TP mode, probably introduced by
2176 Pierre's last changes
2178 Revision 1.64 2000/06/20 12:47:52 pierre
2179 * equal_paras and convertable_paras changed by transforming third parameter
2180 into an enum with three possible values:
2181 cp_none, cp_value_equal_const and cp_all.
2183 Revision 1.63 2000/06/18 18:12:40 peter
2184 * support overload keyword
2186 Revision 1.62 2000/06/02 21:24:48 pierre
2187 * operator overloading now uses isbinaryoperatoracceptable
2188 and is unaryoperatoracceptable
2190 Revision 1.61 2000/05/10 19:22:51 pierre
2191 * Delphi defines TP so that code compiles
2192 sent by Kovacs Attila Zoltan
2194 Revision 1.60 2000/05/09 14:19:08 pierre
2195 * calculate para_offset for interrupt procedures
2197 Revision 1.59 2000/04/26 08:54:19 pierre
2198 * More changes for operator bug
2199 Order_overloaded method removed because it conflicted with
2200 new implementation where the defs are ordered
2201 according to the unit loading order !
2203 Revision 1.58 2000/04/25 23:55:29 pierre
2204 + Hint about unused unit
2205 * Testop bug fixed !!
2206 Now the operators are only applied if the unit is explicitly loaded
2208 Revision 1.57 2000/04/24 12:48:37 peter
2209 * removed unused vars
2211 Revision 1.56 2000/03/31 22:56:47 pierre
2212 * fix the handling of value parameters in cdecl function
2214 Revision 1.55 2000/03/27 11:57:22 pierre
2217 Revision 1.54 2000/03/23 22:17:51 pierre
2220 Revision 1.53 2000/03/16 16:41:13 pierre
2223 Revision 1.52 2000/03/15 23:10:00 pierre
2224 * fix for bug 848 (that still genrated wrong code)
2225 + better testing for variables used in assembler
2226 (gives an error if variable is not directly reachable !)
2228 Revision 1.51 2000/02/27 14:44:39 peter
2229 * if calling convention doesn't match don't print note about
2230 different manglednames
2232 Revision 1.50 2000/02/20 20:49:45 florian
2233 * newcg is compiling
2234 * fixed the dup id problem reported by Paul Y.
2236 Revision 1.49 2000/02/17 14:53:42 florian
2237 * some updates for the newcg
2239 Revision 1.48 2000/02/09 13:23:00 peter
2242 Revision 1.47 2000/02/08 13:55:13 peter
2243 * reset section back to code after localdata
2245 Revision 1.46 2000/02/04 20:00:22 florian
2246 * an exception in a construcor calls now the destructor (this applies only
2249 Revision 1.45 2000/02/04 14:54:17 jonas
2250 * moved call to resetusableregs to compile_proc_body (put it right before the
2251 reset of the temp generator) so the optimizer can know which registers are
2254 Revision 1.44 2000/01/28 23:17:53 florian
2255 * virtual XXXX; support for objects, only if -dWITHDMT is defined
2257 Revision 1.43 2000/01/21 22:06:16 florian
2258 * fixed for the fix of bug 793
2259 * fpu variables modified by nested subroutines aren't regable anymore
2260 * $maxfpuregisters doesn't modify anymore the behavior of a procedure before
2262 Revision 1.42 2000/01/16 22:17:12 peter
2263 * renamed call_offset to para_offset
2265 Revision 1.41 2000/01/11 17:16:06 jonas
2266 * removed a lot of memory leaks when an error is encountered (caused by
2267 procinfo and pstringcontainers). There are still plenty left though :)
2269 Revision 1.40 2000/01/07 01:14:31 peter
2270 * updated copyright to 2000
2272 Revision 1.39 1999/12/22 01:01:52 peter
2273 - removed freelabel()
2274 * added undefined label detection in internal assembler, this prevents
2275 a lot of ld crashes and wrong .o files
2276 * .o files aren't written anymore if errors have occured
2277 * inlining of assembler labels is now correct
2279 Revision 1.38 1999/12/06 18:17:09 peter
2280 * newcg compiler compiles again
2282 Revision 1.37 1999/11/30 10:40:48 peter
2285 Revision 1.36 1999/11/22 00:23:09 pierre
2286 * also complain about unused functions in program
2288 Revision 1.35 1999/11/17 17:05:02 pierre
2289 * Notes/hints changes
2291 Revision 1.34 1999/11/10 00:24:02 pierre
2292 * more browser details
2294 Revision 1.33 1999/11/09 23:43:08 pierre
2295 * better browser info
2297 Revision 1.32 1999/11/09 23:06:45 peter
2298 * esi_offset -> selfpointer_offset to be newcg compatible
2299 * hcogegen -> cgbase fixes for newcg
2301 Revision 1.31 1999/11/06 14:34:23 peter
2302 * truncated log to 20 revs
2304 Revision 1.30 1999/10/26 12:30:44 peter
2305 * const parameter is now checked
2306 * better and generic check if a node can be used for assigning
2308 * procvar equal works now (it never had worked at least from 0.99.8)
2309 * defcoll changed to linkedlist with pparaitem so it can easily be
2310 walked both directions
2312 Revision 1.29 1999/10/22 10:39:35 peter
2313 * split type reading from pdecl to ptype unit
2314 * parameter_dec routine is now used for procedure and procvars
2316 Revision 1.28 1999/10/13 10:37:36 peter
2317 * moved mangledname creation of normal proc so it also handles a wrong