ncal.pas 88 KB

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