pexpr.pas 104 KB

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