htypechk.pas 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit exports some help routines for the type checking
  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 htypechk;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. tokens,
  23. {$ifdef cg11}
  24. node,
  25. {$else cg11}
  26. tree,
  27. {$endif cg11}
  28. symtable;
  29. type
  30. {$ifdef cg11}
  31. Ttok2nodeRec=record
  32. tok : ttoken;
  33. nod : tnodetype;
  34. op_overloading_supported : boolean;
  35. {$else cg11}
  36. Ttok2nodeRec=record
  37. tok : ttoken;
  38. nod : ttreetyp;
  39. op_overloading_supported : boolean;
  40. {$endif cg11}
  41. end;
  42. const
  43. tok2nodes=25;
  44. tok2node:array[1..tok2nodes] of ttok2noderec=(
  45. (tok:_PLUS ;nod:addn;op_overloading_supported:true), { binary overloading supported }
  46. (tok:_MINUS ;nod:subn;op_overloading_supported:true), { binary and unary overloading supported }
  47. (tok:_STAR ;nod:muln;op_overloading_supported:true), { binary overloading supported }
  48. (tok:_SLASH ;nod:slashn;op_overloading_supported:true), { binary overloading supported }
  49. (tok:_EQUAL ;nod:equaln;op_overloading_supported:true), { binary overloading supported }
  50. (tok:_GT ;nod:gtn;op_overloading_supported:true), { binary overloading supported }
  51. (tok:_LT ;nod:ltn;op_overloading_supported:true), { binary overloading supported }
  52. (tok:_GTE ;nod:gten;op_overloading_supported:true), { binary overloading supported }
  53. (tok:_LTE ;nod:lten;op_overloading_supported:true), { binary overloading supported }
  54. (tok:_SYMDIF ;nod:symdifn;op_overloading_supported:true), { binary overloading supported }
  55. (tok:_STARSTAR;nod:starstarn;op_overloading_supported:true), { binary overloading supported }
  56. (tok:_OP_AS ;nod:asn;op_overloading_supported:false), { binary overloading NOT supported }
  57. (tok:_OP_IN ;nod:inn;op_overloading_supported:false), { binary overloading NOT supported }
  58. (tok:_OP_IS ;nod:isn;op_overloading_supported:false), { binary overloading NOT supported }
  59. (tok:_OP_OR ;nod:orn;op_overloading_supported:true), { binary overloading supported }
  60. (tok:_OP_AND ;nod:andn;op_overloading_supported:true), { binary overloading supported }
  61. (tok:_OP_DIV ;nod:divn;op_overloading_supported:true), { binary overloading supported }
  62. (tok:_OP_NOT ;nod:notn;op_overloading_supported:true), { unary overloading supported }
  63. (tok:_OP_MOD ;nod:modn;op_overloading_supported:true), { binary overloading supported }
  64. (tok:_OP_SHL ;nod:shln;op_overloading_supported:true), { binary overloading supported }
  65. (tok:_OP_SHR ;nod:shrn;op_overloading_supported:true), { binary overloading supported }
  66. (tok:_OP_XOR ;nod:xorn;op_overloading_supported:true), { binary overloading supported }
  67. (tok:_ASSIGNMENT;nod:assignn;op_overloading_supported:true), { unary overloading supported }
  68. (tok:_CARET ;nod:caretn;op_overloading_supported:false), { binary overloading NOT supported }
  69. (tok:_UNEQUAL ;nod:unequaln;op_overloading_supported:false) { binary overloading NOT supported overload = instead }
  70. );
  71. const
  72. { firstcallparan without varspez we don't count the ref }
  73. {$ifdef extdebug}
  74. count_ref : boolean = true;
  75. {$endif def extdebug}
  76. get_para_resulttype : boolean = false;
  77. allow_array_constructor : boolean = false;
  78. {$ifdef cg11}
  79. { is overloading of this operator allowed for this
  80. binary operator }
  81. function isbinaryoperatoroverloadable(ld, rd,dd : pdef;
  82. treetyp : tnodetype) : boolean;
  83. { is overloading of this operator allowed for this
  84. unary operator }
  85. function isunaryoperatoroverloadable(rd,dd : pdef;
  86. treetyp : tnodetype) : boolean;
  87. { check operator args and result type }
  88. function isoperatoracceptable(pf : pprocdef; optoken : ttoken) : boolean;
  89. function isbinaryoverloaded(var t : tnode) : boolean;
  90. { Register Allocation }
  91. procedure make_not_regable(p : tnode);
  92. procedure calcregisters(p : tbinarynode;r32,fpu,mmx : word);
  93. { subroutine handling }
  94. procedure test_protected_sym(sym : psym);
  95. procedure test_protected(p : tnode);
  96. function valid_for_formal_var(p : tnode) : boolean;
  97. function valid_for_formal_const(p : tnode) : boolean;
  98. function is_procsym_load(p:tnode):boolean;
  99. function is_procsym_call(p:tnode):boolean;
  100. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  101. function valid_for_assign(p:tnode;allowprop:boolean):boolean;
  102. { sets the callunique flag, if the node is a vecn, }
  103. { takes care of type casts etc. }
  104. procedure set_unique(p : tnode);
  105. { sets funcret_is_valid to true, if p contains a funcref node }
  106. procedure set_funcret_is_valid(p : tnode);
  107. {
  108. type
  109. tvarstaterequire = (vsr_can_be_undefined,vsr_must_be_valid,
  110. vsr_is_used_after,vsr_must_be_valid_and_is_used_after); }
  111. { sets varsym varstate field correctly }
  112. procedure unset_varstate(p : tnode);
  113. procedure set_varstate(p : tnode;must_be_valid : boolean);
  114. {$else cg11}
  115. { Conversion }
  116. function isconvertable(def_from,def_to : pdef;
  117. var doconv : tconverttype;fromtreetype : ttreetyp;
  118. explicit : boolean) : byte;
  119. { is overloading of this operator allowed for this
  120. binary operator }
  121. function isbinaryoperatoroverloadable(ld, rd,dd : pdef;
  122. treetyp : ttreetyp) : boolean;
  123. { is overloading of this operator allowed for this
  124. unary operator }
  125. function isunaryoperatoroverloadable(rd,dd : pdef;
  126. treetyp : ttreetyp) : boolean;
  127. { check operator args and result type }
  128. function isoperatoracceptable(pf : pprocdef; optoken : ttoken) : boolean;
  129. { Register Allocation }
  130. procedure make_not_regable(p : ptree);
  131. procedure left_right_max(p : ptree);
  132. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  133. { subroutine handling }
  134. procedure test_protected_sym(sym : psym);
  135. procedure test_protected(p : ptree);
  136. function valid_for_formal_var(p : ptree) : boolean;
  137. function valid_for_formal_const(p : ptree) : boolean;
  138. function is_procsym_load(p:Ptree):boolean;
  139. function is_procsym_call(p:Ptree):boolean;
  140. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  141. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  142. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  143. { sets the callunique flag, if the node is a vecn, }
  144. { takes care of type casts etc. }
  145. procedure set_unique(p : ptree);
  146. { sets funcret_is_valid to true, if p contains a funcref node }
  147. procedure set_funcret_is_valid(p : ptree);
  148. {
  149. type
  150. tvarstaterequire = (vsr_can_be_undefined,vsr_must_be_valid,
  151. vsr_is_used_after,vsr_must_be_valid_and_is_used_after); }
  152. { sets varsym varstate field correctly }
  153. procedure unset_varstate(p : ptree);
  154. procedure set_varstate(p : ptree;must_be_valid : boolean);
  155. {$endif cg11}
  156. implementation
  157. uses
  158. globtype,systems,
  159. cutils,cobjects,verbose,globals,
  160. symconst,
  161. types,pass_1,cpubase,
  162. {$ifdef cg11}
  163. ncnv,nld,
  164. nmem,ncal,nmat,
  165. {$endif cg11}
  166. {$ifdef newcg}
  167. cgbase
  168. {$else}
  169. hcodegen
  170. {$endif}
  171. ;
  172. {$ifdef cg11}
  173. { ld is the left type definition
  174. rd the right type definition
  175. dd the result type definition or voiddef if unkown }
  176. function isbinaryoperatoroverloadable(ld, rd, dd : pdef;
  177. treetyp : tnodetype) : boolean;
  178. begin
  179. isbinaryoperatoroverloadable:=
  180. (treetyp=starstarn) or
  181. (ld^.deftype=recorddef) or
  182. (rd^.deftype=recorddef) or
  183. ((rd^.deftype=pointerdef) and
  184. not(is_pchar(rd) and
  185. (is_chararray(ld) or
  186. (ld^.deftype=stringdef) or
  187. (treetyp=addn))) and
  188. (not(ld^.deftype in [pointerdef,objectdef,classrefdef,procvardef]) or
  189. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,subn])
  190. ) and
  191. (not is_integer(ld) or not (treetyp in [addn,subn]))
  192. ) or
  193. ((ld^.deftype=pointerdef) and
  194. not(is_pchar(ld) and
  195. (is_chararray(rd) or
  196. (rd^.deftype=stringdef) or
  197. (treetyp=addn))) and
  198. (not(rd^.deftype in [stringdef,pointerdef,objectdef,classrefdef,procvardef]) and
  199. ((not is_integer(rd) and (rd^.deftype<>objectdef)
  200. and (rd^.deftype<>classrefdef)) or
  201. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,addn,subn])
  202. )
  203. )
  204. ) or
  205. { array def, but not mmx or chararray+[char,string,chararray] }
  206. ((ld^.deftype=arraydef) and
  207. not((cs_mmx in aktlocalswitches) and
  208. is_mmx_able_array(ld)) and
  209. not(is_chararray(ld) and
  210. (is_char(rd) or
  211. is_pchar(rd) or
  212. (rd^.deftype=stringdef) or
  213. is_chararray(rd)))
  214. ) or
  215. ((rd^.deftype=arraydef) and
  216. not((cs_mmx in aktlocalswitches) and
  217. is_mmx_able_array(rd)) and
  218. not(is_chararray(rd) and
  219. (is_char(ld) or
  220. is_pchar(ld) or
  221. (ld^.deftype=stringdef) or
  222. is_chararray(ld)))
  223. ) or
  224. { <> and = are defined for classes }
  225. ((ld^.deftype=objectdef) and
  226. (not(pobjectdef(ld)^.is_class) or
  227. not(treetyp in [equaln,unequaln])
  228. )
  229. ) or
  230. ((rd^.deftype=objectdef) and
  231. (not(pobjectdef(rd)^.is_class) or
  232. not(treetyp in [equaln,unequaln])
  233. )
  234. or
  235. { allow other operators that + on strings }
  236. (
  237. (is_char(rd) or
  238. is_pchar(rd) or
  239. (rd^.deftype=stringdef) or
  240. is_chararray(rd) or
  241. is_char(ld) or
  242. is_pchar(ld) or
  243. (ld^.deftype=stringdef) or
  244. is_chararray(ld)
  245. ) and
  246. not(treetyp in [addn,equaln,unequaln,gtn,gten,ltn,lten]) and
  247. not(is_pchar(ld) and
  248. (is_integer(rd) or (rd^.deftype=pointerdef)) and
  249. (treetyp=subn)
  250. )
  251. )
  252. );
  253. end;
  254. function isunaryoperatoroverloadable(rd,dd : pdef;
  255. treetyp : tnodetype) : boolean;
  256. begin
  257. isunaryoperatoroverloadable:=false;
  258. { what assignment overloading should be allowed ?? }
  259. if (treetyp=assignn) then
  260. begin
  261. isunaryoperatoroverloadable:=true;
  262. { this already get tbs0261 to fail
  263. isunaryoperatoroverloadable:=not is_equal(rd,dd); PM }
  264. end
  265. { should we force that rd and dd are equal ?? }
  266. else if (treetyp=subn { unaryminusn }) then
  267. begin
  268. isunaryoperatoroverloadable:=
  269. not is_integer(rd) and not (rd^.deftype=floatdef)
  270. {$ifdef SUPPORT_MMX}
  271. and not ((cs_mmx in aktlocalswitches) and
  272. is_mmx_able_array(rd))
  273. {$endif SUPPORT_MMX}
  274. ;
  275. end
  276. else if (treetyp=notn) then
  277. begin
  278. isunaryoperatoroverloadable:=not is_integer(rd) and not is_boolean(rd)
  279. {$ifdef SUPPORT_MMX}
  280. and not ((cs_mmx in aktlocalswitches) and
  281. is_mmx_able_array(rd))
  282. {$endif SUPPORT_MMX}
  283. ;
  284. end;
  285. end;
  286. function isoperatoracceptable(pf : pprocdef; optoken : ttoken) : boolean;
  287. var
  288. ld,rd,dd : pdef;
  289. i : longint;
  290. begin
  291. case pf^.parast^.symindex^.count of
  292. 2 : begin
  293. isoperatoracceptable:=false;
  294. for i:=1 to tok2nodes do
  295. if tok2node[i].tok=optoken then
  296. begin
  297. ld:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  298. rd:=pvarsym(pf^.parast^.symindex^.first^.indexnext)^.vartype.def;
  299. dd:=pf^.rettype.def;
  300. isoperatoracceptable:=
  301. tok2node[i].op_overloading_supported and
  302. isbinaryoperatoroverloadable(ld,rd,dd,tok2node[i].nod);
  303. break;
  304. end;
  305. end;
  306. 1 : begin
  307. rd:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  308. dd:=pf^.rettype.def;
  309. for i:=1 to tok2nodes do
  310. if tok2node[i].tok=optoken then
  311. begin
  312. isoperatoracceptable:=
  313. tok2node[i].op_overloading_supported and
  314. isunaryoperatoroverloadable(rd,dd,tok2node[i].nod);
  315. break;
  316. end;
  317. end;
  318. else
  319. isoperatoracceptable:=false;
  320. end;
  321. end;
  322. function isbinaryoverloaded(var t : tnode) : boolean;
  323. var
  324. rd,ld : pdef;
  325. optoken : ttoken;
  326. ht : tnode;
  327. begin
  328. isbinaryoverloaded:=false;
  329. { overloaded operator ? }
  330. { load easier access variables }
  331. rd:=tbinarynode(t).right.resulttype;
  332. ld:=tbinarynode(t).left.resulttype;
  333. if isbinaryoperatoroverloadable(ld,rd,voiddef,t.nodetype) then
  334. begin
  335. isbinaryoverloaded:=true;
  336. {!!!!!!!!! handle paras }
  337. case t.nodetype of
  338. addn:
  339. optoken:=_PLUS;
  340. subn:
  341. optoken:=_MINUS;
  342. muln:
  343. optoken:=_STAR;
  344. starstarn:
  345. optoken:=_STARSTAR;
  346. slashn:
  347. optoken:=_SLASH;
  348. ltn:
  349. optoken:=tokens._lt;
  350. gtn:
  351. optoken:=tokens._gt;
  352. lten:
  353. optoken:=_lte;
  354. gten:
  355. optoken:=_gte;
  356. equaln,unequaln :
  357. optoken:=_EQUAL;
  358. symdifn :
  359. optoken:=_SYMDIF;
  360. modn :
  361. optoken:=_OP_MOD;
  362. orn :
  363. optoken:=_OP_OR;
  364. xorn :
  365. optoken:=_OP_XOR;
  366. andn :
  367. optoken:=_OP_AND;
  368. divn :
  369. optoken:=_OP_DIV;
  370. shln :
  371. optoken:=_OP_SHL;
  372. shrn :
  373. optoken:=_OP_SHR;
  374. else
  375. exit;
  376. end;
  377. { the nil as symtable signs firstcalln that this is
  378. an overloaded operator }
  379. ht:=gencallnode(overloaded_operators[optoken],nil);
  380. { we have to convert p^.left and p^.right into
  381. callparanodes }
  382. if tcallnode(ht).symtableprocentry=nil then
  383. begin
  384. CGMessage(parser_e_operator_not_overloaded);
  385. ht.free;
  386. end
  387. else
  388. begin
  389. inc(tcallnode(ht).symtableprocentry^.refs);
  390. tcallnode(ht).left:=gencallparanode(tbinarynode(t).right,
  391. gencallparanode(tbinarynode(t).left,nil));
  392. if t.nodetype=unequaln then
  393. ht:=cnotnode.create(ht);
  394. firstpass(ht);
  395. t:=ht;
  396. end;
  397. end;
  398. end;
  399. {****************************************************************************
  400. Register Calculation
  401. ****************************************************************************}
  402. { marks an lvalue as "unregable" }
  403. procedure make_not_regable(p : tnode);
  404. begin
  405. case p.nodetype of
  406. typeconvn :
  407. make_not_regable(ttypeconvnode(p).left);
  408. loadn :
  409. if tloadnode(p).symtableentry^.typ=varsym then
  410. pvarsym(tloadnode(p).symtableentry)^.varoptions:=pvarsym(tloadnode(p).symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  411. end;
  412. end;
  413. { calculates the needed registers for a binary operator }
  414. procedure calcregisters(p : tbinarynode;r32,fpu,mmx : word);
  415. begin
  416. p.left_right_max;
  417. { Only when the difference between the left and right registers < the
  418. wanted registers allocate the amount of registers }
  419. if assigned(p.left) then
  420. begin
  421. if assigned(p.right) then
  422. begin
  423. if (abs(p.left.registers32-p.right.registers32)<r32) then
  424. inc(p.registers32,r32);
  425. if (abs(p.left.registersfpu-p.right.registersfpu)<fpu) then
  426. inc(p.registersfpu,fpu);
  427. {$ifdef SUPPORT_MMX}
  428. if (abs(p.left.registersmmx-p.right.registersmmx)<mmx) then
  429. inc(p.registersmmx,mmx);
  430. {$endif SUPPORT_MMX}
  431. { the following is a little bit guessing but I think }
  432. { it's the only way to solve same internalerrors: }
  433. { if the left and right node both uses registers }
  434. { and return a mem location, but the current node }
  435. { doesn't use an integer register we get probably }
  436. { trouble when restoring a node }
  437. if (p.left.registers32=p.right.registers32) and
  438. (p.registers32=p.left.registers32) and
  439. (p.registers32>0) and
  440. (p.left.location.loc in [LOC_REFERENCE,LOC_MEM]) and
  441. (p.right.location.loc in [LOC_REFERENCE,LOC_MEM]) then
  442. inc(p.registers32);
  443. end
  444. else
  445. begin
  446. if (p.left.registers32<r32) then
  447. inc(p.registers32,r32);
  448. if (p.left.registersfpu<fpu) then
  449. inc(p.registersfpu,fpu);
  450. {$ifdef SUPPORT_MMX}
  451. if (p.left.registersmmx<mmx) then
  452. inc(p.registersmmx,mmx);
  453. {$endif SUPPORT_MMX}
  454. end;
  455. end;
  456. { error CGMessage, if more than 8 floating point }
  457. { registers are needed }
  458. if p.registersfpu>8 then
  459. CGMessage(cg_e_too_complex_expr);
  460. end;
  461. {****************************************************************************
  462. Subroutine Handling
  463. ****************************************************************************}
  464. { protected field handling
  465. protected field can not appear in
  466. var parameters of function !!
  467. this can only be done after we have determined the
  468. overloaded function
  469. this is the reason why it is not in the parser, PM }
  470. procedure test_protected_sym(sym : psym);
  471. begin
  472. if (sp_protected in sym^.symoptions) and
  473. ((sym^.owner^.symtabletype=unitsymtable) or
  474. ((sym^.owner^.symtabletype=objectsymtable) and
  475. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  476. ) then
  477. CGMessage(parser_e_cant_access_protected_member);
  478. end;
  479. procedure test_protected(p : tnode);
  480. begin
  481. case p.nodetype of
  482. loadn : test_protected_sym(tloadnode(p).symtableentry);
  483. typeconvn : test_protected(ttypeconvnode(p).left);
  484. derefn : test_protected(tderefnode(p).left);
  485. subscriptn : begin
  486. { test_protected(p.left);
  487. Is a field of a protected var
  488. also protected ??? PM }
  489. test_protected_sym(tsubscriptnode(p).vs);
  490. end;
  491. end;
  492. end;
  493. function valid_for_formal_var(p : tnode) : boolean;
  494. var
  495. v : boolean;
  496. begin
  497. case p.nodetype of
  498. loadn :
  499. v:=(tloadnode(p).symtableentry^.typ in [typedconstsym,varsym]);
  500. typeconvn :
  501. v:=valid_for_formal_var(ttypeconvnode(p).left);
  502. derefn,
  503. subscriptn,
  504. vecn,
  505. funcretn,
  506. selfn :
  507. v:=true;
  508. calln : { procvars are callnodes first }
  509. v:=assigned(tcallnode(p).right) and not assigned(tcallnode(p).left);
  510. addrn :
  511. begin
  512. { addrn is not allowed as this generate a constant value,
  513. but a tp procvar are allowed (PFV) }
  514. if nf_procvarload in p.flags then
  515. v:=true
  516. else
  517. v:=false;
  518. end;
  519. else
  520. v:=false;
  521. end;
  522. valid_for_formal_var:=v;
  523. end;
  524. function valid_for_formal_const(p : tnode) : boolean;
  525. var
  526. v : boolean;
  527. begin
  528. { p must have been firstpass'd before }
  529. { accept about anything but not a statement ! }
  530. case p.nodetype of
  531. calln,
  532. statementn,
  533. addrn :
  534. begin
  535. { addrn is not allowed as this generate a constant value,
  536. but a tp procvar are allowed (PFV) }
  537. if nf_procvarload in p.flags then
  538. v:=true
  539. else
  540. v:=false;
  541. end;
  542. else
  543. v:=true;
  544. end;
  545. valid_for_formal_const:=v;
  546. end;
  547. function is_procsym_load(p:tnode):boolean;
  548. begin
  549. is_procsym_load:=((p.nodetype=loadn) and (tloadnode(p).symtableentry^.typ=procsym)) or
  550. ((p.nodetype=addrn) and (taddrnode(p).left.nodetype=loadn)
  551. and (tloadnode(taddrnode(p).left).symtableentry^.typ=procsym)) ;
  552. end;
  553. { change a proc call to a procload for assignment to a procvar }
  554. { this can only happen for proc/function without arguments }
  555. function is_procsym_call(p:tnode):boolean;
  556. begin
  557. is_procsym_call:=(p.nodetype=calln) and (tcallnode(p).left=nil) and
  558. (((tcallnode(p).symtableprocentry^.typ=procsym) and (tcallnode(p).right=nil)) or
  559. (assigned(tcallnode(p).right) and (tcallnode(tcallnode(p).right).symtableprocentry^.typ=varsym)));
  560. end;
  561. { local routines can't be assigned to procvars }
  562. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  563. begin
  564. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  565. CGMessage(type_e_cannot_local_proc_to_procvar);
  566. end;
  567. function valid_for_assign(p:tnode;allowprop:boolean):boolean;
  568. var
  569. hp : tnode;
  570. gotwith,
  571. gotsubscript,
  572. gotpointer,
  573. gotclass,
  574. gotderef : boolean;
  575. begin
  576. valid_for_assign:=false;
  577. gotsubscript:=false;
  578. gotderef:=false;
  579. gotclass:=false;
  580. gotpointer:=false;
  581. gotwith:=false;
  582. hp:=p;
  583. while assigned(hp) do
  584. begin
  585. { property allowed? calln has a property check itself }
  586. if (not allowprop) and
  587. (nf_isproperty in hp.flags) and
  588. (hp.nodetype<>calln) then
  589. begin
  590. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  591. exit;
  592. end;
  593. case hp.nodetype of
  594. derefn :
  595. begin
  596. gotderef:=true;
  597. hp:=tderefnode(hp).left;
  598. end;
  599. typeconvn :
  600. begin
  601. case hp.resulttype^.deftype of
  602. pointerdef :
  603. gotpointer:=true;
  604. objectdef :
  605. gotclass:=pobjectdef(hp.resulttype)^.is_class;
  606. classrefdef :
  607. gotclass:=true;
  608. arraydef :
  609. begin
  610. { pointer -> array conversion is done then we need to see it
  611. as a deref, because a ^ is then not required anymore }
  612. if (ttypeconvnode(hp).left.resulttype^.deftype=pointerdef) then
  613. gotderef:=true;
  614. end;
  615. end;
  616. hp:=ttypeconvnode(hp).left;
  617. end;
  618. vecn,
  619. asn :
  620. hp:=tunarynode(hp).left;
  621. subscriptn :
  622. begin
  623. gotsubscript:=true;
  624. hp:=tsubscriptnode(hp).left;
  625. end;
  626. subn,
  627. addn :
  628. begin
  629. { Allow add/sub operators on a pointer, or an integer
  630. and a pointer typecast and deref has been found }
  631. if (hp.resulttype^.deftype=pointerdef) or
  632. (is_integer(hp.resulttype) and gotpointer and gotderef) then
  633. valid_for_assign:=true
  634. else
  635. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  636. exit;
  637. end;
  638. addrn :
  639. begin
  640. if not(gotderef) and
  641. not(nf_procvarload in hp.flags) then
  642. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  643. exit;
  644. end;
  645. selfn,
  646. funcretn :
  647. begin
  648. valid_for_assign:=true;
  649. exit;
  650. end;
  651. calln :
  652. begin
  653. { check return type }
  654. case hp.resulttype^.deftype of
  655. pointerdef :
  656. gotpointer:=true;
  657. objectdef :
  658. gotclass:=pobjectdef(hp.resulttype)^.is_class;
  659. recorddef, { handle record like class it needs a subscription }
  660. classrefdef :
  661. gotclass:=true;
  662. end;
  663. { 1. if it returns a pointer and we've found a deref,
  664. 2. if it returns a class or record and a subscription or with is found,
  665. 3. property is allowed }
  666. if (gotpointer and gotderef) or
  667. (gotclass and (gotsubscript or gotwith)) or
  668. ((nf_isproperty in hp.flags) and allowprop) then
  669. valid_for_assign:=true
  670. else
  671. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  672. exit;
  673. end;
  674. loadn :
  675. begin
  676. case tloadnode(hp).symtableentry^.typ of
  677. absolutesym,
  678. varsym :
  679. begin
  680. if (pvarsym(tloadnode(hp).symtableentry)^.varspez=vs_const) then
  681. begin
  682. { allow p^:= constructions with p is const parameter }
  683. if gotderef then
  684. valid_for_assign:=true
  685. else
  686. CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
  687. exit;
  688. end;
  689. { Are we at a with symtable, then we need to process the
  690. withrefnode also to check for maybe a const load }
  691. if (tloadnode(hp).symtable^.symtabletype=withsymtable) then
  692. begin
  693. { continue with processing the withref node }
  694. hp:=tnode(pwithsymtable(tloadnode(hp).symtable)^.withrefnode);
  695. gotwith:=true;
  696. end
  697. else
  698. begin
  699. { set the assigned flag for varsyms }
  700. if (pvarsym(tloadnode(hp).symtableentry)^.varstate=vs_declared) then
  701. pvarsym(tloadnode(hp).symtableentry)^.varstate:=vs_assigned;
  702. valid_for_assign:=true;
  703. exit;
  704. end;
  705. end;
  706. funcretsym,
  707. typedconstsym :
  708. begin
  709. valid_for_assign:=true;
  710. exit;
  711. end;
  712. end;
  713. end;
  714. else
  715. begin
  716. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  717. exit;
  718. end;
  719. end;
  720. end;
  721. end;
  722. procedure set_varstate(p : tnode;must_be_valid : boolean);
  723. var
  724. hsym : pvarsym;
  725. begin
  726. while assigned(p) do
  727. begin
  728. if (nf_varstateset in p.flags) then
  729. exit;
  730. include(p.flags,nf_varstateset);
  731. case p.nodetype of
  732. typeconvn :
  733. begin
  734. case ttypeconvnode(p).convtype of
  735. tc_cchar_2_pchar,
  736. tc_cstring_2_pchar,
  737. tc_array_2_pointer :
  738. must_be_valid:=false;
  739. tc_pchar_2_string,
  740. tc_pointer_2_array :
  741. must_be_valid:=true;
  742. end;
  743. p:=tunarynode(p).left;
  744. end;
  745. subscriptn :
  746. p:=tunarynode(p).left;
  747. vecn:
  748. begin
  749. set_varstate(tbinarynode(p).right,true);
  750. if not(tunarynode(p).left.resulttype^.deftype in [stringdef,arraydef]) then
  751. must_be_valid:=true;
  752. p:=tunarynode(p).left;
  753. end;
  754. { do not parse calln }
  755. calln :
  756. break;
  757. callparan :
  758. begin
  759. set_varstate(tbinarynode(p).right,must_be_valid);
  760. p:=tunarynode(p).left;
  761. end;
  762. loadn :
  763. begin
  764. if (tloadnode(p).symtableentry^.typ=varsym) then
  765. begin
  766. hsym:=pvarsym(tloadnode(p).symtableentry);
  767. if must_be_valid and (nf_first in p.flags) then
  768. begin
  769. if (hsym^.varstate=vs_declared_and_first_found) or
  770. (hsym^.varstate=vs_set_but_first_not_passed) then
  771. begin
  772. if (assigned(hsym^.owner) and
  773. assigned(aktprocsym) and
  774. (hsym^.owner = aktprocsym^.definition^.localst)) then
  775. begin
  776. if tloadnode(p).symtable^.symtabletype=localsymtable then
  777. CGMessage1(sym_n_uninitialized_local_variable,hsym^.name)
  778. else
  779. CGMessage1(sym_n_uninitialized_variable,hsym^.name);
  780. end;
  781. end;
  782. end;
  783. if (nf_first in p.flags) then
  784. begin
  785. if hsym^.varstate=vs_declared_and_first_found then
  786. begin
  787. { this can only happen at left of an assignment, no ? PM }
  788. if (parsing_para_level=0) and not must_be_valid then
  789. hsym^.varstate:=vs_assigned
  790. else
  791. hsym^.varstate:=vs_used;
  792. end
  793. else
  794. if hsym^.varstate=vs_set_but_first_not_passed then
  795. hsym^.varstate:=vs_used;
  796. exclude(p.flags,nf_first);
  797. end
  798. else
  799. begin
  800. if (hsym^.varstate=vs_assigned) and
  801. (must_be_valid or (parsing_para_level>0) or
  802. (p.resulttype^.deftype=procvardef)) then
  803. hsym^.varstate:=vs_used;
  804. if (hsym^.varstate=vs_declared_and_first_found) and
  805. (must_be_valid or (parsing_para_level>0) or
  806. (p.resulttype^.deftype=procvardef)) then
  807. hsym^.varstate:=vs_set_but_first_not_passed;
  808. end;
  809. end;
  810. break;
  811. end;
  812. funcretn:
  813. begin
  814. { no claim if setting higher return value_str }
  815. if must_be_valid and
  816. (procinfo=pprocinfo(tfuncretnode(p).funcretprocinfo)) and
  817. ((procinfo^.funcret_state=vs_declared) or
  818. ((nf_is_first_funcret in p.flags) and
  819. (procinfo^.funcret_state=vs_declared_and_first_found))) then
  820. begin
  821. CGMessage(sym_w_function_result_not_set);
  822. { avoid multiple warnings }
  823. procinfo^.funcret_state:=vs_assigned;
  824. end;
  825. if (nf_is_first_funcret in p.flags) and not must_be_valid then
  826. pprocinfo(tfuncretnode(p).funcretprocinfo)^.funcret_state:=vs_assigned;
  827. break;
  828. end;
  829. else
  830. break;
  831. end;{case }
  832. end;
  833. end;
  834. procedure unset_varstate(p : tnode);
  835. begin
  836. while assigned(p) do
  837. begin
  838. exclude(p.flags,nf_varstateset);
  839. case p.nodetype of
  840. typeconvn,
  841. subscriptn,
  842. vecn :
  843. p:=tunarynode(p).left;
  844. else
  845. break;
  846. end;
  847. end;
  848. end;
  849. procedure set_unique(p : tnode);
  850. begin
  851. while assigned(p) do
  852. begin
  853. case p.nodetype of
  854. vecn:
  855. begin
  856. include(p.flags,nf_callunique);
  857. break;
  858. end;
  859. typeconvn,
  860. subscriptn,
  861. derefn:
  862. p:=tunarynode(p).left;
  863. else
  864. break;
  865. end;
  866. end;
  867. end;
  868. procedure set_funcret_is_valid(p:tnode);
  869. begin
  870. while assigned(p) do
  871. begin
  872. case p.nodetype of
  873. funcretn:
  874. begin
  875. if (nf_is_first_funcret in p.flags) then
  876. pprocinfo(tfuncretnode(p).funcretprocinfo)^.funcret_state:=vs_assigned;
  877. break;
  878. end;
  879. vecn,
  880. {derefn,}
  881. typeconvn,
  882. subscriptn:
  883. p:=tunarynode(p).left;
  884. else
  885. break;
  886. end;
  887. end;
  888. end;
  889. {$else cg11}
  890. {****************************************************************************
  891. Convert
  892. ****************************************************************************}
  893. { Returns:
  894. 0 - Not convertable
  895. 1 - Convertable
  896. 2 - Convertable, but not first choice }
  897. function isconvertable(def_from,def_to : pdef;
  898. var doconv : tconverttype;fromtreetype : ttreetyp;
  899. explicit : boolean) : byte;
  900. { Tbasetype: uauto,uvoid,uchar,
  901. u8bit,u16bit,u32bit,
  902. s8bit,s16bit,s32,
  903. bool8bit,bool16bit,bool32bit,
  904. u64bit,s64bitint }
  905. type
  906. tbasedef=(bvoid,bchar,bint,bbool);
  907. const
  908. basedeftbl:array[tbasetype] of tbasedef =
  909. (bvoid,bvoid,bchar,
  910. bint,bint,bint,
  911. bint,bint,bint,
  912. bbool,bbool,bbool,bint,bint,bchar);
  913. basedefconverts : array[tbasedef,tbasedef] of tconverttype =
  914. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  915. (tc_not_possible,tc_equal,tc_not_possible,tc_not_possible),
  916. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_int_2_bool),
  917. (tc_not_possible,tc_not_possible,tc_bool_2_int,tc_bool_2_bool));
  918. var
  919. b : byte;
  920. hd1,hd2 : pdef;
  921. hct : tconverttype;
  922. begin
  923. { safety check }
  924. if not(assigned(def_from) and assigned(def_to)) then
  925. begin
  926. isconvertable:=0;
  927. exit;
  928. end;
  929. { tp7 procvar def support, in tp7 a procvar is always called, if the
  930. procvar is passed explicit a addrn would be there }
  931. if (m_tp_procvar in aktmodeswitches) and
  932. (def_from^.deftype=procvardef) and
  933. (fromtreetype=loadn) then
  934. begin
  935. def_from:=pprocvardef(def_from)^.rettype.def;
  936. end;
  937. { we walk the wanted (def_to) types and check then the def_from
  938. types if there is a conversion possible }
  939. b:=0;
  940. case def_to^.deftype of
  941. orddef :
  942. begin
  943. case def_from^.deftype of
  944. orddef :
  945. begin
  946. doconv:=basedefconverts[basedeftbl[porddef(def_from)^.typ],basedeftbl[porddef(def_to)^.typ]];
  947. b:=1;
  948. if (doconv=tc_not_possible) or
  949. ((doconv=tc_int_2_bool) and
  950. (not explicit) and
  951. (not is_boolean(def_from))) or
  952. ((doconv=tc_bool_2_int) and
  953. (not explicit) and
  954. (not is_boolean(def_to))) then
  955. b:=0;
  956. end;
  957. enumdef :
  958. begin
  959. { needed for char(enum) }
  960. if explicit then
  961. begin
  962. doconv:=tc_int_2_int;
  963. b:=1;
  964. end;
  965. end;
  966. end;
  967. end;
  968. stringdef :
  969. begin
  970. case def_from^.deftype of
  971. stringdef :
  972. begin
  973. doconv:=tc_string_2_string;
  974. b:=1;
  975. end;
  976. orddef :
  977. begin
  978. { char to string}
  979. if is_char(def_from) then
  980. begin
  981. doconv:=tc_char_2_string;
  982. b:=1;
  983. end;
  984. end;
  985. arraydef :
  986. begin
  987. { array of char to string, the length check is done by the firstpass of this node }
  988. if is_chararray(def_from) then
  989. begin
  990. doconv:=tc_chararray_2_string;
  991. if (not(cs_ansistrings in aktlocalswitches) and
  992. is_shortstring(def_to)) or
  993. ((cs_ansistrings in aktlocalswitches) and
  994. is_ansistring(def_to)) then
  995. b:=1
  996. else
  997. b:=2;
  998. end;
  999. end;
  1000. pointerdef :
  1001. begin
  1002. { pchar can be assigned to short/ansistrings,
  1003. but not in tp7 compatible mode }
  1004. if is_pchar(def_from) and not(m_tp7 in aktmodeswitches) then
  1005. begin
  1006. doconv:=tc_pchar_2_string;
  1007. b:=1;
  1008. end;
  1009. end;
  1010. end;
  1011. end;
  1012. floatdef :
  1013. begin
  1014. case def_from^.deftype of
  1015. orddef :
  1016. begin { ordinal to real }
  1017. if is_integer(def_from) then
  1018. begin
  1019. if pfloatdef(def_to)^.typ=f32bit then
  1020. doconv:=tc_int_2_fix
  1021. else
  1022. doconv:=tc_int_2_real;
  1023. b:=1;
  1024. end;
  1025. end;
  1026. floatdef :
  1027. begin { 2 float types ? }
  1028. if pfloatdef(def_from)^.typ=pfloatdef(def_to)^.typ then
  1029. doconv:=tc_equal
  1030. else
  1031. begin
  1032. if pfloatdef(def_from)^.typ=f32bit then
  1033. doconv:=tc_fix_2_real
  1034. else
  1035. if pfloatdef(def_to)^.typ=f32bit then
  1036. doconv:=tc_real_2_fix
  1037. else
  1038. doconv:=tc_real_2_real;
  1039. end;
  1040. b:=1;
  1041. end;
  1042. end;
  1043. end;
  1044. enumdef :
  1045. begin
  1046. if (def_from^.deftype=enumdef) then
  1047. begin
  1048. hd1:=def_from;
  1049. while assigned(penumdef(hd1)^.basedef) do
  1050. hd1:=penumdef(hd1)^.basedef;
  1051. hd2:=def_to;
  1052. while assigned(penumdef(hd2)^.basedef) do
  1053. hd2:=penumdef(hd2)^.basedef;
  1054. if (hd1=hd2) then
  1055. begin
  1056. b:=1;
  1057. { because of packenum they can have different sizes! (JM) }
  1058. doconv:=tc_int_2_int;
  1059. end;
  1060. end;
  1061. end;
  1062. arraydef :
  1063. begin
  1064. { open array is also compatible with a single element of its base type }
  1065. if is_open_array(def_to) and
  1066. is_equal(parraydef(def_to)^.elementtype.def,def_from) then
  1067. begin
  1068. doconv:=tc_equal;
  1069. b:=1;
  1070. end
  1071. else
  1072. begin
  1073. case def_from^.deftype of
  1074. arraydef :
  1075. begin
  1076. { array constructor -> open array }
  1077. if is_open_array(def_to) and
  1078. is_array_constructor(def_from) then
  1079. begin
  1080. if is_void(parraydef(def_from)^.elementtype.def) or
  1081. is_equal(parraydef(def_to)^.elementtype.def,parraydef(def_from)^.elementtype.def) then
  1082. begin
  1083. doconv:=tc_equal;
  1084. b:=1;
  1085. end
  1086. else
  1087. if isconvertable(parraydef(def_from)^.elementtype.def,
  1088. parraydef(def_to)^.elementtype.def,hct,arrayconstructn,false)<>0 then
  1089. begin
  1090. doconv:=hct;
  1091. b:=2;
  1092. end;
  1093. end;
  1094. end;
  1095. pointerdef :
  1096. begin
  1097. if is_zero_based_array(def_to) and
  1098. is_equal(ppointerdef(def_from)^.pointertype.def,parraydef(def_to)^.elementtype.def) then
  1099. begin
  1100. doconv:=tc_pointer_2_array;
  1101. b:=1;
  1102. end;
  1103. end;
  1104. stringdef :
  1105. begin
  1106. { string to array of char}
  1107. if (not(is_special_array(def_to)) or is_open_array(def_to)) and
  1108. is_equal(parraydef(def_to)^.elementtype.def,cchardef) then
  1109. begin
  1110. doconv:=tc_string_2_chararray;
  1111. b:=1;
  1112. end;
  1113. end;
  1114. end;
  1115. end;
  1116. end;
  1117. pointerdef :
  1118. begin
  1119. case def_from^.deftype of
  1120. stringdef :
  1121. begin
  1122. { string constant (which can be part of array constructor)
  1123. to zero terminated string constant }
  1124. if (fromtreetype in [arrayconstructn,stringconstn]) and
  1125. is_pchar(def_to) then
  1126. begin
  1127. doconv:=tc_cstring_2_pchar;
  1128. b:=1;
  1129. end;
  1130. end;
  1131. orddef :
  1132. begin
  1133. { char constant to zero terminated string constant }
  1134. if (fromtreetype=ordconstn) then
  1135. begin
  1136. if is_equal(def_from,cchardef) and
  1137. is_pchar(def_to) then
  1138. begin
  1139. doconv:=tc_cchar_2_pchar;
  1140. b:=1;
  1141. end
  1142. else
  1143. if is_integer(def_from) then
  1144. begin
  1145. doconv:=tc_cord_2_pointer;
  1146. b:=1;
  1147. end;
  1148. end;
  1149. end;
  1150. arraydef :
  1151. begin
  1152. { chararray to pointer }
  1153. if is_zero_based_array(def_from) and
  1154. is_equal(parraydef(def_from)^.elementtype.def,ppointerdef(def_to)^.pointertype.def) then
  1155. begin
  1156. doconv:=tc_array_2_pointer;
  1157. b:=1;
  1158. end;
  1159. end;
  1160. pointerdef :
  1161. begin
  1162. { child class pointer can be assigned to anchestor pointers }
  1163. if (
  1164. (ppointerdef(def_from)^.pointertype.def^.deftype=objectdef) and
  1165. (ppointerdef(def_to)^.pointertype.def^.deftype=objectdef) and
  1166. pobjectdef(ppointerdef(def_from)^.pointertype.def)^.is_related(
  1167. pobjectdef(ppointerdef(def_to)^.pointertype.def))
  1168. ) or
  1169. { all pointers can be assigned to void-pointer }
  1170. is_equal(ppointerdef(def_to)^.pointertype.def,voiddef) or
  1171. { in my opnion, is this not clean pascal }
  1172. { well, but it's handy to use, it isn't ? (FK) }
  1173. is_equal(ppointerdef(def_from)^.pointertype.def,voiddef) then
  1174. begin
  1175. doconv:=tc_equal;
  1176. b:=1;
  1177. end;
  1178. end;
  1179. procvardef :
  1180. begin
  1181. { procedure variable can be assigned to an void pointer }
  1182. { Not anymore. Use the @ operator now.}
  1183. if not(m_tp_procvar in aktmodeswitches) and
  1184. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  1185. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  1186. begin
  1187. doconv:=tc_equal;
  1188. b:=1;
  1189. end;
  1190. end;
  1191. classrefdef,
  1192. objectdef :
  1193. begin
  1194. { class types and class reference type
  1195. can be assigned to void pointers }
  1196. if (
  1197. ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.is_class) or
  1198. (def_from^.deftype=classrefdef)
  1199. ) and
  1200. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  1201. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  1202. begin
  1203. doconv:=tc_equal;
  1204. b:=1;
  1205. end;
  1206. end;
  1207. end;
  1208. end;
  1209. setdef :
  1210. begin
  1211. { automatic arrayconstructor -> set conversion }
  1212. if is_array_constructor(def_from) then
  1213. begin
  1214. doconv:=tc_arrayconstructor_2_set;
  1215. b:=1;
  1216. end;
  1217. end;
  1218. procvardef :
  1219. begin
  1220. { proc -> procvar }
  1221. if (def_from^.deftype=procdef) then
  1222. begin
  1223. doconv:=tc_proc_2_procvar;
  1224. if proc_to_procvar_equal(pprocdef(def_from),pprocvardef(def_to)) then
  1225. b:=1;
  1226. end
  1227. else
  1228. { for example delphi allows the assignement from pointers }
  1229. { to procedure variables }
  1230. if (m_pointer_2_procedure in aktmodeswitches) and
  1231. (def_from^.deftype=pointerdef) and
  1232. (ppointerdef(def_from)^.pointertype.def^.deftype=orddef) and
  1233. (porddef(ppointerdef(def_from)^.pointertype.def)^.typ=uvoid) then
  1234. begin
  1235. doconv:=tc_equal;
  1236. b:=1;
  1237. end
  1238. else
  1239. { nil is compatible with procvars }
  1240. if (fromtreetype=niln) then
  1241. begin
  1242. doconv:=tc_equal;
  1243. b:=1;
  1244. end;
  1245. end;
  1246. objectdef :
  1247. begin
  1248. { object pascal objects }
  1249. if (def_from^.deftype=objectdef) {and
  1250. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  1251. begin
  1252. doconv:=tc_equal;
  1253. if pobjectdef(def_from)^.is_related(pobjectdef(def_to)) then
  1254. b:=1;
  1255. end
  1256. else
  1257. { Class specific }
  1258. if (pobjectdef(def_to)^.is_class) then
  1259. begin
  1260. { void pointer also for delphi mode }
  1261. if (m_delphi in aktmodeswitches) and
  1262. is_voidpointer(def_from) then
  1263. begin
  1264. doconv:=tc_equal;
  1265. b:=1;
  1266. end
  1267. else
  1268. { nil is compatible with class instances }
  1269. if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
  1270. begin
  1271. doconv:=tc_equal;
  1272. b:=1;
  1273. end;
  1274. end;
  1275. end;
  1276. classrefdef :
  1277. begin
  1278. { class reference types }
  1279. if (def_from^.deftype=classrefdef) then
  1280. begin
  1281. doconv:=tc_equal;
  1282. if pobjectdef(pclassrefdef(def_from)^.pointertype.def)^.is_related(
  1283. pobjectdef(pclassrefdef(def_to)^.pointertype.def)) then
  1284. b:=1;
  1285. end
  1286. else
  1287. { nil is compatible with class references }
  1288. if (fromtreetype=niln) then
  1289. begin
  1290. doconv:=tc_equal;
  1291. b:=1;
  1292. end;
  1293. end;
  1294. filedef :
  1295. begin
  1296. { typed files are all equal to the abstract file type
  1297. name TYPEDFILE in system.pp in is_equal in types.pas
  1298. the problem is that it sholud be also compatible to FILE
  1299. but this would leed to a problem for ASSIGN RESET and REWRITE
  1300. when trying to find the good overloaded function !!
  1301. so all file function are doubled in system.pp
  1302. this is not very beautiful !!}
  1303. if (def_from^.deftype=filedef) and
  1304. (
  1305. (
  1306. (pfiledef(def_from)^.filetyp = ft_typed) and
  1307. (pfiledef(def_to)^.filetyp = ft_typed) and
  1308. (
  1309. (pfiledef(def_from)^.typedfiletype.def = pdef(voiddef)) or
  1310. (pfiledef(def_to)^.typedfiletype.def = pdef(voiddef))
  1311. )
  1312. ) or
  1313. (
  1314. (
  1315. (pfiledef(def_from)^.filetyp = ft_untyped) and
  1316. (pfiledef(def_to)^.filetyp = ft_typed)
  1317. ) or
  1318. (
  1319. (pfiledef(def_from)^.filetyp = ft_typed) and
  1320. (pfiledef(def_to)^.filetyp = ft_untyped)
  1321. )
  1322. )
  1323. ) then
  1324. begin
  1325. doconv:=tc_equal;
  1326. b:=1;
  1327. end
  1328. end;
  1329. else
  1330. begin
  1331. { assignment overwritten ?? }
  1332. if assignment_overloaded(def_from,def_to)<>nil then
  1333. b:=2;
  1334. end;
  1335. end;
  1336. isconvertable:=b;
  1337. end;
  1338. { ld is the left type definition
  1339. rd the right type definition
  1340. dd the result type definition or voiddef if unkown }
  1341. function isbinaryoperatoroverloadable(ld, rd, dd : pdef;
  1342. treetyp : ttreetyp) : boolean;
  1343. begin
  1344. isbinaryoperatoroverloadable:=
  1345. (treetyp=starstarn) or
  1346. (ld^.deftype=recorddef) or
  1347. (rd^.deftype=recorddef) or
  1348. ((rd^.deftype=pointerdef) and
  1349. not(is_pchar(rd) and
  1350. (is_chararray(ld) or
  1351. (ld^.deftype=stringdef) or
  1352. (treetyp=addn))) and
  1353. (not(ld^.deftype in [pointerdef,objectdef,classrefdef,procvardef]) or
  1354. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,subn])
  1355. ) and
  1356. (not is_integer(ld) or not (treetyp in [addn,subn]))
  1357. ) or
  1358. ((ld^.deftype=pointerdef) and
  1359. not(is_pchar(ld) and
  1360. (is_chararray(rd) or
  1361. (rd^.deftype=stringdef) or
  1362. (treetyp=addn))) and
  1363. (not(rd^.deftype in [stringdef,pointerdef,objectdef,classrefdef,procvardef]) and
  1364. ((not is_integer(rd) and (rd^.deftype<>objectdef)
  1365. and (rd^.deftype<>classrefdef)) or
  1366. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,addn,subn])
  1367. )
  1368. )
  1369. ) or
  1370. { array def, but not mmx or chararray+[char,string,chararray] }
  1371. ((ld^.deftype=arraydef) and
  1372. not((cs_mmx in aktlocalswitches) and
  1373. is_mmx_able_array(ld)) and
  1374. not(is_chararray(ld) and
  1375. (is_char(rd) or
  1376. is_pchar(rd) or
  1377. (rd^.deftype=stringdef) or
  1378. is_chararray(rd)))
  1379. ) or
  1380. ((rd^.deftype=arraydef) and
  1381. not((cs_mmx in aktlocalswitches) and
  1382. is_mmx_able_array(rd)) and
  1383. not(is_chararray(rd) and
  1384. (is_char(ld) or
  1385. is_pchar(ld) or
  1386. (ld^.deftype=stringdef) or
  1387. is_chararray(ld)))
  1388. ) or
  1389. { <> and = are defined for classes }
  1390. ((ld^.deftype=objectdef) and
  1391. (not(pobjectdef(ld)^.is_class) or
  1392. not(treetyp in [equaln,unequaln])
  1393. )
  1394. ) or
  1395. ((rd^.deftype=objectdef) and
  1396. (not(pobjectdef(rd)^.is_class) or
  1397. not(treetyp in [equaln,unequaln])
  1398. )
  1399. or
  1400. { allow other operators that + on strings }
  1401. (
  1402. (is_char(rd) or
  1403. is_pchar(rd) or
  1404. (rd^.deftype=stringdef) or
  1405. is_chararray(rd) or
  1406. is_char(ld) or
  1407. is_pchar(ld) or
  1408. (ld^.deftype=stringdef) or
  1409. is_chararray(ld)
  1410. ) and
  1411. not(treetyp in [addn,equaln,unequaln,gtn,gten,ltn,lten]) and
  1412. not(is_pchar(ld) and
  1413. (is_integer(rd) or (rd^.deftype=pointerdef)) and
  1414. (treetyp=subn)
  1415. )
  1416. )
  1417. );
  1418. end;
  1419. function isunaryoperatoroverloadable(rd,dd : pdef;
  1420. treetyp : ttreetyp) : boolean;
  1421. begin
  1422. isunaryoperatoroverloadable:=false;
  1423. { what assignment overloading should be allowed ?? }
  1424. if (treetyp=assignn) then
  1425. begin
  1426. isunaryoperatoroverloadable:=true;
  1427. { this already get tbs0261 to fail
  1428. isunaryoperatoroverloadable:=not is_equal(rd,dd); PM }
  1429. end
  1430. { should we force that rd and dd are equal ?? }
  1431. else if (treetyp=subn { unaryminusn }) then
  1432. begin
  1433. isunaryoperatoroverloadable:=
  1434. not is_integer(rd) and not (rd^.deftype=floatdef)
  1435. {$ifdef SUPPORT_MMX}
  1436. and not ((cs_mmx in aktlocalswitches) and
  1437. is_mmx_able_array(rd))
  1438. {$endif SUPPORT_MMX}
  1439. ;
  1440. end
  1441. else if (treetyp=notn) then
  1442. begin
  1443. isunaryoperatoroverloadable:=not is_integer(rd) and not is_boolean(rd)
  1444. {$ifdef SUPPORT_MMX}
  1445. and not ((cs_mmx in aktlocalswitches) and
  1446. is_mmx_able_array(rd))
  1447. {$endif SUPPORT_MMX}
  1448. ;
  1449. end;
  1450. end;
  1451. function isoperatoracceptable(pf : pprocdef; optoken : ttoken) : boolean;
  1452. var
  1453. ld,rd,dd : pdef;
  1454. i : longint;
  1455. begin
  1456. case pf^.parast^.symindex^.count of
  1457. 2 : begin
  1458. isoperatoracceptable:=false;
  1459. for i:=1 to tok2nodes do
  1460. if tok2node[i].tok=optoken then
  1461. begin
  1462. ld:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  1463. rd:=pvarsym(pf^.parast^.symindex^.first^.indexnext)^.vartype.def;
  1464. dd:=pf^.rettype.def;
  1465. isoperatoracceptable:=
  1466. tok2node[i].op_overloading_supported and
  1467. isbinaryoperatoroverloadable(ld,rd,dd,tok2node[i].nod);
  1468. break;
  1469. end;
  1470. end;
  1471. 1 : begin
  1472. rd:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  1473. dd:=pf^.rettype.def;
  1474. for i:=1 to tok2nodes do
  1475. if tok2node[i].tok=optoken then
  1476. begin
  1477. isoperatoracceptable:=
  1478. tok2node[i].op_overloading_supported and
  1479. isunaryoperatoroverloadable(rd,dd,tok2node[i].nod);
  1480. break;
  1481. end;
  1482. end;
  1483. else
  1484. isoperatoracceptable:=false;
  1485. end;
  1486. end;
  1487. {****************************************************************************
  1488. Register Calculation
  1489. ****************************************************************************}
  1490. { marks an lvalue as "unregable" }
  1491. procedure make_not_regable(p : ptree);
  1492. begin
  1493. case p^.treetype of
  1494. typeconvn :
  1495. make_not_regable(p^.left);
  1496. loadn :
  1497. if p^.symtableentry^.typ=varsym then
  1498. pvarsym(p^.symtableentry)^.varoptions:=pvarsym(p^.symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  1499. end;
  1500. end;
  1501. procedure left_right_max(p : ptree);
  1502. begin
  1503. if assigned(p^.left) then
  1504. begin
  1505. if assigned(p^.right) then
  1506. begin
  1507. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  1508. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  1509. {$ifdef SUPPORT_MMX}
  1510. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  1511. {$endif SUPPORT_MMX}
  1512. end
  1513. else
  1514. begin
  1515. p^.registers32:=p^.left^.registers32;
  1516. p^.registersfpu:=p^.left^.registersfpu;
  1517. {$ifdef SUPPORT_MMX}
  1518. p^.registersmmx:=p^.left^.registersmmx;
  1519. {$endif SUPPORT_MMX}
  1520. end;
  1521. end;
  1522. end;
  1523. { calculates the needed registers for a binary operator }
  1524. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  1525. begin
  1526. left_right_max(p);
  1527. { Only when the difference between the left and right registers < the
  1528. wanted registers allocate the amount of registers }
  1529. if assigned(p^.left) then
  1530. begin
  1531. if assigned(p^.right) then
  1532. begin
  1533. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  1534. inc(p^.registers32,r32);
  1535. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  1536. inc(p^.registersfpu,fpu);
  1537. {$ifdef SUPPORT_MMX}
  1538. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  1539. inc(p^.registersmmx,mmx);
  1540. {$endif SUPPORT_MMX}
  1541. { the following is a little bit guessing but I think }
  1542. { it's the only way to solve same internalerrors: }
  1543. { if the left and right node both uses registers }
  1544. { and return a mem location, but the current node }
  1545. { doesn't use an integer register we get probably }
  1546. { trouble when restoring a node }
  1547. if (p^.left^.registers32=p^.right^.registers32) and
  1548. (p^.registers32=p^.left^.registers32) and
  1549. (p^.registers32>0) and
  1550. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM]) and
  1551. (p^.right^.location.loc in [LOC_REFERENCE,LOC_MEM]) then
  1552. inc(p^.registers32);
  1553. end
  1554. else
  1555. begin
  1556. if (p^.left^.registers32<r32) then
  1557. inc(p^.registers32,r32);
  1558. if (p^.left^.registersfpu<fpu) then
  1559. inc(p^.registersfpu,fpu);
  1560. {$ifdef SUPPORT_MMX}
  1561. if (p^.left^.registersmmx<mmx) then
  1562. inc(p^.registersmmx,mmx);
  1563. {$endif SUPPORT_MMX}
  1564. end;
  1565. end;
  1566. { error CGMessage, if more than 8 floating point }
  1567. { registers are needed }
  1568. if p^.registersfpu>8 then
  1569. CGMessage(cg_e_too_complex_expr);
  1570. end;
  1571. {****************************************************************************
  1572. Subroutine Handling
  1573. ****************************************************************************}
  1574. { protected field handling
  1575. protected field can not appear in
  1576. var parameters of function !!
  1577. this can only be done after we have determined the
  1578. overloaded function
  1579. this is the reason why it is not in the parser, PM }
  1580. procedure test_protected_sym(sym : psym);
  1581. begin
  1582. if (sp_protected in sym^.symoptions) and
  1583. ((sym^.owner^.symtabletype=unitsymtable) or
  1584. ((sym^.owner^.symtabletype=objectsymtable) and
  1585. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  1586. ) then
  1587. CGMessage(parser_e_cant_access_protected_member);
  1588. end;
  1589. procedure test_protected(p : ptree);
  1590. begin
  1591. case p^.treetype of
  1592. loadn : test_protected_sym(p^.symtableentry);
  1593. typeconvn : test_protected(p^.left);
  1594. derefn : test_protected(p^.left);
  1595. subscriptn : begin
  1596. { test_protected(p^.left);
  1597. Is a field of a protected var
  1598. also protected ??? PM }
  1599. test_protected_sym(p^.vs);
  1600. end;
  1601. end;
  1602. end;
  1603. function valid_for_formal_var(p : ptree) : boolean;
  1604. var
  1605. v : boolean;
  1606. begin
  1607. case p^.treetype of
  1608. loadn :
  1609. v:=(p^.symtableentry^.typ in [typedconstsym,varsym]);
  1610. typeconvn :
  1611. v:=valid_for_formal_var(p^.left);
  1612. derefn,
  1613. subscriptn,
  1614. vecn,
  1615. funcretn,
  1616. selfn :
  1617. v:=true;
  1618. calln : { procvars are callnodes first }
  1619. v:=assigned(p^.right) and not assigned(p^.left);
  1620. addrn :
  1621. begin
  1622. { addrn is not allowed as this generate a constant value,
  1623. but a tp procvar are allowed (PFV) }
  1624. if p^.procvarload then
  1625. v:=true
  1626. else
  1627. v:=false;
  1628. end;
  1629. else
  1630. v:=false;
  1631. end;
  1632. valid_for_formal_var:=v;
  1633. end;
  1634. function valid_for_formal_const(p : ptree) : boolean;
  1635. var
  1636. v : boolean;
  1637. begin
  1638. { p must have been firstpass'd before }
  1639. { accept about anything but not a statement ! }
  1640. case p^.treetype of
  1641. calln,
  1642. statementn,
  1643. addrn :
  1644. begin
  1645. { addrn is not allowed as this generate a constant value,
  1646. but a tp procvar are allowed (PFV) }
  1647. if p^.procvarload then
  1648. v:=true
  1649. else
  1650. v:=false;
  1651. end;
  1652. else
  1653. v:=true;
  1654. end;
  1655. valid_for_formal_const:=v;
  1656. end;
  1657. function is_procsym_load(p:Ptree):boolean;
  1658. begin
  1659. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  1660. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  1661. and (p^.left^.symtableentry^.typ=procsym)) ;
  1662. end;
  1663. { change a proc call to a procload for assignment to a procvar }
  1664. { this can only happen for proc/function without arguments }
  1665. function is_procsym_call(p:Ptree):boolean;
  1666. begin
  1667. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  1668. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  1669. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  1670. end;
  1671. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  1672. var
  1673. passproc : pprocdef;
  1674. convtyp : tconverttype;
  1675. begin
  1676. assignment_overloaded:=nil;
  1677. if assigned(overloaded_operators[_assignment]) then
  1678. passproc:=overloaded_operators[_assignment]^.definition
  1679. else
  1680. exit;
  1681. while passproc<>nil do
  1682. begin
  1683. if is_equal(passproc^.rettype.def,to_def) and
  1684. (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
  1685. (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
  1686. begin
  1687. assignment_overloaded:=passproc;
  1688. break;
  1689. end;
  1690. passproc:=passproc^.nextoverloaded;
  1691. end;
  1692. end;
  1693. { local routines can't be assigned to procvars }
  1694. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  1695. begin
  1696. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  1697. CGMessage(type_e_cannot_local_proc_to_procvar);
  1698. end;
  1699. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  1700. var
  1701. hp : ptree;
  1702. gotwith,
  1703. gotsubscript,
  1704. gotpointer,
  1705. gotclass,
  1706. gotderef : boolean;
  1707. begin
  1708. valid_for_assign:=false;
  1709. gotsubscript:=false;
  1710. gotderef:=false;
  1711. gotclass:=false;
  1712. gotpointer:=false;
  1713. gotwith:=false;
  1714. hp:=p;
  1715. while assigned(hp) do
  1716. begin
  1717. { property allowed? calln has a property check itself }
  1718. if (not allowprop) and
  1719. (hp^.isproperty) and
  1720. (hp^.treetype<>calln) then
  1721. begin
  1722. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  1723. exit;
  1724. end;
  1725. case hp^.treetype of
  1726. derefn :
  1727. begin
  1728. gotderef:=true;
  1729. hp:=hp^.left;
  1730. end;
  1731. typeconvn :
  1732. begin
  1733. case hp^.resulttype^.deftype of
  1734. pointerdef :
  1735. gotpointer:=true;
  1736. objectdef :
  1737. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  1738. classrefdef :
  1739. gotclass:=true;
  1740. arraydef :
  1741. begin
  1742. { pointer -> array conversion is done then we need to see it
  1743. as a deref, because a ^ is then not required anymore }
  1744. if (hp^.left^.resulttype^.deftype=pointerdef) then
  1745. gotderef:=true;
  1746. end;
  1747. end;
  1748. hp:=hp^.left;
  1749. end;
  1750. vecn,
  1751. asn :
  1752. hp:=hp^.left;
  1753. subscriptn :
  1754. begin
  1755. gotsubscript:=true;
  1756. hp:=hp^.left;
  1757. end;
  1758. subn,
  1759. addn :
  1760. begin
  1761. { Allow add/sub operators on a pointer, or an integer
  1762. and a pointer typecast and deref has been found }
  1763. if (hp^.resulttype^.deftype=pointerdef) or
  1764. (is_integer(hp^.resulttype) and gotpointer and gotderef) then
  1765. valid_for_assign:=true
  1766. else
  1767. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  1768. exit;
  1769. end;
  1770. addrn :
  1771. begin
  1772. if not(gotderef) and
  1773. not(hp^.procvarload) then
  1774. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_addr);
  1775. exit;
  1776. end;
  1777. selfn,
  1778. funcretn :
  1779. begin
  1780. valid_for_assign:=true;
  1781. exit;
  1782. end;
  1783. calln :
  1784. begin
  1785. { check return type }
  1786. case hp^.resulttype^.deftype of
  1787. pointerdef :
  1788. gotpointer:=true;
  1789. objectdef :
  1790. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  1791. recorddef, { handle record like class it needs a subscription }
  1792. classrefdef :
  1793. gotclass:=true;
  1794. end;
  1795. { 1. if it returns a pointer and we've found a deref,
  1796. 2. if it returns a class or record and a subscription or with is found,
  1797. 3. property is allowed }
  1798. if (gotpointer and gotderef) or
  1799. (gotclass and (gotsubscript or gotwith)) or
  1800. (hp^.isproperty and allowprop) then
  1801. valid_for_assign:=true
  1802. else
  1803. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  1804. exit;
  1805. end;
  1806. loadn :
  1807. begin
  1808. case hp^.symtableentry^.typ of
  1809. absolutesym,
  1810. varsym :
  1811. begin
  1812. if (pvarsym(hp^.symtableentry)^.varspez=vs_const) then
  1813. begin
  1814. { allow p^:= constructions with p is const parameter }
  1815. if gotderef then
  1816. valid_for_assign:=true
  1817. else
  1818. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_const);
  1819. exit;
  1820. end;
  1821. { Are we at a with symtable, then we need to process the
  1822. withrefnode also to check for maybe a const load }
  1823. if (hp^.symtable^.symtabletype=withsymtable) then
  1824. begin
  1825. { continue with processing the withref node }
  1826. hp:=ptree(pwithsymtable(hp^.symtable)^.withrefnode);
  1827. gotwith:=true;
  1828. end
  1829. else
  1830. begin
  1831. { set the assigned flag for varsyms }
  1832. if (pvarsym(hp^.symtableentry)^.varstate=vs_declared) then
  1833. pvarsym(hp^.symtableentry)^.varstate:=vs_assigned;
  1834. valid_for_assign:=true;
  1835. exit;
  1836. end;
  1837. end;
  1838. funcretsym,
  1839. typedconstsym :
  1840. begin
  1841. valid_for_assign:=true;
  1842. exit;
  1843. end;
  1844. end;
  1845. end;
  1846. else
  1847. begin
  1848. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  1849. exit;
  1850. end;
  1851. end;
  1852. end;
  1853. end;
  1854. procedure set_varstate(p : ptree;must_be_valid : boolean);
  1855. begin
  1856. while assigned(p) do
  1857. begin
  1858. if p^.varstateset then
  1859. exit;
  1860. p^.varstateset:=true;
  1861. case p^.treetype of
  1862. typeconvn :
  1863. begin
  1864. case p^.convtyp of
  1865. tc_cchar_2_pchar,
  1866. tc_cstring_2_pchar,
  1867. tc_array_2_pointer :
  1868. must_be_valid:=false;
  1869. tc_pchar_2_string,
  1870. tc_pointer_2_array :
  1871. must_be_valid:=true;
  1872. end;
  1873. p:=p^.left;
  1874. end;
  1875. subscriptn :
  1876. p:=p^.left;
  1877. vecn:
  1878. begin
  1879. set_varstate(p^.right,true);
  1880. if not(p^.left^.resulttype^.deftype in [stringdef,arraydef]) then
  1881. must_be_valid:=true;
  1882. p:=p^.left;
  1883. end;
  1884. { do not parse calln }
  1885. calln :
  1886. break;
  1887. callparan :
  1888. begin
  1889. set_varstate(p^.right,must_be_valid);
  1890. p:=p^.left;
  1891. end;
  1892. loadn :
  1893. begin
  1894. if (p^.symtableentry^.typ=varsym) then
  1895. begin
  1896. if must_be_valid and p^.is_first then
  1897. begin
  1898. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) or
  1899. (pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed) then
  1900. begin
  1901. if (assigned(pvarsym(p^.symtableentry)^.owner) and
  1902. assigned(aktprocsym) and
  1903. (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)) then
  1904. begin
  1905. if p^.symtable^.symtabletype=localsymtable then
  1906. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
  1907. else
  1908. CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
  1909. end;
  1910. end;
  1911. end;
  1912. if (p^.is_first) then
  1913. begin
  1914. if pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found then
  1915. begin
  1916. { this can only happen at left of an assignment, no ? PM }
  1917. if (parsing_para_level=0) and not must_be_valid then
  1918. pvarsym(p^.symtableentry)^.varstate:=vs_assigned
  1919. else
  1920. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1921. end
  1922. else
  1923. if pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed then
  1924. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1925. p^.is_first:=false;
  1926. end
  1927. else
  1928. begin
  1929. if (pvarsym(p^.symtableentry)^.varstate=vs_assigned) and
  1930. (must_be_valid or (parsing_para_level>0) or
  1931. (p^.resulttype^.deftype=procvardef)) then
  1932. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1933. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) and
  1934. (must_be_valid or (parsing_para_level>0) or
  1935. (p^.resulttype^.deftype=procvardef)) then
  1936. pvarsym(p^.symtableentry)^.varstate:=vs_set_but_first_not_passed;
  1937. end;
  1938. end;
  1939. break;
  1940. end;
  1941. funcretn:
  1942. begin
  1943. { no claim if setting higher return value_str }
  1944. if must_be_valid and
  1945. (procinfo=pprocinfo(p^.funcretprocinfo)) and
  1946. ((procinfo^.funcret_state=vs_declared) or
  1947. ((p^.is_first_funcret) and
  1948. (procinfo^.funcret_state=vs_declared_and_first_found))) then
  1949. begin
  1950. CGMessage(sym_w_function_result_not_set);
  1951. { avoid multiple warnings }
  1952. procinfo^.funcret_state:=vs_assigned;
  1953. end;
  1954. if p^.is_first_funcret and not must_be_valid then
  1955. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  1956. break;
  1957. end;
  1958. else
  1959. break;
  1960. end;{case }
  1961. end;
  1962. end;
  1963. procedure unset_varstate(p : ptree);
  1964. begin
  1965. while assigned(p) do
  1966. begin
  1967. p^.varstateset:=false;
  1968. case p^.treetype of
  1969. typeconvn,
  1970. subscriptn,
  1971. vecn :
  1972. p:=p^.left;
  1973. else
  1974. break;
  1975. end;
  1976. end;
  1977. end;
  1978. procedure set_unique(p : ptree);
  1979. begin
  1980. while assigned(p) do
  1981. begin
  1982. case p^.treetype of
  1983. vecn:
  1984. begin
  1985. p^.callunique:=true;
  1986. break;
  1987. end;
  1988. typeconvn,
  1989. subscriptn,
  1990. derefn:
  1991. p:=p^.left;
  1992. else
  1993. break;
  1994. end;
  1995. end;
  1996. end;
  1997. procedure set_funcret_is_valid(p : ptree);
  1998. begin
  1999. while assigned(p) do
  2000. begin
  2001. case p^.treetype of
  2002. funcretn:
  2003. begin
  2004. if p^.is_first_funcret then
  2005. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  2006. break;
  2007. end;
  2008. vecn,
  2009. {derefn,}
  2010. typeconvn,
  2011. subscriptn:
  2012. p:=p^.left;
  2013. else
  2014. break;
  2015. end;
  2016. end;
  2017. end;
  2018. {$endif cg11}
  2019. end.
  2020. {
  2021. $Log$
  2022. Revision 1.11 2000-10-01 19:48:23 peter
  2023. * lot of compile updates for cg11
  2024. Revision 1.10 2000/09/29 15:45:23 florian
  2025. * make cycle fixed
  2026. Revision 1.9 2000/09/28 19:49:51 florian
  2027. *** empty log message ***
  2028. Revision 1.8 2000/09/27 18:14:31 florian
  2029. * fixed a lot of syntax errors in the n*.pas stuff
  2030. Revision 1.7 2000/09/26 20:06:13 florian
  2031. * hmm, still a lot of work to get things compilable
  2032. Revision 1.6 2000/09/24 15:06:17 peter
  2033. * use defines.inc
  2034. Revision 1.5 2000/08/27 16:11:51 peter
  2035. * moved some util functions from globals,cobjects to cutils
  2036. * splitted files into finput,fmodule
  2037. Revision 1.4 2000/08/16 18:33:53 peter
  2038. * splitted namedobjectitem.next into indexnext and listnext so it
  2039. can be used in both lists
  2040. * don't allow "word = word" type definitions (merged)
  2041. Revision 1.3 2000/08/07 11:31:04 jonas
  2042. * fixed bug in type conversions between enum subranges (it didn't take
  2043. the packenum directive into account)
  2044. + define PACKENUMFIXED symbol in options.pas
  2045. (merged from fixes branch)
  2046. Revision 1.2 2000/07/13 11:32:41 michael
  2047. + removed logs
  2048. }