ncal.pas 88 KB

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