psub.pas 80 KB

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