psub.pas 94 KB

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