pexpr.pas 99 KB

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