psub.pas 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Florian Klaempfl, Daniel Mantione
  4. Does the parsing of the procedures/functions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit psub;
  19. interface
  20. uses
  21. cobjects,
  22. symconst,tokens,symtable;
  23. const
  24. pd_global = $1; { directive must be global }
  25. pd_body = $2; { directive needs a body }
  26. pd_implemen = $4; { directive can be used implementation section }
  27. pd_interface = $8; { directive can be used interface section }
  28. pd_object = $10; { directive can be used object declaration }
  29. pd_procvar = $20; { directive can be used procvar declaration }
  30. pd_notobject = $40;{ directive can not be used object declaration }
  31. procedure compile_proc_body(const proc_names:Tstringcontainer;
  32. make_global,parent_has_class:boolean);
  33. procedure parse_proc_head(options:tproctypeoption);
  34. procedure parse_proc_dec;
  35. function is_proc_directive(tok:ttoken):boolean;
  36. procedure parse_var_proc_directives(var sym : psym);
  37. procedure parse_object_proc_directives(var sym : pprocsym);
  38. procedure read_proc;
  39. implementation
  40. uses
  41. globtype,systems,
  42. strings,globals,verbose,files,
  43. scanner,aasm,tree,types,
  44. import,gendef,
  45. {$ifdef newcg}
  46. cgbase,
  47. {$else newcg}
  48. hcodegen,
  49. {$endif newcg}
  50. temp_gen,pass_1,cpubase,cpuasm
  51. {$ifndef NOPASS2}
  52. ,pass_2
  53. {$endif}
  54. {$ifdef GDB}
  55. ,gdb
  56. {$endif GDB}
  57. {$ifdef i386}
  58. {$ifndef newcg}
  59. ,tgeni386
  60. ,cgai386
  61. {$endif newcg}
  62. {$ifndef NoOpt}
  63. ,aopt386
  64. {$endif}
  65. {$endif}
  66. {$ifdef m68k}
  67. ,tgen68k,cga68k
  68. {$endif}
  69. { parser specific stuff }
  70. ,pbase,ptype,pdecl,pexpr,pstatmnt
  71. {$ifdef newcg}
  72. ,tgcpu,convtree,cgobj,tgeni386 { for the new code generator tgeni386 is only a dummy }
  73. {$endif newcg}
  74. ;
  75. var
  76. realname:string; { contains the real name of a procedure as it's typed }
  77. procedure parse_proc_head(options:tproctypeoption);
  78. var sp:stringid;
  79. pd:Pprocdef;
  80. paramoffset:longint;
  81. sym:Psym;
  82. hs:string;
  83. st : psymtable;
  84. overloaded_level:word;
  85. procstartfilepos : tfileposinfo;
  86. begin
  87. { Save the position where this procedure really starts and set col to 1 which
  88. looks nicer }
  89. procstartfilepos:=aktfilepos;
  90. procstartfilepos.column:=1;
  91. if (options=potype_operator) then
  92. begin
  93. sp:=overloaded_names[optoken];
  94. realname:=sp;
  95. end
  96. else
  97. begin
  98. sp:=pattern;
  99. realname:=orgpattern;
  100. consume(_ID);
  101. end;
  102. { method ? }
  103. if not(parse_only) and try_to_consume(_POINT) then
  104. begin
  105. getsym(sp,true);
  106. sym:=srsym;
  107. { load proc name }
  108. sp:=pattern;
  109. realname:=orgpattern;
  110. { qualifier is class name ? }
  111. if (sym^.typ<>typesym) or
  112. (ptypesym(sym)^.definition^.deftype<>objectdef) then
  113. begin
  114. Message(parser_e_class_id_expected);
  115. aktprocsym:=nil;
  116. consume(_ID);
  117. end
  118. else
  119. begin
  120. { used to allow private syms to be seen }
  121. aktobjectdef:=pobjectdef(ptypesym(sym)^.definition);
  122. consume(_ID);
  123. procinfo^._class:=pobjectdef(ptypesym(sym)^.definition);
  124. aktprocsym:=pprocsym(procinfo^._class^.symtable^.search(sp));
  125. {The procedure has been found. So it is
  126. a global one. Set the flags to mark this.}
  127. procinfo^.flags:=procinfo^.flags or pi_is_global;
  128. aktobjectdef:=nil;
  129. { we solve this below }
  130. if not(assigned(aktprocsym)) then
  131. Message(parser_e_methode_id_expected);
  132. end;
  133. end
  134. else
  135. begin
  136. { check for constructor/destructor which is not allowed here }
  137. if (not parse_only) and
  138. (options in [potype_constructor,potype_destructor]) then
  139. Message(parser_e_constructors_always_objects);
  140. aktprocsym:=pprocsym(symtablestack^.search(sp));
  141. if not(parse_only) then
  142. begin
  143. {The procedure we prepare for is in the implementation
  144. part of the unit we compile. It is also possible that we
  145. are compiling a program, which is also some kind of
  146. implementaion part.
  147. We need to find out if the procedure is global. If it is
  148. global, it is in the global symtable.}
  149. if not assigned(aktprocsym) and
  150. (symtablestack^.symtabletype=staticsymtable) then
  151. begin
  152. {Search the procedure in the global symtable.}
  153. aktprocsym:=Pprocsym(search_a_symtable(sp,globalsymtable));
  154. if assigned(aktprocsym) then
  155. begin
  156. {Check if it is a procedure.}
  157. if aktprocsym^.typ<>procsym then
  158. DuplicateSym(aktprocsym);
  159. {The procedure has been found. So it is
  160. a global one. Set the flags to mark this.}
  161. procinfo^.flags:=procinfo^.flags or pi_is_global;
  162. end;
  163. end;
  164. end;
  165. end;
  166. { Create the mangledname }
  167. {$ifndef UseNiceNames}
  168. if assigned(procinfo^._class) then
  169. begin
  170. if (pos('_$$_',procprefix)=0) then
  171. hs:=procprefix+'_$$_'+procinfo^._class^.objname^+'_$$_'+sp
  172. else
  173. hs:=procprefix+'_$'+sp;
  174. end
  175. else
  176. begin
  177. if lexlevel=normal_function_level then
  178. hs:=procprefix+'_'+sp
  179. else
  180. hs:=procprefix+'_$'+sp;
  181. end;
  182. {$else UseNiceNames}
  183. if assigned(procinfo^._class) then
  184. begin
  185. if (pos('_5Class_',procprefix)=0) then
  186. hs:=procprefix+'_5Class_'+procinfo^._class^.name^+'_'+tostr(length(sp))+sp
  187. else
  188. hs:=procprefix+'_'+tostr(length(sp))+sp;
  189. end
  190. else
  191. begin
  192. if lexlevel=normal_function_level then
  193. hs:=procprefix+'_'+tostr(length(sp))+sp
  194. else
  195. hs:=lowercase(procprefix)+'_'+tostr(length(sp))+sp;
  196. end;
  197. {$endif UseNiceNames}
  198. if assigned(aktprocsym) then
  199. begin
  200. { Check if overloading is enabled }
  201. if not(m_fpc in aktmodeswitches) then
  202. begin
  203. if aktprocsym^.typ<>procsym then
  204. begin
  205. DuplicateSym(aktprocsym);
  206. { try to recover by creating a new aktprocsym }
  207. aktprocsym:=new(pprocsym,init(sp));
  208. end
  209. else
  210. begin
  211. if not(aktprocsym^.definition^.forwarddef) then
  212. Message(parser_e_procedure_overloading_is_off);
  213. end;
  214. end
  215. else
  216. begin
  217. { Check if the overloaded sym is realy a procsym }
  218. if aktprocsym^.typ<>procsym then
  219. begin
  220. Message1(parser_e_overloaded_no_procedure,aktprocsym^.name);
  221. { try to recover by creating a new aktprocsym }
  222. aktprocsym:=new(pprocsym,init(sp));
  223. end;
  224. end;
  225. end
  226. else
  227. begin
  228. { create a new procsym and set the real filepos }
  229. aktprocsym:=new(pprocsym,init(sp));
  230. { for operator we have only one definition for each overloaded
  231. operation }
  232. if (options=potype_operator) then
  233. begin
  234. { the only problem is that nextoverloaded might not be in a unit
  235. known for the unit itself }
  236. if assigned(overloaded_operators[optoken]) then
  237. aktprocsym^.definition:=overloaded_operators[optoken]^.definition;
  238. end;
  239. symtablestack^.insert(aktprocsym);
  240. end;
  241. st:=symtablestack;
  242. pd:=new(pprocdef,init);
  243. pd^.symtablelevel:=symtablestack^.symtablelevel;
  244. if assigned(procinfo^._class) then
  245. pd^._class := procinfo^._class;
  246. { set the options from the caller (podestructor or poconstructor) }
  247. pd^.proctypeoption:=options;
  248. { calculate the offset of the parameters }
  249. paramoffset:=8;
  250. { calculate frame pointer offset }
  251. if lexlevel>normal_function_level then
  252. begin
  253. procinfo^.framepointer_offset:=paramoffset;
  254. inc(paramoffset,target_os.size_of_pointer);
  255. { this is needed to get correct framepointer push for local
  256. forward functions !! }
  257. pd^.parast^.symtablelevel:=lexlevel;
  258. end;
  259. if assigned (procinfo^._Class) and
  260. not(procinfo^._Class^.is_class) and
  261. (pd^.proctypeoption in [potype_constructor,potype_destructor]) then
  262. inc(paramoffset,target_os.size_of_pointer);
  263. { self pointer offset }
  264. { self isn't pushed in nested procedure of methods }
  265. if assigned(procinfo^._class) and (lexlevel=normal_function_level) then
  266. begin
  267. {$ifdef newcg}
  268. procinfo^.selfpointer_offset:=paramoffset;
  269. {$else newcg}
  270. procinfo^.ESI_offset:=paramoffset;
  271. {$endif newcg}
  272. if assigned(aktprocsym^.definition) and
  273. not(po_containsself in aktprocsym^.definition^.procoptions) then
  274. inc(paramoffset,target_os.size_of_pointer);
  275. end;
  276. { destructor flag ? }
  277. if assigned (procinfo^._Class) and
  278. procinfo^._class^.is_class and
  279. (pd^.proctypeoption=potype_destructor) then
  280. inc(paramoffset,target_os.size_of_pointer);
  281. procinfo^.call_offset:=paramoffset;
  282. pd^.parast^.datasize:=0;
  283. pd^.nextoverloaded:=aktprocsym^.definition;
  284. aktprocsym^.definition:=pd;
  285. aktprocsym^.definition^.fileinfo:=procstartfilepos;
  286. aktprocsym^.definition^.setmangledname(hs);
  287. aktprocsym^.definition^.procsym:=aktprocsym;
  288. { update also the current filepos for aktprocsym }
  289. aktprocsym^.fileinfo:=procstartfilepos;
  290. if not parse_only then
  291. begin
  292. overloaded_level:=0;
  293. { we need another procprefix !!! }
  294. { count, but only those in the same unit !!}
  295. while assigned(pd) and
  296. (pd^.owner^.symtabletype in [globalsymtable,staticsymtable]) do
  297. begin
  298. { only count already implemented functions }
  299. if not(pd^.forwarddef) then
  300. inc(overloaded_level);
  301. pd:=pd^.nextoverloaded;
  302. end;
  303. if overloaded_level>0 then
  304. procprefix:=hs+'$'+tostr(overloaded_level)+'$'
  305. else
  306. procprefix:=hs+'$';
  307. end;
  308. { this must also be inserted in the right symtable !! PM }
  309. { otherwise we get subbtle problems with
  310. definitions of args defs in staticsymtable for
  311. implementation of a global method }
  312. if token=_LKLAMMER then
  313. parameter_dec(aktprocsym^.definition);
  314. { so we only restore the symtable now }
  315. symtablestack:=st;
  316. if (options=potype_operator) then
  317. overloaded_operators[optoken]:=aktprocsym;
  318. end;
  319. procedure parse_proc_dec;
  320. var
  321. hs : string;
  322. isclassmethod : boolean;
  323. begin
  324. inc(lexlevel);
  325. { read class method }
  326. if token=_CLASS then
  327. begin
  328. consume(_CLASS);
  329. isclassmethod:=true;
  330. end
  331. else
  332. isclassmethod:=false;
  333. case token of
  334. _FUNCTION : begin
  335. consume(_FUNCTION);
  336. parse_proc_head(potype_none);
  337. if token<>_COLON then
  338. begin
  339. if not(aktprocsym^.definition^.forwarddef) or
  340. (m_repeat_forward in aktmodeswitches) then
  341. begin
  342. consume(_COLON);
  343. consume_all_until(_SEMICOLON);
  344. end;
  345. end
  346. else
  347. begin
  348. consume(_COLON);
  349. inc(testcurobject);
  350. aktprocsym^.definition^.retdef:=single_type(hs,false);
  351. aktprocsym^.definition^.test_if_fpu_result;
  352. dec(testcurobject);
  353. end;
  354. end;
  355. _PROCEDURE : begin
  356. consume(_PROCEDURE);
  357. parse_proc_head(potype_none);
  358. aktprocsym^.definition^.retdef:=voiddef;
  359. end;
  360. _CONSTRUCTOR : begin
  361. consume(_CONSTRUCTOR);
  362. parse_proc_head(potype_constructor);
  363. if assigned(procinfo^._class) and
  364. procinfo^._class^.is_class then
  365. begin
  366. { CLASS constructors return the created instance }
  367. aktprocsym^.definition^.retdef:=procinfo^._class;
  368. end
  369. else
  370. begin
  371. { OBJECT constructors return a boolean }
  372. {$IfDef GDB}
  373. { GDB doesn't like unnamed types !}
  374. aktprocsym^.definition^.retdef:=globaldef('boolean');
  375. {$else GDB}
  376. aktprocsym^.definition^.retdef:=new(porddef,init(bool8bit,0,1));
  377. {$Endif GDB}
  378. end;
  379. end;
  380. _DESTRUCTOR : begin
  381. consume(_DESTRUCTOR);
  382. parse_proc_head(potype_destructor);
  383. aktprocsym^.definition^.retdef:=voiddef;
  384. end;
  385. _OPERATOR : begin
  386. if lexlevel>normal_function_level then
  387. Message(parser_e_no_local_operator);
  388. consume(_OPERATOR);
  389. if not(token in [_PLUS..last_overloaded]) then
  390. Message(parser_e_overload_operator_failed);
  391. optoken:=token;
  392. consume(Token);
  393. procinfo^.flags:=procinfo^.flags or pi_operator;
  394. parse_proc_head(potype_operator);
  395. if token<>_ID then
  396. begin
  397. opsym:=nil;
  398. if not(m_result in aktmodeswitches) then
  399. consume(_ID);
  400. end
  401. else
  402. begin
  403. opsym:=new(pvarsym,init(pattern,voiddef));
  404. consume(_ID);
  405. end;
  406. if not try_to_consume(_COLON) then
  407. begin
  408. consume(_COLON);
  409. aktprocsym^.definition^.retdef:=generrordef;
  410. consume_all_until(_SEMICOLON);
  411. end
  412. else
  413. begin
  414. aktprocsym^.definition^.retdef:=
  415. single_type(hs,false);
  416. aktprocsym^.definition^.test_if_fpu_result;
  417. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  418. ((aktprocsym^.definition^.retdef^.deftype<>
  419. orddef) or (porddef(aktprocsym^.definition^.
  420. retdef)^.typ<>bool8bit)) then
  421. Message(parser_e_comparative_operator_return_boolean);
  422. if assigned(opsym) then
  423. opsym^.definition:=aktprocsym^.definition^.retdef;
  424. { We need to add the retrun type in the mangledname
  425. to allow overloading with just different results !! (PM) }
  426. aktprocsym^.definition^.setmangledname(
  427. aktprocsym^.definition^.mangledname+'$$'+hs);
  428. end;
  429. end;
  430. end;
  431. if isclassmethod and
  432. assigned(aktprocsym) then
  433. {$ifdef INCLUDEOK}
  434. include(aktprocsym^.definition^.procoptions,po_classmethod);
  435. {$else}
  436. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+[po_classmethod];
  437. {$endif}
  438. consume(_SEMICOLON);
  439. dec(lexlevel);
  440. end;
  441. {****************************************************************************
  442. Procedure directive handlers
  443. ****************************************************************************}
  444. {$ifdef tp}
  445. {$F+}
  446. {$endif}
  447. procedure pd_far(const procnames:Tstringcontainer);
  448. begin
  449. Message(parser_w_proc_far_ignored);
  450. end;
  451. procedure pd_near(const procnames:Tstringcontainer);
  452. begin
  453. Message(parser_w_proc_near_ignored);
  454. end;
  455. procedure pd_export(const procnames:Tstringcontainer);
  456. begin
  457. if assigned(procinfo^._class) then
  458. Message(parser_e_methods_dont_be_export);
  459. if lexlevel<>normal_function_level then
  460. Message(parser_e_dont_nest_export);
  461. { only os/2 needs this }
  462. if target_info.target=target_i386_os2 then
  463. begin
  464. procnames.insert(realname);
  465. procinfo^.exported:=true;
  466. if cs_link_deffile in aktglobalswitches then
  467. deffile.AddExport(aktprocsym^.definition^.mangledname);
  468. end;
  469. end;
  470. procedure pd_inline(const procnames:Tstringcontainer);
  471. begin
  472. if not(cs_support_inline in aktmoduleswitches) then
  473. Message(parser_e_proc_inline_not_supported);
  474. end;
  475. procedure pd_forward(const procnames:Tstringcontainer);
  476. begin
  477. aktprocsym^.definition^.forwarddef:=true;
  478. end;
  479. procedure pd_stdcall(const procnames:Tstringcontainer);
  480. begin
  481. end;
  482. procedure pd_safecall(const procnames:Tstringcontainer);
  483. begin
  484. end;
  485. procedure pd_alias(const procnames:Tstringcontainer);
  486. begin
  487. consume(_COLON);
  488. procnames.insert(get_stringconst);
  489. end;
  490. procedure pd_asmname(const procnames:Tstringcontainer);
  491. begin
  492. aktprocsym^.definition^.setmangledname(target_os.Cprefix+pattern);
  493. if token=_CCHAR then
  494. consume(_CCHAR)
  495. else
  496. consume(_CSTRING);
  497. { we don't need anything else }
  498. aktprocsym^.definition^.forwarddef:=false;
  499. end;
  500. procedure pd_intern(const procnames:Tstringcontainer);
  501. begin
  502. consume(_COLON);
  503. aktprocsym^.definition^.extnumber:=get_intconst;
  504. end;
  505. procedure pd_system(const procnames:Tstringcontainer);
  506. begin
  507. aktprocsym^.definition^.setmangledname(realname);
  508. end;
  509. procedure pd_abstract(const procnames:Tstringcontainer);
  510. begin
  511. if (po_virtualmethod in aktprocsym^.definition^.procoptions) then
  512. {$ifdef INCLUDEOK}
  513. include(aktprocsym^.definition^.procoptions,po_abstractmethod)
  514. {$else}
  515. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+[po_abstractmethod]
  516. {$endif}
  517. else
  518. Message(parser_e_only_virtual_methods_abstract);
  519. { the method is defined }
  520. aktprocsym^.definition^.forwarddef:=false;
  521. end;
  522. procedure pd_virtual(const procnames:Tstringcontainer);
  523. begin
  524. if (aktprocsym^.definition^.proctypeoption=potype_constructor) and
  525. not(aktprocsym^.definition^._class^.is_class) then
  526. Message(parser_e_constructor_cannot_be_not_virtual);
  527. end;
  528. procedure pd_static(const procnames:Tstringcontainer);
  529. begin
  530. if (cs_static_keyword in aktmoduleswitches) then
  531. begin
  532. {$ifdef INCLUDEOK}
  533. include(aktprocsym^.symoptions,sp_static);
  534. include(aktprocsym^.definition^.procoptions,po_staticmethod);
  535. {$else}
  536. aktprocsym^.symoptions:=aktprocsym^.symoptions+[sp_static];
  537. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+[po_staticmethod];
  538. {$endif}
  539. end;
  540. end;
  541. procedure pd_override(const procnames:Tstringcontainer);
  542. begin
  543. if not(aktprocsym^.definition^._class^.is_class) then
  544. Message(parser_e_no_object_override);
  545. end;
  546. procedure pd_message(const procnames:Tstringcontainer);
  547. var
  548. pt : ptree;
  549. begin
  550. { check parameter type }
  551. if not(po_containsself in aktprocsym^.definition^.procoptions) and
  552. ((aktprocsym^.definition^.para^.count<>1) or
  553. (pparaitem(aktprocsym^.definition^.para^.first)^.paratyp<>vs_var)) then
  554. Message(parser_e_ill_msg_param);
  555. pt:=comp_expr(true);
  556. do_firstpass(pt);
  557. if pt^.treetype=stringconstn then
  558. begin
  559. {$ifdef INCLUDEOK}
  560. include(aktprocsym^.definition^.procoptions,po_msgstr);
  561. {$else}
  562. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+[po_msgstr];
  563. {$endif}
  564. aktprocsym^.definition^.messageinf.str:=strnew(pt^.value_str);
  565. end
  566. else
  567. if is_constintnode(pt) then
  568. begin
  569. {$ifdef INCLUDEOK}
  570. include(aktprocsym^.definition^.procoptions,po_msgint);
  571. {$else}
  572. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+[po_msgint];
  573. {$endif}
  574. aktprocsym^.definition^.messageinf.i:=pt^.value;
  575. end
  576. else
  577. Message(parser_e_ill_msg_expr);
  578. disposetree(pt);
  579. end;
  580. procedure pd_cdecl(const procnames:Tstringcontainer);
  581. begin
  582. if aktprocsym^.definition^.deftype<>procvardef then
  583. aktprocsym^.definition^.setmangledname(target_os.Cprefix+realname);
  584. end;
  585. procedure pd_register(const procnames:Tstringcontainer);
  586. begin
  587. Message(parser_w_proc_register_ignored);
  588. end;
  589. procedure pd_syscall(const procnames:Tstringcontainer);
  590. begin
  591. aktprocsym^.definition^.forwarddef:=false;
  592. aktprocsym^.definition^.extnumber:=get_intconst;
  593. end;
  594. procedure pd_external(const procnames:Tstringcontainer);
  595. {
  596. If import_dll=nil the procedure is assumed to be in another
  597. object file. In that object file it should have the name to
  598. which import_name is pointing to. Otherwise, the procedure is
  599. assumed to be in the DLL to which import_dll is pointing to. In
  600. that case either import_nr<>0 or import_name<>nil is true, so
  601. the procedure is either imported by number or by name. (DM)
  602. }
  603. var
  604. import_dll,
  605. import_name : string;
  606. import_nr : word;
  607. begin
  608. aktprocsym^.definition^.forwarddef:=false;
  609. { If the procedure should be imported from a DLL, a constant string follows.
  610. This isn't really correct, an contant string expression follows
  611. so we check if an semicolon follows, else a string constant have to
  612. follow (FK) }
  613. import_nr:=0;
  614. import_name:='';
  615. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  616. begin
  617. import_dll:=get_stringconst;
  618. if (idtoken=_NAME) then
  619. begin
  620. consume(_NAME);
  621. import_name:=get_stringconst;
  622. end;
  623. if (idtoken=_INDEX) then
  624. begin
  625. {After the word index follows the index number in the DLL.}
  626. consume(_INDEX);
  627. import_nr:=get_intconst;
  628. end;
  629. if (import_nr=0) and (import_name='') then
  630. {if (aktprocsym^.definition^.options and pocdecl)<>0 then
  631. import_name:=aktprocsym^.definition^.mangledname
  632. else
  633. Message(parser_w_empty_import_name);}
  634. { this should work both for win32 and Linux !! PM }
  635. import_name:=realname;
  636. if not(current_module^.uses_imports) then
  637. begin
  638. current_module^.uses_imports:=true;
  639. importlib^.preparelib(current_module^.modulename^);
  640. end;
  641. if not(m_repeat_forward in aktmodeswitches) then
  642. begin
  643. { we can only have one overloaded here ! }
  644. if assigned(aktprocsym^.definition^.nextoverloaded) then
  645. importlib^.importprocedure(aktprocsym^.definition^.nextoverloaded^.mangledname,
  646. import_dll,import_nr,import_name)
  647. else
  648. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  649. end
  650. else
  651. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  652. end
  653. else
  654. begin
  655. if (idtoken=_NAME) then
  656. begin
  657. consume(_NAME);
  658. import_name:=get_stringconst;
  659. aktprocsym^.definition^.setmangledname(import_name);
  660. end
  661. else
  662. begin
  663. { external shouldn't override the cdecl/system name }
  664. if not (pocall_clearstack in aktprocsym^.definition^.proccalloptions) then
  665. aktprocsym^.definition^.setmangledname(aktprocsym^.name);
  666. end;
  667. end;
  668. end;
  669. {$ifdef TP}
  670. {$F-}
  671. {$endif}
  672. const
  673. namelength=15;
  674. type
  675. pd_handler=procedure(const procnames:Tstringcontainer);
  676. proc_dir_rec=record
  677. idtok : ttoken;
  678. pd_flags : longint;
  679. handler : pd_handler;
  680. pocall : tproccalloptions;
  681. pooption : tprocoptions;
  682. mutexclpocall : tproccalloptions;
  683. mutexclpotype : tproctypeoptions;
  684. mutexclpo : tprocoptions;
  685. end;
  686. const
  687. {Should contain the number of procedure directives we support.}
  688. num_proc_directives=29;
  689. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  690. (
  691. (
  692. idtok:_ABSTRACT;
  693. pd_flags : pd_interface+pd_object;
  694. handler : {$ifndef TP}@{$endif}pd_abstract;
  695. pocall : [];
  696. pooption : [po_abstractmethod];
  697. mutexclpocall : [pocall_internproc,pocall_inline];
  698. mutexclpotype : [potype_constructor,potype_destructor];
  699. mutexclpo : [po_exports,po_interrupt,po_external]
  700. ),(
  701. idtok:_ALIAS;
  702. pd_flags : pd_implemen+pd_body;
  703. handler : {$ifndef TP}@{$endif}pd_alias;
  704. pocall : [];
  705. pooption : [];
  706. mutexclpocall : [pocall_inline];
  707. mutexclpotype : [];
  708. mutexclpo : [po_external]
  709. ),(
  710. idtok:_ASMNAME;
  711. pd_flags : pd_interface+pd_implemen;
  712. handler : {$ifndef TP}@{$endif}pd_asmname;
  713. pocall : [pocall_cdecl,pocall_clearstack];
  714. pooption : [po_external];
  715. mutexclpocall : [pocall_internproc];
  716. mutexclpotype : [];
  717. mutexclpo : [po_external]
  718. ),(
  719. idtok:_ASSEMBLER;
  720. pd_flags : pd_implemen+pd_body;
  721. handler : nil;
  722. pocall : [];
  723. pooption : [po_assembler];
  724. mutexclpocall : [];
  725. mutexclpotype : [];
  726. mutexclpo : [po_external]
  727. ),(
  728. idtok:_CDECL;
  729. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  730. handler : {$ifndef TP}@{$endif}pd_cdecl;
  731. pocall : [pocall_cdecl,pocall_clearstack];
  732. pooption : [po_savestdregs];
  733. mutexclpocall : [pocall_internproc,pocall_leftright,pocall_inline];
  734. mutexclpotype : [];
  735. mutexclpo : [po_assembler,po_external]
  736. ),(
  737. idtok:_DYNAMIC;
  738. pd_flags : pd_interface+pd_object;
  739. handler : {$ifndef TP}@{$endif}pd_virtual;
  740. pocall : [];
  741. pooption : [po_virtualmethod];
  742. mutexclpocall : [pocall_internproc,pocall_inline];
  743. mutexclpotype : [];
  744. mutexclpo : [po_exports,po_interrupt,po_external]
  745. ),(
  746. idtok:_EXPORT;
  747. pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??};
  748. handler : {$ifndef TP}@{$endif}pd_export;
  749. pocall : [];
  750. pooption : [po_exports];
  751. mutexclpocall : [pocall_internproc,pocall_inline];
  752. mutexclpotype : [];
  753. mutexclpo : [po_external,po_interrupt]
  754. ),(
  755. idtok:_EXTERNAL;
  756. pd_flags : pd_implemen+pd_interface;
  757. handler : {$ifndef TP}@{$endif}pd_external;
  758. pocall : [];
  759. pooption : [po_external];
  760. mutexclpocall : [pocall_internproc,pocall_inline,pocall_palmossyscall];
  761. mutexclpotype : [];
  762. mutexclpo : [po_exports,po_interrupt,po_assembler]
  763. ),(
  764. idtok:_FAR;
  765. pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar;
  766. handler : {$ifndef TP}@{$endif}pd_far;
  767. pocall : [];
  768. pooption : [];
  769. mutexclpocall : [pocall_internproc,pocall_inline];
  770. mutexclpotype : [];
  771. mutexclpo : []
  772. ),(
  773. idtok:_FORWARD;
  774. pd_flags : pd_implemen;
  775. handler : {$ifndef TP}@{$endif}pd_forward;
  776. pocall : [];
  777. pooption : [];
  778. mutexclpocall : [pocall_internproc,pocall_inline];
  779. mutexclpotype : [];
  780. mutexclpo : [po_external]
  781. ),(
  782. idtok:_INLINE;
  783. pd_flags : pd_implemen+pd_body;
  784. handler : {$ifndef TP}@{$endif}pd_inline;
  785. pocall : [pocall_inline];
  786. pooption : [];
  787. mutexclpocall : [pocall_internproc];
  788. mutexclpotype : [potype_constructor,potype_destructor];
  789. mutexclpo : [po_exports,po_external,po_interrupt]
  790. ),(
  791. idtok:_INTERNCONST;
  792. pd_flags : pd_implemen+pd_body;
  793. handler : {$ifndef TP}@{$endif}pd_intern;
  794. pocall : [pocall_internconst];
  795. pooption : [];
  796. mutexclpocall : [];
  797. mutexclpotype : [potype_operator];
  798. mutexclpo : []
  799. ),(
  800. idtok:_INTERNPROC;
  801. pd_flags : pd_implemen;
  802. handler : {$ifndef TP}@{$endif}pd_intern;
  803. pocall : [pocall_internproc];
  804. pooption : [];
  805. mutexclpocall : [pocall_inline,pocall_clearstack,pocall_leftright,pocall_cdecl];
  806. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  807. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck]
  808. ),(
  809. idtok:_INTERRUPT;
  810. pd_flags : pd_implemen+pd_body;
  811. handler : nil;
  812. pocall : [];
  813. pooption : [po_interrupt];
  814. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_clearstack,pocall_leftright,pocall_inline];
  815. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  816. mutexclpo : [po_external]
  817. ),(
  818. idtok:_IOCHECK;
  819. pd_flags : pd_implemen+pd_body;
  820. handler : nil;
  821. pocall : [];
  822. pooption : [po_iocheck];
  823. mutexclpocall : [pocall_internproc];
  824. mutexclpotype : [];
  825. mutexclpo : [po_external]
  826. ),(
  827. idtok:_MESSAGE;
  828. pd_flags : pd_interface+pd_object;
  829. handler : {$ifndef TP}@{$endif}pd_message;
  830. pocall : [];
  831. pooption : []; { can be po_msgstr or po_msgint }
  832. mutexclpocall : [pocall_inline,pocall_internproc];
  833. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  834. mutexclpo : [po_interrupt,po_external]
  835. ),(
  836. idtok:_NEAR;
  837. pd_flags : pd_implemen+pd_body+pd_procvar;
  838. handler : {$ifndef TP}@{$endif}pd_near;
  839. pocall : [];
  840. pooption : [];
  841. mutexclpocall : [pocall_internproc];
  842. mutexclpotype : [];
  843. mutexclpo : []
  844. ),(
  845. idtok:_OVERRIDE;
  846. pd_flags : pd_interface+pd_object;
  847. handler : {$ifndef TP}@{$endif}pd_override;
  848. pocall : [];
  849. pooption : [po_overridingmethod,po_virtualmethod];
  850. mutexclpocall : [pocall_inline,pocall_internproc];
  851. mutexclpotype : [];
  852. mutexclpo : [po_exports,po_external,po_interrupt]
  853. ),(
  854. idtok:_PASCAL;
  855. pd_flags : pd_implemen+pd_body+pd_procvar;
  856. handler : nil;
  857. pocall : [pocall_leftright];
  858. pooption : [];
  859. mutexclpocall : [pocall_internproc];
  860. mutexclpotype : [];
  861. mutexclpo : [po_external]
  862. ),(
  863. idtok:_POPSTACK;
  864. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  865. handler : nil;
  866. pocall : [pocall_clearstack];
  867. pooption : [];
  868. mutexclpocall : [pocall_inline,pocall_internproc];
  869. mutexclpotype : [];
  870. mutexclpo : [po_assembler,po_external]
  871. ),(
  872. idtok:_PUBLIC;
  873. pd_flags : pd_implemen+pd_body+pd_global+pd_notobject;
  874. handler : nil;
  875. pocall : [];
  876. pooption : [];
  877. mutexclpocall : [pocall_internproc,pocall_inline];
  878. mutexclpotype : [];
  879. mutexclpo : [po_external]
  880. ),(
  881. idtok:_REGISTER;
  882. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  883. handler : {$ifndef TP}@{$endif}pd_register;
  884. pocall : [pocall_register];
  885. pooption : [];
  886. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_internproc];
  887. mutexclpotype : [];
  888. mutexclpo : [po_external]
  889. ),(
  890. idtok:_SAFECALL;
  891. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  892. handler : {$ifndef TP}@{$endif}pd_safecall;
  893. pocall : [pocall_safecall];
  894. pooption : [po_savestdregs];
  895. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_internproc,pocall_inline];
  896. mutexclpotype : [];
  897. mutexclpo : [po_external]
  898. ),(
  899. idtok:_SAVEREGISTERS;
  900. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  901. handler : nil;
  902. pocall : [];
  903. pooption : [po_saveregisters];
  904. mutexclpocall : [pocall_internproc];
  905. mutexclpotype : [];
  906. mutexclpo : [po_external]
  907. ),(
  908. idtok:_STATIC;
  909. pd_flags : pd_interface+pd_object;
  910. handler : {$ifndef TP}@{$endif}pd_static;
  911. pocall : [];
  912. pooption : [po_staticmethod];
  913. mutexclpocall : [pocall_inline,pocall_internproc];
  914. mutexclpotype : [potype_constructor,potype_destructor];
  915. mutexclpo : [po_external,po_interrupt,po_exports]
  916. ),(
  917. idtok:_STDCALL;
  918. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  919. handler : {$ifndef TP}@{$endif}pd_stdcall;
  920. pocall : [pocall_stdcall];
  921. pooption : [po_savestdregs];
  922. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_inline,pocall_internproc];
  923. mutexclpotype : [];
  924. mutexclpo : [po_external]
  925. ),(
  926. idtok:_SYSCALL;
  927. pd_flags : pd_interface;
  928. handler : {$ifndef TP}@{$endif}pd_syscall;
  929. pocall : [pocall_palmossyscall];
  930. pooption : [];
  931. mutexclpocall : [pocall_cdecl,pocall_inline,pocall_internproc];
  932. mutexclpotype : [];
  933. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  934. ),(
  935. idtok:_SYSTEM;
  936. pd_flags : pd_implemen;
  937. handler : {$ifndef TP}@{$endif}pd_system;
  938. pocall : [pocall_clearstack];
  939. pooption : [];
  940. mutexclpocall : [pocall_leftright,pocall_inline,pocall_internproc];
  941. mutexclpotype : [];
  942. mutexclpo : [po_external,po_assembler,po_interrupt]
  943. ),(
  944. idtok:_VIRTUAL;
  945. pd_flags : pd_interface+pd_object;
  946. handler : {$ifndef TP}@{$endif}pd_virtual;
  947. pocall : [];
  948. pooption : [po_virtualmethod];
  949. mutexclpocall : [pocall_inline,pocall_internproc];
  950. mutexclpotype : [];
  951. mutexclpo : [po_external,po_interrupt,po_exports]
  952. )
  953. );
  954. function is_proc_directive(tok:ttoken):boolean;
  955. var
  956. i : longint;
  957. begin
  958. is_proc_directive:=false;
  959. for i:=1 to num_proc_directives do
  960. if proc_direcdata[i].idtok=idtoken then
  961. begin
  962. is_proc_directive:=true;
  963. exit;
  964. end;
  965. end;
  966. function parse_proc_direc(const proc_names:Tstringcontainer;var pdflags:word):boolean;
  967. {
  968. Parse the procedure directive, returns true if a correct directive is found
  969. }
  970. var
  971. p : longint;
  972. found : boolean;
  973. name : string;
  974. begin
  975. parse_proc_direc:=false;
  976. name:=pattern;
  977. found:=false;
  978. for p:=1 to num_proc_directives do
  979. if proc_direcdata[p].idtok=idtoken then
  980. begin
  981. found:=true;
  982. break;
  983. end;
  984. { Check if the procedure directive is known }
  985. if not found then
  986. begin
  987. { parsing a procvar type the name can be any
  988. next variable !! }
  989. if (pdflags and (pd_procvar or pd_object))=0 then
  990. Message1(parser_w_unknown_proc_directive_ignored,name);
  991. exit;
  992. end;
  993. { static needs a special treatment }
  994. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  995. exit;
  996. { Conflicts between directives ? }
  997. if (aktprocsym^.definition^.proctypeoption in proc_direcdata[p].mutexclpotype) or
  998. ((aktprocsym^.definition^.proccalloptions*proc_direcdata[p].mutexclpocall)<>[]) or
  999. ((aktprocsym^.definition^.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1000. begin
  1001. Message1(parser_e_proc_dir_conflict,name);
  1002. exit;
  1003. end;
  1004. { Check if the directive is only for objects }
  1005. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1006. not assigned(aktprocsym^.definition^._class) then
  1007. begin
  1008. exit;
  1009. end;
  1010. { check if method and directive not for object public }
  1011. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1012. assigned(aktprocsym^.definition^._class) then
  1013. begin
  1014. exit;
  1015. end;
  1016. { consume directive, and turn flag on }
  1017. consume(token);
  1018. parse_proc_direc:=true;
  1019. { Check the pd_flags if the directive should be allowed }
  1020. if ((pdflags and pd_interface)<>0) and
  1021. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1022. begin
  1023. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1024. exit;
  1025. end;
  1026. if ((pdflags and pd_implemen)<>0) and
  1027. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1028. begin
  1029. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1030. exit;
  1031. end;
  1032. if ((pdflags and pd_procvar)<>0) and
  1033. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1034. begin
  1035. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1036. exit;
  1037. end;
  1038. { Return the new pd_flags }
  1039. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1040. pdflags:=pdflags and (not pd_body);
  1041. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1042. pdflags:=pdflags or pd_global;
  1043. { Add the correct flag }
  1044. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions+proc_direcdata[p].pocall;
  1045. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+proc_direcdata[p].pooption;
  1046. { Adjust positions of args for cdecl or stdcall }
  1047. if (aktprocsym^.definition^.deftype=procdef) and
  1048. (([pocall_cdecl,pocall_stdcall]*aktprocsym^.definition^.proccalloptions)<>[]) then
  1049. aktprocsym^.definition^.parast^.set_alignment(target_os.size_of_longint);
  1050. { Call the handler }
  1051. if pointer({$ifndef FPC}@{$endif}proc_direcdata[p].handler)<>nil then
  1052. proc_direcdata[p].handler(proc_names);
  1053. end;
  1054. {***************************************************************************}
  1055. function check_identical(var p : pprocdef) : boolean;
  1056. {
  1057. Search for idendical definitions,
  1058. if there is a forward, then kill this.
  1059. Returns the result of the forward check.
  1060. Removed from unter_dec to keep the source readable
  1061. }
  1062. var
  1063. hd,pd : Pprocdef;
  1064. storeparast : psymtable;
  1065. ad,fd : psym;
  1066. s : string;
  1067. begin
  1068. check_identical:=false;
  1069. p:=nil;
  1070. pd:=aktprocsym^.definition;
  1071. if assigned(pd) then
  1072. begin
  1073. { Is there an overload/forward ? }
  1074. if assigned(pd^.nextoverloaded) then
  1075. begin
  1076. { walk the procdef list }
  1077. while (assigned(pd)) and (assigned(pd^.nextoverloaded)) do
  1078. begin
  1079. if not(m_repeat_forward in aktmodeswitches) or
  1080. (equal_paras(aktprocsym^.definition^.para,pd^.nextoverloaded^.para,false) and
  1081. { for operators equal_paras is not enough !! }
  1082. ((aktprocsym^.definition^.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1083. is_equal(pd^.nextoverloaded^.retdef,aktprocsym^.definition^.retdef))) then
  1084. begin
  1085. if pd^.nextoverloaded^.forwarddef then
  1086. { remove the forward definition but don't delete it, }
  1087. { the symtable is the owner !! }
  1088. begin
  1089. hd:=pd^.nextoverloaded;
  1090. { Check if the procedure type and return type are correct }
  1091. if (hd^.proctypeoption<>aktprocsym^.definition^.proctypeoption) or
  1092. (not(is_equal(hd^.retdef,aktprocsym^.definition^.retdef)) and
  1093. (m_repeat_forward in aktmodeswitches)) then
  1094. begin
  1095. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName);
  1096. exit;
  1097. end;
  1098. { Check calling convention, no check for internconst,internproc which
  1099. are only defined in interface or implementation }
  1100. if (hd^.proccalloptions-[pocall_internconst,pocall_internproc]<>
  1101. aktprocsym^.definition^.proccalloptions-[pocall_internconst,pocall_internproc]) then
  1102. begin
  1103. { only trigger an error, becuase it doesn't hurt }
  1104. Message(parser_e_call_convention_dont_match_forward);
  1105. end;
  1106. { manglednames are equal? }
  1107. hd^.count:=false;
  1108. if (m_repeat_forward in aktmodeswitches) or
  1109. aktprocsym^.definition^.haspara then
  1110. begin
  1111. if (hd^.mangledname<>aktprocsym^.definition^.mangledname) then
  1112. begin
  1113. { When overloading is not possible then we issue an error }
  1114. { This is not true, tp7/delphi don't give an error when a renamed
  1115. type is used in the other declaration (PFV)
  1116. if not(m_repeat_forward in aktmodeswitches) then
  1117. begin
  1118. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName);
  1119. exit;
  1120. end; }
  1121. if not(po_external in aktprocsym^.definition^.procoptions) then
  1122. Message2(parser_n_interface_name_diff_implementation_name,hd^.mangledname,
  1123. aktprocsym^.definition^.mangledname);
  1124. { reset the mangledname of the interface part to be sure }
  1125. { this is wrong because the mangled name might have been used already !! }
  1126. if hd^.is_used then
  1127. renameasmsymbol(hd^.mangledname,aktprocsym^.definition^.mangledname);
  1128. hd^.setmangledname(aktprocsym^.definition^.mangledname);
  1129. { so we need to keep the name of interface !!
  1130. No!!!! The procedure directives can change the mangledname.
  1131. I fixed this by first calling check_identical and then doing
  1132. the proc directives, but this is not a good solution.(DM)}
  1133. { this is also wrong (PM)
  1134. aktprocsym^.definition^.setmangledname(hd^.mangledname);}
  1135. end
  1136. else
  1137. begin
  1138. { If mangled names are equal, therefore }
  1139. { they have the same number of parameters }
  1140. { Therefore we can check the name of these }
  1141. { parameters... }
  1142. if hd^.forwarddef and aktprocsym^.definition^.forwarddef then
  1143. begin
  1144. Message1(parser_e_function_already_declared_public_forward,aktprocsym^.demangledName);
  1145. Check_identical:=true;
  1146. { Remove other forward from the list to reduce errors }
  1147. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1148. exit;
  1149. end;
  1150. ad:=psym(hd^.parast^.symindex^.first);
  1151. fd:=psym(aktprocsym^.definition^.parast^.symindex^.first);
  1152. if assigned(ad) and assigned(fd) then
  1153. begin
  1154. while assigned(ad) and assigned(fd) do
  1155. begin
  1156. s:=ad^.name;
  1157. if s<>fd^.name then
  1158. begin
  1159. Message3(parser_e_header_different_var_names,
  1160. aktprocsym^.name,s,fd^.name);
  1161. break;
  1162. end;
  1163. { it is impossible to have a nil pointer }
  1164. { for only one parameter - since they }
  1165. { have the same number of parameters. }
  1166. { Left = next parameter. }
  1167. ad:=psym(ad^.left);
  1168. fd:=psym(fd^.left);
  1169. end;
  1170. end;
  1171. end;
  1172. end;
  1173. { also the call_offset }
  1174. hd^.parast^.address_fixup:=aktprocsym^.definition^.parast^.address_fixup;
  1175. hd^.count:=true;
  1176. { remove pd^.nextoverloaded from the list }
  1177. { and add aktprocsym^.definition }
  1178. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1179. hd^.nextoverloaded:=aktprocsym^.definition^.nextoverloaded;
  1180. { Alert! All fields of aktprocsym^.definition that are modified
  1181. by the procdir handlers must be copied here!.}
  1182. hd^.forwarddef:=false;
  1183. hd^.proccalloptions:=hd^.proccalloptions + aktprocsym^.definition^.proccalloptions;
  1184. hd^.procoptions:=hd^.procoptions + aktprocsym^.definition^.procoptions;
  1185. if aktprocsym^.definition^.extnumber=-1 then
  1186. aktprocsym^.definition^.extnumber:=hd^.extnumber
  1187. else
  1188. if hd^.extnumber=-1 then
  1189. hd^.extnumber:=aktprocsym^.definition^.extnumber;
  1190. { switch parast for warning in implementation PM }
  1191. if (m_repeat_forward in aktmodeswitches) or
  1192. aktprocsym^.definition^.haspara then
  1193. begin
  1194. storeparast:=hd^.parast;
  1195. hd^.parast:=aktprocsym^.definition^.parast;
  1196. aktprocsym^.definition^.parast:=storeparast;
  1197. end;
  1198. if pd=aktprocsym^.definition then
  1199. p:=nil
  1200. else
  1201. p:=pd;
  1202. aktprocsym^.definition:=hd;
  1203. check_identical:=true;
  1204. end
  1205. else
  1206. { abstract methods aren't forward defined, but this }
  1207. { needs another error message }
  1208. if not(po_abstractmethod in pd^.nextoverloaded^.procoptions) then
  1209. Message(parser_e_overloaded_have_same_parameters)
  1210. else
  1211. Message(parser_e_abstract_no_definition);
  1212. break;
  1213. end;
  1214. pd:=pd^.nextoverloaded;
  1215. end;
  1216. end
  1217. else
  1218. begin
  1219. { there is no overloaded, so its always identical with itself }
  1220. check_identical:=true;
  1221. end;
  1222. end;
  1223. { insert opsym only in the right symtable }
  1224. if ((procinfo^.flags and pi_operator)<>0) and assigned(opsym)
  1225. and not parse_only then
  1226. begin
  1227. if ret_in_param(aktprocsym^.definition^.retdef) then
  1228. begin
  1229. pprocdef(aktprocsym^.definition)^.parast^.insert(opsym);
  1230. { this increases the data size }
  1231. { correct this to get the right ret $value }
  1232. dec(pprocdef(aktprocsym^.definition)^.parast^.datasize,opsym^.getpushsize);
  1233. { this allows to read the funcretoffset }
  1234. opsym^.address:=-4;
  1235. opsym^.varspez:=vs_var;
  1236. end
  1237. else
  1238. pprocdef(aktprocsym^.definition)^.localst^.insert(opsym);
  1239. end;
  1240. end;
  1241. procedure compile_proc_body(const proc_names:Tstringcontainer;
  1242. make_global,parent_has_class:boolean);
  1243. {
  1244. Compile the body of a procedure
  1245. }
  1246. var
  1247. oldexitlabel,oldexit2label : pasmlabel;
  1248. oldfaillabel,oldquickexitlabel:Pasmlabel;
  1249. _class,hp:Pobjectdef;
  1250. { switches can change inside the procedure }
  1251. entryswitches, exitswitches : tlocalswitches;
  1252. { code for the subroutine as tree }
  1253. {$ifdef newcg}
  1254. code:pnode;
  1255. {$else newcg}
  1256. code:ptree;
  1257. {$endif newcg}
  1258. { size of the local strackframe }
  1259. stackframe:longint;
  1260. { true when no stackframe is required }
  1261. nostackframe:boolean;
  1262. { number of bytes which have to be cleared by RET }
  1263. parasize:longint;
  1264. { filepositions }
  1265. entrypos,
  1266. savepos,
  1267. exitpos : tfileposinfo;
  1268. begin
  1269. { calculate the lexical level }
  1270. inc(lexlevel);
  1271. if lexlevel>32 then
  1272. Message(parser_e_too_much_lexlevel);
  1273. { static is also important for local procedures !! }
  1274. if (po_staticmethod in aktprocsym^.definition^.procoptions) then
  1275. allow_only_static:=true
  1276. else if (lexlevel=normal_function_level) then
  1277. allow_only_static:=false;
  1278. { save old labels }
  1279. oldexitlabel:=aktexitlabel;
  1280. oldexit2label:=aktexit2label;
  1281. oldquickexitlabel:=quickexitlabel;
  1282. oldfaillabel:=faillabel;
  1283. { get new labels }
  1284. getlabel(aktexitlabel);
  1285. getlabel(aktexit2label);
  1286. { exit for fail in constructors }
  1287. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  1288. begin
  1289. getlabel(faillabel);
  1290. getlabel(quickexitlabel);
  1291. end;
  1292. { reset break and continue labels }
  1293. block_type:=bt_general;
  1294. aktbreaklabel:=nil;
  1295. aktcontinuelabel:=nil;
  1296. { insert symtables for the class, by only if it is no nested function }
  1297. if assigned(procinfo^._class) and not(parent_has_class) then
  1298. begin
  1299. { insert them in the reverse order ! }
  1300. hp:=nil;
  1301. repeat
  1302. _class:=procinfo^._class;
  1303. while _class^.childof<>hp do
  1304. _class:=_class^.childof;
  1305. hp:=_class;
  1306. _class^.symtable^.next:=symtablestack;
  1307. symtablestack:=_class^.symtable;
  1308. until hp=procinfo^._class;
  1309. end;
  1310. { insert parasymtable in symtablestack}
  1311. { only if lexlevel > 1 !!! global symtable should be right after staticsymtazble
  1312. for checking of same names used in interface and implementation !! }
  1313. if lexlevel>=normal_function_level then
  1314. begin
  1315. aktprocsym^.definition^.parast^.next:=symtablestack;
  1316. symtablestack:=aktprocsym^.definition^.parast;
  1317. symtablestack^.symtablelevel:=lexlevel;
  1318. end;
  1319. { insert localsymtable in symtablestack}
  1320. aktprocsym^.definition^.localst^.next:=symtablestack;
  1321. symtablestack:=aktprocsym^.definition^.localst;
  1322. symtablestack^.symtablelevel:=lexlevel;
  1323. { constant symbols are inserted in this symboltable }
  1324. constsymtable:=symtablestack;
  1325. { reset the temporary memory }
  1326. cleartempgen;
  1327. {$ifdef newcg}
  1328. tg.usedinproc:=[];
  1329. {$else newcg}
  1330. { no registers are used }
  1331. usedinproc:=0;
  1332. {$endif newcg}
  1333. { save entry info }
  1334. entrypos:=aktfilepos;
  1335. entryswitches:=aktlocalswitches;
  1336. {$ifdef newcg}
  1337. { parse the code ... }
  1338. if (po_assembler in aktprocsym^.definition^.procoptions) then
  1339. code:=convtree2node(assembler_block)
  1340. else
  1341. code:=convtree2node(block(current_module^.islibrary));
  1342. {$else newcg}
  1343. { parse the code ... }
  1344. if (po_assembler in aktprocsym^.definition^.procoptions) then
  1345. code:=assembler_block
  1346. else
  1347. code:=block(current_module^.islibrary);
  1348. {$endif newcg}
  1349. { get a better entry point }
  1350. if assigned(code) then
  1351. entrypos:=code^.fileinfo;
  1352. { save exit info }
  1353. exitswitches:=aktlocalswitches;
  1354. exitpos:=last_endtoken_filepos;
  1355. { save current filepos }
  1356. savepos:=aktfilepos;
  1357. {When we are called to compile the body of a unit, aktprocsym should
  1358. point to the unit initialization. If the unit has no initialization,
  1359. aktprocsym=nil. But in that case code=nil. hus we should check for
  1360. code=nil, when we use aktprocsym.}
  1361. { set the framepointer to esp for assembler functions }
  1362. { but only if the are no local variables }
  1363. { already done in assembler_block }
  1364. {$ifdef newcg}
  1365. tg.setfirsttemp(procinfo^.firsttemp);
  1366. {$else newcg}
  1367. setfirsttemp(procinfo^.firsttemp);
  1368. {$endif newcg}
  1369. { ... and generate assembler }
  1370. { but set the right switches for entry !! }
  1371. aktlocalswitches:=entryswitches;
  1372. {$ifndef NOPASS2}
  1373. {$ifdef newcg}
  1374. tg.setfirsttemp(procinfo^.firsttemp);
  1375. {$else newcg}
  1376. if assigned(code) then
  1377. generatecode(code);
  1378. {$endif newcg}
  1379. { set switches to status at end of procedure }
  1380. aktlocalswitches:=exitswitches;
  1381. if assigned(code) then
  1382. begin
  1383. aktprocsym^.definition^.code:=code;
  1384. { the procedure is now defined }
  1385. aktprocsym^.definition^.forwarddef:=false;
  1386. {$ifdef newcg}
  1387. aktprocsym^.definition^.usedregisters:=tg.usedinproc;
  1388. {$else newcg}
  1389. aktprocsym^.definition^.usedregisters:=usedinproc;
  1390. {$endif newcg}
  1391. end;
  1392. {$ifdef newcg}
  1393. stackframe:=tg.gettempsize;
  1394. {$else newcg}
  1395. stackframe:=gettempsize;
  1396. {$endif newcg}
  1397. { first generate entry code with the correct position and switches }
  1398. aktfilepos:=entrypos;
  1399. aktlocalswitches:=entryswitches;
  1400. {$ifdef newcg}
  1401. if assigned(code) then
  1402. cg^.g_entrycode(procinfo^.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
  1403. {$else newcg}
  1404. if assigned(code) then
  1405. genentrycode(procinfo^.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
  1406. {$endif newcg}
  1407. { now generate exit code with the correct position and switches }
  1408. aktfilepos:=exitpos;
  1409. aktlocalswitches:=exitswitches;
  1410. if assigned(code) then
  1411. begin
  1412. {$ifdef newcg}
  1413. cg^.g_exitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
  1414. {$else newcg}
  1415. genexitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
  1416. {$endif newcg}
  1417. procinfo^.aktproccode^.insertlist(procinfo^.aktentrycode);
  1418. procinfo^.aktproccode^.concatlist(procinfo^.aktexitcode);
  1419. {$ifdef i386}
  1420. {$ifndef NoOpt}
  1421. if (cs_optimize in aktglobalswitches) and
  1422. { do not optimize pure assembler procedures }
  1423. ((procinfo^.flags and pi_is_assembler)=0) then
  1424. Optimize(procinfo^.aktproccode);
  1425. {$endif NoOpt}
  1426. {$endif}
  1427. { save local data (casetable) also in the same file }
  1428. if assigned(procinfo^.aktlocaldata) and
  1429. (not procinfo^.aktlocaldata^.empty) then
  1430. begin
  1431. procinfo^.aktproccode^.concat(new(pai_section,init(sec_data)));
  1432. procinfo^.aktproccode^.concatlist(procinfo^.aktlocaldata);
  1433. end;
  1434. { now we can insert a cut }
  1435. if (cs_create_smart in aktmoduleswitches) then
  1436. codesegment^.concat(new(pai_cut,init));
  1437. { add the procedure to the codesegment }
  1438. codesegment^.concatlist(procinfo^.aktproccode);
  1439. end;
  1440. {$else}
  1441. if assigned(code) then
  1442. firstpass(code);
  1443. {$endif NOPASS2}
  1444. { ... remove symbol tables, for the browser leave the static table }
  1445. { if (cs_browser in aktmoduleswitches) and (symtablestack^.symtabletype=staticsymtable) then
  1446. symtablestack^.next:=symtablestack^.next^.next
  1447. else }
  1448. if lexlevel>=normal_function_level then
  1449. symtablestack:=symtablestack^.next^.next
  1450. else
  1451. symtablestack:=symtablestack^.next;
  1452. { ... check for unused symbols }
  1453. { but only if there is no asm block }
  1454. if assigned(code) then
  1455. begin
  1456. if (Errorcount=0) then
  1457. begin
  1458. aktprocsym^.definition^.localst^.check_forwards;
  1459. aktprocsym^.definition^.localst^.checklabels;
  1460. end;
  1461. if (procinfo^.flags and pi_uses_asm)=0 then
  1462. begin
  1463. { not for unit init, becuase the var can be used in finalize,
  1464. it will be done in proc_unit }
  1465. if not(aktprocsym^.definition^.proctypeoption in [potype_unitinit,potype_unitfinalize]) then
  1466. aktprocsym^.definition^.localst^.allsymbolsused;
  1467. aktprocsym^.definition^.parast^.allsymbolsused;
  1468. end;
  1469. end;
  1470. { the local symtables can be deleted, but the parast }
  1471. { doesn't, (checking definitons when calling a }
  1472. { function }
  1473. { not for a inline procedure !! (PM) }
  1474. { at lexlevel = 1 localst is the staticsymtable itself }
  1475. { so no dispose here !! }
  1476. if assigned(code) and
  1477. not(cs_browser in aktmoduleswitches) and
  1478. not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1479. begin
  1480. if lexlevel>=normal_function_level then
  1481. dispose(aktprocsym^.definition^.localst,done);
  1482. aktprocsym^.definition^.localst:=nil;
  1483. end;
  1484. { only now we can remove the temps }
  1485. resettempgen;
  1486. { remove code tree, if not inline procedure }
  1487. if assigned(code) and not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1488. {$ifdef newcg}
  1489. dispose(code,done);
  1490. {$else newcg}
  1491. disposetree(code);
  1492. {$endif newcg}
  1493. { remove class member symbol tables }
  1494. while symtablestack^.symtabletype=objectsymtable do
  1495. symtablestack:=symtablestack^.next;
  1496. { restore filepos, the switches are already set }
  1497. aktfilepos:=savepos;
  1498. { free labels }
  1499. freelabel(aktexitlabel);
  1500. freelabel(aktexit2label);
  1501. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  1502. begin
  1503. freelabel(faillabel);
  1504. freelabel(quickexitlabel);
  1505. end;
  1506. { restore labels }
  1507. aktexitlabel:=oldexitlabel;
  1508. aktexit2label:=oldexit2label;
  1509. quickexitlabel:=oldquickexitlabel;
  1510. faillabel:=oldfaillabel;
  1511. { reset to normal non static function }
  1512. if (lexlevel=normal_function_level) then
  1513. allow_only_static:=false;
  1514. { previous lexlevel }
  1515. dec(lexlevel);
  1516. end;
  1517. procedure parse_proc_directives(Anames:Pstringcontainer;var pdflags:word);
  1518. {
  1519. Parse the procedure directives. It does not matter if procedure directives
  1520. are written using ;procdir; or ['procdir'] syntax.
  1521. }
  1522. var
  1523. res : boolean;
  1524. begin
  1525. while token in [_ID,_LECKKLAMMER] do
  1526. begin
  1527. if try_to_consume(_LECKKLAMMER) then
  1528. begin
  1529. repeat
  1530. parse_proc_direc(Anames^,pdflags);
  1531. until not try_to_consume(_COMMA);
  1532. consume(_RECKKLAMMER);
  1533. { we always expect at least '[];' }
  1534. res:=true;
  1535. end
  1536. else
  1537. res:=parse_proc_direc(Anames^,pdflags);
  1538. { A procedure directive normally followed by a semicolon, but in
  1539. a const section we should stop when _EQUAL is found }
  1540. if res then
  1541. begin
  1542. if (block_type=bt_const) and
  1543. (token=_EQUAL) then
  1544. break;
  1545. consume(_SEMICOLON);
  1546. end
  1547. else
  1548. break;
  1549. end;
  1550. end;
  1551. procedure parse_var_proc_directives(var sym : psym);
  1552. var
  1553. anames : pstringcontainer;
  1554. pdflags : word;
  1555. oldsym : pprocsym;
  1556. pd : pabstractprocdef;
  1557. begin
  1558. oldsym:=aktprocsym;
  1559. anames:=new(pstringcontainer,init);
  1560. pdflags:=pd_procvar;
  1561. { we create a temporary aktprocsym to read the directives }
  1562. aktprocsym:=new(pprocsym,init(sym^.name));
  1563. case sym^.typ of
  1564. varsym :
  1565. pd:=pabstractprocdef(pvarsym(sym)^.definition);
  1566. typedconstsym :
  1567. pd:=pabstractprocdef(ptypedconstsym(sym)^.definition);
  1568. typesym :
  1569. pd:=pabstractprocdef(ptypesym(sym)^.definition);
  1570. else
  1571. internalerror(994932432);
  1572. end;
  1573. if pd^.deftype<>procvardef then
  1574. internalerror(994932433);
  1575. pabstractprocdef(aktprocsym^.definition):=pd;
  1576. { names should never be used anyway }
  1577. inc(lexlevel);
  1578. parse_proc_directives(anames,pdflags);
  1579. dec(lexlevel);
  1580. aktprocsym^.definition:=nil;
  1581. dispose(aktprocsym,done);
  1582. dispose(anames,done);
  1583. aktprocsym:=oldsym;
  1584. end;
  1585. procedure parse_object_proc_directives(var sym : pprocsym);
  1586. var
  1587. anames : pstringcontainer;
  1588. pdflags : word;
  1589. begin
  1590. pdflags:=pd_object;
  1591. anames:=new(pstringcontainer,init);
  1592. inc(lexlevel);
  1593. parse_proc_directives(anames,pdflags);
  1594. dec(lexlevel);
  1595. dispose(anames,done);
  1596. if (po_containsself in aktprocsym^.definition^.procoptions) and
  1597. (([po_msgstr,po_msgint]*aktprocsym^.definition^.procoptions)=[]) then
  1598. Message(parser_e_self_in_non_message_handler);
  1599. end;
  1600. procedure checkvaluepara(p:pnamedindexobject);{$ifndef FPC}far;{$endif}
  1601. var
  1602. vs : pvarsym;
  1603. s : string;
  1604. begin
  1605. with pvarsym(p)^ do
  1606. begin
  1607. if copy(name,1,3)='val' then
  1608. begin
  1609. s:=Copy(name,4,255);
  1610. if not(po_assembler in aktprocsym^.definition^.procoptions) then
  1611. begin
  1612. vs:=new(Pvarsym,init(s,definition));
  1613. vs^.fileinfo:=fileinfo;
  1614. vs^.varspez:=varspez;
  1615. aktprocsym^.definition^.localst^.insert(vs);
  1616. vs^.islocalcopy:=true;
  1617. vs^.varstate:=vs_used;
  1618. localvarsym:=vs;
  1619. end
  1620. else
  1621. begin
  1622. aktprocsym^.definition^.parast^.rename(name,s);
  1623. end;
  1624. end;
  1625. end;
  1626. end;
  1627. procedure read_proc;
  1628. {
  1629. Parses the procedure directives, then parses the procedure body, then
  1630. generates the code for it
  1631. }
  1632. var
  1633. oldprefix : string;
  1634. oldprocsym : Pprocsym;
  1635. oldprocinfo : pprocinfo;
  1636. oldconstsymtable : Psymtable;
  1637. oldfilepos : tfileposinfo;
  1638. names : Pstringcontainer;
  1639. pdflags : word;
  1640. prevdef,stdef : pprocdef;
  1641. begin
  1642. { save old state }
  1643. oldprocsym:=aktprocsym;
  1644. oldprefix:=procprefix;
  1645. oldconstsymtable:=constsymtable;
  1646. oldprocinfo:=procinfo;
  1647. { create a new procedure }
  1648. new(names,init);
  1649. codegen_newprocedure;
  1650. with procinfo^ do
  1651. begin
  1652. parent:=oldprocinfo;
  1653. { clear flags }
  1654. flags:=0;
  1655. { standard frame pointer }
  1656. framepointer:=frame_pointer;
  1657. funcret_is_valid:=false;
  1658. { is this a nested function of a method ? }
  1659. if assigned(oldprocinfo) then
  1660. _class:=oldprocinfo^._class;
  1661. end;
  1662. parse_proc_dec;
  1663. { set the default function options }
  1664. if parse_only then
  1665. begin
  1666. aktprocsym^.definition^.forwarddef:=true;
  1667. { set also the interface flag, for better error message when the
  1668. implementation doesn't much this header }
  1669. aktprocsym^.definition^.interfacedef:=true;
  1670. pdflags:=pd_interface;
  1671. end
  1672. else
  1673. begin
  1674. pdflags:=pd_body;
  1675. if current_module^.in_implementation then
  1676. pdflags:=pdflags or pd_implemen;
  1677. if (not current_module^.is_unit) or (cs_create_smart in aktmoduleswitches) then
  1678. pdflags:=pdflags or pd_global;
  1679. procinfo^.exported:=false;
  1680. aktprocsym^.definition^.forwarddef:=false;
  1681. end;
  1682. { parse the directives that may follow }
  1683. inc(lexlevel);
  1684. parse_proc_directives(names,pdflags);
  1685. dec(lexlevel);
  1686. { set aktfilepos to the beginning of the function declaration }
  1687. oldfilepos:=aktfilepos;
  1688. aktfilepos:=aktprocsym^.definition^.fileinfo;
  1689. { search for forward declarations }
  1690. if not check_identical(prevdef) then
  1691. begin
  1692. { A method must be forward defined (in the object declaration) }
  1693. if assigned(procinfo^._class) and (not assigned(oldprocinfo^._class)) then
  1694. Message(parser_e_header_dont_match_any_member);
  1695. { Give a better error if there is a forward def in the interface and only
  1696. a single implementation }
  1697. if (not aktprocsym^.definition^.forwarddef) and
  1698. assigned(aktprocsym^.definition^.nextoverloaded) and
  1699. aktprocsym^.definition^.nextoverloaded^.forwarddef and
  1700. aktprocsym^.definition^.nextoverloaded^.interfacedef and
  1701. not(assigned(aktprocsym^.definition^.nextoverloaded^.nextoverloaded)) then
  1702. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName)
  1703. else
  1704. begin
  1705. { check the global flag }
  1706. if (procinfo^.flags and pi_is_global)<>0 then
  1707. Message(parser_e_overloaded_must_be_all_global);
  1708. end
  1709. end;
  1710. { set return type here, becuase the aktprocsym^.definition can be
  1711. changed by check_identical (PFV) }
  1712. procinfo^.retdef:=aktprocsym^.definition^.retdef;
  1713. { pointer to the return value ? }
  1714. if ret_in_param(procinfo^.retdef) then
  1715. begin
  1716. procinfo^.retoffset:=procinfo^.call_offset;
  1717. inc(procinfo^.call_offset,target_os.size_of_pointer);
  1718. end;
  1719. { allows to access the parameters of main functions in nested functions }
  1720. aktprocsym^.definition^.parast^.address_fixup:=procinfo^.call_offset;
  1721. { when it is a value para and it needs a local copy then rename
  1722. the parameter and insert a copy in the localst. This is not done
  1723. for assembler procedures }
  1724. if (not parse_only) and (not aktprocsym^.definition^.forwarddef) then
  1725. aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}checkvaluepara);
  1726. { restore file pos }
  1727. aktfilepos:=oldfilepos;
  1728. { compile procedure when a body is needed }
  1729. if (pdflags and pd_body)<>0 then
  1730. begin
  1731. Message1(parser_p_procedure_start,aktprocsym^.demangledname);
  1732. names^.insert(aktprocsym^.definition^.mangledname);
  1733. { set _FAIL as keyword if constructor }
  1734. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  1735. tokeninfo^[_FAIL].keyword:=m_all;
  1736. if assigned(aktprocsym^.definition^._class) then
  1737. tokeninfo^[_SELF].keyword:=m_all;
  1738. compile_proc_body(names^,((pdflags and pd_global)<>0),assigned(oldprocinfo^._class));
  1739. { reset _FAIL as normal }
  1740. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  1741. tokeninfo^[_FAIL].keyword:=m_none;
  1742. if assigned(aktprocsym^.definition^._class) and (lexlevel=main_program_level) then
  1743. tokeninfo^[_SELF].keyword:=m_none;
  1744. consume(_SEMICOLON);
  1745. end;
  1746. { close }
  1747. dispose(names,done);
  1748. codegen_doneprocedure;
  1749. { Restore old state }
  1750. constsymtable:=oldconstsymtable;
  1751. { from now on all refernece to mangledname means
  1752. that the function is already used }
  1753. aktprocsym^.definition^.count:=true;
  1754. { restore the interface order to maintain CRC values PM }
  1755. if assigned(prevdef) and assigned(aktprocsym^.definition^.nextoverloaded) then
  1756. begin
  1757. stdef:=aktprocsym^.definition;
  1758. aktprocsym^.definition:=stdef^.nextoverloaded;
  1759. stdef^.nextoverloaded:=prevdef^.nextoverloaded;
  1760. prevdef^.nextoverloaded:=stdef;
  1761. end;
  1762. aktprocsym:=oldprocsym;
  1763. procprefix:=oldprefix;
  1764. procinfo:=oldprocinfo;
  1765. opsym:=nil;
  1766. end;
  1767. end.
  1768. {
  1769. $Log$
  1770. Revision 1.30 1999-10-26 12:30:44 peter
  1771. * const parameter is now checked
  1772. * better and generic check if a node can be used for assigning
  1773. * export fixes
  1774. * procvar equal works now (it never had worked at least from 0.99.8)
  1775. * defcoll changed to linkedlist with pparaitem so it can easily be
  1776. walked both directions
  1777. Revision 1.29 1999/10/22 10:39:35 peter
  1778. * split type reading from pdecl to ptype unit
  1779. * parameter_dec routine is now used for procedure and procvars
  1780. Revision 1.28 1999/10/13 10:37:36 peter
  1781. * moved mangledname creation of normal proc so it also handles a wrong
  1782. method proc
  1783. Revision 1.27 1999/10/12 21:20:46 florian
  1784. * new codegenerator compiles again
  1785. Revision 1.26 1999/10/03 19:38:39 peter
  1786. * fixed forward decl check for tp7/delphi
  1787. Revision 1.25 1999/10/01 10:05:44 peter
  1788. + procedure directive support in const declarations, fixes bug 232
  1789. Revision 1.24 1999/10/01 08:02:47 peter
  1790. * forward type declaration rewritten
  1791. Revision 1.23 1999/09/27 23:44:56 peter
  1792. * procinfo is now a pointer
  1793. * support for result setting in sub procedure
  1794. Revision 1.22 1999/09/20 16:39:00 peter
  1795. * cs_create_smart instead of cs_smartlink
  1796. * -CX is create smartlink
  1797. * -CD is create dynamic, but does nothing atm.
  1798. Revision 1.21 1999/09/15 20:35:42 florian
  1799. * small fix to operator overloading when in MMX mode
  1800. + the compiler uses now fldz and fld1 if possible
  1801. + some fixes to floating point registers
  1802. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  1803. * .... ???
  1804. Revision 1.20 1999/09/10 18:48:09 florian
  1805. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  1806. * most things for stored properties fixed
  1807. Revision 1.19 1999/09/07 14:59:40 pierre
  1808. * bugfix for 237 and 244
  1809. Revision 1.18 1999/09/02 18:47:45 daniel
  1810. * Could not compile with TP, some arrays moved to heap
  1811. * NOAG386BIN default for TP
  1812. * AG386* files were not compatible with TP, fixed.
  1813. Revision 1.17 1999/08/30 10:17:57 peter
  1814. * fixed crash in psub
  1815. * ansistringcompare fixed
  1816. * support for #$0b8
  1817. Revision 1.16 1999/08/27 10:41:46 pierre
  1818. * pi_is_global was missing for global methods
  1819. + code to restore overloaded list order
  1820. (necessary to get same CRC values after interface and after
  1821. implementation)
  1822. Revision 1.15 1999/08/19 13:02:11 pierre
  1823. + label faillabel added for _FAIL support
  1824. Revision 1.14 1999/08/10 16:24:44 pierre
  1825. * linking to C code with cdecl;external; was broken
  1826. Revision 1.13 1999/08/10 12:37:44 pierre
  1827. + procsym field of tprocdef set
  1828. Revision 1.12 1999/08/05 16:53:06 peter
  1829. * V_Fatal=1, all other V_ are also increased
  1830. * Check for local procedure when assigning procvar
  1831. * fixed comment parsing because directives
  1832. * oldtp mode directives better supported
  1833. * added some messages to errore.msg
  1834. Revision 1.11 1999/08/04 13:03:01 jonas
  1835. * all tokens now start with an underscore
  1836. * PowerPC compiles!!
  1837. Revision 1.10 1999/08/04 00:23:20 florian
  1838. * renamed i386asm and i386base to cpuasm and cpubase
  1839. Revision 1.9 1999/08/03 22:03:05 peter
  1840. * moved bitmask constants to sets
  1841. * some other type/const renamings
  1842. Revision 1.8 1999/08/03 17:09:42 florian
  1843. * the alpha compiler can be compiled now
  1844. Revision 1.7 1999/08/02 21:29:01 florian
  1845. * the main branch psub.pas is now used for
  1846. newcg compiler
  1847. Revision 1.6 1999/07/27 23:42:16 peter
  1848. * indirect type referencing is now allowed
  1849. Revision 1.5 1999/07/26 09:42:15 florian
  1850. * bugs 494-496 fixed
  1851. Revision 1.4 1999/07/11 20:10:24 peter
  1852. * merged
  1853. Revision 1.3 1999/07/02 13:02:24 peter
  1854. * merged
  1855. Revision 1.2 1999/06/17 13:19:56 pierre
  1856. * merged from 0_99_12 branch
  1857. Revision 1.1.2.4 1999/07/11 20:07:39 peter
  1858. * message crash fixed
  1859. * no error if self is used with non-string message
  1860. Revision 1.1.2.3 1999/07/11 20:04:05 pierre
  1861. * fix for problem with external without parameters in Delphi mode
  1862. Revision 1.1.2.2 1999/07/02 12:59:52 peter
  1863. * fixed parsing of message directive
  1864. Revision 1.1.2.1 1999/06/17 12:44:47 pierre
  1865. * solve problems related to assignment overloading
  1866. * support Delphi syntax for operator
  1867. * avoid problems if local procedure in operator
  1868. Revision 1.1 1999/06/11 13:21:37 peter
  1869. * reinserted
  1870. Revision 1.153 1999/06/02 22:44:14 pierre
  1871. * previous wrong log corrected
  1872. Revision 1.152 1999/06/02 22:25:46 pierre
  1873. * changed $ifdef FPC @ into $ifndef TP
  1874. Revision 1.151 1999/06/01 22:47:06 pierre
  1875. * problem with static keyword solved
  1876. Revision 1.150 1999/06/01 14:45:53 peter
  1877. * @procvar is now always needed for FPC
  1878. Revision 1.149 1999/05/31 16:42:31 peter
  1879. * interfacedef flag for procdef if it's defined in the interface, to
  1880. make a difference with 'forward;' directive forwarddef. Fixes 253
  1881. Revision 1.148 1999/05/27 19:44:52 peter
  1882. * removed oldasm
  1883. * plabel -> pasmlabel
  1884. * -a switches to source writing automaticly
  1885. * assembler readers OOPed
  1886. * asmsymbol automaticly external
  1887. * jumptables and other label fixes for asm readers
  1888. Revision 1.147 1999/05/24 08:55:27 florian
  1889. * non working safecall directiv implemented, I don't know if we
  1890. need it
  1891. Revision 1.146 1999/05/23 18:42:11 florian
  1892. * better error recovering in typed constants
  1893. * some problems with arrays of const fixed, some problems
  1894. due my previous
  1895. - the location type of array constructor is now LOC_MEM
  1896. - the pushing of high fixed
  1897. - parameter copying fixed
  1898. - zero temp. allocation removed
  1899. * small problem in the assembler writers fixed:
  1900. ref to nil wasn't written correctly
  1901. Revision 1.145 1999/05/21 13:55:09 peter
  1902. * NEWLAB for label as symbol
  1903. Revision 1.144 1999/05/18 14:15:55 peter
  1904. * containsself fixes
  1905. * checktypes()
  1906. Revision 1.143 1999/05/17 21:57:13 florian
  1907. * new temporary ansistring handling
  1908. Revision 1.142 1999/05/17 15:06:38 pierre
  1909. * fixes for object type check
  1910. Revision 1.141 1999/05/13 21:59:39 peter
  1911. * removed oldppu code
  1912. * warning if objpas is loaded from uses
  1913. * first things for new deref writing
  1914. Revision 1.140 1999/05/12 22:36:12 florian
  1915. * override isn't allowed in objects!
  1916. Revision 1.139 1999/05/10 09:01:41 peter
  1917. * small message fixes
  1918. Revision 1.138 1999/05/09 12:46:24 peter
  1919. + hint where a duplicate sym is already defined
  1920. Revision 1.137 1999/05/08 19:48:45 peter
  1921. * better error message if declaration doesn't match forward
  1922. Revision 1.136 1999/05/08 15:26:15 peter
  1923. * print also manglednames when changed
  1924. Revision 1.135 1999/05/06 10:12:10 peter
  1925. * fixed operator result offset which destroyed parast^.datasize
  1926. Revision 1.134 1999/05/01 13:24:36 peter
  1927. * merged nasm compiler
  1928. * old asm moved to oldasm/
  1929. Revision 1.133 1999/04/28 11:12:03 peter
  1930. * fixed crash with self pointer
  1931. Revision 1.132 1999/04/28 06:02:09 florian
  1932. * changes of Bruessel:
  1933. + message handler can now take an explicit self
  1934. * typinfo fixed: sometimes the type names weren't written
  1935. * the type checking for pointer comparisations and subtraction
  1936. and are now more strict (was also buggy)
  1937. * small bug fix to link.pas to support compiling on another
  1938. drive
  1939. * probable bug in popt386 fixed: call/jmp => push/jmp
  1940. transformation didn't count correctly the jmp references
  1941. + threadvar support
  1942. * warning if ln/sqrt gets an invalid constant argument
  1943. Revision 1.131 1999/04/26 13:31:44 peter
  1944. * release storenumber,double_checksum
  1945. Revision 1.130 1999/04/21 09:43:49 peter
  1946. * storenumber works
  1947. * fixed some typos in double_checksum
  1948. + incompatible types type1 and type2 message (with storenumber)
  1949. Revision 1.129 1999/04/20 14:39:07 daniel
  1950. *** empty log message ***
  1951. Revision 1.125 1999/04/14 09:14:55 peter
  1952. * first things to store the symbol/def number in the ppu
  1953. Revision 1.124 1999/04/07 15:31:13 pierre
  1954. * all formaldefs are now a sinlge definition
  1955. cformaldef (this was necessary for double_checksum)
  1956. + small part of double_checksum code
  1957. Revision 1.123 1999/04/06 11:21:58 peter
  1958. * more use of ttoken
  1959. Revision 1.122 1999/03/31 13:55:16 peter
  1960. * assembler inlining working for ag386bin
  1961. Revision 1.121 1999/03/26 00:05:39 peter
  1962. * released valintern
  1963. + deffile is now removed when compiling is finished
  1964. * ^( compiles now correct
  1965. + static directive
  1966. * shrd fixed
  1967. Revision 1.120 1999/03/24 23:17:18 peter
  1968. * fixed bugs 212,222,225,227,229,231,233
  1969. Revision 1.119 1999/03/05 09:46:18 pierre
  1970. * public problem for methods
  1971. Revision 1.118 1999/03/05 01:14:24 pierre
  1972. * bug0198 : call conventions for methods
  1973. not yet implemented is the control of same calling convention
  1974. for virtual and child's virtual
  1975. * msgstr and msgint only created if message was found
  1976. who implemented this by the way ?
  1977. it leaks lots of plabels !!!! (check with heaptrc !)
  1978. Revision 1.117 1999/03/04 13:55:47 pierre
  1979. * some m68k fixes (still not compilable !)
  1980. * new(tobj) does not give warning if tobj has no VMT !
  1981. Revision 1.116 1999/03/01 15:40:52 peter
  1982. * external name <str> didn't concatexternal()
  1983. Revision 1.115 1999/03/01 13:31:58 pierre
  1984. * external used before implemented problem fixed
  1985. Revision 1.114 1999/02/24 00:59:15 peter
  1986. * small updates for ag386bin
  1987. Revision 1.113 1999/02/23 18:29:21 pierre
  1988. * win32 compilation error fix
  1989. + some work for local browser (not cl=omplete yet)
  1990. Revision 1.112 1999/02/22 13:07:03 pierre
  1991. + -b and -bl options work !
  1992. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1993. is not enabled when quitting global section
  1994. * local vars and procedures are not yet stored into PPU
  1995. Revision 1.111 1999/02/22 02:15:33 peter
  1996. * updates for ag386bin
  1997. Revision 1.110 1999/02/16 12:23:19 pierre
  1998. * nested forward procedure bug solved
  1999. Revision 1.109 1999/02/15 10:07:06 pierre
  2000. * memory leaks due to last commit solved
  2001. Revision 1.108 1999/02/11 09:46:27 pierre
  2002. * fix for normal method calls inside static methods :
  2003. WARNING there were both parser and codegen errors !!
  2004. added static_call boolean to calln tree
  2005. Revision 1.107 1999/02/10 11:27:39 pierre
  2006. * overloaded function locals problem bug0213
  2007. Revision 1.106 1999/02/08 11:29:05 pierre
  2008. * fix for bug0214
  2009. several problems where combined
  2010. search_class_member did not set srsymtable
  2011. => in do_member_read the call node got a wrong symtable
  2012. in cg386cal the vmt was pushed twice without chacking if it exists
  2013. now %esi is set to zero and pushed if not vmt
  2014. (not very efficient but should work !)
  2015. Revision 1.105 1999/02/05 12:51:20 florian
  2016. + openstring id is now supported
  2017. Revision 1.104 1999/02/03 09:26:44 pierre
  2018. + better reference for args of procs
  2019. Revision 1.103 1999/02/02 11:04:37 florian
  2020. * class destructors fixed, class instances weren't disposed correctly
  2021. Revision 1.102 1999/01/21 22:10:46 peter
  2022. * fixed array of const
  2023. * generic platform independent high() support
  2024. Revision 1.101 1999/01/20 14:18:38 pierre
  2025. * bugs related to mangledname solved
  2026. - linux external without name
  2027. -external procs already used
  2028. (added count and is_used boolean fiels in tprocvar)
  2029. Revision 1.100 1999/01/20 10:20:19 peter
  2030. * don't make localvar copies for assembler procedures
  2031. Revision 1.99 1999/01/19 15:59:40 pierre
  2032. * fix for function a;
  2033. Revision 1.98 1999/01/19 12:16:07 peter
  2034. * NOPASS2 now calls firstpass
  2035. Revision 1.97 1999/01/14 11:35:30 daniel
  2036. * Fixed manglednames
  2037. Revision 1.96 1998/12/30 13:41:10 peter
  2038. * released valuepara
  2039. Revision 1.95 1998/12/30 10:36:39 michael
  2040. + Delphi also allows external in interface section
  2041. Revision 1.94 1998/12/29 18:48:26 jonas
  2042. + optimize pascal code surrounding assembler blocks
  2043. Revision 1.93 1998/12/28 15:44:49 peter
  2044. + NOPASS2 define
  2045. Revision 1.92 1998/12/11 00:03:39 peter
  2046. + globtype,tokens,version unit splitted from globals
  2047. Revision 1.91 1998/11/27 14:50:42 peter
  2048. + open strings, $P switch support
  2049. Revision 1.90 1998/11/18 17:45:27 peter
  2050. * fixes for VALUEPARA
  2051. Revision 1.89 1998/11/18 15:44:15 peter
  2052. * VALUEPARA for tp7 compatible value parameters
  2053. Revision 1.88 1998/11/16 15:40:30 pierre
  2054. * mangling name and -So bugs solved
  2055. Revision 1.87 1998/11/16 11:29:02 pierre
  2056. * stackcheck removed for i386_win32
  2057. * exportlist does not crash at least !!
  2058. (was need for tests dir !)z
  2059. Revision 1.86 1998/11/16 10:13:54 peter
  2060. * label defines are checked at the end of the proc
  2061. Revision 1.85 1998/11/13 15:40:26 pierre
  2062. + added -Se in Makefile cvstest target
  2063. + lexlevel cleanup
  2064. normal_function_level main_program_level and unit_init_level defined
  2065. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  2066. (test added in code !)
  2067. * -Un option was wrong
  2068. * _FAIL and _SELF only keyword inside
  2069. constructors and methods respectively
  2070. Revision 1.84 1998/11/10 10:09:13 peter
  2071. * va_list -> array of const
  2072. Revision 1.83 1998/11/09 11:44:34 peter
  2073. + va_list for printf support
  2074. Revision 1.82 1998/10/29 11:35:53 florian
  2075. * some dll support for win32
  2076. * fixed assembler writing for PalmOS
  2077. Revision 1.81 1998/10/28 18:26:16 pierre
  2078. * removed some erros after other errors (introduced by useexcept)
  2079. * stabs works again correctly (for how long !)
  2080. Revision 1.80 1998/10/27 13:45:37 pierre
  2081. * classes get a vmt allways
  2082. * better error info (tried to remove
  2083. several error strings introduced by the tpexcept handling)
  2084. Revision 1.79 1998/10/23 00:09:43 peter
  2085. * fixed message for forward declaration
  2086. Revision 1.78 1998/10/20 13:10:37 peter
  2087. * fixed crash when aktprocsym<>procsym
  2088. Revision 1.77 1998/10/20 08:06:55 pierre
  2089. * several memory corruptions due to double freemem solved
  2090. => never use p^.loc.location:=p^.left^.loc.location;
  2091. + finally I added now by default
  2092. that ra386dir translates global and unit symbols
  2093. + added a first field in tsymtable and
  2094. a nextsym field in tsym
  2095. (this allows to obtain ordered type info for
  2096. records and objects in gdb !)
  2097. Revision 1.76 1998/10/19 08:55:02 pierre
  2098. * wrong stabs info corrected once again !!
  2099. + variable vmt offset with vmt field only if required
  2100. implemented now !!!
  2101. Revision 1.75 1998/10/16 08:51:48 peter
  2102. + target_os.stackalignment
  2103. + stack can be aligned at 2 or 4 byte boundaries
  2104. Revision 1.74 1998/10/14 20:39:21 florian
  2105. * syscall for PalmOs fixed
  2106. Revision 1.73 1998/10/12 12:20:56 pierre
  2107. + added tai_const_symbol_offset
  2108. for r : pointer = @var.field;
  2109. * better message for different arg names on implementation
  2110. of function
  2111. Revision 1.72 1998/10/08 23:29:03 peter
  2112. * -vu shows unit info, -vt shows tried/used files
  2113. Revision 1.71 1998/10/08 17:17:28 pierre
  2114. * current_module old scanner tagged as invalid if unit is recompiled
  2115. + added ppheap for better info on tracegetmem of heaptrc
  2116. (adds line column and file index)
  2117. * several memory leaks removed ith help of heaptrc !!
  2118. Revision 1.70 1998/10/08 13:48:49 peter
  2119. * fixed memory leaks for do nothing source
  2120. * fixed unit interdependency
  2121. Revision 1.69 1998/10/05 21:33:27 peter
  2122. * fixed 161,165,166,167,168
  2123. Revision 1.68 1998/09/29 11:31:30 florian
  2124. * better error recovering when the object type of procedure tobject.method
  2125. isn't found
  2126. Revision 1.67 1998/09/26 17:45:39 peter
  2127. + idtoken and only one token table
  2128. Revision 1.66 1998/09/24 23:49:16 peter
  2129. + aktmodeswitches
  2130. Revision 1.65 1998/09/24 11:08:14 florian
  2131. * small problem in _proc_header with array of const fixed:
  2132. getsymonlyin doesn't set srsym to nil
  2133. Revision 1.64 1998/09/23 15:39:12 pierre
  2134. * browser bugfixes
  2135. was adding a reference when looking for the symbol
  2136. if -bSYM_NAME was used
  2137. Revision 1.63 1998/09/22 17:13:50 pierre
  2138. + browsing updated and developed
  2139. records and objects fields are also stored
  2140. Revision 1.62 1998/09/22 15:37:21 peter
  2141. + array of const start
  2142. Revision 1.61 1998/09/21 08:45:20 pierre
  2143. + added vmt_offset in tobjectdef.write for fututre use
  2144. (first steps to have objects without vmt if no virtual !!)
  2145. + added fpu_used field for tabstractprocdef :
  2146. sets this level to 2 if the functions return with value in FPU
  2147. (is then set to correct value at parsing of implementation)
  2148. THIS MIGHT refuse some code with FPU expression too complex
  2149. that were accepted before and even in some cases
  2150. that don't overflow in fact
  2151. ( like if f : float; is a forward that finally in implementation
  2152. only uses one fpu register !!)
  2153. Nevertheless I think that it will improve security on
  2154. FPU operations !!
  2155. * most other changes only for UseBrowser code
  2156. (added symtable references for record and objects)
  2157. local switch for refs to args and local of each function
  2158. (static symtable still missing)
  2159. UseBrowser still not stable and probably broken by
  2160. the definition hash array !!
  2161. Revision 1.60 1998/09/17 09:42:42 peter
  2162. + pass_2 for cg386
  2163. * Message() -> CGMessage() for pass_1/pass_2
  2164. Revision 1.59 1998/09/15 14:05:25 jonas
  2165. * fixed optimizer incompatibilities with freelabel code in psub
  2166. Revision 1.58 1998/09/14 21:27:41 peter
  2167. - freelabel calls, becuase they are instable with -O2
  2168. Revision 1.57 1998/09/14 10:38:27 peter
  2169. * pd_alias now uses get_stringconst
  2170. Revision 1.56 1998/09/14 10:29:38 daniel
  2171. * Fixed memory leaks.
  2172. Revision 1.55 1998/09/09 11:50:56 pierre
  2173. * forward def are not put in record or objects
  2174. + added check for forwards also in record and objects
  2175. * dummy parasymtable for unit initialization removed from
  2176. symtable stack
  2177. Revision 1.54 1998/09/04 08:42:05 peter
  2178. * updated some error messages
  2179. Revision 1.53 1998/09/01 17:39:51 peter
  2180. + internal constant functions
  2181. Revision 1.52 1998/09/01 09:07:12 peter
  2182. * m68k fixes, splitted cg68k like cgi386
  2183. Revision 1.51 1998/09/01 07:54:21 pierre
  2184. * UseBrowser a little updated (might still be buggy !!)
  2185. * bug in psub.pas in function specifier removed
  2186. * stdcall allowed in interface and in implementation
  2187. (FPC will not yet complain if it is missing in either part
  2188. because stdcall is only a dummy !!)
  2189. Revision 1.50 1998/08/31 12:26:31 peter
  2190. * m68k and palmos updates from surebugfixes
  2191. Revision 1.49 1998/08/25 12:42:43 pierre
  2192. * CDECL changed to CVAR for variables
  2193. specifications are read in structures also
  2194. + started adding GPC compatibility mode ( option -Sp)
  2195. * names changed to lowercase
  2196. Revision 1.48 1998/08/21 08:43:30 pierre
  2197. * pocdecl and poclearstack are now different
  2198. external must but written as last specification
  2199. Revision 1.47 1998/08/20 09:26:44 pierre
  2200. + funcret setting in underproc testing
  2201. compile with _dTEST_FUNCRET
  2202. Revision 1.46 1998/08/19 18:04:55 peter
  2203. * fixed current_module^.in_implementation flag
  2204. Revision 1.45 1998/08/13 10:58:38 peter
  2205. * fixed function reading for -So which was not correct after my previous
  2206. fix for bug 147
  2207. Revision 1.44 1998/08/10 14:50:18 peter
  2208. + localswitches, moduleswitches, globalswitches splitting
  2209. Revision 1.43 1998/08/10 09:58:33 peter
  2210. * Fixed function b; in -So mode
  2211. Revision 1.42 1998/07/30 16:07:11 florian
  2212. * try ... expect <statement> end; works now
  2213. Revision 1.41 1998/07/23 19:31:19 jonas
  2214. * split the optimizer
  2215. Revision 1.40 1998/07/21 11:16:24 florian
  2216. * bug0147 fixed
  2217. Revision 1.39 1998/07/14 21:46:54 peter
  2218. * updated messages file
  2219. Revision 1.38 1998/07/14 14:46:57 peter
  2220. * released NEWINPUT
  2221. Revision 1.37 1998/07/10 13:12:53 peter
  2222. * carls patch
  2223. Revision 1.36 1998/07/10 13:06:53 michael
  2224. + Carls patch. Checked make cycle.
  2225. Revision 1.35 1998/07/10 00:00:01 peter
  2226. * fixed ttypesym bug finally
  2227. * fileinfo in the symtable and better using for unused vars
  2228. Revision 1.34 1998/07/07 11:20:05 peter
  2229. + NEWINPUT for a better inputfile and scanner object
  2230. Revision 1.33 1998/06/15 15:38:08 pierre
  2231. * small bug in systems.pas corrected
  2232. + operators in different units better hanlded
  2233. Revision 1.32 1998/06/13 00:10:13 peter
  2234. * working browser and newppu
  2235. * some small fixes against crashes which occured in bp7 (but not in
  2236. fpc?!)
  2237. Revision 1.31 1998/06/10 17:04:05 michael
  2238. + Fix for reading untyped const parameters
  2239. Revision 1.30 1998/06/09 16:01:50 pierre
  2240. + added procedure directive parsing for procvars
  2241. (accepted are popstack cdecl and pascal)
  2242. + added C vars with the following syntax
  2243. var C calias 'true_c_name';(can be followed by external)
  2244. reason is that you must add the Cprefix
  2245. which is target dependent
  2246. Revision 1.29 1998/06/08 22:59:51 peter
  2247. * smartlinking works for win32
  2248. * some defines to exclude some compiler parts
  2249. Revision 1.28 1998/06/08 13:13:45 pierre
  2250. + temporary variables now in temp_gen.pas unit
  2251. because it is processor independent
  2252. * mppc68k.bat modified to undefine i386 and support_mmx
  2253. (which are defaults for i386)
  2254. Revision 1.27 1998/06/05 17:47:30 peter
  2255. * some better uses clauses
  2256. Revision 1.26 1998/06/05 14:37:36 pierre
  2257. * fixes for inline for operators
  2258. * inline procedure more correctly restricted
  2259. Revision 1.25 1998/06/04 23:51:54 peter
  2260. * m68k compiles
  2261. + .def file creation moved to gendef.pas so it could also be used
  2262. for win32
  2263. Revision 1.24 1998/06/04 09:55:44 pierre
  2264. * demangled name of procsym reworked to become independant of the mangling scheme
  2265. Revision 1.23 1998/05/28 17:26:51 peter
  2266. * fixed -R switch, it didn't work after my previous akt/init patch
  2267. * fixed bugs 110,130,136
  2268. Revision 1.22 1998/05/28 14:40:27 peter
  2269. * fixes for newppu, remake3 works now with it
  2270. Revision 1.21 1998/05/23 01:21:25 peter
  2271. + aktasmmode, aktoptprocessor, aktoutputformat
  2272. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  2273. + $LIBNAME to set the library name where the unit will be put in
  2274. * splitted cgi386 a bit (codeseg to large for bp7)
  2275. * nasm, tasm works again. nasm moved to ag386nsm.pas
  2276. Revision 1.20 1998/05/21 19:33:34 peter
  2277. + better procedure directive handling and only one table
  2278. Revision 1.19 1998/05/20 09:42:36 pierre
  2279. + UseTokenInfo now default
  2280. * unit in interface uses and implementation uses gives error now
  2281. * only one error for unknown symbol (uses lastsymknown boolean)
  2282. the problem came from the label code !
  2283. + first inlined procedures and function work
  2284. (warning there might be allowed cases were the result is still wrong !!)
  2285. * UseBrower updated gives a global list of all position of all used symbols
  2286. with switch -gb
  2287. Revision 1.18 1998/05/11 13:07:56 peter
  2288. + $ifdef NEWPPU for the new ppuformat
  2289. + $define GDB not longer required
  2290. * removed all warnings and stripped some log comments
  2291. * no findfirst/findnext anymore to remove smartlink *.o files
  2292. Revision 1.17 1998/05/06 18:36:54 peter
  2293. * tai_section extended with code,data,bss sections and enumerated type
  2294. * ident 'compiled by FPC' moved to pmodules
  2295. * small fix for smartlink
  2296. Revision 1.16 1998/05/06 08:38:47 pierre
  2297. * better position info with UseTokenInfo
  2298. UseTokenInfo greatly simplified
  2299. + added check for changed tree after first time firstpass
  2300. (if we could remove all the cases were it happen
  2301. we could skip all firstpass if firstpasscount > 1)
  2302. Only with ExtDebug
  2303. Revision 1.15 1998/05/04 17:54:28 peter
  2304. + smartlinking works (only case jumptable left todo)
  2305. * redesign of systems.pas to support assemblers and linkers
  2306. + Unitname is now also in the PPU-file, increased version to 14
  2307. Revision 1.14 1998/05/01 09:01:24 florian
  2308. + correct semantics of private and protected
  2309. * small fix in variable scope:
  2310. a id can be used in a parameter list of a method, even it is used in
  2311. an anchestor class as field id
  2312. Revision 1.13 1998/04/30 15:59:42 pierre
  2313. * GDB works again better :
  2314. correct type info in one pass
  2315. + UseTokenInfo for better source position
  2316. * fixed one remaining bug in scanner for line counts
  2317. * several little fixes
  2318. Revision 1.12 1998/04/29 10:34:00 pierre
  2319. + added some code for ansistring (not complete nor working yet)
  2320. * corrected operator overloading
  2321. * corrected nasm output
  2322. + started inline procedures
  2323. + added starstarn : use ** for exponentiation (^ gave problems)
  2324. + started UseTokenInfo cond to get accurate positions
  2325. Revision 1.11 1998/04/27 23:10:28 peter
  2326. + new scanner
  2327. * $makelib -> if smartlink
  2328. * small filename fixes pmodule.setfilename
  2329. * moved import from files.pas -> import.pas
  2330. Revision 1.10 1998/04/21 10:16:48 peter
  2331. * patches from strasbourg
  2332. * objects is not used anymore in the fpc compiled version
  2333. Revision 1.9 1998/04/13 22:20:36 florian
  2334. + stricter checking for duplicate id, solves also bug0097
  2335. Revision 1.8 1998/04/13 21:15:42 florian
  2336. * error handling of pass_1 and cgi386 fixed
  2337. * the following bugs fixed: 0117, 0118, 0119 and 0129, 0122 was already
  2338. fixed, verified
  2339. Revision 1.7 1998/04/13 08:42:52 florian
  2340. * call by reference and call by value open arrays fixed
  2341. Revision 1.6 1998/04/10 15:39:48 florian
  2342. * more fixes to get classes.pas compiled
  2343. Revision 1.5 1998/04/10 14:41:43 peter
  2344. * removed some Hints
  2345. * small speed optimization for AsmLn
  2346. Revision 1.4 1998/04/08 16:58:05 pierre
  2347. * several bugfixes
  2348. ADD ADC and AND are also sign extended
  2349. nasm output OK (program still crashes at end
  2350. and creates wrong assembler files !!)
  2351. procsym types sym in tdef removed !!
  2352. }