psub.pas 86 KB

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