pexpr.pas 101 KB

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