ncal.pas 85 KB

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