pexpr.pas 105 KB

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