pexpr.pas 102 KB

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