pexpr.pas 103 KB

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