psub.pas 81 KB

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