psub.pas 83 KB

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