pexpr.pas 102 KB

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