ncal.pas 111 KB

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