pexpr.pas 101 KB

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