pexpr.pas 99 KB

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