psub.pas 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495
  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_message(const procnames:Tstringcontainer);
  675. var
  676. pt : ptree;
  677. begin
  678. { check parameter type }
  679. if ((aktprocsym^.definition^.options and pocontainsself)=0) and
  680. (assigned(aktprocsym^.definition^.para1^.next) or
  681. (aktprocsym^.definition^.para1^.paratyp<>vs_var)) then
  682. Message(parser_e_ill_msg_param);
  683. pt:=comp_expr(true);
  684. do_firstpass(pt);
  685. if pt^.treetype=stringconstn then
  686. begin
  687. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or pomsgstr;
  688. aktprocsym^.definition^.messageinf.str:=strnew(pt^.value_str);
  689. end
  690. else
  691. if is_constintnode(pt) then
  692. begin
  693. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or pomsgint;
  694. aktprocsym^.definition^.messageinf.i:=pt^.value;
  695. end
  696. else
  697. Message(parser_e_ill_msg_expr);
  698. disposetree(pt);
  699. end;
  700. procedure pd_cdecl(const procnames:Tstringcontainer);
  701. begin
  702. if aktprocsym^.definition^.deftype<>procvardef then
  703. aktprocsym^.definition^.setmangledname(target_os.Cprefix+realname);
  704. end;
  705. procedure pd_register(const procnames:Tstringcontainer);
  706. begin
  707. Message(parser_w_proc_register_ignored);
  708. end;
  709. procedure pd_syscall(const procnames:Tstringcontainer);
  710. begin
  711. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or poclearstack;
  712. aktprocsym^.definition^.forwarddef:=false;
  713. aktprocsym^.definition^.extnumber:=get_intconst;
  714. end;
  715. procedure pd_external(const procnames:Tstringcontainer);
  716. {
  717. If import_dll=nil the procedure is assumed to be in another
  718. object file. In that object file it should have the name to
  719. which import_name is pointing to. Otherwise, the procedure is
  720. assumed to be in the DLL to which import_dll is pointing to. In
  721. that case either import_nr<>0 or import_name<>nil is true, so
  722. the procedure is either imported by number or by name. (DM)
  723. }
  724. var
  725. import_dll,
  726. import_name : string;
  727. import_nr : word;
  728. begin
  729. aktprocsym^.definition^.forwarddef:=false;
  730. { If the procedure should be imported from a DLL, a constant string follows.
  731. This isn't really correct, an contant string expression follows
  732. so we check if an semicolon follows, else a string constant have to
  733. follow (FK) }
  734. import_nr:=0;
  735. import_name:='';
  736. if not(token=SEMICOLON) and not(idtoken=_NAME) then
  737. begin
  738. import_dll:=get_stringconst;
  739. if (idtoken=_NAME) then
  740. begin
  741. consume(_NAME);
  742. import_name:=get_stringconst;
  743. end;
  744. if (idtoken=_INDEX) then
  745. begin
  746. {After the word index follows the index number in the DLL.}
  747. consume(_INDEX);
  748. import_nr:=get_intconst;
  749. end;
  750. if (import_nr=0) and (import_name='') then
  751. {if (aktprocsym^.definition^.options and pocdecl)<>0 then
  752. import_name:=aktprocsym^.definition^.mangledname
  753. else
  754. Message(parser_w_empty_import_name);}
  755. { this should work both for win32 and Linux !! PM }
  756. import_name:=realname;
  757. if not(current_module^.uses_imports) then
  758. begin
  759. current_module^.uses_imports:=true;
  760. importlib^.preparelib(current_module^.modulename^);
  761. end;
  762. if not(m_repeat_forward in aktmodeswitches) then
  763. begin
  764. { we can only have one overloaded here ! }
  765. if assigned(aktprocsym^.definition^.nextoverloaded) then
  766. importlib^.importprocedure(aktprocsym^.definition^.nextoverloaded^.mangledname,
  767. import_dll,import_nr,import_name)
  768. else
  769. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  770. end
  771. else
  772. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  773. end
  774. else
  775. begin
  776. if (idtoken=_NAME) then
  777. begin
  778. consume(_NAME);
  779. import_name:=get_stringconst;
  780. aktprocsym^.definition^.setmangledname(import_name);
  781. end
  782. else
  783. begin
  784. { external shouldn't override the cdecl/system name }
  785. if (aktprocsym^.definition^.options and poclearstack)=0 then
  786. aktprocsym^.definition^.setmangledname(aktprocsym^.name);
  787. end;
  788. end;
  789. end;
  790. {$ifdef TP}
  791. {$F-}
  792. {$endif}
  793. function parse_proc_direc(const proc_names:Tstringcontainer;var pdflags:word):boolean;
  794. {
  795. Parse the procedure directive, returns true if a correct directive is found
  796. }
  797. const
  798. namelength=15;
  799. type
  800. pd_handler=procedure(const procnames:Tstringcontainer);
  801. proc_dir_rec=record
  802. idtok : ttoken;
  803. handler : pd_handler; {Handler.}
  804. flag : longint; {Procedure flag. May be zero}
  805. pd_flags : longint; {Parse options}
  806. mut_excl : longint; {List of mutually exclusive flags.}
  807. end;
  808. const
  809. {Should contain the number of procedure directives we support.}
  810. num_proc_directives=28;
  811. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  812. (
  813. (
  814. idtok:_ABSTRACT;
  815. handler:{$ifndef TP}@{$endif}pd_abstract;
  816. flag:poabstractmethod;
  817. pd_flags:pd_interface+pd_object;
  818. mut_excl:poexports+poinline+pointernproc+pointerrupt+poexternal+poconstructor+podestructor
  819. ),(
  820. idtok:_ALIAS;
  821. handler:{$ifndef TP}@{$endif}pd_alias;
  822. flag:0;
  823. pd_flags:pd_implemen+pd_body;
  824. mut_excl:poinline+poexternal
  825. ),(
  826. idtok:_ASMNAME;
  827. handler:{$ifndef TP}@{$endif}pd_asmname;
  828. flag:pocdecl+poclearstack+poexternal;
  829. pd_flags:pd_interface+pd_implemen;
  830. mut_excl:pointernproc+poexternal
  831. ),(
  832. idtok:_ASSEMBLER;
  833. handler:nil;
  834. flag:poassembler;pd_flags:pd_implemen+pd_body;
  835. mut_excl:pointernproc+poexternal
  836. ),(
  837. idtok:_CDECL;
  838. handler:{$ifndef TP}@{$endif}pd_cdecl;
  839. flag:pocdecl+poclearstack+posavestdregs;
  840. pd_flags:pd_interface+pd_implemen+pd_body+pd_procvar;
  841. mut_excl:poleftright+poinline+poassembler+pointernproc+poexternal
  842. ),(
  843. idtok:_DYNAMIC;
  844. handler:{$ifndef TP}@{$endif}pd_virtual;
  845. flag:povirtualmethod;
  846. pd_flags:pd_interface+pd_object;
  847. mut_excl:poexports+poinline+pointernproc+pointerrupt+poexternal
  848. ),(
  849. idtok:_EXPORT;
  850. handler:{$ifndef TP}@{$endif}pd_export;
  851. flag:poexports;
  852. pd_flags:pd_body+pd_global+pd_interface+pd_implemen{??};
  853. mut_excl:poexternal+poinline+pointernproc+pointerrupt
  854. ),(
  855. idtok:_EXTERNAL;
  856. handler:{$ifndef TP}@{$endif}pd_external;
  857. flag:poexternal;
  858. pd_flags:pd_implemen+pd_interface;
  859. mut_excl:poexports+poinline+pointernproc+pointerrupt+poassembler+popalmossyscall
  860. ),(
  861. idtok:_FAR;handler:{$ifndef TP}@{$endif}pd_far;
  862. flag:0;
  863. pd_flags:pd_implemen+pd_body+pd_interface+pd_procvar;
  864. mut_excl:pointernproc
  865. ),(
  866. idtok:_FORWARD;
  867. handler:{$ifndef TP}@{$endif}pd_forward;
  868. flag:0;
  869. pd_flags:pd_implemen;
  870. mut_excl:pointernproc+poexternal
  871. ),(
  872. idtok:_INLINE;
  873. handler:{$ifndef TP}@{$endif}pd_inline;
  874. flag:poinline;
  875. pd_flags:pd_implemen+pd_body;
  876. mut_excl:poexports+poexternal+pointernproc+pointerrupt+poconstructor+podestructor
  877. ),(
  878. idtok:_INTERNCONST;
  879. handler:{$ifndef TP}@{$endif}pd_intern;
  880. flag:pointernconst;
  881. pd_flags:pd_implemen+pd_body;
  882. mut_excl:pointernproc+pooperator
  883. ),(
  884. idtok:_INTERNPROC;
  885. handler:{$ifndef TP}@{$endif}pd_intern;
  886. flag:pointernproc;
  887. pd_flags:pd_implemen;
  888. mut_excl:poexports+poexternal+pointerrupt+poassembler+poclearstack+poleftright+poiocheck+
  889. poconstructor+podestructor+pooperator
  890. ),(
  891. idtok:_INTERRUPT;
  892. handler:nil;
  893. flag:pointerrupt;
  894. pd_flags:pd_implemen+pd_body;
  895. mut_excl:pointernproc+poclearstack+poleftright+poinline+
  896. poconstructor+podestructor+pooperator+poexternal
  897. ),(
  898. idtok:_IOCHECK;
  899. handler:nil;
  900. flag:poiocheck;
  901. pd_flags:pd_implemen+pd_body;
  902. mut_excl:pointernproc+poexternal
  903. ),(
  904. idtok:_MESSAGE;
  905. handler:{$ifndef TP}@{$endif}pd_message;
  906. flag:0; { can be pomsgstr or pomsgint }
  907. pd_flags:pd_interface+pd_object;
  908. mut_excl:poinline+pointernproc+pointerrupt+poexternal
  909. ),(
  910. idtok:_NEAR;
  911. handler:{$ifndef TP}@{$endif}pd_near;
  912. flag:0;
  913. pd_flags:pd_implemen+pd_body+pd_procvar;
  914. mut_excl:pointernproc
  915. ),(
  916. idtok:_OVERRIDE;
  917. handler:{$ifndef TP}@{$endif}pd_override;
  918. flag:pooverridingmethod or povirtualmethod;
  919. pd_flags:pd_interface+pd_object;
  920. mut_excl:poexports+poinline+pointernproc+pointerrupt+poexternal
  921. ),(
  922. idtok:_PASCAL;
  923. handler:nil;
  924. flag:poleftright;
  925. pd_flags:pd_implemen+pd_body+pd_procvar;
  926. mut_excl:pointernproc+poexternal
  927. ),(
  928. idtok:_POPSTACK;
  929. handler:nil;
  930. flag:poclearstack;
  931. pd_flags:pd_interface+pd_implemen+pd_body+pd_procvar;
  932. mut_excl:poinline+pointernproc+poassembler+poexternal
  933. ),(
  934. idtok:_PUBLIC;
  935. handler:nil;
  936. flag:0;
  937. pd_flags:pd_implemen+pd_body+pd_global+pd_notobject;
  938. mut_excl:pointernproc+poinline+poexternal
  939. ),(
  940. idtok:_REGISTER;
  941. handler:{$ifndef TP}@{$endif}pd_register;
  942. flag:poregister;
  943. pd_flags:pd_interface+pd_implemen+pd_body+pd_procvar;
  944. mut_excl:poleftright+pocdecl+pointernproc+poexternal
  945. ),(
  946. idtok:_SAFECALL;
  947. handler:{$ifndef TP}@{$endif}pd_safecall;
  948. flag:posafecall+posavestdregs;
  949. pd_flags:pd_interface+pd_implemen+pd_body+pd_procvar;
  950. mut_excl:poleftright+pocdecl+pointernproc+poinline+poexternal
  951. ),(
  952. idtok:_STATIC;
  953. handler:{$ifndef TP}@{$endif}pd_static;
  954. flag:postaticmethod;
  955. pd_flags:pd_interface+pd_object;
  956. mut_excl:poexports+poinline+pointernproc+pointerrupt+poexternal+
  957. poconstructor+podestructor
  958. ),(
  959. idtok:_STDCALL;
  960. handler:{$ifndef TP}@{$endif}pd_stdcall;
  961. flag:postdcall+posavestdregs;
  962. pd_flags:pd_interface+pd_implemen+pd_body+pd_procvar;
  963. mut_excl:poleftright+pocdecl+pointernproc+poinline+poexternal
  964. ),(
  965. idtok:_SYSCALL;
  966. handler:{$ifndef TP}@{$endif}pd_syscall;
  967. flag:popalmossyscall;
  968. pd_flags:pd_interface;
  969. mut_excl:poexports+poinline+pointernproc+pointerrupt+poassembler+poexternal
  970. ),(
  971. idtok:_SYSTEM;
  972. handler:{$ifndef TP}@{$endif}pd_system;
  973. flag:poclearstack;
  974. pd_flags:pd_implemen;
  975. mut_excl:poleftright+poinline+poassembler+pointernproc+poexternal
  976. ),(
  977. idtok:_VIRTUAL;
  978. handler:{$ifndef TP}@{$endif}pd_virtual;
  979. flag:povirtualmethod;
  980. pd_flags:pd_interface+pd_object;
  981. mut_excl:poexports+poinline+pointernproc+pointerrupt+poexternal
  982. )
  983. );
  984. var
  985. p : longint;
  986. found : boolean;
  987. name : string;
  988. begin
  989. parse_proc_direc:=false;
  990. name:=pattern;
  991. found:=false;
  992. for p:=1 to num_proc_directives do
  993. if proc_direcdata[p].idtok=idtoken then
  994. begin
  995. found:=true;
  996. break;
  997. end;
  998. { Check if the procedure directive is known }
  999. if not found then
  1000. begin
  1001. { parsing a procvar type the name can be any
  1002. next variable !! }
  1003. if (pdflags and (pd_procvar or pd_object))=0 then
  1004. Message1(parser_w_unknown_proc_directive_ignored,name);
  1005. exit;
  1006. end;
  1007. { static needs a special treatment }
  1008. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1009. exit;
  1010. { Conflicts between directives ? }
  1011. if (aktprocsym^.definition^.options and proc_direcdata[p].mut_excl)<>0 then
  1012. begin
  1013. Message1(parser_e_proc_dir_conflict,name);
  1014. exit;
  1015. end;
  1016. { Check if the directive is only for objects }
  1017. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1018. not assigned(aktprocsym^.definition^._class) then
  1019. begin
  1020. exit;
  1021. end;
  1022. { check if method and directive not for object public }
  1023. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1024. assigned(aktprocsym^.definition^._class) then
  1025. begin
  1026. exit;
  1027. end;
  1028. { consume directive, and turn flag on }
  1029. consume(token);
  1030. parse_proc_direc:=true;
  1031. { Check the pd_flags if the directive should be allowed }
  1032. if ((pdflags and pd_interface)<>0) and
  1033. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1034. begin
  1035. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1036. exit;
  1037. end;
  1038. if ((pdflags and pd_implemen)<>0) and
  1039. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1040. begin
  1041. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1042. exit;
  1043. end;
  1044. if ((pdflags and pd_procvar)<>0) and
  1045. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1046. begin
  1047. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1048. exit;
  1049. end;
  1050. { Return the new pd_flags }
  1051. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1052. pdflags:=pdflags and (not pd_body);
  1053. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1054. pdflags:=pdflags or pd_global;
  1055. { Add the correct flag }
  1056. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or proc_direcdata[p].flag;
  1057. { Adjust positions of args for cdecl or stdcall }
  1058. if (aktprocsym^.definition^.deftype=procdef) and
  1059. ((aktprocsym^.definition^.options and (pocdecl or postdcall))<>0) then
  1060. aktprocsym^.definition^.parast^.set_alignment(target_os.size_of_longint);
  1061. { Call the handler }
  1062. if pointer({$ifndef FPC}@{$endif}proc_direcdata[p].handler)<>nil then
  1063. proc_direcdata[p].handler(proc_names);
  1064. end;
  1065. {***************************************************************************}
  1066. function check_identical : boolean;
  1067. {
  1068. Search for idendical definitions,
  1069. if there is a forward, then kill this.
  1070. Returns the result of the forward check.
  1071. Removed from unter_dec to keep the source readable
  1072. }
  1073. const
  1074. {List of procedure options that affect the procedure type.}
  1075. po_type_params=poconstructor+podestructor+pooperator;
  1076. po_call_params=pocdecl+poclearstack+poleftright+poregister;
  1077. var
  1078. hd,pd : Pprocdef;
  1079. storeparast : psymtable;
  1080. ad,fd : psym;
  1081. s : string;
  1082. begin
  1083. check_identical:=false;
  1084. pd:=aktprocsym^.definition;
  1085. if assigned(pd) then
  1086. begin
  1087. { Is there an overload/forward ? }
  1088. if assigned(pd^.nextoverloaded) then
  1089. begin
  1090. { walk the procdef list }
  1091. while (assigned(pd)) and (assigned(pd^.nextoverloaded)) do
  1092. begin
  1093. if not(m_repeat_forward in aktmodeswitches) or
  1094. (equal_paras(aktprocsym^.definition^.para1,pd^.nextoverloaded^.para1,false) and
  1095. { for operators equal_paras is not enough !! }
  1096. (((aktprocsym^.definition^.options and pooperator)=0) or (optoken<>ASSIGNMENT) or
  1097. is_equal(pd^.nextoverloaded^.retdef,aktprocsym^.definition^.retdef))) then
  1098. begin
  1099. if pd^.nextoverloaded^.forwarddef then
  1100. { remove the forward definition but don't delete it, }
  1101. { the symtable is the owner !! }
  1102. begin
  1103. hd:=pd^.nextoverloaded;
  1104. { Check if the procedure type and return type are correct }
  1105. if ((hd^.options and po_type_params)<>(aktprocsym^.definition^.options and po_type_params)) or
  1106. (not(is_equal(hd^.retdef,aktprocsym^.definition^.retdef)) and
  1107. (m_repeat_forward in aktmodeswitches)) then
  1108. begin
  1109. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName);
  1110. exit;
  1111. end;
  1112. { Check calling convention }
  1113. if ((hd^.options and po_call_params)<>(aktprocsym^.definition^.options and po_call_params)) then
  1114. begin
  1115. { only trigger an error, becuase it doesn't hurt }
  1116. Message(parser_e_call_convention_dont_match_forward);
  1117. end;
  1118. { manglednames are equal? }
  1119. hd^.count:=false;
  1120. if (m_repeat_forward in aktmodeswitches) or
  1121. aktprocsym^.definition^.haspara then
  1122. begin
  1123. if (hd^.mangledname<>aktprocsym^.definition^.mangledname) then
  1124. begin
  1125. { When overloading is not possible then we issue an error }
  1126. if not(m_repeat_forward in aktmodeswitches) then
  1127. begin
  1128. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName);
  1129. exit;
  1130. end;
  1131. if (aktprocsym^.definition^.options and poexternal)=0 then
  1132. Message2(parser_n_interface_name_diff_implementation_name,hd^.mangledname,
  1133. aktprocsym^.definition^.mangledname);
  1134. { reset the mangledname of the interface part to be sure }
  1135. { this is wrong because the mangled name might have been used already !! }
  1136. if hd^.is_used then
  1137. renameasmsymbol(hd^.mangledname,aktprocsym^.definition^.mangledname);
  1138. hd^.setmangledname(aktprocsym^.definition^.mangledname);
  1139. { so we need to keep the name of interface !!
  1140. No!!!! The procedure directives can change the mangledname.
  1141. I fixed this by first calling check_identical and then doing
  1142. the proc directives, but this is not a good solution.(DM)}
  1143. { this is also wrong (PM)
  1144. aktprocsym^.definition^.setmangledname(hd^.mangledname);}
  1145. end
  1146. else
  1147. begin
  1148. { If mangled names are equal, therefore }
  1149. { they have the same number of parameters }
  1150. { Therefore we can check the name of these }
  1151. { parameters... }
  1152. if hd^.forwarddef and aktprocsym^.definition^.forwarddef then
  1153. begin
  1154. Message1(parser_e_function_already_declared_public_forward,aktprocsym^.demangledName);
  1155. Check_identical:=true;
  1156. { Remove other forward from the list to reduce errors }
  1157. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1158. exit;
  1159. end;
  1160. ad:=psym(hd^.parast^.symindex^.first);
  1161. fd:=psym(aktprocsym^.definition^.parast^.symindex^.first);
  1162. if assigned(ad) and assigned(fd) then
  1163. begin
  1164. while assigned(ad) and assigned(fd) do
  1165. begin
  1166. s:=ad^.name;
  1167. if s<>fd^.name then
  1168. begin
  1169. Message3(parser_e_header_different_var_names,
  1170. aktprocsym^.name,s,fd^.name);
  1171. break;
  1172. end;
  1173. { it is impossible to have a nil pointer }
  1174. { for only one parameter - since they }
  1175. { have the same number of parameters. }
  1176. { Left = next parameter. }
  1177. ad:=psym(ad^.left);
  1178. fd:=psym(fd^.left);
  1179. end;
  1180. end;
  1181. end;
  1182. end;
  1183. { also the call_offset }
  1184. hd^.parast^.address_fixup:=aktprocsym^.definition^.parast^.address_fixup;
  1185. hd^.count:=true;
  1186. { remove pd^.nextoverloaded from the list }
  1187. { and add aktprocsym^.definition }
  1188. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1189. hd^.nextoverloaded:=aktprocsym^.definition^.nextoverloaded;
  1190. { Alert! All fields of aktprocsym^.definition that are modified
  1191. by the procdir handlers must be copied here!.}
  1192. hd^.forwarddef:=false;
  1193. hd^.options:=hd^.options or aktprocsym^.definition^.options;
  1194. if aktprocsym^.definition^.extnumber=-1 then
  1195. aktprocsym^.definition^.extnumber:=hd^.extnumber
  1196. else
  1197. if hd^.extnumber=-1 then
  1198. hd^.extnumber:=aktprocsym^.definition^.extnumber;
  1199. { switch parast for warning in implementation PM }
  1200. if (m_repeat_forward in aktmodeswitches) or
  1201. aktprocsym^.definition^.haspara then
  1202. begin
  1203. storeparast:=hd^.parast;
  1204. hd^.parast:=aktprocsym^.definition^.parast;
  1205. aktprocsym^.definition^.parast:=storeparast;
  1206. end;
  1207. aktprocsym^.definition:=hd;
  1208. check_identical:=true;
  1209. end
  1210. else
  1211. { abstract methods aren't forward defined, but this }
  1212. { needs another error message }
  1213. if (pd^.nextoverloaded^.options and poabstractmethod)=0 then
  1214. Message(parser_e_overloaded_have_same_parameters)
  1215. else
  1216. Message(parser_e_abstract_no_definition);
  1217. break;
  1218. end;
  1219. pd:=pd^.nextoverloaded;
  1220. end;
  1221. end
  1222. else
  1223. begin
  1224. { there is no overloaded, so its always identical with itself }
  1225. check_identical:=true;
  1226. end;
  1227. end;
  1228. { insert opsym only in the right symtable }
  1229. if ((procinfo.flags and pi_operator)<>0) and assigned(opsym)
  1230. and not parse_only then
  1231. begin
  1232. if ret_in_param(aktprocsym^.definition^.retdef) then
  1233. begin
  1234. pprocdef(aktprocsym^.definition)^.parast^.insert(opsym);
  1235. { this increases the data size }
  1236. { correct this to get the right ret $value }
  1237. dec(pprocdef(aktprocsym^.definition)^.parast^.datasize,opsym^.getpushsize);
  1238. { this allows to read the funcretoffset }
  1239. opsym^.address:=-4;
  1240. opsym^.varspez:=vs_var;
  1241. end
  1242. else
  1243. pprocdef(aktprocsym^.definition)^.localst^.insert(opsym);
  1244. end;
  1245. end;
  1246. procedure compile_proc_body(const proc_names:Tstringcontainer;
  1247. make_global,parent_has_class:boolean);
  1248. {
  1249. Compile the body of a procedure
  1250. }
  1251. var
  1252. oldexitlabel,oldexit2label,oldquickexitlabel:Pasmlabel;
  1253. _class,hp:Pobjectdef;
  1254. { switches can change inside the procedure }
  1255. entryswitches, exitswitches : tlocalswitches;
  1256. { code for the subroutine as tree }
  1257. code:ptree;
  1258. { size of the local strackframe }
  1259. stackframe:longint;
  1260. { true when no stackframe is required }
  1261. nostackframe:boolean;
  1262. { number of bytes which have to be cleared by RET }
  1263. parasize:longint;
  1264. { filepositions }
  1265. entrypos,
  1266. savepos,
  1267. exitpos : tfileposinfo;
  1268. begin
  1269. { calculate the lexical level }
  1270. inc(lexlevel);
  1271. if lexlevel>32 then
  1272. Message(parser_e_too_much_lexlevel);
  1273. { static is also important for local procedures !! }
  1274. if ((aktprocsym^.definition^.options and postaticmethod)<>0) then
  1275. allow_only_static:=true
  1276. else if (lexlevel=normal_function_level) then
  1277. allow_only_static:=false;
  1278. { save old labels }
  1279. oldexitlabel:=aktexitlabel;
  1280. oldexit2label:=aktexit2label;
  1281. oldquickexitlabel:=quickexitlabel;
  1282. { get new labels }
  1283. getlabel(aktexitlabel);
  1284. getlabel(aktexit2label);
  1285. { exit for fail in constructors }
  1286. if (aktprocsym^.definition^.options and poconstructor)<>0 then
  1287. getlabel(quickexitlabel);
  1288. { reset break and continue labels }
  1289. in_except_block:=false;
  1290. aktbreaklabel:=nil;
  1291. aktcontinuelabel:=nil;
  1292. { insert symtables for the class, by only if it is no nested function }
  1293. if assigned(procinfo._class) and not(parent_has_class) then
  1294. begin
  1295. { insert them in the reverse order ! }
  1296. hp:=nil;
  1297. repeat
  1298. _class:=procinfo._class;
  1299. while _class^.childof<>hp do
  1300. _class:=_class^.childof;
  1301. hp:=_class;
  1302. _class^.publicsyms^.next:=symtablestack;
  1303. symtablestack:=_class^.publicsyms;
  1304. until hp=procinfo._class;
  1305. end;
  1306. { insert parasymtable in symtablestack}
  1307. { only if lexlevel > 1 !!! global symtable should be right after staticsymtazble
  1308. for checking of same names used in interface and implementation !! }
  1309. if lexlevel>=normal_function_level then
  1310. begin
  1311. aktprocsym^.definition^.parast^.next:=symtablestack;
  1312. symtablestack:=aktprocsym^.definition^.parast;
  1313. symtablestack^.symtablelevel:=lexlevel;
  1314. end;
  1315. { insert localsymtable in symtablestack}
  1316. aktprocsym^.definition^.localst^.next:=symtablestack;
  1317. symtablestack:=aktprocsym^.definition^.localst;
  1318. symtablestack^.symtablelevel:=lexlevel;
  1319. { constant symbols are inserted in this symboltable }
  1320. constsymtable:=symtablestack;
  1321. { reset the temporary memory }
  1322. cleartempgen;
  1323. { no registers are used }
  1324. usedinproc:=0;
  1325. { save entry info }
  1326. entrypos:=aktfilepos;
  1327. entryswitches:=aktlocalswitches;
  1328. { parse the code ... }
  1329. if (aktprocsym^.definition^.options and poassembler)<> 0 then
  1330. code:=assembler_block
  1331. else
  1332. code:=block(current_module^.islibrary);
  1333. { get a better entry point }
  1334. if assigned(code) then
  1335. entrypos:=code^.fileinfo;
  1336. { save exit info }
  1337. exitswitches:=aktlocalswitches;
  1338. exitpos:=last_endtoken_filepos;
  1339. { save current filepos }
  1340. savepos:=aktfilepos;
  1341. {When we are called to compile the body of a unit, aktprocsym should
  1342. point to the unit initialization. If the unit has no initialization,
  1343. aktprocsym=nil. But in that case code=nil. hus we should check for
  1344. code=nil, when we use aktprocsym.}
  1345. { set the framepointer to esp for assembler functions }
  1346. { but only if the are no local variables }
  1347. { already done in assembler_block }
  1348. setfirsttemp(procinfo.firsttemp);
  1349. { ... and generate assembler }
  1350. { but set the right switches for entry !! }
  1351. aktlocalswitches:=entryswitches;
  1352. {$ifndef NOPASS2}
  1353. if assigned(code) then
  1354. generatecode(code);
  1355. { set switches to status at end of procedure }
  1356. aktlocalswitches:=exitswitches;
  1357. if assigned(code) then
  1358. begin
  1359. aktprocsym^.definition^.code:=code;
  1360. { the procedure is now defined }
  1361. aktprocsym^.definition^.forwarddef:=false;
  1362. aktprocsym^.definition^.usedregisters:=usedinproc;
  1363. end;
  1364. stackframe:=gettempsize;
  1365. { first generate entry code with the correct position and switches }
  1366. aktfilepos:=entrypos;
  1367. aktlocalswitches:=entryswitches;
  1368. if assigned(code) then
  1369. genentrycode(procinfo.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
  1370. { now generate exit code with the correct position and switches }
  1371. aktfilepos:=exitpos;
  1372. aktlocalswitches:=exitswitches;
  1373. if assigned(code) then
  1374. begin
  1375. genexitcode(procinfo.aktexitcode,parasize,nostackframe,false);
  1376. procinfo.aktproccode^.insertlist(procinfo.aktentrycode);
  1377. procinfo.aktproccode^.concatlist(procinfo.aktexitcode);
  1378. {$ifdef i386}
  1379. {$ifndef NoOpt}
  1380. if (cs_optimize in aktglobalswitches) and
  1381. { do not optimize pure assembler procedures }
  1382. ((procinfo.flags and pi_is_assembler)=0) then
  1383. Optimize(procinfo.aktproccode);
  1384. {$endif NoOpt}
  1385. {$endif}
  1386. { save local data (casetable) also in the same file }
  1387. if assigned(procinfo.aktlocaldata) and
  1388. (not procinfo.aktlocaldata^.empty) then
  1389. begin
  1390. procinfo.aktproccode^.concat(new(pai_section,init(sec_data)));
  1391. procinfo.aktproccode^.concatlist(procinfo.aktlocaldata);
  1392. end;
  1393. { now we can insert a cut }
  1394. if (cs_smartlink in aktmoduleswitches) then
  1395. codesegment^.concat(new(pai_cut,init));
  1396. { add the procedure to the codesegment }
  1397. codesegment^.concatlist(procinfo.aktproccode);
  1398. end;
  1399. {$else}
  1400. if assigned(code) then
  1401. firstpass(code);
  1402. {$endif NOPASS2}
  1403. { ... remove symbol tables, for the browser leave the static table }
  1404. { if (cs_browser in aktmoduleswitches) and (symtablestack^.symtabletype=staticsymtable) then
  1405. symtablestack^.next:=symtablestack^.next^.next
  1406. else }
  1407. if lexlevel>=normal_function_level then
  1408. symtablestack:=symtablestack^.next^.next
  1409. else
  1410. symtablestack:=symtablestack^.next;
  1411. { ... check for unused symbols }
  1412. { but only if there is no asm block }
  1413. if assigned(code) then
  1414. begin
  1415. if (Errorcount=0) then
  1416. begin
  1417. aktprocsym^.definition^.localst^.check_forwards;
  1418. aktprocsym^.definition^.localst^.checklabels;
  1419. end;
  1420. if (procinfo.flags and pi_uses_asm)=0 then
  1421. begin
  1422. { not for unit init, becuase the var can be used in finalize,
  1423. it will be done in proc_unit }
  1424. if (aktprocsym^.definition^.options and (pounitinit or pounitfinalize))=0 then
  1425. aktprocsym^.definition^.localst^.allsymbolsused;
  1426. aktprocsym^.definition^.parast^.allsymbolsused;
  1427. end;
  1428. end;
  1429. { the local symtables can be deleted, but the parast }
  1430. { doesn't, (checking definitons when calling a }
  1431. { function }
  1432. { not for a inline procedure !! (PM) }
  1433. { at lexlevel = 1 localst is the staticsymtable itself }
  1434. { so no dispose here !! }
  1435. if assigned(code) and
  1436. not(cs_browser in aktmoduleswitches) and
  1437. ((aktprocsym^.definition^.options and poinline)=0) then
  1438. begin
  1439. if lexlevel>=normal_function_level then
  1440. dispose(aktprocsym^.definition^.localst,done);
  1441. aktprocsym^.definition^.localst:=nil;
  1442. end;
  1443. { only now we can remove the temps }
  1444. resettempgen;
  1445. { remove code tree, if not inline procedure }
  1446. if assigned(code) and ((aktprocsym^.definition^.options and poinline)=0) then
  1447. disposetree(code);
  1448. { remove class member symbol tables }
  1449. while symtablestack^.symtabletype=objectsymtable do
  1450. symtablestack:=symtablestack^.next;
  1451. { restore filepos, the switches are already set }
  1452. aktfilepos:=savepos;
  1453. { free labels }
  1454. freelabel(aktexitlabel);
  1455. freelabel(aktexit2label);
  1456. if (aktprocsym^.definition^.options and poconstructor)<>0 then
  1457. freelabel(quickexitlabel);
  1458. { restore labels }
  1459. aktexitlabel:=oldexitlabel;
  1460. aktexit2label:=oldexit2label;
  1461. quickexitlabel:=oldquickexitlabel;
  1462. { reset to normal non static function }
  1463. if (lexlevel=normal_function_level) then
  1464. allow_only_static:=false;
  1465. { previous lexlevel }
  1466. dec(lexlevel);
  1467. end;
  1468. procedure parse_proc_directives(Anames:Pstringcontainer;var pdflags:word);
  1469. {
  1470. Parse the procedure directives. It does not matter if procedure directives
  1471. are written using ;procdir; or ['procdir'] syntax.
  1472. }
  1473. var
  1474. res : boolean;
  1475. begin
  1476. while token in [ID,LECKKLAMMER] do
  1477. begin
  1478. if try_to_consume(LECKKLAMMER) then
  1479. begin
  1480. repeat
  1481. parse_proc_direc(Anames^,pdflags);
  1482. until not try_to_consume(COMMA);
  1483. consume(RECKKLAMMER);
  1484. { we always expect at least '[];' }
  1485. res:=true;
  1486. end
  1487. else
  1488. res:=parse_proc_direc(Anames^,pdflags);
  1489. { A procedure directive is always followed by a semicolon }
  1490. if res then
  1491. consume(SEMICOLON)
  1492. else
  1493. break;
  1494. end;
  1495. end;
  1496. procedure parse_var_proc_directives(var sym : ptypesym);
  1497. var
  1498. anames : pstringcontainer;
  1499. pdflags : word;
  1500. oldsym : pprocsym;
  1501. begin
  1502. oldsym:=aktprocsym;
  1503. anames:=new(pstringcontainer,init);
  1504. pdflags:=pd_procvar;
  1505. { we create a temporary aktprocsym to read the directives }
  1506. aktprocsym:=new(pprocsym,init(sym^.name));
  1507. { aktprocsym^.definition:=pprocdef(sym^.definition);
  1508. this breaks the rule for TESTOBJEXT !! }
  1509. pabstractprocdef(aktprocsym^.definition):=pabstractprocdef(sym^.definition);
  1510. { names should never be used anyway }
  1511. inc(lexlevel);
  1512. parse_proc_directives(anames,pdflags);
  1513. dec(lexlevel);
  1514. aktprocsym^.definition:=nil;
  1515. dispose(aktprocsym,done);
  1516. dispose(anames,done);
  1517. aktprocsym:=oldsym;
  1518. end;
  1519. procedure parse_object_proc_directives(var sym : pprocsym);
  1520. var
  1521. anames : pstringcontainer;
  1522. pdflags : word;
  1523. begin
  1524. pdflags:=pd_object;
  1525. anames:=new(pstringcontainer,init);
  1526. inc(lexlevel);
  1527. parse_proc_directives(anames,pdflags);
  1528. dec(lexlevel);
  1529. dispose(anames,done);
  1530. if ((aktprocsym^.definition^.options and pocontainsself)<>0) and
  1531. ((aktprocsym^.definition^.options and pomsgstr)=0) and
  1532. ((aktprocsym^.definition^.options and pomsgint)=0) then
  1533. message(parser_e_self_in_non_message_handler);
  1534. end;
  1535. procedure checkvaluepara(p:pnamedindexobject);{$ifndef FPC}far;{$endif}
  1536. var
  1537. vs : pvarsym;
  1538. s : string;
  1539. begin
  1540. with pvarsym(p)^ do
  1541. begin
  1542. if copy(name,1,3)='val' then
  1543. begin
  1544. s:=Copy(name,4,255);
  1545. if ((aktprocsym^.definition^.options and poassembler)=0) then
  1546. begin
  1547. vs:=new(Pvarsym,init(s,definition));
  1548. vs^.fileinfo:=fileinfo;
  1549. vs^.varspez:=varspez;
  1550. aktprocsym^.definition^.localst^.insert(vs);
  1551. vs^.islocalcopy:=true;
  1552. vs^.is_valid:=1;
  1553. localvarsym:=vs;
  1554. end
  1555. else
  1556. begin
  1557. aktprocsym^.definition^.parast^.rename(name,s);
  1558. end;
  1559. end;
  1560. end;
  1561. end;
  1562. procedure read_proc;
  1563. {
  1564. Parses the procedure directives, then parses the procedure body, then
  1565. generates the code for it
  1566. }
  1567. var
  1568. oldprefix : string;
  1569. oldprocsym : Pprocsym;
  1570. oldprocinfo : tprocinfo;
  1571. oldconstsymtable : Psymtable;
  1572. oldfilepos : tfileposinfo;
  1573. names : Pstringcontainer;
  1574. pdflags : word;
  1575. begin
  1576. { save old state }
  1577. oldprocsym:=aktprocsym;
  1578. oldprefix:=procprefix;
  1579. oldconstsymtable:=constsymtable;
  1580. oldprocinfo:=procinfo;
  1581. { create a new procedure }
  1582. new(names,init);
  1583. codegen_newprocedure;
  1584. with procinfo do
  1585. begin
  1586. parent:=@oldprocinfo;
  1587. { clear flags }
  1588. flags:=0;
  1589. { standard frame pointer }
  1590. framepointer:=frame_pointer;
  1591. funcret_is_valid:=false;
  1592. { is this a nested function of a method ? }
  1593. _class:=oldprocinfo._class;
  1594. end;
  1595. parse_proc_dec;
  1596. { set the default function options }
  1597. if parse_only then
  1598. begin
  1599. aktprocsym^.properties:=aktprocsym^.properties or sp_forwarddef;
  1600. aktprocsym^.definition^.forwarddef:=true;
  1601. { set also the interface flag, for better error message when the
  1602. implementation doesn't much this header }
  1603. aktprocsym^.definition^.interfacedef:=true;
  1604. pdflags:=pd_interface;
  1605. end
  1606. else
  1607. begin
  1608. pdflags:=pd_body;
  1609. if current_module^.in_implementation then
  1610. pdflags:=pdflags or pd_implemen;
  1611. if (not current_module^.is_unit) or (cs_smartlink in aktmoduleswitches) then
  1612. pdflags:=pdflags or pd_global;
  1613. procinfo.exported:=false;
  1614. aktprocsym^.definition^.forwarddef:=false;
  1615. end;
  1616. { parse the directives that may follow }
  1617. inc(lexlevel);
  1618. parse_proc_directives(names,pdflags);
  1619. dec(lexlevel);
  1620. { set aktfilepos to the beginning of the function declaration }
  1621. oldfilepos:=aktfilepos;
  1622. aktfilepos:=aktprocsym^.definition^.fileinfo;
  1623. { search for forward declarations }
  1624. if not check_identical then
  1625. begin
  1626. { A method must be forward defined (in the object declaration) }
  1627. if assigned(procinfo._class) and (not assigned(oldprocinfo._class)) then
  1628. Message(parser_e_header_dont_match_any_member);
  1629. { Give a better error if there is a forward def in the interface and only
  1630. a single implementation }
  1631. if (not aktprocsym^.definition^.forwarddef) and
  1632. assigned(aktprocsym^.definition^.nextoverloaded) and
  1633. aktprocsym^.definition^.nextoverloaded^.forwarddef and
  1634. aktprocsym^.definition^.nextoverloaded^.interfacedef and
  1635. not(assigned(aktprocsym^.definition^.nextoverloaded^.nextoverloaded)) then
  1636. Message1(parser_e_header_dont_match_forward,aktprocsym^.demangledName)
  1637. else
  1638. begin
  1639. { check the global flag }
  1640. if (procinfo.flags and pi_is_global)<>0 then
  1641. Message(parser_e_overloaded_must_be_all_global);
  1642. end
  1643. end;
  1644. { set return type here, becuase the aktprocsym^.definition can be
  1645. changed by check_identical (PFV) }
  1646. procinfo.retdef:=aktprocsym^.definition^.retdef;
  1647. { pointer to the return value ? }
  1648. if ret_in_param(procinfo.retdef) then
  1649. begin
  1650. procinfo.retoffset:=procinfo.call_offset;
  1651. inc(procinfo.call_offset,target_os.size_of_pointer);
  1652. end;
  1653. { allows to access the parameters of main functions in nested functions }
  1654. aktprocsym^.definition^.parast^.address_fixup:=procinfo.call_offset;
  1655. { when it is a value para and it needs a local copy then rename
  1656. the parameter and insert a copy in the localst. This is not done
  1657. for assembler procedures }
  1658. if (not parse_only) and (not aktprocsym^.definition^.forwarddef) then
  1659. aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}checkvaluepara);
  1660. { restore file pos }
  1661. aktfilepos:=oldfilepos;
  1662. { compile procedure when a body is needed }
  1663. if (pdflags and pd_body)<>0 then
  1664. begin
  1665. Message1(parser_p_procedure_start,aktprocsym^.demangledname);
  1666. names^.insert(aktprocsym^.definition^.mangledname);
  1667. { set _FAIL as keyword if constructor }
  1668. if (aktprocsym^.definition^.options and poconstructor)<>0 then
  1669. tokeninfo[_FAIL].keyword:=m_all;
  1670. if assigned(aktprocsym^.definition^._class) then
  1671. tokeninfo[_SELF].keyword:=m_all;
  1672. compile_proc_body(names^,((pdflags and pd_global)<>0),assigned(oldprocinfo._class));
  1673. { reset _FAIL as normal }
  1674. if (aktprocsym^.definition^.options and poconstructor)<>0 then
  1675. tokeninfo[_FAIL].keyword:=m_none;
  1676. if assigned(aktprocsym^.definition^._class) and (lexlevel=main_program_level) then
  1677. tokeninfo[_SELF].keyword:=m_none;
  1678. consume(SEMICOLON);
  1679. end;
  1680. { close }
  1681. dispose(names,done);
  1682. codegen_doneprocedure;
  1683. { Restore old state }
  1684. constsymtable:=oldconstsymtable;
  1685. { from now on all refernece to mangledname means
  1686. that the function is already used }
  1687. aktprocsym^.definition^.count:=true;
  1688. aktprocsym:=oldprocsym;
  1689. procprefix:=oldprefix;
  1690. procinfo:=oldprocinfo;
  1691. opsym:=nil;
  1692. end;
  1693. end.
  1694. {
  1695. $Log$
  1696. Revision 1.4 1999-07-11 20:10:24 peter
  1697. * merged
  1698. Revision 1.3 1999/07/02 13:02:24 peter
  1699. * merged
  1700. Revision 1.2 1999/06/17 13:19:56 pierre
  1701. * merged from 0_99_12 branch
  1702. Revision 1.1.2.4 1999/07/11 20:07:39 peter
  1703. * message crash fixed
  1704. * no error if self is used with non-string message
  1705. Revision 1.1.2.3 1999/07/11 20:04:05 pierre
  1706. * fix for problem with external without parameters in Delphi mode
  1707. Revision 1.1.2.2 1999/07/02 12:59:52 peter
  1708. * fixed parsing of message directive
  1709. Revision 1.1.2.1 1999/06/17 12:44:47 pierre
  1710. * solve problems related to assignment overloading
  1711. * support Delphi syntax for operator
  1712. * avoid problems if local procedure in operator
  1713. Revision 1.1 1999/06/11 13:21:37 peter
  1714. * reinserted
  1715. Revision 1.153 1999/06/02 22:44:14 pierre
  1716. * previous wrong log corrected
  1717. Revision 1.152 1999/06/02 22:25:46 pierre
  1718. * changed $ifdef FPC @ into $ifndef TP
  1719. Revision 1.151 1999/06/01 22:47:06 pierre
  1720. * problem with static keyword solved
  1721. Revision 1.150 1999/06/01 14:45:53 peter
  1722. * @procvar is now always needed for FPC
  1723. Revision 1.149 1999/05/31 16:42:31 peter
  1724. * interfacedef flag for procdef if it's defined in the interface, to
  1725. make a difference with 'forward;' directive forwarddef. Fixes 253
  1726. Revision 1.148 1999/05/27 19:44:52 peter
  1727. * removed oldasm
  1728. * plabel -> pasmlabel
  1729. * -a switches to source writing automaticly
  1730. * assembler readers OOPed
  1731. * asmsymbol automaticly external
  1732. * jumptables and other label fixes for asm readers
  1733. Revision 1.147 1999/05/24 08:55:27 florian
  1734. * non working safecall directiv implemented, I don't know if we
  1735. need it
  1736. Revision 1.146 1999/05/23 18:42:11 florian
  1737. * better error recovering in typed constants
  1738. * some problems with arrays of const fixed, some problems
  1739. due my previous
  1740. - the location type of array constructor is now LOC_MEM
  1741. - the pushing of high fixed
  1742. - parameter copying fixed
  1743. - zero temp. allocation removed
  1744. * small problem in the assembler writers fixed:
  1745. ref to nil wasn't written correctly
  1746. Revision 1.145 1999/05/21 13:55:09 peter
  1747. * NEWLAB for label as symbol
  1748. Revision 1.144 1999/05/18 14:15:55 peter
  1749. * containsself fixes
  1750. * checktypes()
  1751. Revision 1.143 1999/05/17 21:57:13 florian
  1752. * new temporary ansistring handling
  1753. Revision 1.142 1999/05/17 15:06:38 pierre
  1754. * fixes for object type check
  1755. Revision 1.141 1999/05/13 21:59:39 peter
  1756. * removed oldppu code
  1757. * warning if objpas is loaded from uses
  1758. * first things for new deref writing
  1759. Revision 1.140 1999/05/12 22:36:12 florian
  1760. * override isn't allowed in objects!
  1761. Revision 1.139 1999/05/10 09:01:41 peter
  1762. * small message fixes
  1763. Revision 1.138 1999/05/09 12:46:24 peter
  1764. + hint where a duplicate sym is already defined
  1765. Revision 1.137 1999/05/08 19:48:45 peter
  1766. * better error message if declaration doesn't match forward
  1767. Revision 1.136 1999/05/08 15:26:15 peter
  1768. * print also manglednames when changed
  1769. Revision 1.135 1999/05/06 10:12:10 peter
  1770. * fixed operator result offset which destroyed parast^.datasize
  1771. Revision 1.134 1999/05/01 13:24:36 peter
  1772. * merged nasm compiler
  1773. * old asm moved to oldasm/
  1774. Revision 1.133 1999/04/28 11:12:03 peter
  1775. * fixed crash with self pointer
  1776. Revision 1.132 1999/04/28 06:02:09 florian
  1777. * changes of Bruessel:
  1778. + message handler can now take an explicit self
  1779. * typinfo fixed: sometimes the type names weren't written
  1780. * the type checking for pointer comparisations and subtraction
  1781. and are now more strict (was also buggy)
  1782. * small bug fix to link.pas to support compiling on another
  1783. drive
  1784. * probable bug in popt386 fixed: call/jmp => push/jmp
  1785. transformation didn't count correctly the jmp references
  1786. + threadvar support
  1787. * warning if ln/sqrt gets an invalid constant argument
  1788. Revision 1.131 1999/04/26 13:31:44 peter
  1789. * release storenumber,double_checksum
  1790. Revision 1.130 1999/04/21 09:43:49 peter
  1791. * storenumber works
  1792. * fixed some typos in double_checksum
  1793. + incompatible types type1 and type2 message (with storenumber)
  1794. Revision 1.129 1999/04/20 14:39:07 daniel
  1795. *** empty log message ***
  1796. Revision 1.125 1999/04/14 09:14:55 peter
  1797. * first things to store the symbol/def number in the ppu
  1798. Revision 1.124 1999/04/07 15:31:13 pierre
  1799. * all formaldefs are now a sinlge definition
  1800. cformaldef (this was necessary for double_checksum)
  1801. + small part of double_checksum code
  1802. Revision 1.123 1999/04/06 11:21:58 peter
  1803. * more use of ttoken
  1804. Revision 1.122 1999/03/31 13:55:16 peter
  1805. * assembler inlining working for ag386bin
  1806. Revision 1.121 1999/03/26 00:05:39 peter
  1807. * released valintern
  1808. + deffile is now removed when compiling is finished
  1809. * ^( compiles now correct
  1810. + static directive
  1811. * shrd fixed
  1812. Revision 1.120 1999/03/24 23:17:18 peter
  1813. * fixed bugs 212,222,225,227,229,231,233
  1814. Revision 1.119 1999/03/05 09:46:18 pierre
  1815. * public problem for methods
  1816. Revision 1.118 1999/03/05 01:14:24 pierre
  1817. * bug0198 : call conventions for methods
  1818. not yet implemented is the control of same calling convention
  1819. for virtual and child's virtual
  1820. * msgstr and msgint only created if message was found
  1821. who implemented this by the way ?
  1822. it leaks lots of plabels !!!! (check with heaptrc !)
  1823. Revision 1.117 1999/03/04 13:55:47 pierre
  1824. * some m68k fixes (still not compilable !)
  1825. * new(tobj) does not give warning if tobj has no VMT !
  1826. Revision 1.116 1999/03/01 15:40:52 peter
  1827. * external name <str> didn't concatexternal()
  1828. Revision 1.115 1999/03/01 13:31:58 pierre
  1829. * external used before implemented problem fixed
  1830. Revision 1.114 1999/02/24 00:59:15 peter
  1831. * small updates for ag386bin
  1832. Revision 1.113 1999/02/23 18:29:21 pierre
  1833. * win32 compilation error fix
  1834. + some work for local browser (not cl=omplete yet)
  1835. Revision 1.112 1999/02/22 13:07:03 pierre
  1836. + -b and -bl options work !
  1837. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1838. is not enabled when quitting global section
  1839. * local vars and procedures are not yet stored into PPU
  1840. Revision 1.111 1999/02/22 02:15:33 peter
  1841. * updates for ag386bin
  1842. Revision 1.110 1999/02/16 12:23:19 pierre
  1843. * nested forward procedure bug solved
  1844. Revision 1.109 1999/02/15 10:07:06 pierre
  1845. * memory leaks due to last commit solved
  1846. Revision 1.108 1999/02/11 09:46:27 pierre
  1847. * fix for normal method calls inside static methods :
  1848. WARNING there were both parser and codegen errors !!
  1849. added static_call boolean to calln tree
  1850. Revision 1.107 1999/02/10 11:27:39 pierre
  1851. * overloaded function locals problem bug0213
  1852. Revision 1.106 1999/02/08 11:29:05 pierre
  1853. * fix for bug0214
  1854. several problems where combined
  1855. search_class_member did not set srsymtable
  1856. => in do_member_read the call node got a wrong symtable
  1857. in cg386cal the vmt was pushed twice without chacking if it exists
  1858. now %esi is set to zero and pushed if not vmt
  1859. (not very efficient but should work !)
  1860. Revision 1.105 1999/02/05 12:51:20 florian
  1861. + openstring id is now supported
  1862. Revision 1.104 1999/02/03 09:26:44 pierre
  1863. + better reference for args of procs
  1864. Revision 1.103 1999/02/02 11:04:37 florian
  1865. * class destructors fixed, class instances weren't disposed correctly
  1866. Revision 1.102 1999/01/21 22:10:46 peter
  1867. * fixed array of const
  1868. * generic platform independent high() support
  1869. Revision 1.101 1999/01/20 14:18:38 pierre
  1870. * bugs related to mangledname solved
  1871. - linux external without name
  1872. -external procs already used
  1873. (added count and is_used boolean fiels in tprocvar)
  1874. Revision 1.100 1999/01/20 10:20:19 peter
  1875. * don't make localvar copies for assembler procedures
  1876. Revision 1.99 1999/01/19 15:59:40 pierre
  1877. * fix for function a;
  1878. Revision 1.98 1999/01/19 12:16:07 peter
  1879. * NOPASS2 now calls firstpass
  1880. Revision 1.97 1999/01/14 11:35:30 daniel
  1881. * Fixed manglednames
  1882. Revision 1.96 1998/12/30 13:41:10 peter
  1883. * released valuepara
  1884. Revision 1.95 1998/12/30 10:36:39 michael
  1885. + Delphi also allows external in interface section
  1886. Revision 1.94 1998/12/29 18:48:26 jonas
  1887. + optimize pascal code surrounding assembler blocks
  1888. Revision 1.93 1998/12/28 15:44:49 peter
  1889. + NOPASS2 define
  1890. Revision 1.92 1998/12/11 00:03:39 peter
  1891. + globtype,tokens,version unit splitted from globals
  1892. Revision 1.91 1998/11/27 14:50:42 peter
  1893. + open strings, $P switch support
  1894. Revision 1.90 1998/11/18 17:45:27 peter
  1895. * fixes for VALUEPARA
  1896. Revision 1.89 1998/11/18 15:44:15 peter
  1897. * VALUEPARA for tp7 compatible value parameters
  1898. Revision 1.88 1998/11/16 15:40:30 pierre
  1899. * mangling name and -So bugs solved
  1900. Revision 1.87 1998/11/16 11:29:02 pierre
  1901. * stackcheck removed for i386_win32
  1902. * exportlist does not crash at least !!
  1903. (was need for tests dir !)z
  1904. Revision 1.86 1998/11/16 10:13:54 peter
  1905. * label defines are checked at the end of the proc
  1906. Revision 1.85 1998/11/13 15:40:26 pierre
  1907. + added -Se in Makefile cvstest target
  1908. + lexlevel cleanup
  1909. normal_function_level main_program_level and unit_init_level defined
  1910. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  1911. (test added in code !)
  1912. * -Un option was wrong
  1913. * _FAIL and _SELF only keyword inside
  1914. constructors and methods respectively
  1915. Revision 1.84 1998/11/10 10:09:13 peter
  1916. * va_list -> array of const
  1917. Revision 1.83 1998/11/09 11:44:34 peter
  1918. + va_list for printf support
  1919. Revision 1.82 1998/10/29 11:35:53 florian
  1920. * some dll support for win32
  1921. * fixed assembler writing for PalmOS
  1922. Revision 1.81 1998/10/28 18:26:16 pierre
  1923. * removed some erros after other errors (introduced by useexcept)
  1924. * stabs works again correctly (for how long !)
  1925. Revision 1.80 1998/10/27 13:45:37 pierre
  1926. * classes get a vmt allways
  1927. * better error info (tried to remove
  1928. several error strings introduced by the tpexcept handling)
  1929. Revision 1.79 1998/10/23 00:09:43 peter
  1930. * fixed message for forward declaration
  1931. Revision 1.78 1998/10/20 13:10:37 peter
  1932. * fixed crash when aktprocsym<>procsym
  1933. Revision 1.77 1998/10/20 08:06:55 pierre
  1934. * several memory corruptions due to double freemem solved
  1935. => never use p^.loc.location:=p^.left^.loc.location;
  1936. + finally I added now by default
  1937. that ra386dir translates global and unit symbols
  1938. + added a first field in tsymtable and
  1939. a nextsym field in tsym
  1940. (this allows to obtain ordered type info for
  1941. records and objects in gdb !)
  1942. Revision 1.76 1998/10/19 08:55:02 pierre
  1943. * wrong stabs info corrected once again !!
  1944. + variable vmt offset with vmt field only if required
  1945. implemented now !!!
  1946. Revision 1.75 1998/10/16 08:51:48 peter
  1947. + target_os.stackalignment
  1948. + stack can be aligned at 2 or 4 byte boundaries
  1949. Revision 1.74 1998/10/14 20:39:21 florian
  1950. * syscall for PalmOs fixed
  1951. Revision 1.73 1998/10/12 12:20:56 pierre
  1952. + added tai_const_symbol_offset
  1953. for r : pointer = @var.field;
  1954. * better message for different arg names on implementation
  1955. of function
  1956. Revision 1.72 1998/10/08 23:29:03 peter
  1957. * -vu shows unit info, -vt shows tried/used files
  1958. Revision 1.71 1998/10/08 17:17:28 pierre
  1959. * current_module old scanner tagged as invalid if unit is recompiled
  1960. + added ppheap for better info on tracegetmem of heaptrc
  1961. (adds line column and file index)
  1962. * several memory leaks removed ith help of heaptrc !!
  1963. Revision 1.70 1998/10/08 13:48:49 peter
  1964. * fixed memory leaks for do nothing source
  1965. * fixed unit interdependency
  1966. Revision 1.69 1998/10/05 21:33:27 peter
  1967. * fixed 161,165,166,167,168
  1968. Revision 1.68 1998/09/29 11:31:30 florian
  1969. * better error recovering when the object type of procedure tobject.method
  1970. isn't found
  1971. Revision 1.67 1998/09/26 17:45:39 peter
  1972. + idtoken and only one token table
  1973. Revision 1.66 1998/09/24 23:49:16 peter
  1974. + aktmodeswitches
  1975. Revision 1.65 1998/09/24 11:08:14 florian
  1976. * small problem in _proc_header with array of const fixed:
  1977. getsymonlyin doesn't set srsym to nil
  1978. Revision 1.64 1998/09/23 15:39:12 pierre
  1979. * browser bugfixes
  1980. was adding a reference when looking for the symbol
  1981. if -bSYM_NAME was used
  1982. Revision 1.63 1998/09/22 17:13:50 pierre
  1983. + browsing updated and developed
  1984. records and objects fields are also stored
  1985. Revision 1.62 1998/09/22 15:37:21 peter
  1986. + array of const start
  1987. Revision 1.61 1998/09/21 08:45:20 pierre
  1988. + added vmt_offset in tobjectdef.write for fututre use
  1989. (first steps to have objects without vmt if no virtual !!)
  1990. + added fpu_used field for tabstractprocdef :
  1991. sets this level to 2 if the functions return with value in FPU
  1992. (is then set to correct value at parsing of implementation)
  1993. THIS MIGHT refuse some code with FPU expression too complex
  1994. that were accepted before and even in some cases
  1995. that don't overflow in fact
  1996. ( like if f : float; is a forward that finally in implementation
  1997. only uses one fpu register !!)
  1998. Nevertheless I think that it will improve security on
  1999. FPU operations !!
  2000. * most other changes only for UseBrowser code
  2001. (added symtable references for record and objects)
  2002. local switch for refs to args and local of each function
  2003. (static symtable still missing)
  2004. UseBrowser still not stable and probably broken by
  2005. the definition hash array !!
  2006. Revision 1.60 1998/09/17 09:42:42 peter
  2007. + pass_2 for cg386
  2008. * Message() -> CGMessage() for pass_1/pass_2
  2009. Revision 1.59 1998/09/15 14:05:25 jonas
  2010. * fixed optimizer incompatibilities with freelabel code in psub
  2011. Revision 1.58 1998/09/14 21:27:41 peter
  2012. - freelabel calls, becuase they are instable with -O2
  2013. Revision 1.57 1998/09/14 10:38:27 peter
  2014. * pd_alias now uses get_stringconst
  2015. Revision 1.56 1998/09/14 10:29:38 daniel
  2016. * Fixed memory leaks.
  2017. Revision 1.55 1998/09/09 11:50:56 pierre
  2018. * forward def are not put in record or objects
  2019. + added check for forwards also in record and objects
  2020. * dummy parasymtable for unit initialization removed from
  2021. symtable stack
  2022. Revision 1.54 1998/09/04 08:42:05 peter
  2023. * updated some error messages
  2024. Revision 1.53 1998/09/01 17:39:51 peter
  2025. + internal constant functions
  2026. Revision 1.52 1998/09/01 09:07:12 peter
  2027. * m68k fixes, splitted cg68k like cgi386
  2028. Revision 1.51 1998/09/01 07:54:21 pierre
  2029. * UseBrowser a little updated (might still be buggy !!)
  2030. * bug in psub.pas in function specifier removed
  2031. * stdcall allowed in interface and in implementation
  2032. (FPC will not yet complain if it is missing in either part
  2033. because stdcall is only a dummy !!)
  2034. Revision 1.50 1998/08/31 12:26:31 peter
  2035. * m68k and palmos updates from surebugfixes
  2036. Revision 1.49 1998/08/25 12:42:43 pierre
  2037. * CDECL changed to CVAR for variables
  2038. specifications are read in structures also
  2039. + started adding GPC compatibility mode ( option -Sp)
  2040. * names changed to lowercase
  2041. Revision 1.48 1998/08/21 08:43:30 pierre
  2042. * pocdecl and poclearstack are now different
  2043. external must but written as last specification
  2044. Revision 1.47 1998/08/20 09:26:44 pierre
  2045. + funcret setting in underproc testing
  2046. compile with _dTEST_FUNCRET
  2047. Revision 1.46 1998/08/19 18:04:55 peter
  2048. * fixed current_module^.in_implementation flag
  2049. Revision 1.45 1998/08/13 10:58:38 peter
  2050. * fixed function reading for -So which was not correct after my previous
  2051. fix for bug 147
  2052. Revision 1.44 1998/08/10 14:50:18 peter
  2053. + localswitches, moduleswitches, globalswitches splitting
  2054. Revision 1.43 1998/08/10 09:58:33 peter
  2055. * Fixed function b; in -So mode
  2056. Revision 1.42 1998/07/30 16:07:11 florian
  2057. * try ... expect <statement> end; works now
  2058. Revision 1.41 1998/07/23 19:31:19 jonas
  2059. * split the optimizer
  2060. Revision 1.40 1998/07/21 11:16:24 florian
  2061. * bug0147 fixed
  2062. Revision 1.39 1998/07/14 21:46:54 peter
  2063. * updated messages file
  2064. Revision 1.38 1998/07/14 14:46:57 peter
  2065. * released NEWINPUT
  2066. Revision 1.37 1998/07/10 13:12:53 peter
  2067. * carls patch
  2068. Revision 1.36 1998/07/10 13:06:53 michael
  2069. + Carls patch. Checked make cycle.
  2070. Revision 1.35 1998/07/10 00:00:01 peter
  2071. * fixed ttypesym bug finally
  2072. * fileinfo in the symtable and better using for unused vars
  2073. Revision 1.34 1998/07/07 11:20:05 peter
  2074. + NEWINPUT for a better inputfile and scanner object
  2075. Revision 1.33 1998/06/15 15:38:08 pierre
  2076. * small bug in systems.pas corrected
  2077. + operators in different units better hanlded
  2078. Revision 1.32 1998/06/13 00:10:13 peter
  2079. * working browser and newppu
  2080. * some small fixes against crashes which occured in bp7 (but not in
  2081. fpc?!)
  2082. Revision 1.31 1998/06/10 17:04:05 michael
  2083. + Fix for reading untyped const parameters
  2084. Revision 1.30 1998/06/09 16:01:50 pierre
  2085. + added procedure directive parsing for procvars
  2086. (accepted are popstack cdecl and pascal)
  2087. + added C vars with the following syntax
  2088. var C calias 'true_c_name';(can be followed by external)
  2089. reason is that you must add the Cprefix
  2090. which is target dependent
  2091. Revision 1.29 1998/06/08 22:59:51 peter
  2092. * smartlinking works for win32
  2093. * some defines to exclude some compiler parts
  2094. Revision 1.28 1998/06/08 13:13:45 pierre
  2095. + temporary variables now in temp_gen.pas unit
  2096. because it is processor independent
  2097. * mppc68k.bat modified to undefine i386 and support_mmx
  2098. (which are defaults for i386)
  2099. Revision 1.27 1998/06/05 17:47:30 peter
  2100. * some better uses clauses
  2101. Revision 1.26 1998/06/05 14:37:36 pierre
  2102. * fixes for inline for operators
  2103. * inline procedure more correctly restricted
  2104. Revision 1.25 1998/06/04 23:51:54 peter
  2105. * m68k compiles
  2106. + .def file creation moved to gendef.pas so it could also be used
  2107. for win32
  2108. Revision 1.24 1998/06/04 09:55:44 pierre
  2109. * demangled name of procsym reworked to become independant of the mangling scheme
  2110. Revision 1.23 1998/05/28 17:26:51 peter
  2111. * fixed -R switch, it didn't work after my previous akt/init patch
  2112. * fixed bugs 110,130,136
  2113. Revision 1.22 1998/05/28 14:40:27 peter
  2114. * fixes for newppu, remake3 works now with it
  2115. Revision 1.21 1998/05/23 01:21:25 peter
  2116. + aktasmmode, aktoptprocessor, aktoutputformat
  2117. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  2118. + $LIBNAME to set the library name where the unit will be put in
  2119. * splitted cgi386 a bit (codeseg to large for bp7)
  2120. * nasm, tasm works again. nasm moved to ag386nsm.pas
  2121. Revision 1.20 1998/05/21 19:33:34 peter
  2122. + better procedure directive handling and only one table
  2123. Revision 1.19 1998/05/20 09:42:36 pierre
  2124. + UseTokenInfo now default
  2125. * unit in interface uses and implementation uses gives error now
  2126. * only one error for unknown symbol (uses lastsymknown boolean)
  2127. the problem came from the label code !
  2128. + first inlined procedures and function work
  2129. (warning there might be allowed cases were the result is still wrong !!)
  2130. * UseBrower updated gives a global list of all position of all used symbols
  2131. with switch -gb
  2132. Revision 1.18 1998/05/11 13:07:56 peter
  2133. + $ifdef NEWPPU for the new ppuformat
  2134. + $define GDB not longer required
  2135. * removed all warnings and stripped some log comments
  2136. * no findfirst/findnext anymore to remove smartlink *.o files
  2137. Revision 1.17 1998/05/06 18:36:54 peter
  2138. * tai_section extended with code,data,bss sections and enumerated type
  2139. * ident 'compiled by FPC' moved to pmodules
  2140. * small fix for smartlink
  2141. Revision 1.16 1998/05/06 08:38:47 pierre
  2142. * better position info with UseTokenInfo
  2143. UseTokenInfo greatly simplified
  2144. + added check for changed tree after first time firstpass
  2145. (if we could remove all the cases were it happen
  2146. we could skip all firstpass if firstpasscount > 1)
  2147. Only with ExtDebug
  2148. Revision 1.15 1998/05/04 17:54:28 peter
  2149. + smartlinking works (only case jumptable left todo)
  2150. * redesign of systems.pas to support assemblers and linkers
  2151. + Unitname is now also in the PPU-file, increased version to 14
  2152. Revision 1.14 1998/05/01 09:01:24 florian
  2153. + correct semantics of private and protected
  2154. * small fix in variable scope:
  2155. a id can be used in a parameter list of a method, even it is used in
  2156. an anchestor class as field id
  2157. Revision 1.13 1998/04/30 15:59:42 pierre
  2158. * GDB works again better :
  2159. correct type info in one pass
  2160. + UseTokenInfo for better source position
  2161. * fixed one remaining bug in scanner for line counts
  2162. * several little fixes
  2163. Revision 1.12 1998/04/29 10:34:00 pierre
  2164. + added some code for ansistring (not complete nor working yet)
  2165. * corrected operator overloading
  2166. * corrected nasm output
  2167. + started inline procedures
  2168. + added starstarn : use ** for exponentiation (^ gave problems)
  2169. + started UseTokenInfo cond to get accurate positions
  2170. Revision 1.11 1998/04/27 23:10:28 peter
  2171. + new scanner
  2172. * $makelib -> if smartlink
  2173. * small filename fixes pmodule.setfilename
  2174. * moved import from files.pas -> import.pas
  2175. Revision 1.10 1998/04/21 10:16:48 peter
  2176. * patches from strasbourg
  2177. * objects is not used anymore in the fpc compiled version
  2178. Revision 1.9 1998/04/13 22:20:36 florian
  2179. + stricter checking for duplicate id, solves also bug0097
  2180. Revision 1.8 1998/04/13 21:15:42 florian
  2181. * error handling of pass_1 and cgi386 fixed
  2182. * the following bugs fixed: 0117, 0118, 0119 and 0129, 0122 was already
  2183. fixed, verified
  2184. Revision 1.7 1998/04/13 08:42:52 florian
  2185. * call by reference and call by value open arrays fixed
  2186. Revision 1.6 1998/04/10 15:39:48 florian
  2187. * more fixes to get classes.pas compiled
  2188. Revision 1.5 1998/04/10 14:41:43 peter
  2189. * removed some Hints
  2190. * small speed optimization for AsmLn
  2191. Revision 1.4 1998/04/08 16:58:05 pierre
  2192. * several bugfixes
  2193. ADD ADC and AND are also sign extended
  2194. nasm output OK (program still crashes at end
  2195. and creates wrong assembler files !!)
  2196. procsym types sym in tdef removed !!
  2197. }