psub.pas 91 KB

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