pexpr.pas 101 KB

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