psub.pas 90 KB

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