ncal.pas 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This file implements the node for sub procedure calling.
  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 ncal;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cutils,cclasses,
  23. globtype,cpuinfo,
  24. node,
  25. {$ifdef state_tracking}
  26. nstate,
  27. {$endif state_tracking}
  28. symbase,symtype,symppu,symsym,symdef,symtable;
  29. type
  30. pcandidate = ^tcandidate;
  31. tcandidate = record
  32. next : pcandidate;
  33. data : tprocdef;
  34. wrongpara,
  35. firstpara : tparaitem;
  36. exact_count,
  37. equal_count,
  38. cl1_count,
  39. cl2_count,
  40. cl3_count,
  41. coper_count : integer; { should be signed }
  42. ordinal_distance : bestreal;
  43. invalid : boolean;
  44. wrongparanr : byte;
  45. end;
  46. tcallnode = class(tbinarynode)
  47. private
  48. paralength : smallint;
  49. function candidates_find:pcandidate;
  50. procedure candidates_free(procs:pcandidate);
  51. procedure candidates_list(procs:pcandidate;all:boolean);
  52. procedure candidates_get_information(procs:pcandidate);
  53. function candidates_choose_best(procs:pcandidate;var bestpd:tprocdef):integer;
  54. procedure candidates_find_wrong_para(procs:pcandidate);
  55. {$ifdef EXTDEBUG}
  56. procedure candidates_dump_info(lvl:longint;procs:pcandidate);
  57. {$endif EXTDEBUG}
  58. public
  59. { the symbol containing the definition of the procedure }
  60. { to call }
  61. symtableprocentry : tprocsym;
  62. { symtable where the entry was found, needed for with support }
  63. symtableproc : tsymtable;
  64. { the definition of the procedure to call }
  65. procdefinition : tabstractprocdef;
  66. methodpointer : tnode;
  67. { separately specified resulttype for some compilerprocs (e.g. }
  68. { you can't have a function with an "array of char" resulttype }
  69. { the RTL) (JM) }
  70. restype: ttype;
  71. restypeset: boolean;
  72. { function return reference node, this is used to pass an already
  73. allocated reference for a ret_in_param return value }
  74. funcretrefnode : tnode;
  75. { only the processor specific nodes need to override this }
  76. { constructor }
  77. constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
  78. constructor createintern(const name: string; params: tnode);
  79. constructor createinternres(const name: string; params: tnode; const res: ttype);
  80. constructor createinternreturn(const name: string; params: tnode; returnnode : tnode);
  81. destructor destroy;override;
  82. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  83. procedure ppuwrite(ppufile:tcompilerppufile);override;
  84. procedure derefimpl;override;
  85. function getcopy : tnode;override;
  86. { Goes through all symbols in a class and subclasses and calls
  87. verify abstract for each .
  88. }
  89. procedure verifyabstractcalls;
  90. { called for each definition in a class and verifies if a method
  91. is abstract or not, if it is abstract, give out a warning
  92. }
  93. procedure verifyabstract(p : tnamedindexitem;arg:pointer);
  94. procedure insertintolist(l : tnodelist);override;
  95. function pass_1 : tnode;override;
  96. function det_resulttype:tnode;override;
  97. {$ifdef state_tracking}
  98. function track_state_pass(exec_known:boolean):boolean;override;
  99. {$endif state_tracking}
  100. function docompare(p: tnode): boolean; override;
  101. procedure set_procvar(procvar:tnode);
  102. private
  103. AbstractMethodsList : TStringList;
  104. end;
  105. tcallnodeclass = class of tcallnode;
  106. tcallparaflags = (
  107. { flags used by tcallparanode }
  108. cpf_exact_match_found,
  109. cpf_convlevel1found,
  110. cpf_convlevel2found,
  111. cpf_is_colon_para
  112. );
  113. tcallparanode = class(tbinarynode)
  114. callparaflags : set of tcallparaflags;
  115. paraitem : tparaitem;
  116. {$ifndef VS_HIDDEN}
  117. hightree : tnode;
  118. {$endif VS_HIDDEN}
  119. { only the processor specific nodes need to override this }
  120. { constructor }
  121. constructor create(expr,next : tnode);virtual;
  122. destructor destroy;override;
  123. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  124. procedure ppuwrite(ppufile:tcompilerppufile);override;
  125. procedure derefimpl;override;
  126. function getcopy : tnode;override;
  127. procedure insertintolist(l : tnodelist);override;
  128. procedure gen_high_tree(openstring:boolean);
  129. procedure get_paratype;
  130. procedure insert_typeconv(defcoll : tparaitem;do_count : boolean);
  131. procedure det_registers;
  132. procedure firstcallparan(do_count : boolean);
  133. procedure secondcallparan(push_from_left_to_right:boolean;calloption:tproccalloption;
  134. para_alignment,para_offset : longint);virtual;abstract;
  135. function docompare(p: tnode): boolean; override;
  136. end;
  137. tcallparanodeclass = class of tcallparanode;
  138. tprocinlinenode = class(tnode)
  139. inlinetree : tnode;
  140. inlineprocdef : tprocdef;
  141. retoffset,para_offset,para_size : longint;
  142. constructor create(p:tprocdef);virtual;
  143. destructor destroy;override;
  144. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  145. procedure ppuwrite(ppufile:tcompilerppufile);override;
  146. procedure derefimpl;override;
  147. function getcopy : tnode;override;
  148. function det_resulttype : tnode;override;
  149. procedure insertintolist(l : tnodelist);override;
  150. function pass_1 : tnode;override;
  151. function docompare(p: tnode): boolean; override;
  152. end;
  153. tprocinlinenodeclass = class of tprocinlinenode;
  154. function reverseparameters(p: tcallparanode): tcallparanode;
  155. var
  156. ccallnode : tcallnodeclass;
  157. ccallparanode : tcallparanodeclass;
  158. cprocinlinenode : tprocinlinenodeclass;
  159. implementation
  160. uses
  161. systems,
  162. verbose,globals,
  163. symconst,paramgr,defutil,defcmp,
  164. htypechk,pass_1,cpubase,
  165. nbas,ncnv,nld,ninl,nadd,ncon,nmem,
  166. rgobj,cgbase
  167. ;
  168. type
  169. tobjectinfoitem = class(tlinkedlistitem)
  170. objinfo : tobjectdef;
  171. constructor create(def : tobjectdef);
  172. end;
  173. {****************************************************************************
  174. HELPERS
  175. ****************************************************************************}
  176. function reverseparameters(p: tcallparanode): tcallparanode;
  177. var
  178. hp1, hp2: tcallparanode;
  179. begin
  180. hp1:=nil;
  181. while assigned(p) do
  182. begin
  183. { pull out }
  184. hp2:=p;
  185. p:=tcallparanode(p.right);
  186. { pull in }
  187. hp2.right:=hp1;
  188. hp1:=hp2;
  189. end;
  190. reverseparameters:=hp1;
  191. end;
  192. procedure search_class_overloads(aprocsym : tprocsym);
  193. { searches n in symtable of pd and all anchestors }
  194. var
  195. speedvalue : cardinal;
  196. srsym : tprocsym;
  197. s : string;
  198. objdef : tobjectdef;
  199. begin
  200. if aprocsym.overloadchecked then
  201. exit;
  202. aprocsym.overloadchecked:=true;
  203. if (aprocsym.owner.symtabletype<>objectsymtable) then
  204. internalerror(200111021);
  205. objdef:=tobjectdef(aprocsym.owner.defowner);
  206. { we start in the parent }
  207. if not assigned(objdef.childof) then
  208. exit;
  209. objdef:=objdef.childof;
  210. s:=aprocsym.name;
  211. speedvalue:=getspeedvalue(s);
  212. while assigned(objdef) do
  213. begin
  214. srsym:=tprocsym(objdef.symtable.speedsearch(s,speedvalue));
  215. if assigned(srsym) then
  216. begin
  217. if (srsym.typ<>procsym) then
  218. internalerror(200111022);
  219. if srsym.is_visible_for_proc(aktprocdef) then
  220. begin
  221. srsym.add_para_match_to(Aprocsym);
  222. { we can stop if the overloads were already added
  223. for the found symbol }
  224. if srsym.overloadchecked then
  225. break;
  226. end;
  227. end;
  228. { next parent }
  229. objdef:=objdef.childof;
  230. end;
  231. end;
  232. function is_better_candidate(currpd,bestpd:pcandidate):integer;
  233. var
  234. res : integer;
  235. begin
  236. {
  237. Return values:
  238. > 0 when currpd is better than bestpd
  239. < 0 when bestpd is better than currpd
  240. = 0 when both are equal
  241. To choose the best candidate we use the following order:
  242. - Incompatible flag
  243. - (Smaller) Number of convert operator parameters.
  244. - (Smaller) Number of convertlevel 2 parameters.
  245. - (Smaller) Number of convertlevel 1 parameters.
  246. - (Bigger) Number of exact parameters.
  247. - (Smaller) Number of equal parameters.
  248. - (Smaller) Total of ordinal distance. For example, the distance of a word
  249. to a byte is 65535-255=65280.
  250. }
  251. if bestpd^.invalid then
  252. begin
  253. if currpd^.invalid then
  254. res:=0
  255. else
  256. res:=1;
  257. end
  258. else
  259. if currpd^.invalid then
  260. res:=-1
  261. else
  262. begin
  263. { less operator parameters? }
  264. res:=(bestpd^.coper_count-currpd^.coper_count);
  265. if (res=0) then
  266. begin
  267. { less cl3 parameters? }
  268. res:=(bestpd^.cl3_count-currpd^.cl3_count);
  269. if (res=0) then
  270. begin
  271. { less cl2 parameters? }
  272. res:=(bestpd^.cl2_count-currpd^.cl2_count);
  273. if (res=0) then
  274. begin
  275. { less cl1 parameters? }
  276. res:=(bestpd^.cl1_count-currpd^.cl1_count);
  277. if (res=0) then
  278. begin
  279. { more exact parameters? }
  280. res:=(currpd^.exact_count-bestpd^.exact_count);
  281. if (res=0) then
  282. begin
  283. { less equal parameters? }
  284. res:=(bestpd^.equal_count-currpd^.equal_count);
  285. if (res=0) then
  286. begin
  287. { smaller ordinal distance? }
  288. if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
  289. res:=1
  290. else
  291. if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
  292. res:=-1
  293. else
  294. res:=0;
  295. end;
  296. end;
  297. end;
  298. end;
  299. end;
  300. end;
  301. end;
  302. is_better_candidate:=res;
  303. end;
  304. procedure var_para_allowed(var eq:tequaltype;def_from,def_to:Tdef);
  305. begin
  306. { Note: eq must be already valid, it will only be updated! }
  307. case def_to.deftype of
  308. formaldef :
  309. begin
  310. { all types can be passed to a formaldef }
  311. eq:=te_equal;
  312. end;
  313. orddef :
  314. begin
  315. { allows conversion from word to integer and
  316. byte to shortint, but only for TP7 compatibility }
  317. if (m_tp7 in aktmodeswitches) and
  318. (def_from.deftype=orddef) and
  319. (def_from.size=def_to.size) then
  320. eq:=te_convert_l1;
  321. end;
  322. pointerdef :
  323. begin
  324. { an implicit pointer conversion is allowed }
  325. if (def_from.deftype=pointerdef) then
  326. eq:=te_convert_l1;
  327. end;
  328. stringdef :
  329. begin
  330. { all shortstrings are allowed, size is not important }
  331. if is_shortstring(def_from) and
  332. is_shortstring(def_to) then
  333. eq:=te_equal;
  334. end;
  335. objectdef :
  336. begin
  337. { child objects can be also passed }
  338. { in non-delphi mode, otherwise }
  339. { they must match exactly, except }
  340. { if they are objects }
  341. if (def_from.deftype=objectdef) and
  342. (
  343. not(m_delphi in aktmodeswitches) or
  344. (
  345. (tobjectdef(def_from).objecttype=odt_object) and
  346. (tobjectdef(def_to).objecttype=odt_object)
  347. )
  348. ) and
  349. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  350. eq:=te_convert_l1;
  351. end;
  352. filedef :
  353. begin
  354. { an implicit file conversion is also allowed }
  355. { from a typed file to an untyped one }
  356. if (def_from.deftype=filedef) and
  357. (tfiledef(def_from).filetyp = ft_typed) and
  358. (tfiledef(def_to).filetyp = ft_untyped) then
  359. eq:=te_convert_l1;
  360. end;
  361. end;
  362. end;
  363. procedure para_allowed(var eq:tequaltype;p:tcallparanode;def_to:tdef);
  364. begin
  365. { Note: eq must be already valid, it will only be updated! }
  366. case def_to.deftype of
  367. formaldef :
  368. begin
  369. { all types can be passed to a formaldef }
  370. eq:=te_equal;
  371. end;
  372. stringdef :
  373. begin
  374. { to support ansi/long/wide strings in a proper way }
  375. { string and string[10] are assumed as equal }
  376. { when searching the correct overloaded procedure }
  377. if (p.resulttype.def.deftype=stringdef) and
  378. (tstringdef(def_to).string_typ=tstringdef(p.resulttype.def).string_typ) then
  379. eq:=te_equal
  380. else
  381. { Passing a constant char to ansistring or shortstring or
  382. a widechar to widestring then handle it as equal. }
  383. if (p.left.nodetype=ordconstn) and
  384. (
  385. is_char(p.resulttype.def) and
  386. (is_shortstring(def_to) or is_ansistring(def_to))
  387. ) or
  388. (
  389. is_widechar(p.resulttype.def) and
  390. is_widestring(def_to)
  391. ) then
  392. eq:=te_equal
  393. end;
  394. setdef :
  395. begin
  396. { set can also be a not yet converted array constructor }
  397. if (p.resulttype.def.deftype=arraydef) and
  398. (tarraydef(p.resulttype.def).IsConstructor) and
  399. not(tarraydef(p.resulttype.def).IsVariant) then
  400. eq:=te_equal;
  401. end;
  402. procvardef :
  403. begin
  404. { in tp7 mode proc -> procvar is allowed }
  405. if (m_tp_procvar in aktmodeswitches) and
  406. (p.left.nodetype=calln) and
  407. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def_to),true)>=te_equal) then
  408. eq:=te_equal;
  409. end;
  410. end;
  411. end;
  412. {****************************************************************************
  413. TOBJECTINFOITEM
  414. ****************************************************************************}
  415. constructor tobjectinfoitem.create(def : tobjectdef);
  416. begin
  417. inherited create;
  418. objinfo := def;
  419. end;
  420. {****************************************************************************
  421. TCALLPARANODE
  422. ****************************************************************************}
  423. constructor tcallparanode.create(expr,next : tnode);
  424. begin
  425. inherited create(callparan,expr,next);
  426. {$ifndef VS_HIDDEN}
  427. hightree:=nil;
  428. {$endif VS_HIDDEN}
  429. if assigned(expr) then
  430. expr.set_file_line(self);
  431. callparaflags:=[];
  432. end;
  433. destructor tcallparanode.destroy;
  434. begin
  435. {$ifndef VS_HIDDEN}
  436. hightree.free;
  437. {$endif VS_HIDDEN}
  438. inherited destroy;
  439. end;
  440. constructor tcallparanode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  441. begin
  442. inherited ppuload(t,ppufile);
  443. ppufile.getsmallset(callparaflags);
  444. {$ifndef VS_HIDDEN}
  445. hightree:=ppuloadnode(ppufile);
  446. {$endif VS_HIDDEN}
  447. end;
  448. procedure tcallparanode.ppuwrite(ppufile:tcompilerppufile);
  449. begin
  450. inherited ppuwrite(ppufile);
  451. ppufile.putsmallset(callparaflags);
  452. {$ifndef VS_HIDDEN}
  453. ppuwritenode(ppufile,hightree);
  454. {$endif VS_HIDDEN}
  455. end;
  456. procedure tcallparanode.derefimpl;
  457. begin
  458. inherited derefimpl;
  459. {$ifndef VS_HIDDEN}
  460. if assigned(hightree) then
  461. hightree.derefimpl;
  462. {$endif VS_HIDDEN}
  463. end;
  464. function tcallparanode.getcopy : tnode;
  465. var
  466. n : tcallparanode;
  467. begin
  468. n:=tcallparanode(inherited getcopy);
  469. n.callparaflags:=callparaflags;
  470. {$ifndef VS_HIDDEN}
  471. if assigned(hightree) then
  472. n.hightree:=hightree.getcopy
  473. else
  474. n.hightree:=nil;
  475. {$endif VS_HIDDEN}
  476. n.paraitem:=paraitem;
  477. result:=n;
  478. end;
  479. procedure tcallparanode.insertintolist(l : tnodelist);
  480. begin
  481. end;
  482. procedure tcallparanode.get_paratype;
  483. var
  484. old_get_para_resulttype : boolean;
  485. old_array_constructor : boolean;
  486. begin
  487. inc(parsing_para_level);
  488. if assigned(right) then
  489. tcallparanode(right).get_paratype;
  490. old_array_constructor:=allow_array_constructor;
  491. old_get_para_resulttype:=get_para_resulttype;
  492. get_para_resulttype:=true;
  493. allow_array_constructor:=true;
  494. resulttypepass(left);
  495. get_para_resulttype:=old_get_para_resulttype;
  496. allow_array_constructor:=old_array_constructor;
  497. if codegenerror then
  498. resulttype:=generrortype
  499. else
  500. resulttype:=left.resulttype;
  501. dec(parsing_para_level);
  502. end;
  503. procedure tcallparanode.insert_typeconv(defcoll : tparaitem;do_count : boolean);
  504. var
  505. oldtype : ttype;
  506. {$ifdef extdebug}
  507. store_count_ref : boolean;
  508. {$endif def extdebug}
  509. begin
  510. inc(parsing_para_level);
  511. paraitem:=defcoll;
  512. if not assigned(paraitem) then
  513. internalerror(200104261);
  514. {$ifdef extdebug}
  515. if do_count then
  516. begin
  517. store_count_ref:=count_ref;
  518. count_ref:=true;
  519. end;
  520. {$endif def extdebug}
  521. if assigned(right) then
  522. begin
  523. { if we are a para that belongs to varargs then keep
  524. the current paraitem }
  525. if (nf_varargs_para in flags) then
  526. tcallparanode(right).insert_typeconv(paraitem,do_count)
  527. else
  528. tcallparanode(right).insert_typeconv(tparaitem(paraitem.next),do_count)
  529. end;
  530. { Be sure to have the resulttype }
  531. if not assigned(left.resulttype.def) then
  532. resulttypepass(left);
  533. { Handle varargs and hidden paras directly, no typeconvs or }
  534. { typechecking needed }
  535. if (nf_varargs_para in flags) or
  536. (paraitem.paratyp = vs_hidden) then
  537. begin
  538. if (paraitem.paratyp <> vs_hidden) then
  539. begin
  540. { convert pascal to C types }
  541. case left.resulttype.def.deftype of
  542. stringdef :
  543. inserttypeconv(left,charpointertype);
  544. floatdef :
  545. inserttypeconv(left,s64floattype);
  546. end;
  547. end;
  548. set_varstate(left,true);
  549. resulttype:=left.resulttype;
  550. dec(parsing_para_level);
  551. exit;
  552. end;
  553. { Do we need arrayconstructor -> set conversion, then insert
  554. it here before the arrayconstructor node breaks the tree
  555. with its conversions of enum->ord }
  556. if (left.nodetype=arrayconstructorn) and
  557. (paraitem.paratype.def.deftype=setdef) then
  558. inserttypeconv(left,paraitem.paratype);
  559. { set some settings needed for arrayconstructor }
  560. if is_array_constructor(left.resulttype.def) then
  561. begin
  562. if is_array_of_const(paraitem.paratype.def) then
  563. begin
  564. if assigned(aktcallprocdef) and
  565. (aktcallprocdef.proccalloption in [pocall_cppdecl,pocall_cdecl]) then
  566. include(left.flags,nf_cargs);
  567. { force variant array }
  568. include(left.flags,nf_forcevaria);
  569. end
  570. else
  571. begin
  572. include(left.flags,nf_novariaallowed);
  573. { now that the resultting type is know we can insert the required
  574. typeconvs for the array constructor }
  575. tarrayconstructornode(left).force_type(tarraydef(paraitem.paratype.def).elementtype);
  576. end;
  577. end;
  578. { check if local proc/func is assigned to procvar }
  579. if left.resulttype.def.deftype=procvardef then
  580. test_local_to_procvar(tprocvardef(left.resulttype.def),paraitem.paratype.def);
  581. { generate the high() value tree }
  582. if paramanager.push_high_param(paraitem.paratype.def,aktcallprocdef.proccalloption) then
  583. gen_high_tree(is_open_string(paraitem.paratype.def));
  584. { test conversions }
  585. if not(is_shortstring(left.resulttype.def) and
  586. is_shortstring(paraitem.paratype.def)) and
  587. (paraitem.paratype.def.deftype<>formaldef) then
  588. begin
  589. { Process open parameters }
  590. if paramanager.push_high_param(paraitem.paratype.def,aktcallprocdef.proccalloption) then
  591. begin
  592. { insert type conv but hold the ranges of the array }
  593. oldtype:=left.resulttype;
  594. inserttypeconv(left,paraitem.paratype);
  595. left.resulttype:=oldtype;
  596. end
  597. else
  598. begin
  599. { for ordinals, floats and enums, verify if we might cause
  600. some range-check errors. }
  601. if (left.resulttype.def.deftype in [enumdef,orddef,floatdef]) and
  602. (left.nodetype in [vecn,loadn,calln]) then
  603. begin
  604. if (left.resulttype.def.size>paraitem.paratype.def.size) then
  605. begin
  606. if (cs_check_range in aktlocalswitches) then
  607. Message(type_w_smaller_possible_range_check)
  608. else
  609. Message(type_h_smaller_possible_range_check);
  610. end;
  611. end;
  612. inserttypeconv(left,paraitem.paratype);
  613. end;
  614. if codegenerror then
  615. begin
  616. dec(parsing_para_level);
  617. exit;
  618. end;
  619. end;
  620. { check var strings }
  621. if (cs_strict_var_strings in aktlocalswitches) and
  622. is_shortstring(left.resulttype.def) and
  623. is_shortstring(paraitem.paratype.def) and
  624. (paraitem.paratyp in [vs_out,vs_var]) and
  625. not(is_open_string(paraitem.paratype.def)) and
  626. not(equal_defs(left.resulttype.def,paraitem.paratype.def)) then
  627. begin
  628. aktfilepos:=left.fileinfo;
  629. CGMessage(type_e_strict_var_string_violation);
  630. end;
  631. { Handle formal parameters separate }
  632. if (paraitem.paratype.def.deftype=formaldef) then
  633. begin
  634. { load procvar if a procedure is passed }
  635. if (m_tp_procvar in aktmodeswitches) and
  636. (left.nodetype=calln) and
  637. (is_void(left.resulttype.def)) then
  638. load_procvar_from_calln(left);
  639. case paraitem.paratyp of
  640. vs_var,
  641. vs_out :
  642. begin
  643. if not valid_for_formal_var(left) then
  644. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  645. end;
  646. vs_const :
  647. begin
  648. if not valid_for_formal_const(left) then
  649. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  650. end;
  651. end;
  652. end
  653. else
  654. begin
  655. { check if the argument is allowed }
  656. if (paraitem.paratyp in [vs_out,vs_var]) then
  657. valid_for_var(left);
  658. end;
  659. if paraitem.paratyp in [vs_var,vs_const] then
  660. begin
  661. { Causes problems with const ansistrings if also }
  662. { done for vs_const (JM) }
  663. if paraitem.paratyp = vs_var then
  664. set_unique(left);
  665. make_not_regable(left);
  666. end;
  667. { ansistrings out paramaters doesn't need to be }
  668. { unique, they are finalized }
  669. if paraitem.paratyp=vs_out then
  670. make_not_regable(left);
  671. if do_count then
  672. begin
  673. { not completly proper, but avoids some warnings }
  674. if (paraitem.paratyp in [vs_var,vs_out]) then
  675. set_funcret_is_valid(left);
  676. set_varstate(left,not(paraitem.paratyp in [vs_var,vs_out]));
  677. end;
  678. { must only be done after typeconv PM }
  679. resulttype:=paraitem.paratype;
  680. dec(parsing_para_level);
  681. {$ifdef extdebug}
  682. if do_count then
  683. count_ref:=store_count_ref;
  684. {$endif def extdebug}
  685. end;
  686. procedure tcallparanode.det_registers;
  687. var
  688. old_get_para_resulttype : boolean;
  689. old_array_constructor : boolean;
  690. begin
  691. if assigned(right) then
  692. begin
  693. tcallparanode(right).det_registers;
  694. registers32:=right.registers32;
  695. registersfpu:=right.registersfpu;
  696. {$ifdef SUPPORT_MMX}
  697. registersmmx:=right.registersmmx;
  698. {$endif}
  699. end;
  700. old_array_constructor:=allow_array_constructor;
  701. old_get_para_resulttype:=get_para_resulttype;
  702. get_para_resulttype:=true;
  703. allow_array_constructor:=true;
  704. firstpass(left);
  705. get_para_resulttype:=old_get_para_resulttype;
  706. allow_array_constructor:=old_array_constructor;
  707. if left.registers32>registers32 then
  708. registers32:=left.registers32;
  709. if left.registersfpu>registersfpu then
  710. registersfpu:=left.registersfpu;
  711. {$ifdef SUPPORT_MMX}
  712. if left.registersmmx>registersmmx then
  713. registersmmx:=left.registersmmx;
  714. {$endif SUPPORT_MMX}
  715. end;
  716. procedure tcallparanode.firstcallparan(do_count : boolean);
  717. begin
  718. if not assigned(left.resulttype.def) then
  719. begin
  720. get_paratype;
  721. {
  722. if assigned(defcoll) then
  723. insert_typeconv(defcoll,do_count);
  724. }
  725. end;
  726. det_registers;
  727. end;
  728. {$ifdef VS_HIDDEN}
  729. procedure tcallparanode.gen_high_tree(openstring:boolean);
  730. var
  731. temp: tnode;
  732. len : integer;
  733. loadconst : boolean;
  734. hightree : tnode;
  735. begin
  736. { if assigned(hightree) then
  737. exit;
  738. }
  739. if (nf_hightree_generated in flags) then
  740. exit;
  741. len:=-1;
  742. loadconst:=true;
  743. case left.resulttype.def.deftype of
  744. arraydef :
  745. begin
  746. { handle via a normal inline in_high_x node }
  747. loadconst := false;
  748. hightree := geninlinenode(in_high_x,false,left.getcopy);
  749. { only substract low(array) if it's <> 0 }
  750. temp := geninlinenode(in_low_x,false,left.getcopy);
  751. firstpass(temp);
  752. if (temp.nodetype <> ordconstn) or
  753. (tordconstnode(temp).value <> 0) then
  754. hightree := caddnode.create(subn,hightree,temp)
  755. else
  756. temp.free;
  757. end;
  758. stringdef :
  759. begin
  760. if openstring then
  761. begin
  762. { handle via a normal inline in_high_x node }
  763. loadconst := false;
  764. hightree := geninlinenode(in_high_x,false,left.getcopy);
  765. end
  766. else
  767. { passing a string to an array of char }
  768. begin
  769. if (left.nodetype=stringconstn) then
  770. begin
  771. len:=str_length(left);
  772. if len>0 then
  773. dec(len);
  774. end
  775. else
  776. begin
  777. hightree:=caddnode.create(subn,geninlinenode(in_length_x,false,left.getcopy),
  778. cordconstnode.create(1,s32bittype,false));
  779. loadconst:=false;
  780. end;
  781. end;
  782. end;
  783. else
  784. len:=0;
  785. end;
  786. if loadconst then
  787. hightree:=cordconstnode.create(len,s32bittype,true)
  788. else
  789. hightree:=ctypeconvnode.create(hightree,s32bittype);
  790. temp:=ccallparanode.create(hightree,right);
  791. right:=temp;
  792. if (tparaitem(paraitem.next).paratyp <> vs_hidden) then
  793. internalerror(200304071);
  794. tcallparanode(right).paraitem := tparaitem(paraitem.next);
  795. tcallparanode(right).firstcallparan(false);
  796. include(flags,nf_hightree_generated);
  797. end;
  798. {$else VS_HIDDEN}
  799. procedure tcallparanode.gen_high_tree(openstring:boolean);
  800. var
  801. temp: tnode;
  802. len : integer;
  803. loadconst : boolean;
  804. begin
  805. if assigned(hightree) then
  806. exit;
  807. len:=-1;
  808. loadconst:=true;
  809. case left.resulttype.def.deftype of
  810. arraydef :
  811. begin
  812. { handle via a normal inline in_high_x node }
  813. loadconst := false;
  814. hightree := geninlinenode(in_high_x,false,left.getcopy);
  815. { only substract low(array) if it's <> 0 }
  816. temp := geninlinenode(in_low_x,false,left.getcopy);
  817. firstpass(temp);
  818. if (temp.nodetype <> ordconstn) or
  819. (tordconstnode(temp).value <> 0) then
  820. hightree := caddnode.create(subn,hightree,temp)
  821. else
  822. temp.free;
  823. end;
  824. stringdef :
  825. begin
  826. if openstring then
  827. begin
  828. { handle via a normal inline in_high_x node }
  829. loadconst := false;
  830. hightree := geninlinenode(in_high_x,false,left.getcopy);
  831. end
  832. else
  833. { passing a string to an array of char }
  834. begin
  835. if (left.nodetype=stringconstn) then
  836. begin
  837. len:=str_length(left);
  838. if len>0 then
  839. dec(len);
  840. end
  841. else
  842. begin
  843. hightree:=caddnode.create(subn,geninlinenode(in_length_x,false,left.getcopy),
  844. cordconstnode.create(1,s32bittype,false));
  845. loadconst:=false;
  846. end;
  847. end;
  848. end;
  849. else
  850. len:=0;
  851. end;
  852. if loadconst then
  853. hightree:=cordconstnode.create(len,s32bittype,true)
  854. else
  855. hightree:=ctypeconvnode.create(hightree,s32bittype);
  856. firstpass(hightree);
  857. end;
  858. {$endif VS_HIDDEN}
  859. function tcallparanode.docompare(p: tnode): boolean;
  860. begin
  861. docompare :=
  862. inherited docompare(p) and
  863. (callparaflags = tcallparanode(p).callparaflags)
  864. {$ifndef VS_HIDDEN}
  865. and hightree.isequal(tcallparanode(p).hightree)
  866. {$endif VS_HIDDEN}
  867. ;
  868. end;
  869. {****************************************************************************
  870. TCALLNODE
  871. ****************************************************************************}
  872. constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
  873. begin
  874. inherited create(calln,l,nil);
  875. symtableprocentry:=v;
  876. symtableproc:=st;
  877. include(flags,nf_return_value_used);
  878. methodpointer:=mp;
  879. procdefinition:=nil;
  880. restypeset := false;
  881. funcretrefnode:=nil;
  882. paralength:=-1;
  883. end;
  884. constructor tcallnode.createintern(const name: string; params: tnode);
  885. var
  886. srsym: tsym;
  887. symowner: tsymtable;
  888. begin
  889. if not (cs_compilesystem in aktmoduleswitches) then
  890. begin
  891. srsym := searchsymonlyin(systemunit,name);
  892. symowner := systemunit;
  893. end
  894. else
  895. begin
  896. searchsym(name,srsym,symowner);
  897. if not assigned(srsym) then
  898. searchsym(upper(name),srsym,symowner);
  899. end;
  900. if not assigned(srsym) or
  901. (srsym.typ <> procsym) then
  902. begin
  903. {$ifdef EXTDEBUG}
  904. Comment(V_Error,'unknown compilerproc '+name);
  905. {$endif EXTDEBUG}
  906. internalerror(200107271);
  907. end;
  908. self.create(params,tprocsym(srsym),symowner,nil);
  909. end;
  910. constructor tcallnode.createinternres(const name: string; params: tnode; const res: ttype);
  911. begin
  912. self.createintern(name,params);
  913. restype := res;
  914. restypeset := true;
  915. { both the normal and specified resulttype either have to be returned via a }
  916. { parameter or not, but no mixing (JM) }
  917. if paramanager.ret_in_param(restype.def,pocall_compilerproc) xor
  918. paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def,symtableprocentry.first_procdef.proccalloption) then
  919. internalerror(200108291);
  920. end;
  921. constructor tcallnode.createinternreturn(const name: string; params: tnode; returnnode : tnode);
  922. begin
  923. self.createintern(name,params);
  924. funcretrefnode:=returnnode;
  925. if not paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def,symtableprocentry.first_procdef.proccalloption) then
  926. internalerror(200204247);
  927. end;
  928. destructor tcallnode.destroy;
  929. begin
  930. methodpointer.free;
  931. funcretrefnode.free;
  932. inherited destroy;
  933. end;
  934. constructor tcallnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  935. begin
  936. inherited ppuload(t,ppufile);
  937. symtableprocentry:=tprocsym(ppufile.getderef);
  938. {$ifdef fpc}
  939. {$warning FIXME: No withsymtable support}
  940. {$endif}
  941. symtableproc:=nil;
  942. procdefinition:=tprocdef(ppufile.getderef);
  943. restypeset:=boolean(ppufile.getbyte);
  944. methodpointer:=ppuloadnode(ppufile);
  945. funcretrefnode:=ppuloadnode(ppufile);
  946. end;
  947. procedure tcallnode.ppuwrite(ppufile:tcompilerppufile);
  948. begin
  949. inherited ppuwrite(ppufile);
  950. ppufile.putderef(symtableprocentry);
  951. ppufile.putderef(procdefinition);
  952. ppufile.putbyte(byte(restypeset));
  953. ppuwritenode(ppufile,methodpointer);
  954. ppuwritenode(ppufile,funcretrefnode);
  955. end;
  956. procedure tcallnode.derefimpl;
  957. begin
  958. inherited derefimpl;
  959. resolvesym(pointer(symtableprocentry));
  960. symtableproc:=symtableprocentry.owner;
  961. resolvedef(pointer(procdefinition));
  962. if assigned(methodpointer) then
  963. methodpointer.derefimpl;
  964. if assigned(funcretrefnode) then
  965. funcretrefnode.derefimpl;
  966. end;
  967. procedure tcallnode.set_procvar(procvar:tnode);
  968. begin
  969. right:=procvar;
  970. end;
  971. function tcallnode.getcopy : tnode;
  972. var
  973. n : tcallnode;
  974. begin
  975. n:=tcallnode(inherited getcopy);
  976. n.symtableprocentry:=symtableprocentry;
  977. n.symtableproc:=symtableproc;
  978. n.procdefinition:=procdefinition;
  979. n.restype := restype;
  980. n.restypeset := restypeset;
  981. if assigned(methodpointer) then
  982. n.methodpointer:=methodpointer.getcopy
  983. else
  984. n.methodpointer:=nil;
  985. if assigned(funcretrefnode) then
  986. n.funcretrefnode:=funcretrefnode.getcopy
  987. else
  988. n.funcretrefnode:=nil;
  989. result:=n;
  990. end;
  991. procedure tcallnode.insertintolist(l : tnodelist);
  992. begin
  993. end;
  994. procedure tcallnode.verifyabstract(p : tnamedindexitem;arg:pointer);
  995. var
  996. hp : tprocdef;
  997. j: integer;
  998. begin
  999. if (tsym(p).typ=procsym) then
  1000. begin
  1001. for j:=1 to tprocsym(p).procdef_count do
  1002. begin
  1003. { index starts at 1 }
  1004. hp:=tprocsym(p).procdef[j];
  1005. { If this is an abstract method insert into the list }
  1006. if (po_abstractmethod in hp.procoptions) then
  1007. AbstractMethodsList.Insert(hp.procsym.name)
  1008. else
  1009. { If this symbol is already in the list, and it is
  1010. an overriding method or dynamic, then remove it from the list
  1011. }
  1012. begin
  1013. { symbol was found }
  1014. if AbstractMethodsList.Find(hp.procsym.name) <> nil then
  1015. begin
  1016. if po_overridingmethod in hp.procoptions then
  1017. AbstractMethodsList.Remove(hp.procsym.name);
  1018. end;
  1019. end;
  1020. end;
  1021. end;
  1022. end;
  1023. procedure tcallnode.verifyabstractcalls;
  1024. var
  1025. objectdf : tobjectdef;
  1026. parents : tlinkedlist;
  1027. objectinfo : tobjectinfoitem;
  1028. stritem : tstringlistitem;
  1029. _classname : string;
  1030. begin
  1031. objectdf := nil;
  1032. { verify if trying to create an instance of a class which contains
  1033. non-implemented abstract methods }
  1034. { first verify this class type, no class than exit }
  1035. { also, this checking can only be done if the constructor is directly
  1036. called, indirect constructor calls cannot be checked.
  1037. }
  1038. if assigned(methodpointer) and assigned(methodpointer.resulttype.def) then
  1039. if (methodpointer.resulttype.def.deftype = classrefdef) and
  1040. (methodpointer.nodetype in [typen,loadvmtn]) then
  1041. begin
  1042. if (tclassrefdef(methodpointer.resulttype.def).pointertype.def.deftype = objectdef) then
  1043. objectdf := tobjectdef(tclassrefdef(methodpointer.resulttype.def).pointertype.def);
  1044. end;
  1045. if not assigned(objectdf) then exit;
  1046. if assigned(objectdf.symtable.name) then
  1047. _classname := objectdf.symtable.name^
  1048. else
  1049. _classname := '';
  1050. parents := tlinkedlist.create;
  1051. AbstractMethodsList := tstringlist.create;
  1052. { insert all parents in this class : the first item in the
  1053. list will be the base parent of the class .
  1054. }
  1055. while assigned(objectdf) do
  1056. begin
  1057. objectinfo:=tobjectinfoitem.create(objectdf);
  1058. parents.insert(objectinfo);
  1059. objectdf := objectdf.childof;
  1060. end;
  1061. { now all parents are in the correct order
  1062. insert all abstract methods in the list, and remove
  1063. those which are overriden by parent classes.
  1064. }
  1065. objectinfo:=tobjectinfoitem(parents.first);
  1066. while assigned(objectinfo) do
  1067. begin
  1068. objectdf := objectinfo.objinfo;
  1069. if assigned(objectdf.symtable) then
  1070. objectdf.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}verifyabstract,nil);
  1071. objectinfo:=tobjectinfoitem(objectinfo.next);
  1072. end;
  1073. if assigned(parents) then
  1074. parents.free;
  1075. { Finally give out a warning for each abstract method still in the list }
  1076. stritem := tstringlistitem(AbstractMethodsList.first);
  1077. while assigned(stritem) do
  1078. begin
  1079. if assigned(stritem.fpstr) then
  1080. Message2(type_w_instance_with_abstract,lower(_classname),lower(stritem.fpstr^));
  1081. stritem := tstringlistitem(stritem.next);
  1082. end;
  1083. if assigned(AbstractMethodsList) then
  1084. AbstractMethodsList.Free;
  1085. end;
  1086. function Tcallnode.candidates_find:pcandidate;
  1087. var
  1088. j : integer;
  1089. pd : tprocdef;
  1090. procs,hp : pcandidate;
  1091. found,
  1092. has_overload_directive : boolean;
  1093. srsymtable : tsymtable;
  1094. srprocsym : tprocsym;
  1095. procedure proc_add(pd:tprocdef);
  1096. var
  1097. i : integer;
  1098. begin
  1099. { generate new candidate entry }
  1100. new(hp);
  1101. fillchar(hp^,sizeof(tcandidate),0);
  1102. hp^.data:=pd;
  1103. hp^.next:=procs;
  1104. procs:=hp;
  1105. { Setup first parameter, skip all default parameters
  1106. that are not passed. Ignore this skipping for varargs }
  1107. hp^.firstpara:=tparaitem(pd.Para.first);
  1108. if not(po_varargs in pd.procoptions) then
  1109. begin
  1110. for i:=1 to pd.maxparacount-paralength do
  1111. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  1112. end;
  1113. end;
  1114. begin
  1115. procs:=nil;
  1116. { when the definition has overload directive set, we search for
  1117. overloaded definitions in the class, this only needs to be done once
  1118. for class entries as the tree keeps always the same }
  1119. if (not symtableprocentry.overloadchecked) and
  1120. (po_overload in symtableprocentry.first_procdef.procoptions) and
  1121. (symtableprocentry.owner.symtabletype=objectsymtable) then
  1122. search_class_overloads(symtableprocentry);
  1123. { link all procedures which have the same # of parameters }
  1124. for j:=1 to symtableprocentry.procdef_count do
  1125. begin
  1126. pd:=symtableprocentry.procdef[j];
  1127. { Is the procdef visible? This needs to be checked on
  1128. procdef level since a symbol can contain both private and
  1129. public declarations. But the check should not be done
  1130. when the callnode is generated by a property }
  1131. if (nf_isproperty in flags) or
  1132. (pd.owner.symtabletype<>objectsymtable) or
  1133. pd.is_visible_for_proc(aktprocdef) then
  1134. begin
  1135. { only when the # of parameter are supported by the
  1136. procedure }
  1137. if (paralength>=pd.minparacount) and
  1138. ((po_varargs in pd.procoptions) or { varargs }
  1139. (paralength<=pd.maxparacount)) then
  1140. proc_add(pd);
  1141. end;
  1142. end;
  1143. { remember if the procedure is declared with the overload directive,
  1144. it's information is still needed also after all procs are removed }
  1145. has_overload_directive:=(po_overload in symtableprocentry.first_procdef.procoptions);
  1146. { when the definition has overload directive set, we search for
  1147. overloaded definitions in the symtablestack. The found
  1148. entries are only added to the procs list and not the procsym, because
  1149. the list can change in every situation }
  1150. if has_overload_directive and
  1151. (symtableprocentry.owner.symtabletype<>objectsymtable) then
  1152. begin
  1153. srsymtable:=symtableprocentry.owner.next;
  1154. while assigned(srsymtable) do
  1155. begin
  1156. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1157. begin
  1158. srprocsym:=tprocsym(srsymtable.speedsearch(symtableprocentry.name,symtableprocentry.speedvalue));
  1159. { process only visible procsyms }
  1160. if assigned(srprocsym) and
  1161. (srprocsym.typ=procsym) and
  1162. srprocsym.is_visible_for_proc(aktprocdef) then
  1163. begin
  1164. { if this procedure doesn't have overload we can stop
  1165. searching }
  1166. if not(po_overload in srprocsym.first_procdef.procoptions) then
  1167. break;
  1168. { process all overloaded definitions }
  1169. for j:=1 to srprocsym.procdef_count do
  1170. begin
  1171. pd:=srprocsym.procdef[j];
  1172. { only when the # of parameter are supported by the
  1173. procedure }
  1174. if (paralength>=pd.minparacount) and
  1175. ((po_varargs in pd.procoptions) or { varargs }
  1176. (paralength<=pd.maxparacount)) then
  1177. begin
  1178. found:=false;
  1179. hp:=procs;
  1180. while assigned(hp) do
  1181. begin
  1182. if compare_paras(hp^.data.para,pd.para,cp_value_equal_const,false)>=te_equal then
  1183. begin
  1184. found:=true;
  1185. break;
  1186. end;
  1187. hp:=hp^.next;
  1188. end;
  1189. if not found then
  1190. proc_add(pd);
  1191. end;
  1192. end;
  1193. end;
  1194. end;
  1195. srsymtable:=srsymtable.next;
  1196. end;
  1197. end;
  1198. candidates_find:=procs;
  1199. end;
  1200. procedure tcallnode.candidates_free(procs:pcandidate);
  1201. var
  1202. hpnext,
  1203. hp : pcandidate;
  1204. begin
  1205. hp:=procs;
  1206. while assigned(hp) do
  1207. begin
  1208. hpnext:=hp^.next;
  1209. dispose(hp);
  1210. hp:=hpnext;
  1211. end;
  1212. end;
  1213. procedure tcallnode.candidates_list(procs:pcandidate;all:boolean);
  1214. var
  1215. hp : pcandidate;
  1216. begin
  1217. hp:=procs;
  1218. while assigned(hp) do
  1219. begin
  1220. if all or
  1221. (not hp^.invalid) then
  1222. MessagePos1(hp^.data.fileinfo,sym_h_param_list,hp^.data.fullprocname);
  1223. hp:=hp^.next;
  1224. end;
  1225. end;
  1226. {$ifdef EXTDEBUG}
  1227. procedure Tcallnode.candidates_dump_info(lvl:longint;procs:pcandidate);
  1228. function ParaTreeStr(p:tcallparanode):string;
  1229. begin
  1230. result:='';
  1231. while assigned(p) do
  1232. begin
  1233. if result<>'' then
  1234. result:=result+',';
  1235. result:=result+p.resulttype.def.typename;
  1236. p:=tcallparanode(p.right);
  1237. end;
  1238. end;
  1239. var
  1240. hp : pcandidate;
  1241. currpara : tparaitem;
  1242. begin
  1243. if not CheckVerbosity(lvl) then
  1244. exit;
  1245. Comment(lvl+V_LineInfo,'Overloaded callnode: '+symtableprocentry.name+'('+ParaTreeStr(tcallparanode(left))+')');
  1246. hp:=procs;
  1247. while assigned(hp) do
  1248. begin
  1249. Comment(lvl,' '+hp^.data.fullprocname);
  1250. if (hp^.invalid) then
  1251. Comment(lvl,' invalid')
  1252. else
  1253. begin
  1254. Comment(lvl,' ex: '+tostr(hp^.exact_count)+
  1255. ' eq: '+tostr(hp^.equal_count)+
  1256. ' l1: '+tostr(hp^.cl1_count)+
  1257. ' l2: '+tostr(hp^.cl2_count)+
  1258. ' l3: '+tostr(hp^.cl3_count)+
  1259. ' oper: '+tostr(hp^.coper_count)+
  1260. ' ord: '+realtostr(hp^.exact_count));
  1261. { Print parameters in left-right order }
  1262. currpara:=hp^.firstpara;
  1263. if assigned(currpara) then
  1264. begin
  1265. while assigned(currpara.next) do
  1266. currpara:=tparaitem(currpara.next);
  1267. end;
  1268. while assigned(currpara) do
  1269. begin
  1270. if (currpara.paratyp<>vs_hidden) then
  1271. Comment(lvl,' - '+currpara.paratype.def.typename+' : '+EqualTypeName[currpara.eqval]);
  1272. currpara:=tparaitem(currpara.previous);
  1273. end;
  1274. end;
  1275. hp:=hp^.next;
  1276. end;
  1277. end;
  1278. {$endif EXTDEBUG}
  1279. procedure Tcallnode.candidates_get_information(procs:pcandidate);
  1280. var
  1281. hp : pcandidate;
  1282. currpara : tparaitem;
  1283. currparanr : byte;
  1284. def_from,
  1285. def_to : tdef;
  1286. pt : tcallparanode;
  1287. eq : tequaltype;
  1288. convtype : tconverttype;
  1289. pdoper : tprocdef;
  1290. begin
  1291. { process all procs }
  1292. hp:=procs;
  1293. while assigned(hp) do
  1294. begin
  1295. { Setup first parameter to compare }
  1296. currparanr:=paralength;
  1297. currpara:=hp^.firstpara;
  1298. while assigned(currpara) and (currpara.paratyp=vs_hidden) do
  1299. currpara:=tparaitem(currpara.next);
  1300. pt:=tcallparanode(left);
  1301. while assigned(pt) and assigned(currpara) do
  1302. begin
  1303. { retrieve current parameter definitions to compares }
  1304. eq:=te_incompatible;
  1305. def_from:=pt.resulttype.def;
  1306. def_to:=currpara.paratype.def;
  1307. if not(assigned(def_from)) then
  1308. internalerror(200212091);
  1309. if not(
  1310. assigned(def_to) or
  1311. ((po_varargs in hp^.data.procoptions) and
  1312. (currparanr>hp^.data.minparacount))
  1313. ) then
  1314. internalerror(200212092);
  1315. { varargs are always equal, but not exact }
  1316. if (po_varargs in hp^.data.procoptions) and
  1317. (currparanr>hp^.data.minparacount) then
  1318. begin
  1319. inc(hp^.equal_count);
  1320. eq:=te_equal;
  1321. end
  1322. else
  1323. { same definition -> exact }
  1324. if (def_from=def_to) then
  1325. begin
  1326. inc(hp^.exact_count);
  1327. eq:=te_exact;
  1328. end
  1329. else
  1330. { for value and const parameters check if a integer is constant or
  1331. included in other integer -> equal and calc ordinal_distance }
  1332. if not(currpara.paratyp in [vs_var,vs_out]) and
  1333. is_integer(def_from) and
  1334. is_integer(def_to) and
  1335. is_in_limit(def_from,def_to) then
  1336. begin
  1337. inc(hp^.equal_count);
  1338. eq:=te_equal;
  1339. hp^.ordinal_distance:=hp^.ordinal_distance+
  1340. abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
  1341. hp^.ordinal_distance:=hp^.ordinal_distance+
  1342. abs(bestreal(torddef(def_to).high)-bestreal(torddef(def_from).high));
  1343. { Give wrong sign a small penalty, this is need to get a diffrence
  1344. from word->[longword,longint] }
  1345. if is_signed(def_from)<>is_signed(def_to) then
  1346. hp^.ordinal_distance:=hp^.ordinal_distance+1.0;
  1347. end
  1348. else
  1349. { generic type comparision }
  1350. begin
  1351. eq:=compare_defs_ext(def_from,def_to,pt.left.nodetype,
  1352. false,true,convtype,pdoper);
  1353. { when the types are not equal we need to check
  1354. some special case for parameter passing }
  1355. if (eq<te_equal) then
  1356. begin
  1357. if currpara.paratyp in [vs_var,vs_out] then
  1358. begin
  1359. { para requires an equal type so the previous found
  1360. match was not good enough, reset to incompatible }
  1361. eq:=te_incompatible;
  1362. { var_para_allowed will return te_equal and te_convert_l1 to
  1363. make a difference for best matching }
  1364. var_para_allowed(eq,pt.resulttype.def,currpara.paratype.def)
  1365. end
  1366. else
  1367. para_allowed(eq,pt,def_to);
  1368. end;
  1369. case eq of
  1370. te_exact :
  1371. internalerror(200212071); { already checked }
  1372. te_equal :
  1373. inc(hp^.equal_count);
  1374. te_convert_l1 :
  1375. inc(hp^.cl1_count);
  1376. te_convert_l2 :
  1377. inc(hp^.cl2_count);
  1378. te_convert_l3 :
  1379. inc(hp^.cl3_count);
  1380. te_convert_operator :
  1381. inc(hp^.coper_count);
  1382. te_incompatible :
  1383. hp^.invalid:=true;
  1384. else
  1385. internalerror(200212072);
  1386. end;
  1387. end;
  1388. { stop checking when an incompatible parameter is found }
  1389. if hp^.invalid then
  1390. begin
  1391. { store the current parameter info for
  1392. a nice error message when no procedure is found }
  1393. hp^.wrongpara:=currpara;
  1394. hp^.wrongparanr:=currparanr;
  1395. break;
  1396. end;
  1397. {$ifdef EXTDEBUG}
  1398. { store equal in node tree for dump }
  1399. currpara.eqval:=eq;
  1400. {$endif EXTDEBUG}
  1401. { next parameter in the call tree }
  1402. pt:=tcallparanode(pt.right);
  1403. { next parameter for definition, only goto next para
  1404. if we're out of the varargs }
  1405. if not(po_varargs in hp^.data.procoptions) or
  1406. (currparanr<=hp^.data.maxparacount) then
  1407. begin
  1408. { Ignore vs_hidden parameters }
  1409. repeat
  1410. currpara:=tparaitem(currpara.next);
  1411. until (not assigned(currpara)) or (currpara.paratyp<>vs_hidden);
  1412. end;
  1413. dec(currparanr);
  1414. end;
  1415. if not(hp^.invalid) and
  1416. (assigned(pt) or assigned(currpara) or (currparanr<>0)) then
  1417. internalerror(200212141);
  1418. { next candidate }
  1419. hp:=hp^.next;
  1420. end;
  1421. end;
  1422. function Tcallnode.candidates_choose_best(procs:pcandidate;var bestpd:tprocdef):integer;
  1423. var
  1424. besthpstart,
  1425. hp : pcandidate;
  1426. cntpd,
  1427. res : integer;
  1428. begin
  1429. {
  1430. Returns the number of candidates left and the
  1431. first candidate is returned in pdbest
  1432. }
  1433. { Setup the first procdef as best, only count it as a result
  1434. when it is valid }
  1435. bestpd:=procs^.data;
  1436. if procs^.invalid then
  1437. cntpd:=0
  1438. else
  1439. cntpd:=1;
  1440. if assigned(procs^.next) then
  1441. begin
  1442. besthpstart:=procs;
  1443. hp:=procs^.next;
  1444. while assigned(hp) do
  1445. begin
  1446. res:=is_better_candidate(hp,besthpstart);
  1447. if (res>0) then
  1448. begin
  1449. { hp is better, flag all procs to be incompatible }
  1450. while (besthpstart<>hp) do
  1451. begin
  1452. besthpstart^.invalid:=true;
  1453. besthpstart:=besthpstart^.next;
  1454. end;
  1455. { besthpstart is already set to hp }
  1456. bestpd:=besthpstart^.data;
  1457. cntpd:=1;
  1458. end
  1459. else
  1460. if (res<0) then
  1461. begin
  1462. { besthpstart is better, flag current hp to be incompatible }
  1463. hp^.invalid:=true;
  1464. end
  1465. else
  1466. begin
  1467. { res=0, both are valid }
  1468. if not hp^.invalid then
  1469. inc(cntpd);
  1470. end;
  1471. hp:=hp^.next;
  1472. end;
  1473. end;
  1474. candidates_choose_best:=cntpd;
  1475. end;
  1476. procedure tcallnode.candidates_find_wrong_para(procs:pcandidate);
  1477. var
  1478. currparanr : smallint;
  1479. hp : pcandidate;
  1480. pt : tcallparanode;
  1481. begin
  1482. { Only process the first overloaded procdef }
  1483. hp:=procs;
  1484. { Find callparanode corresponding to the argument }
  1485. pt:=tcallparanode(left);
  1486. currparanr:=paralength;
  1487. while assigned(pt) and
  1488. (currparanr>hp^.wrongparanr) do
  1489. begin
  1490. pt:=tcallparanode(pt.right);
  1491. dec(currparanr);
  1492. end;
  1493. if (currparanr<>hp^.wrongparanr) or
  1494. not assigned(pt) then
  1495. internalerror(200212094);
  1496. { Show error message, when it was a var or out parameter
  1497. guess that it is a missing typeconv }
  1498. if hp^.wrongpara.paratyp in [vs_var,vs_out] then
  1499. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  1500. pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename)
  1501. else
  1502. CGMessagePos3(pt.fileinfo,type_e_wrong_parameter_type,
  1503. tostr(hp^.wrongparanr),pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename);
  1504. end;
  1505. function tcallnode.det_resulttype:tnode;
  1506. var
  1507. procs : pcandidate;
  1508. oldcallprocdef : tabstractprocdef;
  1509. hpt : tnode;
  1510. pt : tcallparanode;
  1511. lastpara : longint;
  1512. pdc : tparaitem;
  1513. cand_cnt : integer;
  1514. i : longint;
  1515. is_const : boolean;
  1516. label
  1517. errorexit;
  1518. begin
  1519. result:=nil;
  1520. procs:=nil;
  1521. oldcallprocdef:=aktcallprocdef;
  1522. aktcallprocdef:=nil;
  1523. { determine length of parameter list }
  1524. pt:=tcallparanode(left);
  1525. paralength:=0;
  1526. while assigned(pt) do
  1527. begin
  1528. inc(paralength);
  1529. pt:=tcallparanode(pt.right);
  1530. end;
  1531. { determine the type of the parameters }
  1532. if assigned(left) then
  1533. begin
  1534. tcallparanode(left).get_paratype;
  1535. if codegenerror then
  1536. goto errorexit;
  1537. end;
  1538. { procedure variable ? }
  1539. if assigned(right) then
  1540. begin
  1541. set_varstate(right,true);
  1542. resulttypepass(right);
  1543. if codegenerror then
  1544. exit;
  1545. procdefinition:=tabstractprocdef(right.resulttype.def);
  1546. { check the amount of parameters }
  1547. pdc:=tparaitem(procdefinition.Para.first);
  1548. while assigned(pdc) and (pdc.paratyp=vs_hidden) do
  1549. pdc:=tparaitem(pdc.next);
  1550. pt:=tcallparanode(left);
  1551. lastpara:=paralength;
  1552. while assigned(pdc) and assigned(pt) do
  1553. begin
  1554. { only goto next para if we're out of the varargs }
  1555. if not(po_varargs in procdefinition.procoptions) or
  1556. (lastpara<=procdefinition.maxparacount) then
  1557. begin
  1558. repeat
  1559. pdc:=tparaitem(pdc.next);
  1560. until (not assigned(pdc)) or (pdc.paratyp<>vs_hidden);
  1561. end;
  1562. pt:=tcallparanode(pt.right);
  1563. dec(lastpara);
  1564. end;
  1565. if assigned(pt) or assigned(pdc) then
  1566. begin
  1567. if assigned(pt) then
  1568. aktfilepos:=pt.fileinfo;
  1569. CGMessage(parser_e_wrong_parameter_size);
  1570. end;
  1571. end
  1572. else
  1573. { not a procedure variable }
  1574. begin
  1575. { do we know the procedure to call ? }
  1576. if not(assigned(procdefinition)) then
  1577. begin
  1578. procs:=candidates_find;
  1579. { no procedures found? then there is something wrong
  1580. with the parameter size }
  1581. if not assigned(procs) then
  1582. begin
  1583. { when it's an auto inherited call and there
  1584. is no procedure found, but the procedures
  1585. were defined with overload directive and at
  1586. least two procedures are defined then we ignore
  1587. this inherited by inserting a nothingn. Only
  1588. do this ugly hack in Delphi mode as it looks more
  1589. like a bug. It's also not documented }
  1590. if (m_delphi in aktmodeswitches) and
  1591. (nf_anon_inherited in flags) and
  1592. (symtableprocentry.owner.symtabletype=objectsymtable) and
  1593. (po_overload in symtableprocentry.first_procdef.procoptions) and
  1594. (symtableprocentry.procdef_count>=2) then
  1595. result:=cnothingnode.create
  1596. else
  1597. begin
  1598. { in tp mode we can try to convert to procvar if
  1599. there are no parameters specified. Only try it
  1600. when there is only one proc definition, else the
  1601. loadnode will give a strange error }
  1602. if not(assigned(left)) and
  1603. (m_tp_procvar in aktmodeswitches) and
  1604. (symtableprocentry.procdef_count=1) then
  1605. begin
  1606. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  1607. if (symtableprocentry.owner.symtabletype=objectsymtable) then
  1608. begin
  1609. if assigned(methodpointer) then
  1610. tloadnode(hpt).set_mp(methodpointer.getcopy)
  1611. else
  1612. tloadnode(hpt).set_mp(cselfnode.create(tobjectdef(symtableprocentry.owner.defowner)));
  1613. end;
  1614. resulttypepass(hpt);
  1615. result:=hpt;
  1616. end
  1617. else
  1618. begin
  1619. if assigned(left) then
  1620. aktfilepos:=left.fileinfo;
  1621. CGMessage(parser_e_wrong_parameter_size);
  1622. symtableprocentry.write_parameter_lists(nil);
  1623. end;
  1624. end;
  1625. goto errorexit;
  1626. end;
  1627. { Retrieve information about the candidates }
  1628. candidates_get_information(procs);
  1629. {$ifdef EXTDEBUG}
  1630. { Display info when multiple candidates are found }
  1631. if assigned(procs^.next) then
  1632. candidates_dump_info(V_Debug,procs);
  1633. {$endif EXTDEBUG}
  1634. { Choose the best candidate and count the number of
  1635. candidates left }
  1636. cand_cnt:=candidates_choose_best(procs,tprocdef(procdefinition));
  1637. { All parameters are checked, check if there are any
  1638. procedures left }
  1639. if cand_cnt>0 then
  1640. begin
  1641. { Multiple candidates left? }
  1642. if cand_cnt>1 then
  1643. begin
  1644. CGMessage(cg_e_cant_choose_overload_function);
  1645. {$ifdef EXTDEBUG}
  1646. candidates_dump_info(V_Hint,procs);
  1647. {$else}
  1648. candidates_list(procs,false);
  1649. {$endif EXTDEBUG}
  1650. { we'll just use the first candidate to make the
  1651. call }
  1652. end;
  1653. { assign procdefinition }
  1654. if symtableproc=nil then
  1655. symtableproc:=procdefinition.owner;
  1656. { update browser information }
  1657. if make_ref then
  1658. begin
  1659. tprocdef(procdefinition).lastref:=tref.create(tprocdef(procdefinition).lastref,@fileinfo);
  1660. inc(tprocdef(procdefinition).refcount);
  1661. if tprocdef(procdefinition).defref=nil then
  1662. tprocdef(procdefinition).defref:=tprocdef(procdefinition).lastref;
  1663. end;
  1664. end
  1665. else
  1666. begin
  1667. { No candidates left, this must be a type error,
  1668. because wrong size is already checked. procdefinition
  1669. is filled with the first (random) definition that is
  1670. found. We use this definition to display a nice error
  1671. message that the wrong type is passed }
  1672. candidates_find_wrong_para(procs);
  1673. candidates_list(procs,true);
  1674. {$ifdef EXTDEBUG}
  1675. candidates_dump_info(V_Hint,procs);
  1676. {$endif EXTDEBUG}
  1677. { We can not proceed, release all procs and exit }
  1678. candidates_free(procs);
  1679. goto errorexit;
  1680. end;
  1681. candidates_free(procs);
  1682. end; { end of procedure to call determination }
  1683. { add needed default parameters }
  1684. if assigned(procdefinition) and
  1685. (paralength<procdefinition.maxparacount) then
  1686. begin
  1687. pdc:=tparaitem(procdefinition.Para.last);
  1688. for i:=1 to paralength do
  1689. pdc:=tparaitem(pdc.previous);
  1690. while assigned(pdc) do
  1691. begin
  1692. if not assigned(pdc.defaultvalue) then
  1693. internalerror(200212142);
  1694. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1695. pdc:=tparaitem(pdc.previous);
  1696. end;
  1697. end;
  1698. end;
  1699. { handle predefined procedures }
  1700. is_const:=(po_internconst in procdefinition.procoptions) and
  1701. ((block_type in [bt_const,bt_type]) or
  1702. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1703. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1704. begin
  1705. if assigned(left) then
  1706. begin
  1707. { ptr and settextbuf needs two args }
  1708. if assigned(tcallparanode(left).right) then
  1709. begin
  1710. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1711. left:=nil;
  1712. end
  1713. else
  1714. begin
  1715. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  1716. tcallparanode(left).left:=nil;
  1717. end;
  1718. end
  1719. else
  1720. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  1721. result:=hpt;
  1722. goto errorexit;
  1723. end;
  1724. { ensure that the result type is set }
  1725. if not restypeset then
  1726. resulttype:=procdefinition.rettype
  1727. else
  1728. resulttype:=restype;
  1729. { modify the exit code, in case of special cases }
  1730. if (not is_void(resulttype.def)) then
  1731. begin
  1732. if paramanager.ret_in_reg(resulttype.def,procdefinition.proccalloption) then
  1733. begin
  1734. { wide- and ansistrings are returned in EAX }
  1735. { but they are imm. moved to a memory location }
  1736. if is_widestring(resulttype.def) or
  1737. is_ansistring(resulttype.def) then
  1738. begin
  1739. { we use ansistrings so no fast exit here }
  1740. if assigned(procinfo) then
  1741. procinfo.no_fast_exit:=true;
  1742. end;
  1743. end;
  1744. end;
  1745. { constructors return their current class type, not the type where the
  1746. constructor is declared, this can be different because of inheritance }
  1747. if (procdefinition.proctypeoption=potype_constructor) then
  1748. begin
  1749. if assigned(methodpointer) and
  1750. assigned(methodpointer.resulttype.def) and
  1751. (methodpointer.resulttype.def.deftype=classrefdef) then
  1752. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1753. end;
  1754. { flag all callparanodes that belong to the varargs }
  1755. if (po_varargs in procdefinition.procoptions) then
  1756. begin
  1757. pt:=tcallparanode(left);
  1758. i:=paralength;
  1759. while (i>procdefinition.maxparacount) do
  1760. begin
  1761. include(tcallparanode(pt).flags,nf_varargs_para);
  1762. pt:=tcallparanode(pt.right);
  1763. dec(i);
  1764. end;
  1765. end;
  1766. { insert type conversions }
  1767. if assigned(left) then
  1768. begin
  1769. aktcallprocdef:=procdefinition;
  1770. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  1771. end;
  1772. { direct call to inherited abstract method, then we
  1773. can already give a error in the compiler instead
  1774. of a runtime error }
  1775. if assigned(methodpointer) and
  1776. (methodpointer.nodetype=typen) and
  1777. (po_abstractmethod in procdefinition.procoptions) then
  1778. CGMessage(cg_e_cant_call_abstract_method);
  1779. errorexit:
  1780. aktcallprocdef:=oldcallprocdef;
  1781. end;
  1782. function tcallnode.pass_1 : tnode;
  1783. var
  1784. inlinecode : tnode;
  1785. inlined : boolean;
  1786. {$ifdef m68k}
  1787. regi : tregister;
  1788. {$endif}
  1789. method_must_be_valid : boolean;
  1790. label
  1791. errorexit;
  1792. begin
  1793. { the default is nothing to return }
  1794. location.loc:=LOC_INVALID;
  1795. result:=nil;
  1796. inlined:=false;
  1797. inlinecode := nil;
  1798. { work trough all parameters to get the register requirements }
  1799. if assigned(left) then
  1800. tcallparanode(left).det_registers;
  1801. { return node }
  1802. if assigned(funcretrefnode) then
  1803. firstpass(funcretrefnode);
  1804. if assigned(procdefinition) and
  1805. (procdefinition.proccalloption=pocall_inline) then
  1806. begin
  1807. inlinecode:=right;
  1808. if assigned(inlinecode) then
  1809. inlined:=true;
  1810. right:=nil;
  1811. end;
  1812. { procedure variable ? }
  1813. if assigned(right) then
  1814. begin
  1815. firstpass(right);
  1816. { procedure does a call }
  1817. if not (block_type in [bt_const,bt_type]) then
  1818. procinfo.flags:=procinfo.flags or pi_do_call;
  1819. rg.incrementintregisterpushed(all_intregisters);
  1820. rg.incrementotherregisterpushed(all_registers);
  1821. end
  1822. else
  1823. { not a procedure variable }
  1824. begin
  1825. { calc the correture value for the register }
  1826. { handle predefined procedures }
  1827. if (procdefinition.proccalloption=pocall_inline) then
  1828. begin
  1829. if assigned(methodpointer) then
  1830. CGMessage(cg_e_unable_inline_object_methods);
  1831. if assigned(right) and (right.nodetype<>procinlinen) then
  1832. CGMessage(cg_e_unable_inline_procvar);
  1833. if not assigned(inlinecode) then
  1834. begin
  1835. if assigned(tprocdef(procdefinition).code) then
  1836. inlinecode:=cprocinlinenode.create(tprocdef(procdefinition))
  1837. else
  1838. CGMessage(cg_e_no_code_for_inline_stored);
  1839. if assigned(inlinecode) then
  1840. begin
  1841. { consider it has not inlined if called
  1842. again inside the args }
  1843. procdefinition.proccalloption:=pocall_fpccall;
  1844. firstpass(inlinecode);
  1845. inlined:=true;
  1846. end;
  1847. end;
  1848. end
  1849. else
  1850. begin
  1851. if not (block_type in [bt_const,bt_type]) then
  1852. procinfo.flags:=procinfo.flags or pi_do_call;
  1853. end;
  1854. { It doesn't hurt to calculate it already though :) (JM) }
  1855. rg.incrementintregisterpushed(tprocdef(procdefinition).usedintregisters);
  1856. rg.incrementotherregisterpushed(tprocdef(procdefinition).usedotherregisters);
  1857. end;
  1858. { get a register for the return value }
  1859. if (not is_void(resulttype.def)) then
  1860. begin
  1861. { for win32 records returned in EDX:EAX, we
  1862. move them to memory after ... }
  1863. if (resulttype.def.deftype=recorddef) then
  1864. begin
  1865. location.loc:=LOC_CREFERENCE;
  1866. end
  1867. else
  1868. if paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then
  1869. begin
  1870. location.loc:=LOC_CREFERENCE;
  1871. end
  1872. else
  1873. { ansi/widestrings must be registered, so we can dispose them }
  1874. if is_ansistring(resulttype.def) or
  1875. is_widestring(resulttype.def) then
  1876. begin
  1877. location.loc:=LOC_CREFERENCE;
  1878. registers32:=1;
  1879. end
  1880. else
  1881. { we have only to handle the result if it is used }
  1882. if (nf_return_value_used in flags) then
  1883. begin
  1884. case resulttype.def.deftype of
  1885. enumdef,
  1886. orddef :
  1887. begin
  1888. if (procdefinition.proctypeoption=potype_constructor) then
  1889. begin
  1890. if assigned(methodpointer) and
  1891. (methodpointer.resulttype.def.deftype=classrefdef) then
  1892. begin
  1893. location.loc:=LOC_REGISTER;
  1894. registers32:=1;
  1895. end
  1896. else
  1897. location.loc:=LOC_FLAGS;
  1898. end
  1899. else
  1900. begin
  1901. location.loc:=LOC_REGISTER;
  1902. if is_64bitint(resulttype.def) then
  1903. registers32:=2
  1904. else
  1905. registers32:=1;
  1906. end;
  1907. end;
  1908. floatdef :
  1909. begin
  1910. location.loc:=LOC_FPUREGISTER;
  1911. {$ifdef cpufpemu}
  1912. if (cs_fp_emulation in aktmoduleswitches) then
  1913. registers32:=1
  1914. else
  1915. {$endif cpufpemu}
  1916. {$ifdef m68k}
  1917. if (tfloatdef(resulttype.def).typ=s32real) then
  1918. registers32:=1
  1919. else
  1920. {$endif m68k}
  1921. registersfpu:=1;
  1922. end;
  1923. else
  1924. begin
  1925. location.loc:=LOC_REGISTER;
  1926. registers32:=1;
  1927. end;
  1928. end;
  1929. end;
  1930. end;
  1931. {$ifdef m68k}
  1932. { we need one more address register for virtual calls on m68k }
  1933. if (po_virtualmethod in procdefinition.procoptions) then
  1934. inc(registers32);
  1935. {$endif m68k}
  1936. { a fpu can be used in any procedure !! }
  1937. {$ifdef i386}
  1938. registersfpu:=procdefinition.fpu_used;
  1939. {$endif i386}
  1940. { if this is a call to a method calc the registers }
  1941. if (methodpointer<>nil) then
  1942. begin
  1943. { if we are calling the constructor }
  1944. if procdefinition.proctypeoption in [potype_constructor] then
  1945. verifyabstractcalls;
  1946. case methodpointer.nodetype of
  1947. { but only, if this is not a supporting node }
  1948. typen: ;
  1949. { we need one register for new return value PM }
  1950. hnewn : if registers32=0 then
  1951. registers32:=1;
  1952. else
  1953. begin
  1954. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
  1955. assigned(symtableproc) and (symtableproc.symtabletype=withsymtable) and
  1956. not twithsymtable(symtableproc).direct_with then
  1957. begin
  1958. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1959. end; { Is accepted by Delphi !! }
  1960. { this is not a good reason to accept it in FPC if we produce
  1961. wrong code for it !!! (PM) }
  1962. { R.Assign is not a constructor !!! }
  1963. { but for R^.Assign, R must be valid !! }
  1964. if (procdefinition.proctypeoption=potype_constructor) or
  1965. ((methodpointer.nodetype=loadn) and
  1966. ((methodpointer.resulttype.def.deftype=classrefdef) or
  1967. ((methodpointer.resulttype.def.deftype=objectdef) and
  1968. not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions)
  1969. )
  1970. )
  1971. ) then
  1972. method_must_be_valid:=false
  1973. else
  1974. method_must_be_valid:=true;
  1975. firstpass(methodpointer);
  1976. set_varstate(methodpointer,method_must_be_valid);
  1977. { The object is already used ven if it is called once }
  1978. if (methodpointer.nodetype=loadn) and
  1979. (tloadnode(methodpointer).symtableentry.typ=varsym) then
  1980. tvarsym(tloadnode(methodpointer).symtableentry).varstate:=vs_used;
  1981. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1982. registers32:=max(methodpointer.registers32,registers32);
  1983. {$ifdef SUPPORT_MMX }
  1984. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1985. {$endif SUPPORT_MMX}
  1986. end;
  1987. end;
  1988. end;
  1989. if inlined then
  1990. right:=inlinecode;
  1991. { determine the registers of the procedure variable }
  1992. { is this OK for inlined procs also ?? (PM) }
  1993. if assigned(right) then
  1994. begin
  1995. registersfpu:=max(right.registersfpu,registersfpu);
  1996. registers32:=max(right.registers32,registers32);
  1997. {$ifdef SUPPORT_MMX}
  1998. registersmmx:=max(right.registersmmx,registersmmx);
  1999. {$endif SUPPORT_MMX}
  2000. end;
  2001. { determine the registers of the procedure }
  2002. if assigned(left) then
  2003. begin
  2004. registersfpu:=max(left.registersfpu,registersfpu);
  2005. registers32:=max(left.registers32,registers32);
  2006. {$ifdef SUPPORT_MMX}
  2007. registersmmx:=max(left.registersmmx,registersmmx);
  2008. {$endif SUPPORT_MMX}
  2009. end;
  2010. errorexit:
  2011. if inlined then
  2012. procdefinition.proccalloption:=pocall_inline;
  2013. end;
  2014. {$ifdef state_tracking}
  2015. function Tcallnode.track_state_pass(exec_known:boolean):boolean;
  2016. var hp:Tcallparanode;
  2017. value:Tnode;
  2018. begin
  2019. track_state_pass:=false;
  2020. hp:=Tcallparanode(left);
  2021. while assigned(hp) do
  2022. begin
  2023. if left.track_state_pass(exec_known) then
  2024. begin
  2025. left.resulttype.def:=nil;
  2026. do_resulttypepass(left);
  2027. end;
  2028. value:=aktstate.find_fact(hp.left);
  2029. if value<>nil then
  2030. begin
  2031. track_state_pass:=true;
  2032. hp.left.destroy;
  2033. hp.left:=value.getcopy;
  2034. do_resulttypepass(hp.left);
  2035. end;
  2036. hp:=Tcallparanode(hp.right);
  2037. end;
  2038. end;
  2039. {$endif}
  2040. function tcallnode.docompare(p: tnode): boolean;
  2041. begin
  2042. docompare :=
  2043. inherited docompare(p) and
  2044. (symtableprocentry = tcallnode(p).symtableprocentry) and
  2045. (procdefinition = tcallnode(p).procdefinition) and
  2046. (methodpointer.isequal(tcallnode(p).methodpointer)) and
  2047. ((restypeset and tcallnode(p).restypeset and
  2048. (equal_defs(restype.def,tcallnode(p).restype.def))) or
  2049. (not restypeset and not tcallnode(p).restypeset));
  2050. end;
  2051. {****************************************************************************
  2052. TPROCINLINENODE
  2053. ****************************************************************************}
  2054. constructor tprocinlinenode.create(p:tprocdef);
  2055. begin
  2056. inherited create(procinlinen);
  2057. inlineprocdef:=p;
  2058. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2059. para_offset:=0;
  2060. para_size:=0;
  2061. { copy inlinetree }
  2062. if assigned(p.code) then
  2063. inlinetree:=p.code.getcopy
  2064. else
  2065. inlinetree:=nil;
  2066. end;
  2067. destructor tprocinlinenode.destroy;
  2068. begin
  2069. if assigned(inlinetree) then
  2070. inlinetree.free;
  2071. inherited destroy;
  2072. end;
  2073. constructor tprocinlinenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  2074. begin
  2075. inherited ppuload(t,ppufile);
  2076. inlineprocdef:=tprocdef(ppufile.getderef);
  2077. inlinetree:=ppuloadnode(ppufile);
  2078. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2079. para_offset:=0;
  2080. para_size:=0;
  2081. end;
  2082. procedure tprocinlinenode.ppuwrite(ppufile:tcompilerppufile);
  2083. begin
  2084. inherited ppuwrite(ppufile);
  2085. ppufile.putderef(inlineprocdef);
  2086. ppuwritenode(ppufile,inlinetree);
  2087. end;
  2088. procedure tprocinlinenode.derefimpl;
  2089. begin
  2090. inherited derefimpl;
  2091. if assigned(inlinetree) then
  2092. inlinetree.derefimpl;
  2093. resolvedef(pointer(inlineprocdef));
  2094. end;
  2095. function tprocinlinenode.getcopy : tnode;
  2096. var
  2097. n : tprocinlinenode;
  2098. begin
  2099. n:=tprocinlinenode(inherited getcopy);
  2100. n.inlineprocdef:=inlineprocdef;
  2101. if assigned(inlinetree) then
  2102. n.inlinetree:=inlinetree.getcopy
  2103. else
  2104. n.inlinetree:=nil;
  2105. n.retoffset:=retoffset;
  2106. n.para_offset:=para_offset;
  2107. n.para_size:=para_size;
  2108. getcopy:=n;
  2109. end;
  2110. procedure tprocinlinenode.insertintolist(l : tnodelist);
  2111. begin
  2112. end;
  2113. function tprocinlinenode.det_resulttype : tnode;
  2114. var
  2115. storesymtablelevel : longint;
  2116. storeparasymtable,
  2117. storelocalsymtable : tsymtabletype;
  2118. oldprocdef : tprocdef;
  2119. oldprocinfo : tprocinfo;
  2120. oldinlining_procedure : boolean;
  2121. begin
  2122. result:=nil;
  2123. oldinlining_procedure:=inlining_procedure;
  2124. oldprocdef:=aktprocdef;
  2125. oldprocinfo:=procinfo;
  2126. { we're inlining a procedure }
  2127. inlining_procedure:=true;
  2128. aktprocdef:=inlineprocdef;
  2129. { clone procinfo, but not the asmlists }
  2130. procinfo:=tprocinfo(cprocinfo.newinstance);
  2131. move(pointer(oldprocinfo)^,pointer(procinfo)^,cprocinfo.InstanceSize);
  2132. procinfo.aktentrycode:=nil;
  2133. procinfo.aktexitcode:=nil;
  2134. procinfo.aktproccode:=nil;
  2135. procinfo.aktlocaldata:=nil;
  2136. { set new procinfo }
  2137. procinfo.return_offset:=retoffset;
  2138. procinfo.para_offset:=para_offset;
  2139. procinfo.no_fast_exit:=false;
  2140. { set it to the same lexical level }
  2141. storesymtablelevel:=aktprocdef.localst.symtablelevel;
  2142. storelocalsymtable:=aktprocdef.localst.symtabletype;
  2143. storeparasymtable:=aktprocdef.parast.symtabletype;
  2144. aktprocdef.localst.symtablelevel:=oldprocdef.localst.symtablelevel;
  2145. aktprocdef.localst.symtabletype:=inlinelocalsymtable;
  2146. aktprocdef.parast.symtabletype:=inlineparasymtable;
  2147. { pass inlinetree }
  2148. resulttypepass(inlinetree);
  2149. resulttype:=inlineprocdef.rettype;
  2150. { retrieve info from inlineprocdef }
  2151. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2152. para_offset:=0;
  2153. para_size:=inlineprocdef.para_size(target_info.alignment.paraalign);
  2154. if paramanager.ret_in_param(inlineprocdef.rettype.def,inlineprocdef.proccalloption) then
  2155. inc(para_size,POINTER_SIZE);
  2156. { restore procinfo }
  2157. procinfo.free;
  2158. procinfo:=oldprocinfo;
  2159. { restore symtable }
  2160. aktprocdef.localst.symtablelevel:=storesymtablelevel;
  2161. aktprocdef.localst.symtabletype:=storelocalsymtable;
  2162. aktprocdef.parast.symtabletype:=storeparasymtable;
  2163. { restore }
  2164. aktprocdef:=oldprocdef;
  2165. inlining_procedure:=oldinlining_procedure;
  2166. end;
  2167. function tprocinlinenode.pass_1 : tnode;
  2168. begin
  2169. firstpass(inlinetree);
  2170. registers32:=inlinetree.registers32;
  2171. registersfpu:=inlinetree.registersfpu;
  2172. {$ifdef SUPPORT_MMX}
  2173. registersmmx:=inlinetree.registersmmx;
  2174. {$endif SUPPORT_MMX}
  2175. result:=nil;
  2176. end;
  2177. function tprocinlinenode.docompare(p: tnode): boolean;
  2178. begin
  2179. docompare :=
  2180. inherited docompare(p) and
  2181. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  2182. (inlineprocdef = tprocinlinenode(p).inlineprocdef);
  2183. end;
  2184. begin
  2185. ccallnode:=tcallnode;
  2186. ccallparanode:=tcallparanode;
  2187. cprocinlinenode:=tprocinlinenode;
  2188. end.
  2189. {
  2190. $Log$
  2191. Revision 1.133 2003-04-07 10:40:21 jonas
  2192. * fixed VS_HIDDEN for high parameter so it works again
  2193. Revision 1.132 2003/04/04 15:38:56 peter
  2194. * moved generic code from n386cal to ncgcal, i386 now also
  2195. uses the generic ncgcal
  2196. Revision 1.131 2003/03/17 18:54:23 peter
  2197. * fix missing self setting for method to procvar conversion in
  2198. tp_procvar mode
  2199. Revision 1.130 2003/03/17 16:54:41 peter
  2200. * support DefaultHandler and anonymous inheritance fixed
  2201. for message methods
  2202. Revision 1.129 2003/03/17 15:54:22 peter
  2203. * store symoptions also for procdef
  2204. * check symoptions (private,public) when calculating possible
  2205. overload candidates
  2206. Revision 1.128 2003/02/19 22:00:14 daniel
  2207. * Code generator converted to new register notation
  2208. - Horribily outdated todo.txt removed
  2209. Revision 1.127 2003/01/16 22:13:52 peter
  2210. * convert_l3 convertlevel added. This level is used for conversions
  2211. where information can be lost like converting widestring->ansistring
  2212. or dword->byte
  2213. Revision 1.126 2003/01/15 01:44:32 peter
  2214. * merged methodpointer fixes from 1.0.x
  2215. Revision 1.125 2003/01/12 17:52:07 peter
  2216. * only check for auto inherited in objectsymtable
  2217. Revision 1.124 2003/01/09 21:45:46 peter
  2218. * extended information about overloaded candidates when compiled
  2219. with EXTDEBUG
  2220. Revision 1.123 2002/12/26 18:24:33 jonas
  2221. * fixed check for whether or not a high parameter was already generated
  2222. * no type checking/conversions for invisible parameters
  2223. Revision 1.122 2002/12/15 22:50:00 florian
  2224. + some stuff for the new hidden parameter handling added
  2225. Revision 1.121 2002/12/15 21:34:15 peter
  2226. * give sign difference between ordinals a small penalty. This is
  2227. needed to get word->[longword|longint] working
  2228. Revision 1.120 2002/12/15 21:30:12 florian
  2229. * tcallnode.paraitem introduced, all references to defcoll removed
  2230. Revision 1.119 2002/12/15 20:59:58 peter
  2231. * fix crash with default parameters
  2232. Revision 1.118 2002/12/15 11:26:02 peter
  2233. * ignore vs_hidden parameters when choosing overloaded proc
  2234. Revision 1.117 2002/12/11 22:42:28 peter
  2235. * tcallnode.det_resulttype rewrite, merged code from nice_ncal and
  2236. the old code. The new code collects the information about possible
  2237. candidates only once resultting in much less calls to type compare
  2238. routines
  2239. Revision 1.116 2002/12/07 14:27:07 carl
  2240. * 3% memory optimization
  2241. * changed some types
  2242. + added type checking with different size for call node and for
  2243. parameters
  2244. Revision 1.115 2002/12/06 17:51:10 peter
  2245. * merged cdecl and array fixes
  2246. Revision 1.114 2002/12/06 16:56:58 peter
  2247. * only compile cs_fp_emulation support when cpufpuemu is defined
  2248. * define cpufpuemu for m68k only
  2249. Revision 1.113 2002/11/27 20:04:38 peter
  2250. * cdecl array of const fixes
  2251. Revision 1.112 2002/11/27 15:33:46 peter
  2252. * the never ending story of tp procvar hacks
  2253. Revision 1.111 2002/11/27 02:31:17 peter
  2254. * fixed inlinetree parsing in det_resulttype
  2255. Revision 1.110 2002/11/25 18:43:32 carl
  2256. - removed the invalid if <> checking (Delphi is strange on this)
  2257. + implemented abstract warning on instance creation of class with
  2258. abstract methods.
  2259. * some error message cleanups
  2260. Revision 1.109 2002/11/25 17:43:17 peter
  2261. * splitted defbase in defutil,symutil,defcmp
  2262. * merged isconvertable and is_equal into compare_defs(_ext)
  2263. * made operator search faster by walking the list only once
  2264. Revision 1.108 2002/11/18 17:31:54 peter
  2265. * pass proccalloption to ret_in_xxx and push_xxx functions
  2266. Revision 1.107 2002/11/15 01:58:50 peter
  2267. * merged changes from 1.0.7 up to 04-11
  2268. - -V option for generating bug report tracing
  2269. - more tracing for option parsing
  2270. - errors for cdecl and high()
  2271. - win32 import stabs
  2272. - win32 records<=8 are returned in eax:edx (turned off by default)
  2273. - heaptrc update
  2274. - more info for temp management in .s file with EXTDEBUG
  2275. Revision 1.106 2002/10/14 18:20:30 carl
  2276. * var parameter checking for classes and interfaces in Delphi mode
  2277. Revision 1.105 2002/10/06 21:02:17 peter
  2278. * fixed limit checking for qword
  2279. Revision 1.104 2002/10/05 15:15:45 peter
  2280. * Write unknwon compiler proc using Comment and only in Extdebug
  2281. Revision 1.103 2002/10/05 12:43:25 carl
  2282. * fixes for Delphi 6 compilation
  2283. (warning : Some features do not work under Delphi)
  2284. Revision 1.102 2002/10/05 00:48:57 peter
  2285. * support inherited; support for overload as it is handled by
  2286. delphi. This is only for delphi mode as it is working is
  2287. undocumented and hard to predict what is done
  2288. Revision 1.101 2002/09/16 14:11:12 peter
  2289. * add argument to equal_paras() to support default values or not
  2290. Revision 1.100 2002/09/15 17:49:59 peter
  2291. * don't have strict var parameter checking for procedures in the
  2292. system unit
  2293. Revision 1.99 2002/09/09 19:30:34 peter
  2294. * don't allow convertable parameters for var and out parameters in
  2295. delphi and tp mode
  2296. Revision 1.98 2002/09/07 15:25:02 peter
  2297. * old logs removed and tabs fixed
  2298. Revision 1.97 2002/09/07 12:16:05 carl
  2299. * second part bug report 1996 fix, testrange in cordconstnode
  2300. only called if option is set (also make parsing a tiny faster)
  2301. Revision 1.96 2002/09/05 14:53:41 peter
  2302. * fixed old callnode.det_resulttype code
  2303. * old ncal code is default again
  2304. Revision 1.95 2002/09/03 21:32:49 daniel
  2305. * Small bugfix for procdef selection
  2306. Revision 1.94 2002/09/03 19:27:22 daniel
  2307. * Activated new ncal code
  2308. Revision 1.93 2002/09/03 16:26:26 daniel
  2309. * Make Tprocdef.defs protected
  2310. Revision 1.92 2002/09/01 13:28:37 daniel
  2311. - write_access fields removed in favor of a flag
  2312. Revision 1.91 2002/09/01 12:14:15 peter
  2313. * remove debug line
  2314. * containself methods can be called directly
  2315. Revision 1.90 2002/09/01 08:01:16 daniel
  2316. * Removed sets from Tcallnode.det_resulttype
  2317. + Added read/write notifications of variables. These will be usefull
  2318. for providing information for several optimizations. For example
  2319. the value of the loop variable of a for loop does matter is the
  2320. variable is read after the for loop, but if it's no longer used
  2321. or written, it doesn't matter and this can be used to optimize
  2322. the loop code generation.
  2323. Revision 1.89 2002/08/23 16:13:16 peter
  2324. * also firstpass funcretrefnode if available. This was breaking the
  2325. asnode compilerproc code
  2326. Revision 1.88 2002/08/20 10:31:26 daniel
  2327. * Tcallnode.det_resulttype rewritten
  2328. Revision 1.87 2002/08/19 19:36:42 peter
  2329. * More fixes for cross unit inlining, all tnodes are now implemented
  2330. * Moved pocall_internconst to po_internconst because it is not a
  2331. calling type at all and it conflicted when inlining of these small
  2332. functions was requested
  2333. Revision 1.86 2002/08/17 22:09:44 florian
  2334. * result type handling in tcgcal.pass_2 overhauled
  2335. * better tnode.dowrite
  2336. * some ppc stuff fixed
  2337. Revision 1.85 2002/08/17 09:23:34 florian
  2338. * first part of procinfo rewrite
  2339. Revision 1.84 2002/08/16 14:24:57 carl
  2340. * issameref() to test if two references are the same (then emit no opcodes)
  2341. + ret_in_reg to replace ret_in_acc
  2342. (fix some register allocation bugs at the same time)
  2343. + save_std_register now has an extra parameter which is the
  2344. usedinproc registers
  2345. Revision 1.83 2002/07/20 11:57:53 florian
  2346. * types.pas renamed to defbase.pas because D6 contains a types
  2347. unit so this would conflicts if D6 programms are compiled
  2348. + Willamette/SSE2 instructions to assembler added
  2349. Revision 1.82 2002/07/19 11:41:35 daniel
  2350. * State tracker work
  2351. * The whilen and repeatn are now completely unified into whilerepeatn. This
  2352. allows the state tracker to change while nodes automatically into
  2353. repeat nodes.
  2354. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  2355. 'not(a>b)' is optimized into 'a<=b'.
  2356. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  2357. by removing the notn and later switchting the true and falselabels. The
  2358. same is done with 'repeat until not a'.
  2359. Revision 1.81 2002/07/15 18:03:14 florian
  2360. * readded removed changes
  2361. Revision 1.79 2002/07/11 14:41:27 florian
  2362. * start of the new generic parameter handling
  2363. Revision 1.80 2002/07/14 18:00:43 daniel
  2364. + Added the beginning of a state tracker. This will track the values of
  2365. variables through procedures and optimize things away.
  2366. Revision 1.78 2002/07/04 20:43:00 florian
  2367. * first x86-64 patches
  2368. }