psub.pas 84 KB

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