pexpr.pas 102 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does parsing of expression for Free Pascal
  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 pexpr;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. symtype,symdef,symbase,
  23. node,
  24. globals,
  25. cpuinfo;
  26. { reads a whole expression }
  27. function expr : tnode;
  28. { reads an expression without assignements and .. }
  29. function comp_expr(accept_equal : boolean):tnode;
  30. { reads a single factor }
  31. function factor(getaddr : boolean) : tnode;
  32. procedure string_dec(var t: ttype);
  33. procedure symlist_to_node(var p1:tnode;st:tsymtable;pl:tsymlist);
  34. function node_to_symlist(p1:tnode):tsymlist;
  35. function parse_paras(__colon,in_prop_paras : boolean) : tnode;
  36. { the ID token has to be consumed before calling this function }
  37. procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
  38. {$ifdef int64funcresok}
  39. function get_intconst:TConstExprInt;
  40. {$else int64funcresok}
  41. function get_intconst:longint;
  42. {$endif int64funcresok}
  43. function get_stringconst:string;
  44. implementation
  45. uses
  46. {$ifdef delphi}
  47. SysUtils,
  48. {$endif}
  49. { common }
  50. cutils,
  51. { global }
  52. globtype,tokens,verbose,
  53. systems,widestr,
  54. { symtable }
  55. symconst,symtable,symsym,defutil,defcmp,
  56. { pass 1 }
  57. pass_1,htypechk,
  58. nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
  59. { parser }
  60. scanner,
  61. pbase,pinline,
  62. { codegen }
  63. procinfo
  64. ;
  65. { sub_expr(opmultiply) is need to get -1 ** 4 to be
  66. read as - (1**4) and not (-1)**4 PM }
  67. type
  68. Toperator_precedence=(opcompare,opaddition,opmultiply,oppower);
  69. const
  70. highest_precedence = oppower;
  71. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;forward;
  72. const
  73. { true, if the inherited call is anonymous }
  74. anon_inherited : boolean = false;
  75. procedure string_dec(var t: ttype);
  76. { reads a string type with optional length }
  77. { and returns a pointer to the string }
  78. { definition }
  79. var
  80. p : tnode;
  81. begin
  82. t:=cshortstringtype;
  83. consume(_STRING);
  84. if try_to_consume(_LECKKLAMMER) then
  85. begin
  86. p:=comp_expr(true);
  87. if not is_constintnode(p) then
  88. begin
  89. Message(cg_e_illegal_expression);
  90. { error recovery }
  91. consume(_RECKKLAMMER);
  92. end
  93. else
  94. begin
  95. if (tordconstnode(p).value<=0) then
  96. begin
  97. Message(parser_e_invalid_string_size);
  98. tordconstnode(p).value:=255;
  99. end;
  100. consume(_RECKKLAMMER);
  101. if tordconstnode(p).value>255 then
  102. begin
  103. { longstring is currently unsupported (CEC)! }
  104. { t.setdef(tstringdef.createlong(tordconstnode(p).value))}
  105. Message(parser_e_invalid_string_size);
  106. tordconstnode(p).value:=255;
  107. t.setdef(tstringdef.createshort(tordconstnode(p).value));
  108. end
  109. else
  110. if tordconstnode(p).value<>255 then
  111. t.setdef(tstringdef.createshort(tordconstnode(p).value));
  112. end;
  113. p.free;
  114. end
  115. else
  116. begin
  117. if cs_ansistrings in aktlocalswitches then
  118. {$ifdef ansistring_bits}
  119. case aktansistring_bits of
  120. sb_16:
  121. t:=cansistringtype16;
  122. sb_32:
  123. t:=cansistringtype32;
  124. sb_64:
  125. t:=cansistringtype64;
  126. end
  127. {$else}
  128. t:=cansistringtype
  129. {$endif}
  130. else
  131. t:=cshortstringtype;
  132. end;
  133. end;
  134. procedure symlist_to_node(var p1:tnode;st:tsymtable;pl:tsymlist);
  135. var
  136. plist : psymlistitem;
  137. begin
  138. plist:=pl.firstsym;
  139. while assigned(plist) do
  140. begin
  141. case plist^.sltype of
  142. sl_load :
  143. begin
  144. if not assigned(st) then
  145. st:=plist^.sym.owner;
  146. { p1 can already contain the loadnode of
  147. the class variable. When there is no tree yet we
  148. may need to load it for with or objects }
  149. if not assigned(p1) then
  150. begin
  151. case st.symtabletype of
  152. withsymtable :
  153. p1:=tnode(twithsymtable(st).withrefnode).getcopy;
  154. objectsymtable :
  155. p1:=load_self_node;
  156. end;
  157. end;
  158. if assigned(p1) then
  159. p1:=csubscriptnode.create(plist^.sym,p1)
  160. else
  161. p1:=cloadnode.create(plist^.sym,st);
  162. end;
  163. sl_subscript :
  164. p1:=csubscriptnode.create(plist^.sym,p1);
  165. sl_typeconv :
  166. p1:=ctypeconvnode.create_explicit(p1,plist^.tt);
  167. sl_vec :
  168. p1:=cvecnode.create(p1,cordconstnode.create(plist^.value,s32inttype,true));
  169. else
  170. internalerror(200110205);
  171. end;
  172. plist:=plist^.next;
  173. end;
  174. end;
  175. function node_to_symlist(p1:tnode):tsymlist;
  176. var
  177. sl : tsymlist;
  178. procedure addnode(p:tnode);
  179. begin
  180. case p.nodetype of
  181. subscriptn :
  182. begin
  183. addnode(tsubscriptnode(p).left);
  184. sl.addsym(sl_subscript,tsubscriptnode(p).vs);
  185. end;
  186. typeconvn :
  187. begin
  188. addnode(ttypeconvnode(p).left);
  189. sl.addtype(sl_typeconv,ttypeconvnode(p).totype);
  190. end;
  191. vecn :
  192. begin
  193. addnode(tvecnode(p).left);
  194. if tvecnode(p).right.nodetype=ordconstn then
  195. sl.addconst(sl_vec,tordconstnode(tvecnode(p).right).value)
  196. else
  197. begin
  198. Message(cg_e_illegal_expression);
  199. { recovery }
  200. sl.addconst(sl_vec,0);
  201. end;
  202. end;
  203. loadn :
  204. sl.addsym(sl_load,tloadnode(p).symtableentry);
  205. else
  206. internalerror(200310282);
  207. end;
  208. end;
  209. begin
  210. sl:=tsymlist.create;
  211. addnode(p1);
  212. result:=sl;
  213. end;
  214. function parse_paras(__colon,in_prop_paras : boolean) : tnode;
  215. var
  216. p1,p2 : tnode;
  217. end_of_paras : ttoken;
  218. prev_in_args : boolean;
  219. old_allow_array_constructor : boolean;
  220. begin
  221. if in_prop_paras then
  222. end_of_paras:=_RECKKLAMMER
  223. else
  224. end_of_paras:=_RKLAMMER;
  225. if token=end_of_paras then
  226. begin
  227. parse_paras:=nil;
  228. exit;
  229. end;
  230. { save old values }
  231. prev_in_args:=in_args;
  232. old_allow_array_constructor:=allow_array_constructor;
  233. { set para parsing values }
  234. in_args:=true;
  235. inc(parsing_para_level);
  236. allow_array_constructor:=true;
  237. p2:=nil;
  238. repeat
  239. p1:=comp_expr(true);
  240. p2:=ccallparanode.create(p1,p2);
  241. { it's for the str(l:5,s); }
  242. if __colon and (token=_COLON) then
  243. begin
  244. consume(_COLON);
  245. p1:=comp_expr(true);
  246. p2:=ccallparanode.create(p1,p2);
  247. include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
  248. if try_to_consume(_COLON) then
  249. begin
  250. p1:=comp_expr(true);
  251. p2:=ccallparanode.create(p1,p2);
  252. include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
  253. end
  254. end;
  255. until not try_to_consume(_COMMA);
  256. allow_array_constructor:=old_allow_array_constructor;
  257. dec(parsing_para_level);
  258. in_args:=prev_in_args;
  259. parse_paras:=p2;
  260. end;
  261. function statement_syssym(l : longint) : tnode;
  262. var
  263. p1,p2,paras : tnode;
  264. err,
  265. prev_in_args : boolean;
  266. begin
  267. prev_in_args:=in_args;
  268. case l of
  269. in_new_x :
  270. begin
  271. if afterassignment or in_args then
  272. statement_syssym:=new_function
  273. else
  274. statement_syssym:=new_dispose_statement(true);
  275. end;
  276. in_dispose_x :
  277. begin
  278. statement_syssym:=new_dispose_statement(false);
  279. end;
  280. in_ord_x :
  281. begin
  282. consume(_LKLAMMER);
  283. in_args:=true;
  284. p1:=comp_expr(true);
  285. consume(_RKLAMMER);
  286. p1:=geninlinenode(in_ord_x,false,p1);
  287. statement_syssym := p1;
  288. end;
  289. in_exit :
  290. begin
  291. if try_to_consume(_LKLAMMER) then
  292. begin
  293. p1:=comp_expr(true);
  294. consume(_RKLAMMER);
  295. if (block_type=bt_except) then
  296. begin
  297. Message(parser_e_exit_with_argument_not__possible);
  298. { recovery }
  299. p1.free;
  300. p1:=nil;
  301. end
  302. else if (not assigned(current_procinfo) or
  303. is_void(current_procinfo.procdef.rettype.def)) then
  304. begin
  305. Message(parser_e_void_function);
  306. { recovery }
  307. p1.free;
  308. p1:=nil;
  309. end;
  310. end
  311. else
  312. p1:=nil;
  313. statement_syssym:=cexitnode.create(p1);
  314. end;
  315. in_break :
  316. begin
  317. statement_syssym:=cbreaknode.create;
  318. end;
  319. in_continue :
  320. begin
  321. statement_syssym:=ccontinuenode.create;
  322. end;
  323. in_typeof_x :
  324. begin
  325. consume(_LKLAMMER);
  326. in_args:=true;
  327. p1:=comp_expr(true);
  328. consume(_RKLAMMER);
  329. if p1.nodetype=typen then
  330. ttypenode(p1).allowed:=true;
  331. { Allow classrefdef, which is required for
  332. Typeof(self) in static class methods }
  333. if (p1.resulttype.def.deftype = objectdef) or
  334. (assigned(current_procinfo) and
  335. ((po_classmethod in current_procinfo.procdef.procoptions) or
  336. (po_staticmethod in current_procinfo.procdef.procoptions)) and
  337. (p1.resulttype.def.deftype=classrefdef)) then
  338. statement_syssym:=geninlinenode(in_typeof_x,false,p1)
  339. else
  340. begin
  341. Message(parser_e_class_id_expected);
  342. p1.destroy;
  343. statement_syssym:=cerrornode.create;
  344. end;
  345. end;
  346. in_sizeof_x :
  347. begin
  348. consume(_LKLAMMER);
  349. in_args:=true;
  350. p1:=comp_expr(true);
  351. consume(_RKLAMMER);
  352. if (p1.nodetype<>typen) and
  353. (
  354. (is_object(p1.resulttype.def) and
  355. (oo_has_constructor in tobjectdef(p1.resulttype.def).objectoptions)) or
  356. is_open_array(p1.resulttype.def) or
  357. is_open_string(p1.resulttype.def)
  358. ) then
  359. statement_syssym:=geninlinenode(in_sizeof_x,false,p1)
  360. else
  361. begin
  362. statement_syssym:=cordconstnode.create(p1.resulttype.def.size,s32inttype,true);
  363. { p1 not needed !}
  364. p1.destroy;
  365. end;
  366. end;
  367. in_typeinfo_x :
  368. begin
  369. consume(_LKLAMMER);
  370. in_args:=true;
  371. p1:=comp_expr(true);
  372. if p1.nodetype=typen then
  373. ttypenode(p1).allowed:=true
  374. else
  375. begin
  376. p1.destroy;
  377. p1:=cerrornode.create;
  378. Message(parser_e_illegal_parameter_list);
  379. end;
  380. consume(_RKLAMMER);
  381. p2:=geninlinenode(in_typeinfo_x,false,p1);
  382. statement_syssym:=p2;
  383. end;
  384. in_assigned_x :
  385. begin
  386. err:=false;
  387. consume(_LKLAMMER);
  388. in_args:=true;
  389. p1:=comp_expr(true);
  390. if not codegenerror then
  391. begin
  392. case p1.resulttype.def.deftype of
  393. procdef, { procvar }
  394. pointerdef,
  395. procvardef,
  396. classrefdef : ;
  397. objectdef :
  398. if not is_class_or_interface(p1.resulttype.def) then
  399. begin
  400. Message(parser_e_illegal_parameter_list);
  401. err:=true;
  402. end;
  403. arraydef :
  404. if not is_dynamic_array(p1.resulttype.def) then
  405. begin
  406. Message(parser_e_illegal_parameter_list);
  407. err:=true;
  408. end;
  409. else
  410. begin
  411. Message(parser_e_illegal_parameter_list);
  412. err:=true;
  413. end;
  414. end;
  415. end
  416. else
  417. err:=true;
  418. if not err then
  419. begin
  420. p2:=ccallparanode.create(p1,nil);
  421. p2:=geninlinenode(in_assigned_x,false,p2);
  422. end
  423. else
  424. begin
  425. p1.free;
  426. p2:=cerrornode.create;
  427. end;
  428. consume(_RKLAMMER);
  429. statement_syssym:=p2;
  430. end;
  431. in_addr_x :
  432. begin
  433. consume(_LKLAMMER);
  434. in_args:=true;
  435. p1:=comp_expr(true);
  436. p1:=caddrnode.create(p1);
  437. if cs_typed_addresses in aktlocalswitches then
  438. include(p1.flags,nf_typedaddr);
  439. consume(_RKLAMMER);
  440. statement_syssym:=p1;
  441. end;
  442. in_ofs_x :
  443. begin
  444. consume(_LKLAMMER);
  445. in_args:=true;
  446. p1:=comp_expr(true);
  447. p1:=caddrnode.create(p1);
  448. do_resulttypepass(p1);
  449. { Ofs() returns a cardinal, not a pointer }
  450. p1.resulttype:=u32inttype;
  451. consume(_RKLAMMER);
  452. statement_syssym:=p1;
  453. end;
  454. in_seg_x :
  455. begin
  456. consume(_LKLAMMER);
  457. in_args:=true;
  458. p1:=comp_expr(true);
  459. p1:=geninlinenode(in_seg_x,false,p1);
  460. consume(_RKLAMMER);
  461. statement_syssym:=p1;
  462. end;
  463. in_high_x,
  464. in_low_x :
  465. begin
  466. consume(_LKLAMMER);
  467. in_args:=true;
  468. p1:=comp_expr(true);
  469. p2:=geninlinenode(l,false,p1);
  470. consume(_RKLAMMER);
  471. statement_syssym:=p2;
  472. end;
  473. in_succ_x,
  474. in_pred_x :
  475. begin
  476. consume(_LKLAMMER);
  477. in_args:=true;
  478. p1:=comp_expr(true);
  479. p2:=geninlinenode(l,false,p1);
  480. consume(_RKLAMMER);
  481. statement_syssym:=p2;
  482. end;
  483. in_inc_x,
  484. in_dec_x :
  485. begin
  486. consume(_LKLAMMER);
  487. in_args:=true;
  488. p1:=comp_expr(true);
  489. if try_to_consume(_COMMA) then
  490. p2:=ccallparanode.create(comp_expr(true),nil)
  491. else
  492. p2:=nil;
  493. p2:=ccallparanode.create(p1,p2);
  494. statement_syssym:=geninlinenode(l,false,p2);
  495. consume(_RKLAMMER);
  496. end;
  497. in_initialize_x:
  498. begin
  499. statement_syssym:=inline_initialize;
  500. end;
  501. in_finalize_x:
  502. begin
  503. statement_syssym:=inline_finalize;
  504. end;
  505. in_copy_x:
  506. begin
  507. statement_syssym:=inline_copy;
  508. end;
  509. in_concat_x :
  510. begin
  511. consume(_LKLAMMER);
  512. in_args:=true;
  513. p2:=nil;
  514. repeat
  515. p1:=comp_expr(true);
  516. set_varstate(p1,vs_used,true);
  517. if not((p1.resulttype.def.deftype=stringdef) or
  518. ((p1.resulttype.def.deftype=orddef) and
  519. (torddef(p1.resulttype.def).typ=uchar))) then
  520. Message(parser_e_illegal_parameter_list);
  521. if p2<>nil then
  522. p2:=caddnode.create(addn,p2,p1)
  523. else
  524. p2:=p1;
  525. until not try_to_consume(_COMMA);
  526. consume(_RKLAMMER);
  527. statement_syssym:=p2;
  528. end;
  529. in_read_x,
  530. in_readln_x :
  531. begin
  532. if try_to_consume(_LKLAMMER) then
  533. begin
  534. paras:=parse_paras(false,false);
  535. consume(_RKLAMMER);
  536. end
  537. else
  538. paras:=nil;
  539. p1:=geninlinenode(l,false,paras);
  540. statement_syssym := p1;
  541. end;
  542. in_setlength_x:
  543. begin
  544. statement_syssym := inline_setlength;
  545. end;
  546. in_length_x:
  547. begin
  548. consume(_LKLAMMER);
  549. in_args:=true;
  550. p1:=comp_expr(true);
  551. p2:=geninlinenode(l,false,p1);
  552. consume(_RKLAMMER);
  553. statement_syssym:=p2;
  554. end;
  555. in_write_x,
  556. in_writeln_x :
  557. begin
  558. if try_to_consume(_LKLAMMER) then
  559. begin
  560. paras:=parse_paras(true,false);
  561. consume(_RKLAMMER);
  562. end
  563. else
  564. paras:=nil;
  565. p1 := geninlinenode(l,false,paras);
  566. statement_syssym := p1;
  567. end;
  568. in_str_x_string :
  569. begin
  570. consume(_LKLAMMER);
  571. paras:=parse_paras(true,false);
  572. consume(_RKLAMMER);
  573. p1 := geninlinenode(l,false,paras);
  574. statement_syssym := p1;
  575. end;
  576. in_val_x:
  577. Begin
  578. consume(_LKLAMMER);
  579. in_args := true;
  580. p1:= ccallparanode.create(comp_expr(true), nil);
  581. consume(_COMMA);
  582. p2 := ccallparanode.create(comp_expr(true),p1);
  583. if try_to_consume(_COMMA) then
  584. p2 := ccallparanode.create(comp_expr(true),p2);
  585. consume(_RKLAMMER);
  586. p2 := geninlinenode(l,false,p2);
  587. statement_syssym := p2;
  588. End;
  589. in_include_x_y,
  590. in_exclude_x_y :
  591. begin
  592. consume(_LKLAMMER);
  593. in_args:=true;
  594. p1:=comp_expr(true);
  595. consume(_COMMA);
  596. p2:=comp_expr(true);
  597. statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
  598. consume(_RKLAMMER);
  599. end;
  600. in_assert_x_y :
  601. begin
  602. consume(_LKLAMMER);
  603. in_args:=true;
  604. p1:=comp_expr(true);
  605. if try_to_consume(_COMMA) then
  606. p2:=comp_expr(true)
  607. else
  608. begin
  609. { then insert an empty string }
  610. p2:=cstringconstnode.createstr('',st_default);
  611. end;
  612. statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
  613. consume(_RKLAMMER);
  614. end;
  615. else
  616. internalerror(15);
  617. end;
  618. in_args:=prev_in_args;
  619. end;
  620. function maybe_load_methodpointer(st:tsymtable;var p1:tnode):boolean;
  621. begin
  622. maybe_load_methodpointer:=false;
  623. if not assigned(p1) then
  624. begin
  625. case st.symtabletype of
  626. withsymtable :
  627. begin
  628. if (st.defowner.deftype=objectdef) then
  629. p1:=tnode(twithsymtable(st).withrefnode).getcopy;
  630. end;
  631. objectsymtable :
  632. begin
  633. p1:=load_self_node;
  634. { We are calling a member }
  635. maybe_load_methodpointer:=true;
  636. end;
  637. end;
  638. end;
  639. end;
  640. { reads the parameter for a subroutine call }
  641. procedure do_proc_call(sym:tsym;st:tsymtable;obj:tobjectdef;getaddr:boolean;var again : boolean;var p1:tnode);
  642. var
  643. membercall,
  644. prevafterassn : boolean;
  645. vs : tvarsym;
  646. para,p2 : tnode;
  647. currpara : tparaitem;
  648. aprocdef : tprocdef;
  649. begin
  650. prevafterassn:=afterassignment;
  651. afterassignment:=false;
  652. membercall:=false;
  653. aprocdef:=nil;
  654. { when it is a call to a member we need to load the
  655. methodpointer first }
  656. membercall:=maybe_load_methodpointer(st,p1);
  657. { When we are expecting a procvar we also need
  658. to get the address in some cases }
  659. if assigned(getprocvardef) then
  660. begin
  661. if (block_type=bt_const) or
  662. getaddr then
  663. begin
  664. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  665. getaddr:=true;
  666. end
  667. else
  668. if (m_tp_procvar in aktmodeswitches) then
  669. begin
  670. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  671. if assigned(aprocdef) then
  672. getaddr:=true;
  673. end;
  674. end;
  675. { only need to get the address of the procedure? }
  676. if getaddr then
  677. begin
  678. { Retrieve info which procvar to call. For tp_procvar the
  679. aprocdef is already loaded above so we can reuse it }
  680. if not assigned(aprocdef) and
  681. assigned(getprocvardef) then
  682. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  683. { generate a methodcallnode or proccallnode }
  684. { we shouldn't convert things like @tcollection.load }
  685. p2:=cloadnode.create_procvar(sym,aprocdef,st);
  686. if assigned(p1) then
  687. begin
  688. if (p1.nodetype<>typen) then
  689. tloadnode(p2).set_mp(p1)
  690. else
  691. p1.free;
  692. end;
  693. p1:=p2;
  694. { no postfix operators }
  695. again:=false;
  696. end
  697. else
  698. begin
  699. para:=nil;
  700. if anon_inherited then
  701. begin
  702. if not assigned(current_procinfo) then
  703. internalerror(200305054);
  704. currpara:=tparaitem(current_procinfo.procdef.para.first);
  705. while assigned(currpara) do
  706. begin
  707. if not currpara.is_hidden then
  708. begin
  709. vs:=tvarsym(currpara.parasym);
  710. para:=ccallparanode.create(cloadnode.create(vs,vs.owner),para);
  711. end;
  712. currpara:=tparaitem(currpara.next);
  713. end;
  714. end
  715. else
  716. begin
  717. if try_to_consume(_LKLAMMER) then
  718. begin
  719. para:=parse_paras(false,false);
  720. consume(_RKLAMMER);
  721. end;
  722. end;
  723. if assigned(obj) then
  724. begin
  725. if (st.symtabletype<>objectsymtable) then
  726. internalerror(200310031);
  727. p1:=ccallnode.create(para,tprocsym(sym),obj.symtable,p1);
  728. end
  729. else
  730. p1:=ccallnode.create(para,tprocsym(sym),st,p1);
  731. { indicate if this call was generated by a member and
  732. no explicit self is used, this is needed to determine
  733. how to handle a destructor call (PFV) }
  734. if membercall then
  735. include(p1.flags,nf_member_call);
  736. end;
  737. afterassignment:=prevafterassn;
  738. end;
  739. procedure handle_procvar(pv : tprocvardef;var p2 : tnode);
  740. var
  741. hp,hp2 : tnode;
  742. hpp : ^tnode;
  743. currprocdef : tprocdef;
  744. begin
  745. if not assigned(pv) then
  746. internalerror(200301121);
  747. if (m_tp_procvar in aktmodeswitches) then
  748. begin
  749. hp:=p2;
  750. hpp:=@p2;
  751. while assigned(hp) and
  752. (hp.nodetype=typeconvn) do
  753. begin
  754. hp:=ttypeconvnode(hp).left;
  755. { save orignal address of the old tree so we can replace the node }
  756. hpp:=@hp;
  757. end;
  758. if (hp.nodetype=calln) and
  759. { a procvar can't have parameters! }
  760. not assigned(tcallnode(hp).left) then
  761. begin
  762. currprocdef:=tcallnode(hp).symtableprocentry.search_procdef_byprocvardef(pv);
  763. if assigned(currprocdef) then
  764. begin
  765. hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc);
  766. if (po_methodpointer in pv.procoptions) then
  767. tloadnode(hp2).set_mp(tnode(tcallnode(hp).methodpointer).getcopy);
  768. hp.destroy;
  769. { replace the old callnode with the new loadnode }
  770. hpp^:=hp2;
  771. end;
  772. end;
  773. end;
  774. end;
  775. { the following procedure handles the access to a property symbol }
  776. procedure handle_propertysym(sym : tsym;st : tsymtable;var p1 : tnode);
  777. var
  778. paras : tnode;
  779. p2 : tnode;
  780. membercall : boolean;
  781. begin
  782. paras:=nil;
  783. { property parameters? read them only if the property really }
  784. { has parameters }
  785. if (ppo_hasparameters in tpropertysym(sym).propoptions) then
  786. begin
  787. if try_to_consume(_LECKKLAMMER) then
  788. begin
  789. paras:=parse_paras(false,true);
  790. consume(_RECKKLAMMER);
  791. end;
  792. end;
  793. { indexed property }
  794. if (ppo_indexed in tpropertysym(sym).propoptions) then
  795. begin
  796. p2:=cordconstnode.create(tpropertysym(sym).index,tpropertysym(sym).indextype,true);
  797. paras:=ccallparanode.create(p2,paras);
  798. end;
  799. { we need only a write property if a := follows }
  800. { if not(afterassignment) and not(in_args) then }
  801. if token=_ASSIGNMENT then
  802. begin
  803. { write property: }
  804. if not tpropertysym(sym).writeaccess.empty then
  805. begin
  806. case tpropertysym(sym).writeaccess.firstsym^.sym.typ of
  807. procsym :
  808. begin
  809. { generate the method call }
  810. membercall:=maybe_load_methodpointer(st,p1);
  811. p1:=ccallnode.create(paras,
  812. tprocsym(tpropertysym(sym).writeaccess.firstsym^.sym),st,p1);
  813. if membercall then
  814. include(tcallnode(p1).flags,nf_member_call);
  815. paras:=nil;
  816. consume(_ASSIGNMENT);
  817. { read the expression }
  818. if tpropertysym(sym).proptype.def.deftype=procvardef then
  819. getprocvardef:=tprocvardef(tpropertysym(sym).proptype.def);
  820. p2:=comp_expr(true);
  821. if assigned(getprocvardef) then
  822. handle_procvar(getprocvardef,p2);
  823. tcallnode(p1).left:=ccallparanode.create(p2,tcallnode(p1).left);
  824. include(tcallnode(p1).flags,nf_isproperty);
  825. getprocvardef:=nil;
  826. end;
  827. varsym :
  828. begin
  829. { generate access code }
  830. symlist_to_node(p1,st,tpropertysym(sym).writeaccess);
  831. include(p1.flags,nf_isproperty);
  832. consume(_ASSIGNMENT);
  833. { read the expression }
  834. p2:=comp_expr(true);
  835. p1:=cassignmentnode.create(p1,p2);
  836. end
  837. else
  838. begin
  839. p1:=cerrornode.create;
  840. Message(parser_e_no_procedure_to_access_property);
  841. end;
  842. end;
  843. end
  844. else
  845. begin
  846. p1:=cerrornode.create;
  847. Message(parser_e_no_procedure_to_access_property);
  848. end;
  849. end
  850. else
  851. begin
  852. { read property: }
  853. if not tpropertysym(sym).readaccess.empty then
  854. begin
  855. case tpropertysym(sym).readaccess.firstsym^.sym.typ of
  856. varsym :
  857. begin
  858. { generate access code }
  859. symlist_to_node(p1,st,tpropertysym(sym).readaccess);
  860. include(p1.flags,nf_isproperty);
  861. end;
  862. procsym :
  863. begin
  864. { generate the method call }
  865. membercall:=maybe_load_methodpointer(st,p1);
  866. p1:=ccallnode.create(paras,tprocsym(tpropertysym(sym).readaccess.firstsym^.sym),st,p1);
  867. if membercall then
  868. include(tcallnode(p1).flags,nf_member_call);
  869. paras:=nil;
  870. include(p1.flags,nf_isproperty);
  871. end
  872. else
  873. begin
  874. p1:=cerrornode.create;
  875. Message(type_e_mismatch);
  876. end;
  877. end;
  878. end
  879. else
  880. begin
  881. { error, no function to read property }
  882. p1:=cerrornode.create;
  883. Message(parser_e_no_procedure_to_access_property);
  884. end;
  885. end;
  886. { release paras if not used }
  887. if assigned(paras) then
  888. paras.free;
  889. end;
  890. { the ID token has to be consumed before calling this function }
  891. procedure do_member_read(classh:tobjectdef;getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
  892. var
  893. static_name : string;
  894. isclassref : boolean;
  895. srsymtable : tsymtable;
  896. {$ifdef CHECKINHERITEDRESULT}
  897. newstatement : tstatementnode;
  898. newblock : tblocknode;
  899. {$endif CHECKINHERITEDRESULT}
  900. begin
  901. if sym=nil then
  902. begin
  903. { pattern is still valid unless
  904. there is another ID just after the ID of sym }
  905. Message1(sym_e_id_no_member,pattern);
  906. p1.free;
  907. p1:=cerrornode.create;
  908. { try to clean up }
  909. again:=false;
  910. end
  911. else
  912. begin
  913. if assigned(p1) then
  914. begin
  915. if not assigned(p1.resulttype.def) then
  916. do_resulttypepass(p1);
  917. isclassref:=(p1.resulttype.def.deftype=classrefdef);
  918. end
  919. else
  920. isclassref:=false;
  921. { we assume, that only procsyms and varsyms are in an object }
  922. { symbol table, for classes, properties are allowed }
  923. case sym.typ of
  924. procsym:
  925. begin
  926. do_proc_call(sym,sym.owner,classh,
  927. (getaddr and not(token in [_CARET,_POINT])),
  928. again,p1);
  929. { add provided flags }
  930. if (p1.nodetype=calln) then
  931. p1.flags:=p1.flags+callnflags;
  932. { we need to know which procedure is called }
  933. do_resulttypepass(p1);
  934. { now we know the method that is called }
  935. if (p1.nodetype=calln) and
  936. assigned(tcallnode(p1).procdefinition) then
  937. begin
  938. { calling using classref? }
  939. if isclassref and
  940. not(po_classmethod in tcallnode(p1).procdefinition.procoptions) and
  941. not(tcallnode(p1).procdefinition.proctypeoption=potype_constructor) then
  942. Message(parser_e_only_class_methods_via_class_ref);
  943. {$ifdef CHECKINHERITEDRESULT}
  944. { when calling inherited constructor we need to check the return value }
  945. if (nf_inherited in callnflags) and
  946. (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) then
  947. begin
  948. {
  949. For Classes:
  950. self:=inherited constructor
  951. if self=nil then
  952. exit
  953. For objects:
  954. if inherited constructor=false then
  955. begin
  956. self:=nil;
  957. exit;
  958. end;
  959. }
  960. if is_class(tprocdef(tcallnode(p1).procdefinition)._class) then
  961. begin
  962. newblock:=internalstatements(newstatement,true);
  963. addstatement(newstatement,cassignmentnode.create(
  964. ctypeconvnode.create(
  965. load_self_pointer_node,
  966. voidpointertype),
  967. ctypeconvnode.create(
  968. p1,
  969. voidpointertype)));
  970. addstatement(newstatement,cifnode.create(
  971. caddnode.create(equaln,
  972. load_self_pointer_node,
  973. cnilnode.create),
  974. cexitnode.create(nil),
  975. nil));
  976. p1:=newblock;
  977. end
  978. else
  979. if is_object(tprocdef(tcallnode(p1).procdefinition)._class) then
  980. begin
  981. newblock:=internalstatements(newstatement,true);
  982. addstatement(newstatement,call_fail_node);
  983. addstatement(newstatement,cexitnode.create(nil));
  984. p1:=cifnode.create(
  985. caddnode.create(equaln,
  986. cordconstnode.create(0,booltype,false),
  987. p1),
  988. newblock,
  989. nil);
  990. end
  991. else
  992. internalerror(200305133);
  993. end;
  994. {$endif CHECKINHERITEDRESULT}
  995. do_resulttypepass(p1);
  996. end;
  997. end;
  998. varsym:
  999. begin
  1000. if (sp_static in sym.symoptions) then
  1001. begin
  1002. static_name:=lower(sym.owner.name^)+'_'+sym.name;
  1003. searchsym(static_name,sym,srsymtable);
  1004. check_hints(sym);
  1005. p1.free;
  1006. p1:=cloadnode.create(sym,srsymtable);
  1007. end
  1008. else
  1009. begin
  1010. if isclassref then
  1011. Message(parser_e_only_class_methods_via_class_ref);
  1012. p1:=csubscriptnode.create(sym,p1);
  1013. end;
  1014. end;
  1015. propertysym:
  1016. begin
  1017. if isclassref then
  1018. Message(parser_e_only_class_methods_via_class_ref);
  1019. handle_propertysym(sym,sym.owner,p1);
  1020. end;
  1021. else internalerror(16);
  1022. end;
  1023. end;
  1024. end;
  1025. {****************************************************************************
  1026. Factor
  1027. ****************************************************************************}
  1028. {$ifdef fpc}
  1029. {$maxfpuregisters 0}
  1030. {$endif fpc}
  1031. function factor(getaddr : boolean) : tnode;
  1032. {---------------------------------------------
  1033. Factor_read_id
  1034. ---------------------------------------------}
  1035. procedure factor_read_id(var p1:tnode;var again:boolean);
  1036. var
  1037. pc : pchar;
  1038. len : longint;
  1039. srsym : tsym;
  1040. possible_error : boolean;
  1041. srsymtable : tsymtable;
  1042. storesymtablestack : tsymtable;
  1043. htype : ttype;
  1044. static_name : string;
  1045. begin
  1046. { allow post fix operators }
  1047. again:=true;
  1048. consume_sym(srsym,srsymtable);
  1049. { Access to funcret or need to call the function? }
  1050. if (srsym.typ in [absolutesym,varsym]) and
  1051. (vo_is_funcret in tvarsym(srsym).varoptions) and
  1052. (
  1053. (token=_LKLAMMER) or
  1054. (not(m_fpc in aktmodeswitches) and
  1055. (afterassignment or in_args) and
  1056. not(vo_is_result in tvarsym(srsym).varoptions))
  1057. ) then
  1058. begin
  1059. storesymtablestack:=symtablestack;
  1060. symtablestack:=srsym.owner.next;
  1061. searchsym(srsym.name,srsym,srsymtable);
  1062. if not assigned(srsym) then
  1063. srsym:=generrorsym;
  1064. if (srsym.typ<>procsym) then
  1065. Message(cg_e_illegal_expression);
  1066. symtablestack:=storesymtablestack;
  1067. end;
  1068. begin
  1069. { check semantics of private }
  1070. if (srsym.typ in [propertysym,procsym,varsym]) and
  1071. (srsym.owner.symtabletype=objectsymtable) then
  1072. begin
  1073. if (sp_private in srsym.symoptions) and
  1074. (tobjectdef(srsym.owner.defowner).owner.symtabletype=globalsymtable) and
  1075. (tobjectdef(srsym.owner.defowner).owner.unitid<>0) then
  1076. Message(parser_e_cant_access_private_member);
  1077. end;
  1078. case srsym.typ of
  1079. absolutesym :
  1080. begin
  1081. if (tabsolutesym(srsym).abstyp=tovar) then
  1082. begin
  1083. p1:=nil;
  1084. symlist_to_node(p1,nil,tabsolutesym(srsym).ref);
  1085. p1:=ctypeconvnode.create(p1,tabsolutesym(srsym).vartype);
  1086. include(p1.flags,nf_absolute);
  1087. end
  1088. else
  1089. p1:=cloadnode.create(srsym,srsymtable);
  1090. end;
  1091. varsym :
  1092. begin
  1093. if (sp_static in srsym.symoptions) then
  1094. begin
  1095. static_name:=lower(srsym.owner.name^)+'_'+srsym.name;
  1096. searchsym(static_name,srsym,srsymtable);
  1097. check_hints(srsym);
  1098. end
  1099. else
  1100. begin
  1101. { are we in a class method, we check here the
  1102. srsymtable, because a field in another object
  1103. also has objectsymtable. And withsymtable is
  1104. not possible for self in class methods (PFV) }
  1105. if (srsymtable.symtabletype=objectsymtable) and
  1106. assigned(current_procinfo) and
  1107. (po_classmethod in current_procinfo.procdef.procoptions) then
  1108. Message(parser_e_only_class_methods);
  1109. end;
  1110. case srsymtable.symtabletype of
  1111. objectsymtable :
  1112. p1:=csubscriptnode.create(srsym,load_self_node);
  1113. withsymtable :
  1114. p1:=csubscriptnode.create(srsym,tnode(twithsymtable(srsymtable).withrefnode).getcopy);
  1115. else
  1116. p1:=cloadnode.create(srsym,srsymtable);
  1117. end;
  1118. end;
  1119. typedconstsym :
  1120. begin
  1121. p1:=cloadnode.create(srsym,srsymtable);
  1122. end;
  1123. syssym :
  1124. begin
  1125. p1:=statement_syssym(tsyssym(srsym).number);
  1126. end;
  1127. typesym :
  1128. begin
  1129. htype.setsym(srsym);
  1130. if not assigned(htype.def) then
  1131. begin
  1132. again:=false;
  1133. end
  1134. else
  1135. begin
  1136. if try_to_consume(_LKLAMMER) then
  1137. begin
  1138. p1:=comp_expr(true);
  1139. consume(_RKLAMMER);
  1140. p1:=ctypeconvnode.create_explicit(p1,htype);
  1141. end
  1142. else { not LKLAMMER }
  1143. if (token=_POINT) and
  1144. is_object(htype.def) then
  1145. begin
  1146. consume(_POINT);
  1147. if assigned(current_procinfo) and
  1148. assigned(current_procinfo.procdef._class) and
  1149. not(getaddr) then
  1150. begin
  1151. if current_procinfo.procdef._class.is_related(tobjectdef(htype.def)) then
  1152. begin
  1153. p1:=ctypenode.create(htype);
  1154. { search also in inherited methods }
  1155. srsym:=searchsym_in_class(tobjectdef(htype.def),pattern);
  1156. check_hints(srsym);
  1157. consume(_ID);
  1158. do_member_read(tobjectdef(htype.def),false,srsym,p1,again,[]);
  1159. end
  1160. else
  1161. begin
  1162. Message(parser_e_no_super_class);
  1163. again:=false;
  1164. end;
  1165. end
  1166. else
  1167. begin
  1168. { allows @TObject.Load }
  1169. { also allows static methods and variables }
  1170. p1:=ctypenode.create(htype);
  1171. { TP allows also @TMenu.Load if Load is only }
  1172. { defined in an anchestor class }
  1173. srsym:=search_class_member(tobjectdef(htype.def),pattern);
  1174. check_hints(srsym);
  1175. if not assigned(srsym) then
  1176. Message1(sym_e_id_no_member,pattern)
  1177. else if not(getaddr) and not(sp_static in srsym.symoptions) then
  1178. Message(sym_e_only_static_in_static)
  1179. else
  1180. begin
  1181. consume(_ID);
  1182. do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
  1183. end;
  1184. end;
  1185. end
  1186. else
  1187. begin
  1188. { class reference ? }
  1189. if is_class(htype.def) then
  1190. begin
  1191. if getaddr and (token=_POINT) then
  1192. begin
  1193. consume(_POINT);
  1194. { allows @Object.Method }
  1195. { also allows static methods and variables }
  1196. p1:=ctypenode.create(htype);
  1197. { TP allows also @TMenu.Load if Load is only }
  1198. { defined in an anchestor class }
  1199. srsym:=search_class_member(tobjectdef(htype.def),pattern);
  1200. check_hints(srsym);
  1201. if not assigned(srsym) then
  1202. Message1(sym_e_id_no_member,pattern)
  1203. else
  1204. begin
  1205. consume(_ID);
  1206. do_member_read(tobjectdef(htype.def),getaddr,srsym,p1,again,[]);
  1207. end;
  1208. end
  1209. else
  1210. begin
  1211. p1:=ctypenode.create(htype);
  1212. { For a type block we simply return only
  1213. the type. For all other blocks we return
  1214. a loadvmt node }
  1215. if (block_type<>bt_type) then
  1216. p1:=cloadvmtaddrnode.create(p1);
  1217. end;
  1218. end
  1219. else
  1220. p1:=ctypenode.create(htype);
  1221. end;
  1222. end;
  1223. end;
  1224. enumsym :
  1225. begin
  1226. p1:=genenumnode(tenumsym(srsym));
  1227. end;
  1228. constsym :
  1229. begin
  1230. case tconstsym(srsym).consttyp of
  1231. constord :
  1232. begin
  1233. if tconstsym(srsym).consttype.def=nil then
  1234. internalerror(200403232);
  1235. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,tconstsym(srsym).consttype,true);
  1236. end;
  1237. conststring :
  1238. begin
  1239. len:=tconstsym(srsym).value.len;
  1240. if not(cs_ansistrings in aktlocalswitches) and (len>255) then
  1241. len:=255;
  1242. getmem(pc,len+1);
  1243. move(pchar(tconstsym(srsym).value.valueptr)^,pc^,len);
  1244. pc[len]:=#0;
  1245. p1:=cstringconstnode.createpchar(pc,len);
  1246. end;
  1247. constreal :
  1248. p1:=crealconstnode.create(pbestreal(tconstsym(srsym).value.valueptr)^,pbestrealtype^);
  1249. constset :
  1250. p1:=csetconstnode.create(pconstset(tconstsym(srsym).value.valueptr),tconstsym(srsym).consttype);
  1251. constpointer :
  1252. p1:=cpointerconstnode.create(tconstsym(srsym).value.valueordptr,tconstsym(srsym).consttype);
  1253. constnil :
  1254. p1:=cnilnode.create;
  1255. constresourcestring:
  1256. begin
  1257. p1:=cloadnode.create(srsym,srsymtable);
  1258. do_resulttypepass(p1);
  1259. {$ifdef ansistring_bits}
  1260. case aktansistring_bits of
  1261. sb_16:
  1262. p1.resulttype:=cansistringtype16;
  1263. sb_32:
  1264. p1.resulttype:=cansistringtype32;
  1265. sb_64:
  1266. p1.resulttype:=cansistringtype64;
  1267. end;
  1268. {$else}
  1269. p1.resulttype:=cansistringtype;
  1270. {$endif}
  1271. end;
  1272. constguid :
  1273. p1:=cguidconstnode.create(pguid(tconstsym(srsym).value.valueptr)^);
  1274. end;
  1275. end;
  1276. procsym :
  1277. begin
  1278. { are we in a class method ? }
  1279. possible_error:=(srsymtable.symtabletype<>withsymtable) and
  1280. (srsym.owner.symtabletype=objectsymtable) and
  1281. not(is_interface(tdef(srsym.owner.defowner))) and
  1282. assigned(current_procinfo) and
  1283. (po_classmethod in current_procinfo.procdef.procoptions);
  1284. do_proc_call(srsym,srsymtable,nil,
  1285. (getaddr and not(token in [_CARET,_POINT])),
  1286. again,p1);
  1287. { we need to know which procedure is called }
  1288. if possible_error then
  1289. begin
  1290. do_resulttypepass(p1);
  1291. if not(tcallnode(p1).procdefinition.proctypeoption=potype_constructor) and
  1292. not(po_classmethod in tcallnode(p1).procdefinition.procoptions) then
  1293. Message(parser_e_only_class_methods);
  1294. end;
  1295. end;
  1296. propertysym :
  1297. begin
  1298. { access to property in a method }
  1299. { are we in a class method ? }
  1300. if (srsymtable.symtabletype=objectsymtable) and
  1301. assigned(current_procinfo) and
  1302. (po_classmethod in current_procinfo.procdef.procoptions) then
  1303. Message(parser_e_only_class_methods);
  1304. { no method pointer }
  1305. p1:=nil;
  1306. handle_propertysym(srsym,srsymtable,p1);
  1307. end;
  1308. labelsym :
  1309. begin
  1310. consume(_COLON);
  1311. if tlabelsym(srsym).defined then
  1312. Message(sym_e_label_already_defined);
  1313. tlabelsym(srsym).defined:=true;
  1314. p1:=clabelnode.create(tlabelsym(srsym),nil);
  1315. end;
  1316. errorsym :
  1317. begin
  1318. p1:=cerrornode.create;
  1319. if try_to_consume(_LKLAMMER) then
  1320. begin
  1321. parse_paras(false,false);
  1322. consume(_RKLAMMER);
  1323. end;
  1324. end;
  1325. else
  1326. begin
  1327. p1:=cerrornode.create;
  1328. Message(cg_e_illegal_expression);
  1329. end;
  1330. end; { end case }
  1331. end;
  1332. end;
  1333. {---------------------------------------------
  1334. Factor_Read_Set
  1335. ---------------------------------------------}
  1336. { Read a set between [] }
  1337. function factor_read_set:tnode;
  1338. var
  1339. p1,p2 : tnode;
  1340. lastp,
  1341. buildp : tarrayconstructornode;
  1342. begin
  1343. buildp:=nil;
  1344. { be sure that a least one arrayconstructn is used, also for an
  1345. empty [] }
  1346. if token=_RECKKLAMMER then
  1347. buildp:=carrayconstructornode.create(nil,buildp)
  1348. else
  1349. repeat
  1350. p1:=comp_expr(true);
  1351. if try_to_consume(_POINTPOINT) then
  1352. begin
  1353. p2:=comp_expr(true);
  1354. p1:=carrayconstructorrangenode.create(p1,p2);
  1355. end;
  1356. { insert at the end of the tree, to get the correct order }
  1357. if not assigned(buildp) then
  1358. begin
  1359. buildp:=carrayconstructornode.create(p1,nil);
  1360. lastp:=buildp;
  1361. end
  1362. else
  1363. begin
  1364. lastp.right:=carrayconstructornode.create(p1,nil);
  1365. lastp:=tarrayconstructornode(lastp.right);
  1366. end;
  1367. { there could be more elements }
  1368. until not try_to_consume(_COMMA);
  1369. factor_read_set:=buildp;
  1370. end;
  1371. {---------------------------------------------
  1372. PostFixOperators
  1373. ---------------------------------------------}
  1374. procedure postfixoperators(var p1:tnode;var again:boolean);
  1375. { tries to avoid syntax errors after invalid qualifiers }
  1376. procedure recoverconsume_postfixops;
  1377. begin
  1378. repeat
  1379. if not try_to_consume(_CARET) then
  1380. if try_to_consume(_POINT) then
  1381. try_to_consume(_ID)
  1382. else if try_to_consume(_LECKKLAMMER) then
  1383. begin
  1384. repeat
  1385. comp_expr(true);
  1386. until not try_to_consume(_COMMA);
  1387. consume(_RECKKLAMMER);
  1388. end
  1389. else
  1390. break;
  1391. until false;
  1392. end;
  1393. var
  1394. store_static : boolean;
  1395. protsym : tpropertysym;
  1396. p2,p3 : tnode;
  1397. hsym : tsym;
  1398. classh : tobjectdef;
  1399. begin
  1400. again:=true;
  1401. while again do
  1402. begin
  1403. { we need the resulttype }
  1404. do_resulttypepass(p1);
  1405. if codegenerror then
  1406. begin
  1407. recoverconsume_postfixops;
  1408. exit;
  1409. end;
  1410. { handle token }
  1411. case token of
  1412. _CARET:
  1413. begin
  1414. consume(_CARET);
  1415. if (p1.resulttype.def.deftype<>pointerdef) then
  1416. begin
  1417. { ^ as binary operator is a problem!!!! (FK) }
  1418. again:=false;
  1419. Message(cg_e_invalid_qualifier);
  1420. recoverconsume_postfixops;
  1421. p1.destroy;
  1422. p1:=cerrornode.create;
  1423. end
  1424. else
  1425. begin
  1426. p1:=cderefnode.create(p1);
  1427. end;
  1428. end;
  1429. _LECKKLAMMER:
  1430. begin
  1431. if is_class_or_interface(p1.resulttype.def) then
  1432. begin
  1433. { default property }
  1434. protsym:=search_default_property(tobjectdef(p1.resulttype.def));
  1435. if not(assigned(protsym)) then
  1436. begin
  1437. p1.destroy;
  1438. p1:=cerrornode.create;
  1439. again:=false;
  1440. message(parser_e_no_default_property_available);
  1441. end
  1442. else
  1443. begin
  1444. { The property symbol is referenced indirect }
  1445. inc(protsym.refs);
  1446. handle_propertysym(protsym,protsym.owner,p1);
  1447. end;
  1448. end
  1449. else
  1450. begin
  1451. consume(_LECKKLAMMER);
  1452. repeat
  1453. case p1.resulttype.def.deftype of
  1454. pointerdef:
  1455. begin
  1456. { support delphi autoderef }
  1457. if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=arraydef) and
  1458. (m_autoderef in aktmodeswitches) then
  1459. begin
  1460. p1:=cderefnode.create(p1);
  1461. end;
  1462. p2:=comp_expr(true);
  1463. p1:=cvecnode.create(p1,p2);
  1464. end;
  1465. variantdef,
  1466. stringdef :
  1467. begin
  1468. p2:=comp_expr(true);
  1469. p1:=cvecnode.create(p1,p2);
  1470. end;
  1471. arraydef :
  1472. begin
  1473. p2:=comp_expr(true);
  1474. { support SEG:OFS for go32v2 Mem[] }
  1475. if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
  1476. (p1.nodetype=loadn) and
  1477. assigned(tloadnode(p1).symtableentry) and
  1478. assigned(tloadnode(p1).symtableentry.owner.name) and
  1479. (tloadnode(p1).symtableentry.owner.name^='SYSTEM') and
  1480. ((tloadnode(p1).symtableentry.name='MEM') or
  1481. (tloadnode(p1).symtableentry.name='MEMW') or
  1482. (tloadnode(p1).symtableentry.name='MEML')) then
  1483. begin
  1484. if try_to_consume(_COLON) then
  1485. begin
  1486. p3:=caddnode.create(muln,cordconstnode.create($10,s32inttype,false),p2);
  1487. p2:=comp_expr(true);
  1488. p2:=caddnode.create(addn,p2,p3);
  1489. p1:=cvecnode.create(p1,p2);
  1490. include(tvecnode(p1).flags,nf_memseg);
  1491. include(tvecnode(p1).flags,nf_memindex);
  1492. end
  1493. else
  1494. begin
  1495. p1:=cvecnode.create(p1,p2);
  1496. include(tvecnode(p1).flags,nf_memindex);
  1497. end;
  1498. end
  1499. else
  1500. p1:=cvecnode.create(p1,p2);
  1501. end;
  1502. else
  1503. begin
  1504. Message(cg_e_invalid_qualifier);
  1505. p1.destroy;
  1506. p1:=cerrornode.create;
  1507. comp_expr(true);
  1508. again:=false;
  1509. end;
  1510. end;
  1511. do_resulttypepass(p1);
  1512. until not try_to_consume(_COMMA);;
  1513. consume(_RECKKLAMMER);
  1514. end;
  1515. end;
  1516. _POINT :
  1517. begin
  1518. consume(_POINT);
  1519. if (p1.resulttype.def.deftype=pointerdef) and
  1520. (m_autoderef in aktmodeswitches) then
  1521. begin
  1522. p1:=cderefnode.create(p1);
  1523. do_resulttypepass(p1);
  1524. end;
  1525. case p1.resulttype.def.deftype of
  1526. recorddef:
  1527. begin
  1528. hsym:=tsym(trecorddef(p1.resulttype.def).symtable.search(pattern));
  1529. check_hints(hsym);
  1530. if assigned(hsym) and
  1531. (hsym.typ=varsym) then
  1532. p1:=csubscriptnode.create(hsym,p1)
  1533. else
  1534. begin
  1535. Message1(sym_e_illegal_field,pattern);
  1536. p1.destroy;
  1537. p1:=cerrornode.create;
  1538. end;
  1539. consume(_ID);
  1540. end;
  1541. variantdef:
  1542. begin
  1543. end;
  1544. classrefdef:
  1545. begin
  1546. classh:=tobjectdef(tclassrefdef(p1.resulttype.def).pointertype.def);
  1547. hsym:=searchsym_in_class(classh,pattern);
  1548. check_hints(hsym);
  1549. if hsym=nil then
  1550. begin
  1551. Message1(sym_e_id_no_member,pattern);
  1552. p1.destroy;
  1553. p1:=cerrornode.create;
  1554. { try to clean up }
  1555. consume(_ID);
  1556. end
  1557. else
  1558. begin
  1559. consume(_ID);
  1560. do_member_read(classh,getaddr,hsym,p1,again,[]);
  1561. end;
  1562. end;
  1563. objectdef:
  1564. begin
  1565. store_static:=allow_only_static;
  1566. allow_only_static:=false;
  1567. classh:=tobjectdef(p1.resulttype.def);
  1568. hsym:=searchsym_in_class(classh,pattern);
  1569. check_hints(hsym);
  1570. allow_only_static:=store_static;
  1571. if hsym=nil then
  1572. begin
  1573. Message1(sym_e_id_no_member,pattern);
  1574. p1.destroy;
  1575. p1:=cerrornode.create;
  1576. { try to clean up }
  1577. consume(_ID);
  1578. end
  1579. else
  1580. begin
  1581. consume(_ID);
  1582. do_member_read(classh,getaddr,hsym,p1,again,[]);
  1583. end;
  1584. end;
  1585. pointerdef:
  1586. begin
  1587. Message(cg_e_invalid_qualifier);
  1588. if tpointerdef(p1.resulttype.def).pointertype.def.deftype in [recorddef,objectdef,classrefdef] then
  1589. Message(parser_h_maybe_deref_caret_missing);
  1590. end;
  1591. else
  1592. begin
  1593. Message(cg_e_invalid_qualifier);
  1594. p1.destroy;
  1595. p1:=cerrornode.create;
  1596. consume(_ID);
  1597. end;
  1598. end;
  1599. end;
  1600. else
  1601. begin
  1602. { is this a procedure variable ? }
  1603. if assigned(p1.resulttype.def) and
  1604. (p1.resulttype.def.deftype=procvardef) then
  1605. begin
  1606. if assigned(getprocvardef) and
  1607. equal_defs(p1.resulttype.def,getprocvardef) then
  1608. again:=false
  1609. else
  1610. begin
  1611. if try_to_consume(_LKLAMMER) then
  1612. begin
  1613. p2:=parse_paras(false,false);
  1614. consume(_RKLAMMER);
  1615. p1:=ccallnode.create_procvar(p2,p1);
  1616. { proc():= is never possible }
  1617. if token=_ASSIGNMENT then
  1618. begin
  1619. Message(cg_e_illegal_expression);
  1620. p1.free;
  1621. p1:=cerrornode.create;
  1622. again:=false;
  1623. end;
  1624. end
  1625. else
  1626. again:=false;
  1627. end;
  1628. end
  1629. else
  1630. again:=false;
  1631. end;
  1632. end;
  1633. end; { while again }
  1634. end;
  1635. {---------------------------------------------
  1636. Factor (Main)
  1637. ---------------------------------------------}
  1638. var
  1639. l : longint;
  1640. {$ifndef cpu64bit}
  1641. card : cardinal;
  1642. {$endif cpu64bit}
  1643. ic : TConstExprInt;
  1644. oldp1,
  1645. p1 : tnode;
  1646. code : integer;
  1647. again : boolean;
  1648. sym : tsym;
  1649. pd : tprocdef;
  1650. classh : tobjectdef;
  1651. d : bestreal;
  1652. hs : string;
  1653. htype : ttype;
  1654. filepos : tfileposinfo;
  1655. {---------------------------------------------
  1656. Helpers
  1657. ---------------------------------------------}
  1658. procedure check_tokenpos;
  1659. begin
  1660. if (p1<>oldp1) then
  1661. begin
  1662. if assigned(p1) then
  1663. p1.set_tree_filepos(filepos);
  1664. oldp1:=p1;
  1665. filepos:=akttokenpos;
  1666. end;
  1667. end;
  1668. begin
  1669. oldp1:=nil;
  1670. p1:=nil;
  1671. filepos:=akttokenpos;
  1672. again:=false;
  1673. if token=_ID then
  1674. begin
  1675. again:=true;
  1676. { Handle references to self }
  1677. if (idtoken=_SELF) and
  1678. not(block_type in [bt_const,bt_type]) and
  1679. assigned(current_procinfo) and
  1680. assigned(current_procinfo.procdef._class) then
  1681. begin
  1682. p1:=load_self_node;
  1683. consume(_ID);
  1684. again:=true;
  1685. end
  1686. else
  1687. factor_read_id(p1,again);
  1688. if again then
  1689. begin
  1690. check_tokenpos;
  1691. { handle post fix operators }
  1692. postfixoperators(p1,again);
  1693. end;
  1694. end
  1695. else
  1696. case token of
  1697. _INHERITED :
  1698. begin
  1699. again:=true;
  1700. consume(_INHERITED);
  1701. if assigned(current_procinfo) and
  1702. assigned(current_procinfo.procdef._class) then
  1703. begin
  1704. classh:=current_procinfo.procdef._class.childof;
  1705. { if inherited; only then we need the method with
  1706. the same name }
  1707. if token in endtokens then
  1708. begin
  1709. hs:=current_procinfo.procdef.procsym.name;
  1710. anon_inherited:=true;
  1711. { For message methods we need to search using the message
  1712. number or string }
  1713. pd:=tprocsym(current_procinfo.procdef.procsym).first_procdef;
  1714. if (po_msgint in pd.procoptions) then
  1715. sym:=searchsym_in_class_by_msgint(classh,pd.messageinf.i)
  1716. else
  1717. if (po_msgstr in pd.procoptions) then
  1718. sym:=searchsym_in_class_by_msgstr(classh,pd.messageinf.str)
  1719. else
  1720. sym:=searchsym_in_class(classh,hs);
  1721. end
  1722. else
  1723. begin
  1724. hs:=pattern;
  1725. consume(_ID);
  1726. anon_inherited:=false;
  1727. sym:=searchsym_in_class(classh,hs);
  1728. end;
  1729. if assigned(sym) then
  1730. begin
  1731. check_hints(sym);
  1732. { load the procdef from the inherited class and
  1733. not from self }
  1734. if sym.typ=procsym then
  1735. begin
  1736. htype.setdef(classh);
  1737. if (po_classmethod in current_procinfo.procdef.procoptions) or
  1738. (po_staticmethod in current_procinfo.procdef.procoptions) then
  1739. htype.setdef(tclassrefdef.create(htype));
  1740. p1:=ctypenode.create(htype);
  1741. end;
  1742. do_member_read(classh,false,sym,p1,again,[nf_inherited,nf_anon_inherited]);
  1743. end
  1744. else
  1745. begin
  1746. if anon_inherited then
  1747. begin
  1748. { For message methods we need to call DefaultHandler }
  1749. if (po_msgint in pd.procoptions) or
  1750. (po_msgstr in pd.procoptions) then
  1751. begin
  1752. sym:=searchsym_in_class(classh,'DEFAULTHANDLER');
  1753. if not assigned(sym) or
  1754. (sym.typ<>procsym) then
  1755. internalerror(200303171);
  1756. p1:=nil;
  1757. do_proc_call(sym,sym.owner,classh,false,again,p1);
  1758. end
  1759. else
  1760. begin
  1761. { we need to ignore the inherited; }
  1762. p1:=cnothingnode.create;
  1763. end;
  1764. end
  1765. else
  1766. begin
  1767. Message1(sym_e_id_no_member,hs);
  1768. p1:=cerrornode.create;
  1769. end;
  1770. again:=false;
  1771. end;
  1772. { turn auto inheriting off }
  1773. anon_inherited:=false;
  1774. end
  1775. else
  1776. begin
  1777. Message(parser_e_generic_methods_only_in_methods);
  1778. again:=false;
  1779. p1:=cerrornode.create;
  1780. end;
  1781. postfixoperators(p1,again);
  1782. end;
  1783. _INTCONST :
  1784. begin
  1785. {$ifdef cpu64bit}
  1786. val(pattern,ic,code);
  1787. if code=0 then
  1788. begin
  1789. consume(_INTCONST);
  1790. int_to_type(ic,htype);
  1791. p1:=cordconstnode.create(ic,htype,true);
  1792. end;
  1793. {$else cpu64bit}
  1794. { try cardinal first }
  1795. val(pattern,card,code);
  1796. if code=0 then
  1797. begin
  1798. consume(_INTCONST);
  1799. int_to_type(card,htype);
  1800. p1:=cordconstnode.create(card,htype,true);
  1801. end
  1802. else
  1803. begin
  1804. { then longint }
  1805. valint(pattern,l,code);
  1806. if code = 0 then
  1807. begin
  1808. consume(_INTCONST);
  1809. int_to_type(l,htype);
  1810. p1:=cordconstnode.create(l,htype,true);
  1811. end
  1812. else
  1813. begin
  1814. { then int64 }
  1815. val(pattern,ic,code);
  1816. if code=0 then
  1817. begin
  1818. consume(_INTCONST);
  1819. int_to_type(ic,htype);
  1820. p1:=cordconstnode.create(ic,htype,true);
  1821. end;
  1822. end;
  1823. end;
  1824. {$endif cpu64bit}
  1825. if code<>0 then
  1826. begin
  1827. { finally float }
  1828. val(pattern,d,code);
  1829. if code<>0 then
  1830. begin
  1831. Message(cg_e_invalid_integer);
  1832. consume(_INTCONST);
  1833. l:=1;
  1834. p1:=cordconstnode.create(l,sinttype,true);
  1835. end
  1836. else
  1837. begin
  1838. consume(_INTCONST);
  1839. p1:=crealconstnode.create(d,pbestrealtype^);
  1840. end;
  1841. end;
  1842. end;
  1843. _REALNUMBER :
  1844. begin
  1845. val(pattern,d,code);
  1846. if code<>0 then
  1847. begin
  1848. Message(parser_e_error_in_real);
  1849. d:=1.0;
  1850. end;
  1851. consume(_REALNUMBER);
  1852. p1:=crealconstnode.create(d,pbestrealtype^);
  1853. end;
  1854. _STRING :
  1855. begin
  1856. string_dec(htype);
  1857. { STRING can be also a type cast }
  1858. if try_to_consume(_LKLAMMER) then
  1859. begin
  1860. p1:=comp_expr(true);
  1861. consume(_RKLAMMER);
  1862. p1:=ctypeconvnode.create_explicit(p1,htype);
  1863. { handle postfix operators here e.g. string(a)[10] }
  1864. again:=true;
  1865. postfixoperators(p1,again);
  1866. end
  1867. else
  1868. p1:=ctypenode.create(htype);
  1869. end;
  1870. _FILE :
  1871. begin
  1872. htype:=cfiletype;
  1873. consume(_FILE);
  1874. { FILE can be also a type cast }
  1875. if try_to_consume(_LKLAMMER) then
  1876. begin
  1877. p1:=comp_expr(true);
  1878. consume(_RKLAMMER);
  1879. p1:=ctypeconvnode.create_explicit(p1,htype);
  1880. { handle postfix operators here e.g. string(a)[10] }
  1881. again:=true;
  1882. postfixoperators(p1,again);
  1883. end
  1884. else
  1885. begin
  1886. p1:=ctypenode.create(htype);
  1887. end;
  1888. end;
  1889. _CSTRING :
  1890. begin
  1891. p1:=cstringconstnode.createstr(pattern,st_default);
  1892. consume(_CSTRING);
  1893. end;
  1894. _CCHAR :
  1895. begin
  1896. p1:=cordconstnode.create(ord(pattern[1]),cchartype,true);
  1897. consume(_CCHAR);
  1898. end;
  1899. _CWSTRING:
  1900. begin
  1901. p1:=cstringconstnode.createwstr(patternw);
  1902. consume(_CWSTRING);
  1903. end;
  1904. _CWCHAR:
  1905. begin
  1906. p1:=cordconstnode.create(ord(getcharwidestring(patternw,0)),cwidechartype,true);
  1907. consume(_CWCHAR);
  1908. end;
  1909. _KLAMMERAFFE :
  1910. begin
  1911. consume(_KLAMMERAFFE);
  1912. got_addrn:=true;
  1913. { support both @<x> and @(<x>) }
  1914. if try_to_consume(_LKLAMMER) then
  1915. begin
  1916. p1:=factor(true);
  1917. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1918. begin
  1919. again:=true;
  1920. postfixoperators(p1,again);
  1921. end;
  1922. consume(_RKLAMMER);
  1923. end
  1924. else
  1925. p1:=factor(true);
  1926. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1927. begin
  1928. again:=true;
  1929. postfixoperators(p1,again);
  1930. end;
  1931. got_addrn:=false;
  1932. p1:=caddrnode.create(p1);
  1933. if cs_typed_addresses in aktlocalswitches then
  1934. include(p1.flags,nf_typedaddr);
  1935. { Store the procvar that we are expecting, the
  1936. addrn will use the information to find the correct
  1937. procdef or it will return an error }
  1938. if assigned(getprocvardef) and
  1939. (taddrnode(p1).left.nodetype = loadn) then
  1940. taddrnode(p1).getprocvardef:=getprocvardef;
  1941. end;
  1942. _LKLAMMER :
  1943. begin
  1944. consume(_LKLAMMER);
  1945. p1:=comp_expr(true);
  1946. consume(_RKLAMMER);
  1947. { it's not a good solution }
  1948. { but (a+b)^ makes some problems }
  1949. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1950. begin
  1951. again:=true;
  1952. postfixoperators(p1,again);
  1953. end;
  1954. end;
  1955. _LECKKLAMMER :
  1956. begin
  1957. consume(_LECKKLAMMER);
  1958. p1:=factor_read_set;
  1959. consume(_RECKKLAMMER);
  1960. end;
  1961. _PLUS :
  1962. begin
  1963. consume(_PLUS);
  1964. p1:=factor(false);
  1965. end;
  1966. _MINUS :
  1967. begin
  1968. consume(_MINUS);
  1969. if (token = _INTCONST) then
  1970. begin
  1971. { ugly hack, but necessary to be able to parse }
  1972. { -9223372036854775808 as int64 (JM) }
  1973. pattern := '-'+pattern;
  1974. p1:=sub_expr(oppower,false);
  1975. { -1 ** 4 should be - (1 ** 4) and not
  1976. (-1) ** 4
  1977. This was the reason of tw0869.pp test failure PM }
  1978. if p1.nodetype=starstarn then
  1979. begin
  1980. if tbinarynode(p1).left.nodetype=ordconstn then
  1981. begin
  1982. tordconstnode(tbinarynode(p1).left).value:=-tordconstnode(tbinarynode(p1).left).value;
  1983. p1:=cunaryminusnode.create(p1);
  1984. end
  1985. else if tbinarynode(p1).left.nodetype=realconstn then
  1986. begin
  1987. trealconstnode(tbinarynode(p1).left).value_real:=-trealconstnode(tbinarynode(p1).left).value_real;
  1988. p1:=cunaryminusnode.create(p1);
  1989. end
  1990. else
  1991. internalerror(20021029);
  1992. end;
  1993. end
  1994. else
  1995. begin
  1996. p1:=sub_expr(oppower,false);
  1997. p1:=cunaryminusnode.create(p1);
  1998. end;
  1999. end;
  2000. _OP_NOT :
  2001. begin
  2002. consume(_OP_NOT);
  2003. p1:=factor(false);
  2004. p1:=cnotnode.create(p1);
  2005. end;
  2006. _TRUE :
  2007. begin
  2008. consume(_TRUE);
  2009. p1:=cordconstnode.create(1,booltype,false);
  2010. end;
  2011. _FALSE :
  2012. begin
  2013. consume(_FALSE);
  2014. p1:=cordconstnode.create(0,booltype,false);
  2015. end;
  2016. _NIL :
  2017. begin
  2018. consume(_NIL);
  2019. p1:=cnilnode.create;
  2020. { It's really ugly code nil^, but delphi allows it }
  2021. if token in [_CARET] then
  2022. begin
  2023. again:=true;
  2024. postfixoperators(p1,again);
  2025. end;
  2026. end;
  2027. else
  2028. begin
  2029. p1:=cerrornode.create;
  2030. consume(token);
  2031. Message(cg_e_illegal_expression);
  2032. end;
  2033. end;
  2034. { generate error node if no node is created }
  2035. if not assigned(p1) then
  2036. begin
  2037. {$ifdef EXTDEBUG}
  2038. Comment(V_Warning,'factor: p1=nil');
  2039. {$endif}
  2040. p1:=cerrornode.create;
  2041. end;
  2042. { get the resulttype for the node }
  2043. if (not assigned(p1.resulttype.def)) then
  2044. do_resulttypepass(p1);
  2045. factor:=p1;
  2046. check_tokenpos;
  2047. end;
  2048. {$ifdef fpc}
  2049. {$maxfpuregisters default}
  2050. {$endif fpc}
  2051. {****************************************************************************
  2052. Sub_Expr
  2053. ****************************************************************************}
  2054. const
  2055. { Warning these stay be ordered !! }
  2056. operator_levels:array[Toperator_precedence] of set of Ttoken=
  2057. ([_LT,_LTE,_GT,_GTE,_EQUAL,_UNEQUAL,_OP_IN,_OP_IS],
  2058. [_PLUS,_MINUS,_OP_OR,_OP_XOR],
  2059. [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,
  2060. _OP_AS,_OP_AND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
  2061. [_STARSTAR] );
  2062. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;
  2063. {Reads a subexpression while the operators are of the current precedence
  2064. level, or any higher level. Replaces the old term, simpl_expr and
  2065. simpl2_expr.}
  2066. var
  2067. p1,p2 : tnode;
  2068. oldt : Ttoken;
  2069. filepos : tfileposinfo;
  2070. begin
  2071. if pred_level=highest_precedence then
  2072. p1:=factor(false)
  2073. else
  2074. p1:=sub_expr(succ(pred_level),true);
  2075. repeat
  2076. if (token in operator_levels[pred_level]) and
  2077. ((token<>_EQUAL) or accept_equal) then
  2078. begin
  2079. oldt:=token;
  2080. filepos:=akttokenpos;
  2081. consume(token);
  2082. if pred_level=highest_precedence then
  2083. p2:=factor(false)
  2084. else
  2085. p2:=sub_expr(succ(pred_level),true);
  2086. case oldt of
  2087. _PLUS :
  2088. p1:=caddnode.create(addn,p1,p2);
  2089. _MINUS :
  2090. p1:=caddnode.create(subn,p1,p2);
  2091. _STAR :
  2092. p1:=caddnode.create(muln,p1,p2);
  2093. _SLASH :
  2094. p1:=caddnode.create(slashn,p1,p2);
  2095. _EQUAL :
  2096. p1:=caddnode.create(equaln,p1,p2);
  2097. _GT :
  2098. p1:=caddnode.create(gtn,p1,p2);
  2099. _LT :
  2100. p1:=caddnode.create(ltn,p1,p2);
  2101. _GTE :
  2102. p1:=caddnode.create(gten,p1,p2);
  2103. _LTE :
  2104. p1:=caddnode.create(lten,p1,p2);
  2105. _SYMDIF :
  2106. p1:=caddnode.create(symdifn,p1,p2);
  2107. _STARSTAR :
  2108. p1:=caddnode.create(starstarn,p1,p2);
  2109. _OP_AS :
  2110. p1:=casnode.create(p1,p2);
  2111. _OP_IN :
  2112. p1:=cinnode.create(p1,p2);
  2113. _OP_IS :
  2114. p1:=cisnode.create(p1,p2);
  2115. _OP_OR :
  2116. p1:=caddnode.create(orn,p1,p2);
  2117. _OP_AND :
  2118. p1:=caddnode.create(andn,p1,p2);
  2119. _OP_DIV :
  2120. p1:=cmoddivnode.create(divn,p1,p2);
  2121. _OP_NOT :
  2122. p1:=cnotnode.create(p1);
  2123. _OP_MOD :
  2124. p1:=cmoddivnode.create(modn,p1,p2);
  2125. _OP_SHL :
  2126. p1:=cshlshrnode.create(shln,p1,p2);
  2127. _OP_SHR :
  2128. p1:=cshlshrnode.create(shrn,p1,p2);
  2129. _OP_XOR :
  2130. p1:=caddnode.create(xorn,p1,p2);
  2131. _ASSIGNMENT :
  2132. p1:=cassignmentnode.create(p1,p2);
  2133. _CARET :
  2134. p1:=caddnode.create(caretn,p1,p2);
  2135. _UNEQUAL :
  2136. p1:=caddnode.create(unequaln,p1,p2);
  2137. end;
  2138. p1.set_tree_filepos(filepos);
  2139. end
  2140. else
  2141. break;
  2142. until false;
  2143. sub_expr:=p1;
  2144. end;
  2145. function comp_expr(accept_equal : boolean):tnode;
  2146. var
  2147. oldafterassignment : boolean;
  2148. p1 : tnode;
  2149. begin
  2150. oldafterassignment:=afterassignment;
  2151. afterassignment:=true;
  2152. p1:=sub_expr(opcompare,accept_equal);
  2153. { get the resulttype for this expression }
  2154. if not assigned(p1.resulttype.def) then
  2155. do_resulttypepass(p1);
  2156. afterassignment:=oldafterassignment;
  2157. comp_expr:=p1;
  2158. end;
  2159. function expr : tnode;
  2160. var
  2161. p1,p2 : tnode;
  2162. oldafterassignment : boolean;
  2163. oldp1 : tnode;
  2164. filepos : tfileposinfo;
  2165. begin
  2166. oldafterassignment:=afterassignment;
  2167. p1:=sub_expr(opcompare,true);
  2168. { get the resulttype for this expression }
  2169. if not assigned(p1.resulttype.def) then
  2170. do_resulttypepass(p1);
  2171. filepos:=akttokenpos;
  2172. if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  2173. afterassignment:=true;
  2174. oldp1:=p1;
  2175. case token of
  2176. _POINTPOINT :
  2177. begin
  2178. consume(_POINTPOINT);
  2179. p2:=sub_expr(opcompare,true);
  2180. p1:=crangenode.create(p1,p2);
  2181. end;
  2182. _ASSIGNMENT :
  2183. begin
  2184. consume(_ASSIGNMENT);
  2185. if (p1.resulttype.def.deftype=procvardef) then
  2186. getprocvardef:=tprocvardef(p1.resulttype.def);
  2187. p2:=sub_expr(opcompare,true);
  2188. if assigned(getprocvardef) then
  2189. handle_procvar(getprocvardef,p2);
  2190. getprocvardef:=nil;
  2191. p1:=cassignmentnode.create(p1,p2);
  2192. end;
  2193. _PLUSASN :
  2194. begin
  2195. consume(_PLUSASN);
  2196. p2:=sub_expr(opcompare,true);
  2197. p1:=cassignmentnode.create(p1,caddnode.create(addn,p1.getcopy,p2));
  2198. end;
  2199. _MINUSASN :
  2200. begin
  2201. consume(_MINUSASN);
  2202. p2:=sub_expr(opcompare,true);
  2203. p1:=cassignmentnode.create(p1,caddnode.create(subn,p1.getcopy,p2));
  2204. end;
  2205. _STARASN :
  2206. begin
  2207. consume(_STARASN );
  2208. p2:=sub_expr(opcompare,true);
  2209. p1:=cassignmentnode.create(p1,caddnode.create(muln,p1.getcopy,p2));
  2210. end;
  2211. _SLASHASN :
  2212. begin
  2213. consume(_SLASHASN );
  2214. p2:=sub_expr(opcompare,true);
  2215. p1:=cassignmentnode.create(p1,caddnode.create(slashn,p1.getcopy,p2));
  2216. end;
  2217. end;
  2218. { get the resulttype for this expression }
  2219. if not assigned(p1.resulttype.def) then
  2220. do_resulttypepass(p1);
  2221. afterassignment:=oldafterassignment;
  2222. if p1<>oldp1 then
  2223. p1.set_tree_filepos(filepos);
  2224. expr:=p1;
  2225. end;
  2226. {$ifdef int64funcresok}
  2227. function get_intconst:TConstExprInt;
  2228. {$else int64funcresok}
  2229. function get_intconst:longint;
  2230. {$endif int64funcresok}
  2231. {Reads an expression, tries to evalute it and check if it is an integer
  2232. constant. Then the constant is returned.}
  2233. var
  2234. p:tnode;
  2235. begin
  2236. p:=comp_expr(true);
  2237. if not codegenerror then
  2238. begin
  2239. if (p.nodetype<>ordconstn) or
  2240. not(is_integer(p.resulttype.def)) then
  2241. Message(cg_e_illegal_expression)
  2242. else
  2243. get_intconst:=tordconstnode(p).value;
  2244. end;
  2245. p.free;
  2246. end;
  2247. function get_stringconst:string;
  2248. {Reads an expression, tries to evaluate it and checks if it is a string
  2249. constant. Then the constant is returned.}
  2250. var
  2251. p:tnode;
  2252. begin
  2253. get_stringconst:='';
  2254. p:=comp_expr(true);
  2255. if p.nodetype<>stringconstn then
  2256. begin
  2257. if (p.nodetype=ordconstn) and is_char(p.resulttype.def) then
  2258. get_stringconst:=char(tordconstnode(p).value)
  2259. else
  2260. Message(cg_e_illegal_expression);
  2261. end
  2262. else
  2263. get_stringconst:=strpas(tstringconstnode(p).value_str);
  2264. p.free;
  2265. end;
  2266. end.
  2267. {
  2268. $Log$
  2269. Revision 1.155 2004-05-16 15:03:48 florian
  2270. + support for assigned(<dyn. array>) added
  2271. Revision 1.154 2004/04/29 19:56:37 daniel
  2272. * Prepare compiler infrastructure for multiple ansistring types
  2273. Revision 1.153 2004/04/12 18:59:32 florian
  2274. * small x86_64 fixes
  2275. Revision 1.152 2004/03/29 14:42:52 peter
  2276. * variant array support
  2277. Revision 1.151 2004/03/23 22:34:49 peter
  2278. * constants ordinals now always have a type assigned
  2279. * integer constants have the smallest type, unsigned prefered over
  2280. signed
  2281. Revision 1.150 2004/02/20 21:55:59 peter
  2282. * procvar cleanup
  2283. Revision 1.149 2004/02/18 21:58:53 peter
  2284. * constants are now parsed as 64bit for cpu64bit
  2285. Revision 1.148 2004/02/17 23:36:40 daniel
  2286. * Make better use of try_to_consume
  2287. Revision 1.147 2004/02/17 15:57:49 peter
  2288. - fix rtti generation for properties containing sl_vec
  2289. - fix crash when overloaded operator is not available
  2290. - fix record alignment for C style variant records
  2291. Revision 1.146 2004/02/03 22:32:54 peter
  2292. * renamed xNNbittype to xNNinttype
  2293. * renamed registers32 to registersint
  2294. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  2295. Revision 1.145 2003/12/29 17:19:35 jonas
  2296. * integrated hack from 1.0.x so we can parse low(int64) as int64 instead
  2297. of as double (in 1.0.x, it was necessary for low(longint))
  2298. Revision 1.144 2003/12/08 22:35:28 peter
  2299. * again procvar fixes
  2300. Revision 1.143 2003/11/29 16:19:54 peter
  2301. * Initialize() added
  2302. Revision 1.142 2003/11/29 14:49:46 peter
  2303. * fix crash with exit() in a procedure
  2304. Revision 1.141 2003/11/29 14:33:13 peter
  2305. * typed address only used for @ and addr() that are parsed
  2306. Revision 1.140 2003/11/10 19:11:39 peter
  2307. * check paralength instead of assigned(left)
  2308. Revision 1.139 2003/11/07 15:58:32 florian
  2309. * Florian's culmutative nr. 1; contains:
  2310. - invalid calling conventions for a certain cpu are rejected
  2311. - arm softfloat calling conventions
  2312. - -Sp for cpu dependend code generation
  2313. - several arm fixes
  2314. - remaining code for value open array paras on heap
  2315. Revision 1.138 2003/11/06 15:54:32 peter
  2316. * fixed calling classmethod for other object from classmethod
  2317. Revision 1.137 2003/11/04 16:42:13 peter
  2318. * assigned(proc()) does not change the calln to loadn
  2319. Revision 1.136 2003/10/28 15:36:01 peter
  2320. * absolute to object field supported, fixes tb0458
  2321. Revision 1.135 2003/10/09 15:20:56 peter
  2322. * self is not a token anymore. It is handled special when found
  2323. in a code block and when parsing an method
  2324. Revision 1.134 2003/10/09 15:00:13 florian
  2325. * fixed constructor call in class methods
  2326. Revision 1.133 2003/10/08 19:19:45 peter
  2327. * set_varstate cleanup
  2328. Revision 1.132 2003/10/05 12:56:04 peter
  2329. * fix assigned(property)
  2330. Revision 1.131 2003/10/02 21:15:31 peter
  2331. * protected visibility fixes
  2332. Revision 1.130 2003/10/01 20:34:49 peter
  2333. * procinfo unit contains tprocinfo
  2334. * cginfo renamed to cgbase
  2335. * moved cgmessage to verbose
  2336. * fixed ppc and sparc compiles
  2337. Revision 1.129 2003/09/23 17:56:05 peter
  2338. * locals and paras are allocated in the code generation
  2339. * tvarsym.localloc contains the location of para/local when
  2340. generating code for the current procedure
  2341. Revision 1.128 2003/09/06 22:27:09 florian
  2342. * fixed web bug 2669
  2343. * cosmetic fix in printnode
  2344. * tobjectdef.gettypename implemented
  2345. Revision 1.127 2003/09/05 17:41:12 florian
  2346. * merged Wiktor's Watcom patches in 1.1
  2347. Revision 1.126 2003/08/23 22:29:51 peter
  2348. * fixed static class check for properties
  2349. Revision 1.125 2003/08/23 18:41:52 peter
  2350. * allow typeof(self) in class methods
  2351. Revision 1.124 2003/08/10 17:25:23 peter
  2352. * fixed some reported bugs
  2353. Revision 1.123 2003/06/13 21:19:31 peter
  2354. * current_procdef removed, use current_procinfo.procdef instead
  2355. Revision 1.122 2003/06/03 21:02:57 peter
  2356. * don't set nf_member when loaded from with symtable
  2357. * allow static variables in class methods
  2358. Revision 1.121 2003/05/22 17:43:21 peter
  2359. * search defaulthandler only for message methods
  2360. Revision 1.120 2003/05/15 18:58:53 peter
  2361. * removed selfpointer_offset, vmtpointer_offset
  2362. * tvarsym.adjusted_address
  2363. * address in localsymtable is now in the real direction
  2364. * removed some obsolete globals
  2365. Revision 1.119 2003/05/13 20:54:39 peter
  2366. * ifdef'd code that checked for failed inherited constructors
  2367. Revision 1.118 2003/05/13 19:14:41 peter
  2368. * failn removed
  2369. * inherited result code check moven to pexpr
  2370. Revision 1.117 2003/05/11 21:37:03 peter
  2371. * moved implicit exception frame from ncgutil to psub
  2372. * constructor/destructor helpers moved from cobj/ncgutil to psub
  2373. Revision 1.116 2003/05/11 14:45:12 peter
  2374. * tloadnode does not support objectsymtable,withsymtable anymore
  2375. * withnode cleanup
  2376. * direct with rewritten to use temprefnode
  2377. Revision 1.115 2003/05/09 17:47:03 peter
  2378. * self moved to hidden parameter
  2379. * removed hdisposen,hnewn,selfn
  2380. Revision 1.114 2003/05/01 07:59:42 florian
  2381. * introduced defaultordconsttype to decribe the default size of ordinal constants
  2382. on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
  2383. + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
  2384. * int64s/qwords are allowed as for loop counter on 64 bit CPUs
  2385. Revision 1.113 2003/04/27 11:21:33 peter
  2386. * aktprocdef renamed to current_procinfo.procdef
  2387. * procinfo renamed to current_procinfo
  2388. * procinfo will now be stored in current_module so it can be
  2389. cleaned up properly
  2390. * gen_main_procsym changed to create_main_proc and release_main_proc
  2391. to also generate a tprocinfo structure
  2392. * fixed unit implicit initfinal
  2393. Revision 1.112 2003/04/27 07:29:50 peter
  2394. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  2395. a new procdef declaration
  2396. * aktprocsym removed
  2397. * lexlevel removed, use symtable.symtablelevel instead
  2398. * implicit init/final code uses the normal genentry/genexit
  2399. * funcret state checking updated for new funcret handling
  2400. Revision 1.111 2003/04/26 00:33:07 peter
  2401. * vo_is_result flag added for the special RESULT symbol
  2402. Revision 1.110 2003/04/25 20:59:33 peter
  2403. * removed funcretn,funcretsym, function result is now in varsym
  2404. and aliases for result and function name are added using absolutesym
  2405. * vs_hidden parameter for funcret passed in parameter
  2406. * vs_hidden fixes
  2407. * writenode changed to printnode and released from extdebug
  2408. * -vp option added to generate a tree.log with the nodetree
  2409. * nicer printnode for statements, callnode
  2410. Revision 1.109 2003/04/23 10:13:55 peter
  2411. * firstaddr will check procvardef
  2412. Revision 1.108 2003/04/22 23:50:23 peter
  2413. * firstpass uses expectloc
  2414. * checks if there are differences between the expectloc and
  2415. location.loc from secondpass in EXTDEBUG
  2416. Revision 1.107 2003/04/11 15:49:01 peter
  2417. * default property also increased the reference count for the
  2418. property symbol
  2419. Revision 1.106 2003/04/11 14:50:08 peter
  2420. * fix tw2454
  2421. Revision 1.105 2003/03/27 17:44:13 peter
  2422. * fixed small mem leaks
  2423. Revision 1.104 2003/03/17 18:55:30 peter
  2424. * allow more tokens instead of only semicolon after inherited
  2425. Revision 1.103 2003/03/17 16:54:41 peter
  2426. * support DefaultHandler and anonymous inheritance fixed
  2427. for message methods
  2428. Revision 1.102 2003/01/30 21:46:57 peter
  2429. * self fixes for static methods (merged)
  2430. Revision 1.101 2003/01/16 22:12:22 peter
  2431. * Find the correct procvar to load when using @ in fpc mode
  2432. Revision 1.100 2003/01/15 01:44:32 peter
  2433. * merged methodpointer fixes from 1.0.x
  2434. Revision 1.98 2003/01/12 17:51:42 peter
  2435. * tp procvar handling fix for tb0448
  2436. Revision 1.97 2003/01/05 22:44:14 peter
  2437. * remove a lot of code to support typen in loadn-procsym
  2438. Revision 1.96 2002/12/11 22:40:36 peter
  2439. * assigned(procvar) fix for delphi mode, fixes tb0430
  2440. Revision 1.95 2002/11/30 11:12:48 carl
  2441. + checking for symbols used with hint directives is done mostly in pexpr
  2442. only now
  2443. Revision 1.94 2002/11/27 15:33:47 peter
  2444. * the never ending story of tp procvar hacks
  2445. Revision 1.93 2002/11/26 22:58:24 peter
  2446. * fix for tw2178. When a ^ or . follows a procsym then the procsym
  2447. needs to be called
  2448. Revision 1.92 2002/11/25 17:43:22 peter
  2449. * splitted defbase in defutil,symutil,defcmp
  2450. * merged isconvertable and is_equal into compare_defs(_ext)
  2451. * made operator search faster by walking the list only once
  2452. Revision 1.91 2002/11/22 22:48:10 carl
  2453. * memory optimization with tconstsym (1.5%)
  2454. Revision 1.90 2002/11/20 22:49:55 pierre
  2455. * commented check code tht was invalid in 1.1
  2456. Revision 1.89 2002/11/18 18:34:41 peter
  2457. * fix crash with EXTDEBUG code
  2458. Revision 1.88 2002/11/18 17:48:21 peter
  2459. * fix tw2209 (merged)
  2460. Revision 1.87 2002/11/18 17:31:58 peter
  2461. * pass proccalloption to ret_in_xxx and push_xxx functions
  2462. Revision 1.86 2002/10/05 00:48:57 peter
  2463. * support inherited; support for overload as it is handled by
  2464. delphi. This is only for delphi mode as it is working is
  2465. undocumented and hard to predict what is done
  2466. Revision 1.85 2002/10/04 21:13:59 peter
  2467. * ignore vecn,subscriptn when checking for a procvar loadn
  2468. Revision 1.84 2002/10/02 20:51:22 peter
  2469. * don't check interfaces for class methods
  2470. Revision 1.83 2002/10/02 18:20:52 peter
  2471. * Copy() is now internal syssym that calls compilerprocs
  2472. Revision 1.82 2002/09/30 07:00:48 florian
  2473. * fixes to common code to get the alpha compiler compiled applied
  2474. Revision 1.81 2002/09/16 19:06:14 peter
  2475. * allow ^ after nil
  2476. Revision 1.80 2002/09/07 15:25:07 peter
  2477. * old logs removed and tabs fixed
  2478. Revision 1.79 2002/09/07 12:16:03 carl
  2479. * second part bug report 1996 fix, testrange in cordconstnode
  2480. only called if option is set (also make parsing a tiny faster)
  2481. Revision 1.78 2002/09/03 16:26:27 daniel
  2482. * Make Tprocdef.defs protected
  2483. Revision 1.77 2002/08/18 20:06:24 peter
  2484. * inlining is now also allowed in interface
  2485. * renamed write/load to ppuwrite/ppuload
  2486. * tnode storing in ppu
  2487. * nld,ncon,nbas are already updated for storing in ppu
  2488. Revision 1.76 2002/08/17 09:23:39 florian
  2489. * first part of procinfo rewrite
  2490. Revision 1.75 2002/08/01 16:37:47 jonas
  2491. - removed some superfluous "in_paras := true" statements
  2492. Revision 1.74 2002/07/26 21:15:41 florian
  2493. * rewrote the system handling
  2494. Revision 1.73 2002/07/23 09:51:23 daniel
  2495. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2496. are worth comitting.
  2497. Revision 1.72 2002/07/20 11:57:55 florian
  2498. * types.pas renamed to defbase.pas because D6 contains a types
  2499. unit so this would conflicts if D6 programms are compiled
  2500. + Willamette/SSE2 instructions to assembler added
  2501. Revision 1.71 2002/07/16 15:34:20 florian
  2502. * exit is now a syssym instead of a keyword
  2503. Revision 1.70 2002/07/06 20:18:02 carl
  2504. * longstring declaration now gives parser error since its not supported!
  2505. Revision 1.69 2002/06/12 15:46:14 jonas
  2506. * fixed web bug 1995
  2507. Revision 1.68 2002/05/18 13:34:12 peter
  2508. * readded missing revisions
  2509. Revision 1.67 2002/05/16 19:46:43 carl
  2510. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2511. + try to fix temp allocation (still in ifdef)
  2512. + generic constructor calls
  2513. + start of tassembler / tmodulebase class cleanup
  2514. Revision 1.65 2002/05/12 16:53:09 peter
  2515. * moved entry and exitcode to ncgutil and cgobj
  2516. * foreach gets extra argument for passing local data to the
  2517. iterator function
  2518. * -CR checks also class typecasts at runtime by changing them
  2519. into as
  2520. * fixed compiler to cycle with the -CR option
  2521. * fixed stabs with elf writer, finally the global variables can
  2522. be watched
  2523. * removed a lot of routines from cga unit and replaced them by
  2524. calls to cgobj
  2525. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2526. u32bit then the other is typecasted also to u32bit without giving
  2527. a rangecheck warning/error.
  2528. * fixed pascal calling method with reversing also the high tree in
  2529. the parast, detected by tcalcst3 test
  2530. Revision 1.64 2002/04/23 19:16:34 peter
  2531. * add pinline unit that inserts compiler supported functions using
  2532. one or more statements
  2533. * moved finalize and setlength from ninl to pinline
  2534. Revision 1.63 2002/04/21 19:02:05 peter
  2535. * removed newn and disposen nodes, the code is now directly
  2536. inlined from pexpr
  2537. * -an option that will write the secondpass nodes to the .s file, this
  2538. requires EXTDEBUG define to actually write the info
  2539. * fixed various internal errors and crashes due recent code changes
  2540. Revision 1.62 2002/04/16 16:11:17 peter
  2541. * using inherited; without a parent having the same function
  2542. will do nothing like delphi
  2543. Revision 1.61 2002/04/07 13:31:36 carl
  2544. + change unit use
  2545. Revision 1.60 2002/04/01 20:57:13 jonas
  2546. * fixed web bug 1907
  2547. * fixed some other procvar related bugs (all related to accepting procvar
  2548. constructs with either too many or too little parameters)
  2549. (both merged, includes second typo fix of pexpr.pas)
  2550. Revision 1.59 2002/03/31 20:26:35 jonas
  2551. + a_loadfpu_* and a_loadmm_* methods in tcg
  2552. * register allocation is now handled by a class and is mostly processor
  2553. independent (+rgobj.pas and i386/rgcpu.pas)
  2554. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  2555. * some small improvements and fixes to the optimizer
  2556. * some register allocation fixes
  2557. * some fpuvaroffset fixes in the unary minus node
  2558. * push/popusedregisters is now called rg.save/restoreusedregisters and
  2559. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  2560. also better optimizable)
  2561. * fixed and optimized register saving/restoring for new/dispose nodes
  2562. * LOC_FPU locations now also require their "register" field to be set to
  2563. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  2564. - list field removed of the tnode class because it's not used currently
  2565. and can cause hard-to-find bugs
  2566. }