ptconst.pas 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Reads typed constants
  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 ptconst;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses symtype,symsym;
  22. { this procedure reads typed constants }
  23. { sym is only needed for ansi strings }
  24. { the assembler label is in the middle (PM) }
  25. procedure readtypedconst(const t:ttype;sym : ttypedconstsym;writable : boolean);
  26. implementation
  27. uses
  28. {$ifdef Delphi}
  29. sysutils,
  30. {$else}
  31. strings,
  32. {$endif Delphi}
  33. globtype,systems,tokens,verbose,
  34. cutils,globals,widestr,scanner,
  35. symconst,symbase,symdef,symtable,
  36. aasmbase,aasmtai,aasmcpu,defutil,defcmp,
  37. { pass 1 }
  38. node,
  39. nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
  40. { parser specific stuff }
  41. pbase,pexpr,
  42. { codegen }
  43. cpuinfo,cgbase
  44. ;
  45. {$ifdef fpc}
  46. {$maxfpuregisters 0}
  47. {$endif fpc}
  48. { this procedure reads typed constants }
  49. procedure readtypedconst(const t:ttype;sym : ttypedconstsym;writable : boolean);
  50. type
  51. setbytes = array[0..31] of byte;
  52. Psetbytes = ^setbytes;
  53. var
  54. len,base : longint;
  55. p,hp,hpstart : tnode;
  56. i,j,l,offset,
  57. varalign,
  58. strlength : longint;
  59. curconstsegment : TAAsmoutput;
  60. ll : tasmlabel;
  61. s,sorg : string;
  62. c : char;
  63. ca : pchar;
  64. tmpguid : tguid;
  65. aktpos : longint;
  66. obj : tobjectdef;
  67. recsym,
  68. srsym : tsym;
  69. symt : tsymtable;
  70. value : bestreal;
  71. intvalue : tconstexprint;
  72. strval : pchar;
  73. pw : pcompilerwidestring;
  74. error : boolean;
  75. old_block_type : tblock_type;
  76. procedure check_range(def:torddef);
  77. begin
  78. if ((tordconstnode(p).value>def.high) or
  79. (tordconstnode(p).value<def.low)) then
  80. begin
  81. if (cs_check_range in aktlocalswitches) then
  82. Message(parser_e_range_check_error)
  83. else
  84. Message(parser_w_range_check_error);
  85. end;
  86. end;
  87. begin
  88. old_block_type:=block_type;
  89. block_type:=bt_const;
  90. if writable then
  91. curconstsegment:=datasegment
  92. else
  93. curconstsegment:=consts;
  94. case t.def.deftype of
  95. orddef:
  96. begin
  97. p:=comp_expr(true);
  98. case torddef(t.def).typ of
  99. bool8bit :
  100. begin
  101. if is_constboolnode(p) then
  102. curconstSegment.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)))
  103. else
  104. Message(cg_e_illegal_expression);
  105. end;
  106. bool16bit :
  107. begin
  108. if is_constboolnode(p) then
  109. curconstSegment.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)))
  110. else
  111. Message(cg_e_illegal_expression);
  112. end;
  113. bool32bit :
  114. begin
  115. if is_constboolnode(p) then
  116. curconstSegment.concat(Tai_const.Create_32bit(cardinal(tordconstnode(p).value)))
  117. else
  118. Message(cg_e_illegal_expression);
  119. end;
  120. uchar :
  121. begin
  122. if is_constcharnode(p) then
  123. curconstSegment.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)))
  124. else
  125. Message(cg_e_illegal_expression);
  126. end;
  127. uwidechar :
  128. begin
  129. if is_constcharnode(p) then
  130. inserttypeconv(p,cwidechartype);
  131. if is_constwidecharnode(p) then
  132. curconstSegment.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)))
  133. else
  134. Message(cg_e_illegal_expression);
  135. end;
  136. s8bit,
  137. u8bit :
  138. begin
  139. if is_constintnode(p) then
  140. begin
  141. curconstSegment.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)));
  142. check_range(torddef(t.def));
  143. end
  144. else
  145. Message(cg_e_illegal_expression);
  146. end;
  147. u16bit,
  148. s16bit :
  149. begin
  150. if is_constintnode(p) then
  151. begin
  152. curconstSegment.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)));
  153. check_range(torddef(t.def));
  154. end
  155. else
  156. Message(cg_e_illegal_expression);
  157. end;
  158. s32bit,
  159. u32bit :
  160. begin
  161. if is_constintnode(p) then
  162. begin
  163. curconstSegment.concat(Tai_const.Create_32bit(cardinal(tordconstnode(p).value)));
  164. if torddef(t.def).typ<>u32bit then
  165. check_range(torddef(t.def));
  166. end
  167. else
  168. Message(cg_e_illegal_expression);
  169. end;
  170. s64bit,
  171. u64bit,
  172. scurrency:
  173. begin
  174. if is_constintnode(p) then
  175. intvalue := tordconstnode(p).value
  176. {$ifndef VER1_0}
  177. else if is_constrealnode(p) and
  178. (torddef(t.def).typ = scurrency) and
  179. (trealconstnode(p).value_real*10000 >= low(int64)) and
  180. (trealconstnode(p).value_real*10000 <= high(int64)) then
  181. intvalue := round(trealconstnode(p).value_real*10000)
  182. {$endif ndef VER1_0}
  183. else
  184. begin
  185. intvalue := 0;
  186. Message(cg_e_illegal_expression);
  187. end;
  188. {$warning maybe change to create_64bit}
  189. if target_info.endian = endian_little then
  190. begin
  191. curconstSegment.concat(Tai_const.Create_32bit(Cardinal(intvalue and $ffffffff)));
  192. curconstSegment.concat(Tai_const.Create_32bit(Cardinal(intvalue shr 32)));
  193. end
  194. else
  195. begin
  196. curconstSegment.concat(Tai_const.Create_32bit(Cardinal(intvalue shr 32)));
  197. curconstSegment.concat(Tai_const.Create_32bit(Cardinal(intvalue and $ffffffff)));
  198. end;
  199. end;
  200. else
  201. internalerror(3799);
  202. end;
  203. p.free;
  204. end;
  205. floatdef:
  206. begin
  207. p:=comp_expr(true);
  208. if is_constrealnode(p) then
  209. value:=trealconstnode(p).value_real
  210. else if is_constintnode(p) then
  211. value:=tordconstnode(p).value
  212. else
  213. Message(cg_e_illegal_expression);
  214. case tfloatdef(t.def).typ of
  215. s32real :
  216. curconstSegment.concat(Tai_real_32bit.Create(ts32real(value)));
  217. s64real :
  218. {$ifdef ARM}
  219. if aktfputype in [fpu_fpa,fpu_fpa10,fpu_fpa11] then
  220. curconstSegment.concat(Tai_real_64bit.Create_hiloswapped(ts64real(value)))
  221. else
  222. {$endif ARM}
  223. curconstSegment.concat(Tai_real_64bit.Create(ts64real(value)));
  224. s80real :
  225. curconstSegment.concat(Tai_real_80bit.Create(value));
  226. {$ifdef ver1_0}
  227. s64comp :
  228. curconstSegment.concat(Tai_comp_64bit.Create(value));
  229. s64currency:
  230. curconstSegment.concat(Tai_comp_64bit.Create(value*10000));
  231. {$else ver1_0}
  232. { the round is necessary for native compilers where comp isn't a float }
  233. s64comp :
  234. curconstSegment.concat(Tai_comp_64bit.Create(round(value)));
  235. s64currency:
  236. curconstSegment.concat(Tai_comp_64bit.Create(round(value*10000)));
  237. {$endif ver1_0}
  238. s128real:
  239. curconstSegment.concat(Tai_real_128bit.Create(value));
  240. else
  241. internalerror(18);
  242. end;
  243. p.free;
  244. end;
  245. classrefdef:
  246. begin
  247. p:=comp_expr(true);
  248. case p.nodetype of
  249. loadvmtaddrn:
  250. with Tclassrefdef(p.resulttype.def) do
  251. begin
  252. if not Tobjectdef(pointertype.def).is_related(Tobjectdef(pointertype.def)) then
  253. message(cg_e_illegal_expression);
  254. curconstSegment.concat(Tai_const_symbol.Create(objectlibrary.newasmsymbol(
  255. Tobjectdef(pointertype.def).vmt_mangledname,AB_EXTERNAL,AT_DATA)));
  256. end;
  257. niln:
  258. curconstSegment.concat(Tai_const.Create_ptr(0));
  259. else Message(cg_e_illegal_expression);
  260. end;
  261. p.free;
  262. end;
  263. pointerdef:
  264. begin
  265. p:=comp_expr(true);
  266. if (p.nodetype=typeconvn) then
  267. with Ttypeconvnode(p) do
  268. if (left.nodetype in [addrn,niln]) and equal_defs(t.def,p.resulttype.def) then
  269. begin
  270. hp:=left;
  271. left:=nil;
  272. p.free;
  273. p:=hp;
  274. end;
  275. { allows horrible ofs(typeof(TButton)^) code !! }
  276. if (p.nodetype=addrn) then
  277. with Taddrnode(p) do
  278. if left.nodetype=derefn then
  279. begin
  280. hp:=tderefnode(left).left;
  281. tderefnode(left).left:=nil;
  282. p.free;
  283. p:=hp;
  284. end;
  285. { const pointer ? }
  286. if (p.nodetype = pointerconstn) then
  287. curconstsegment.concat(Tai_const.Create_ptr(TConstPtrUInt(tpointerconstnode(p).value)))
  288. { nil pointer ? }
  289. else if p.nodetype=niln then
  290. curconstSegment.concat(Tai_const.Create_ptr(0))
  291. { maybe pchar ? }
  292. else
  293. if is_char(tpointerdef(t.def).pointertype.def) and
  294. (p.nodetype<>addrn) then
  295. begin
  296. objectlibrary.getdatalabel(ll);
  297. curconstSegment.concat(Tai_const_symbol.Create(ll));
  298. if p.nodetype=stringconstn then
  299. varalign:=tstringconstnode(p).len
  300. else
  301. varalign:=0;
  302. varalign:=const_align(varalign);
  303. Consts.concat(Tai_align.Create(varalign));
  304. Consts.concat(Tai_label.Create(ll));
  305. if p.nodetype=stringconstn then
  306. begin
  307. len:=tstringconstnode(p).len;
  308. { For tp7 the maximum lentgh can be 255 }
  309. if (m_tp7 in aktmodeswitches) and
  310. (len>255) then
  311. len:=255;
  312. getmem(ca,len+2);
  313. move(tstringconstnode(p).value_str^,ca^,len+1);
  314. Consts.concat(Tai_string.Create_length_pchar(ca,len+1));
  315. end
  316. else
  317. if is_constcharnode(p) then
  318. Consts.concat(Tai_string.Create(char(byte(tordconstnode(p).value))+#0))
  319. else
  320. Message(cg_e_illegal_expression);
  321. end
  322. { maybe pwidechar ? }
  323. else
  324. if is_widechar(tpointerdef(t.def).pointertype.def) and
  325. (p.nodetype<>addrn) then
  326. begin
  327. objectlibrary.getdatalabel(ll);
  328. curconstSegment.concat(Tai_const_symbol.Create(ll));
  329. Consts.concat(tai_align.create(const_align(pointer_size)));
  330. Consts.concat(Tai_label.Create(ll));
  331. if (p.nodetype in [stringconstn,ordconstn]) then
  332. begin
  333. { convert to widestring stringconstn }
  334. inserttypeconv(p,cwidestringtype);
  335. if (p.nodetype=stringconstn) and
  336. (tstringconstnode(p).st_type=st_widestring) then
  337. begin
  338. pw:=pcompilerwidestring(tstringconstnode(p).value_str);
  339. for i:=0 to tstringconstnode(p).len-1 do
  340. Consts.concat(Tai_const.Create_16bit(pw^.data[i]));
  341. { ending #0 }
  342. Consts.concat(Tai_const.Create_16bit(0))
  343. end;
  344. end
  345. else
  346. Message(cg_e_illegal_expression);
  347. end
  348. else
  349. if p.nodetype=addrn then
  350. begin
  351. { support @@procvar in tp mode }
  352. if (m_tp_procvar in aktmodeswitches) and
  353. (taddrnode(p).left.nodetype=addrn) then
  354. p:=taddrnode(p).left;
  355. { insert typeconv }
  356. inserttypeconv(p,t);
  357. { if a typeconv node was inserted then check if it was an tc_equal. If
  358. true then we remove the node. If not tc_equal then we leave the typeconvn
  359. and the nodetype=loadn will always be false and generate the error (PFV) }
  360. if (p.nodetype=typeconvn) then
  361. begin
  362. if (ttypeconvnode(p).convtype=tc_equal) then
  363. hpstart:=taddrnode(ttypeconvnode(p).left).left
  364. else
  365. hpstart:=p;
  366. end
  367. else
  368. hpstart:=taddrnode(p).left;
  369. hp:=hpstart;
  370. while assigned(hp) and (hp.nodetype in [subscriptn,vecn]) do
  371. hp:=tunarynode(hp).left;
  372. if (hp.nodetype=loadn) then
  373. begin
  374. hp:=hpstart;
  375. offset:=0;
  376. while assigned(hp) and (hp.nodetype<>loadn) do
  377. begin
  378. case hp.nodetype of
  379. vecn :
  380. begin
  381. case tvecnode(hp).left.resulttype.def.deftype of
  382. stringdef :
  383. begin
  384. { this seems OK for shortstring and ansistrings PM }
  385. { it is wrong for widestrings !! }
  386. len:=1;
  387. base:=0;
  388. end;
  389. arraydef :
  390. begin
  391. len:=tarraydef(tvecnode(hp).left.resulttype.def).elesize;
  392. base:=tarraydef(tvecnode(hp).left.resulttype.def).lowrange;
  393. end
  394. else
  395. Message(cg_e_illegal_expression);
  396. end;
  397. if is_constintnode(tvecnode(hp).right) then
  398. inc(offset,len*(get_ordinal_value(tvecnode(hp).right)-base))
  399. else
  400. Message(cg_e_illegal_expression);
  401. end;
  402. subscriptn :
  403. inc(offset,tsubscriptnode(hp).vs.fieldoffset)
  404. else
  405. Message(cg_e_illegal_expression);
  406. end;
  407. hp:=tbinarynode(hp).left;
  408. end;
  409. srsym:=tloadnode(hp).symtableentry;
  410. case srsym.typ of
  411. procsym :
  412. begin
  413. if Tprocsym(srsym).procdef_count>1 then
  414. Message(parser_e_no_overloaded_procvars);
  415. if po_abstractmethod in tprocsym(srsym).first_procdef.procoptions then
  416. Message(type_e_cant_take_address_of_abstract_method)
  417. else
  418. curconstSegment.concat(Tai_const_symbol.Createname(tprocsym(srsym).first_procdef.mangledname,AT_FUNCTION,offset));
  419. end;
  420. varsym :
  421. curconstSegment.concat(Tai_const_symbol.Createname(tvarsym(srsym).mangledname,AT_DATA,offset));
  422. typedconstsym :
  423. curconstSegment.concat(Tai_const_symbol.Createname(ttypedconstsym(srsym).mangledname,AT_DATA,offset));
  424. else
  425. Message(type_e_variable_id_expected);
  426. end;
  427. end
  428. else
  429. Message(cg_e_illegal_expression);
  430. end
  431. else
  432. { allow typeof(Object type)}
  433. if (p.nodetype=inlinen) and
  434. (tinlinenode(p).inlinenumber=in_typeof_x) then
  435. begin
  436. if (tinlinenode(p).left.nodetype=typen) then
  437. begin
  438. curconstSegment.concat(Tai_const_symbol.createname(
  439. tobjectdef(tinlinenode(p).left.resulttype.def).vmt_mangledname,AT_DATA,0));
  440. end
  441. else
  442. Message(cg_e_illegal_expression);
  443. end
  444. else
  445. Message(cg_e_illegal_expression);
  446. p.free;
  447. end;
  448. setdef:
  449. begin
  450. p:=comp_expr(true);
  451. if p.nodetype=setconstn then
  452. begin
  453. { be sure to convert to the correct result, else
  454. it can generate smallset data instead of normalset (PFV) }
  455. inserttypeconv(p,t);
  456. { we only allow const sets }
  457. if assigned(tsetconstnode(p).left) then
  458. Message(cg_e_illegal_expression)
  459. else
  460. begin
  461. { this writing is endian independant }
  462. { untrue - because they are considered }
  463. { arrays of 32-bit values CEC }
  464. if source_info.endian = target_info.endian then
  465. begin
  466. for l:=0 to p.resulttype.def.size-1 do
  467. curconstsegment.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[l]));
  468. end
  469. else
  470. begin
  471. { store as longint values in swaped format }
  472. j:=0;
  473. for l:=0 to ((p.resulttype.def.size-1) div 4) do
  474. begin
  475. curconstsegment.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+3]));
  476. curconstsegment.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+2]));
  477. curconstsegment.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+1]));
  478. curconstsegment.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j]));
  479. Inc(j,4);
  480. end;
  481. end;
  482. end;
  483. end
  484. else
  485. Message(cg_e_illegal_expression);
  486. p.free;
  487. end;
  488. enumdef:
  489. begin
  490. p:=comp_expr(true);
  491. if p.nodetype=ordconstn then
  492. begin
  493. if equal_defs(p.resulttype.def,t.def) or
  494. is_subequal(p.resulttype.def,t.def) then
  495. begin
  496. case p.resulttype.def.size of
  497. 1 : curconstSegment.concat(Tai_const.Create_8bit(Byte(tordconstnode(p).value)));
  498. 2 : curconstSegment.concat(Tai_const.Create_16bit(Word(tordconstnode(p).value)));
  499. 4 : curconstSegment.concat(Tai_const.Create_32bit(Cardinal(tordconstnode(p).value)));
  500. end;
  501. end
  502. else
  503. IncompatibleTypes(p.resulttype.def,t.def);
  504. end
  505. else
  506. Message(cg_e_illegal_expression);
  507. p.free;
  508. end;
  509. stringdef:
  510. begin
  511. p:=comp_expr(true);
  512. { load strval and strlength of the constant tree }
  513. if (p.nodetype=stringconstn) or is_widestring(t.def) then
  514. begin
  515. { convert to the expected string type so that
  516. for widestrings strval is a pcompilerwidestring }
  517. inserttypeconv(p,t);
  518. strlength:=tstringconstnode(p).len;
  519. strval:=tstringconstnode(p).value_str;
  520. end
  521. else if is_constcharnode(p) then
  522. begin
  523. { strval:=pchar(@tordconstnode(p).value);
  524. THIS FAIL on BIG_ENDIAN MACHINES PM }
  525. c:=chr(tordconstnode(p).value and $ff);
  526. strval:=@c;
  527. strlength:=1
  528. end
  529. else if is_constresourcestringnode(p) then
  530. begin
  531. strval:=pchar(tconstsym(tloadnode(p).symtableentry).value.valueptr);
  532. strlength:=tconstsym(tloadnode(p).symtableentry).value.len;
  533. end
  534. else
  535. begin
  536. Message(cg_e_illegal_expression);
  537. strlength:=-1;
  538. end;
  539. if strlength>=0 then
  540. begin
  541. case tstringdef(t.def).string_typ of
  542. st_shortstring:
  543. begin
  544. if strlength>=t.def.size then
  545. begin
  546. message2(parser_w_string_too_long,strpas(strval),tostr(t.def.size-1));
  547. strlength:=t.def.size-1;
  548. end;
  549. curconstSegment.concat(Tai_const.Create_8bit(strlength));
  550. { this can also handle longer strings }
  551. getmem(ca,strlength+1);
  552. move(strval^,ca^,strlength);
  553. ca[strlength]:=#0;
  554. curconstSegment.concat(Tai_string.Create_length_pchar(ca,strlength));
  555. { fillup with spaces if size is shorter }
  556. if t.def.size>strlength then
  557. begin
  558. getmem(ca,t.def.size-strlength);
  559. { def.size contains also the leading length, so we }
  560. { we have to subtract one }
  561. fillchar(ca[0],t.def.size-strlength-1,' ');
  562. ca[t.def.size-strlength-1]:=#0;
  563. { this can also handle longer strings }
  564. curconstSegment.concat(Tai_string.Create_length_pchar(ca,t.def.size-strlength-1));
  565. end;
  566. end;
  567. {$ifdef ansistrings_bits}
  568. st_ansistring16:
  569. begin
  570. { an empty ansi string is nil! }
  571. if (strlength=0) then
  572. curconstSegment.concat(Tai_const.Create_ptr(0))
  573. else
  574. begin
  575. objectlibrary.getdatalabel(ll);
  576. curconstSegment.concat(Tai_const_symbol.Create(ll));
  577. { the actual structure starts at -12 from start label - CEC }
  578. Consts.concat(tai_align.create(const_align(pointer_size)));
  579. { first write the maximum size }
  580. Consts.concat(Tai_const.Create_16bit(strlength));
  581. { second write the real length }
  582. Consts.concat(Tai_const.Create_16bit(strlength));
  583. { redondent with maxlength but who knows ... (PM) }
  584. { third write use count (set to -1 for safety ) }
  585. Consts.concat(Tai_const.Create_16bit(Cardinal(-1)));
  586. Consts.concat(Tai_label.Create(ll));
  587. getmem(ca,strlength+2);
  588. move(strval^,ca^,strlength);
  589. { The terminating #0 to be stored in the .data section (JM) }
  590. ca[strlength]:=#0;
  591. { End of the PChar. The memory has to be allocated because in }
  592. { tai_string.done, there is a freemem(len+1) (JM) }
  593. ca[strlength+1]:=#0;
  594. Consts.concat(Tai_string.Create_length_pchar(ca,strlength+1));
  595. end;
  596. end;
  597. {$endif}
  598. {$ifdef ansistring_bits}st_ansistring32{$else}st_ansistring{$endif}:
  599. begin
  600. { an empty ansi string is nil! }
  601. if (strlength=0) then
  602. curconstSegment.concat(Tai_const.Create_ptr(0))
  603. else
  604. begin
  605. objectlibrary.getdatalabel(ll);
  606. curconstSegment.concat(Tai_const_symbol.Create(ll));
  607. { the actual structure starts at -12 from start label - CEC }
  608. Consts.concat(tai_align.create(const_align(pointer_size)));
  609. { first write the maximum size }
  610. Consts.concat(Tai_const.Create_32bit(strlength));
  611. { second write the real length }
  612. Consts.concat(Tai_const.Create_32bit(strlength));
  613. { redondent with maxlength but who knows ... (PM) }
  614. { third write use count (set to -1 for safety ) }
  615. Consts.concat(Tai_const.Create_32bit(Cardinal(-1)));
  616. Consts.concat(Tai_label.Create(ll));
  617. getmem(ca,strlength+2);
  618. move(strval^,ca^,strlength);
  619. { The terminating #0 to be stored in the .data section (JM) }
  620. ca[strlength]:=#0;
  621. { End of the PChar. The memory has to be allocated because in }
  622. { tai_string.done, there is a freemem(len+1) (JM) }
  623. ca[strlength+1]:=#0;
  624. Consts.concat(Tai_string.Create_length_pchar(ca,strlength+1));
  625. end;
  626. end;
  627. {$ifdef ansistring_bits}
  628. st_ansistring64:
  629. begin
  630. { an empty ansi string is nil! }
  631. if (strlength=0) then
  632. curconstSegment.concat(Tai_const.Create_ptr(0))
  633. else
  634. begin
  635. objectlibrary.getdatalabel(ll);
  636. curconstSegment.concat(Tai_const_symbol.Create(ll));
  637. { the actual structure starts at -12 from start label - CEC }
  638. Consts.concat(tai_align.create(const_align(pointer_size)));
  639. { first write the maximum size }
  640. Consts.concat(Tai_const.Create_64bit(strlength));
  641. { second write the real length }
  642. Consts.concat(Tai_const.Create_64bit(strlength));
  643. { redondent with maxlength but who knows ... (PM) }
  644. { third write use count (set to -1 for safety ) }
  645. Consts.concat(Tai_const.Create_64bit(Cardinal(-1)));
  646. Consts.concat(Tai_label.Create(ll));
  647. getmem(ca,strlength+2);
  648. move(strval^,ca^,strlength);
  649. { The terminating #0 to be stored in the .data section (JM) }
  650. ca[strlength]:=#0;
  651. { End of the PChar. The memory has to be allocated because in }
  652. { tai_string.done, there is a freemem(len+1) (JM) }
  653. ca[strlength+1]:=#0;
  654. Consts.concat(Tai_string.Create_length_pchar(ca,strlength+1));
  655. end;
  656. end;
  657. {$endif}
  658. st_widestring:
  659. begin
  660. { an empty ansi string is nil! }
  661. if (strlength=0) then
  662. curconstSegment.concat(Tai_const.Create_ptr(0))
  663. else
  664. begin
  665. objectlibrary.getdatalabel(ll);
  666. curconstSegment.concat(Tai_const_symbol.Create(ll));
  667. { the actual structure starts at -12 from start label - CEC }
  668. Consts.concat(tai_align.create(const_align(pointer_size)));
  669. Consts.concat(Tai_const.Create_32bit(strlength));
  670. Consts.concat(Tai_const.Create_32bit(strlength));
  671. Consts.concat(Tai_const.Create_32bit(Cardinal(-1)));
  672. Consts.concat(Tai_label.Create(ll));
  673. for i:=0 to strlength-1 do
  674. Consts.concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
  675. { ending #0 }
  676. Consts.concat(Tai_const.Create_16bit(0))
  677. end;
  678. end;
  679. st_longstring:
  680. begin
  681. internalerror(200107081);
  682. {curconstSegment.concat(Tai_const.Create_32bit(strlength))));
  683. curconstSegment.concat(Tai_const.Create_8bit(0));
  684. getmem(ca,strlength+1);
  685. move(strval^,ca^,strlength);
  686. ca[strlength]:=#0;
  687. generate_pascii(consts,ca,strlength);
  688. curconstSegment.concat(Tai_const.Create_8bit(0));}
  689. end;
  690. end;
  691. end;
  692. p.free;
  693. end;
  694. arraydef:
  695. begin
  696. if try_to_consume(_LKLAMMER) then
  697. begin
  698. for l:=tarraydef(t.def).lowrange to tarraydef(t.def).highrange-1 do
  699. begin
  700. readtypedconst(tarraydef(t.def).elementtype,nil,writable);
  701. consume(_COMMA);
  702. end;
  703. readtypedconst(tarraydef(t.def).elementtype,nil,writable);
  704. consume(_RKLAMMER);
  705. end
  706. else
  707. { if array of char then we allow also a string }
  708. if is_char(tarraydef(t.def).elementtype.def) then
  709. begin
  710. p:=comp_expr(true);
  711. if p.nodetype=stringconstn then
  712. begin
  713. len:=tstringconstnode(p).len;
  714. { For tp7 the maximum lentgh can be 255 }
  715. if (m_tp7 in aktmodeswitches) and
  716. (len>255) then
  717. len:=255;
  718. ca:=tstringconstnode(p).value_str;
  719. end
  720. else
  721. if is_constcharnode(p) then
  722. begin
  723. c:=chr(tordconstnode(p).value and $ff);
  724. ca:=@c;
  725. len:=1;
  726. end
  727. else
  728. begin
  729. Message(cg_e_illegal_expression);
  730. len:=0;
  731. end;
  732. if len>(tarraydef(t.def).highrange-tarraydef(t.def).lowrange+1) then
  733. Message(parser_e_string_larger_array);
  734. for i:=tarraydef(t.def).lowrange to tarraydef(t.def).highrange do
  735. begin
  736. if i+1-tarraydef(t.def).lowrange<=len then
  737. begin
  738. curconstSegment.concat(Tai_const.Create_8bit(byte(ca^)));
  739. inc(ca);
  740. end
  741. else
  742. {Fill the remaining positions with #0.}
  743. curconstSegment.concat(Tai_const.Create_8bit(0));
  744. end;
  745. p.free;
  746. end
  747. else
  748. { dynamic array nil }
  749. if is_dynamic_array(t.def) then
  750. begin
  751. { Only allow nil initialization }
  752. consume(_NIL);
  753. curconstSegment.concat(Tai_const.Create_ptr(0));
  754. end
  755. else
  756. begin
  757. { we want the ( }
  758. consume(_LKLAMMER);
  759. end;
  760. end;
  761. procvardef:
  762. begin
  763. { Procvars and pointers are no longer compatible. }
  764. { under tp: =nil or =var under fpc: =nil or =@var }
  765. if token=_NIL then
  766. begin
  767. curconstSegment.concat(Tai_const.Create_ptr(0));
  768. if (po_methodpointer in tprocvardef(t.def).procoptions) then
  769. curconstSegment.concat(Tai_const.Create_ptr(0));
  770. consume(_NIL);
  771. exit;
  772. end;
  773. { you can't assign a value other than NIL to a typed constant }
  774. { which is a "procedure of object", because this also requires }
  775. { address of an object/class instance, which is not known at }
  776. { compile time (JM) }
  777. if (po_methodpointer in tprocvardef(t.def).procoptions) then
  778. Message(parser_e_no_procvarobj_const);
  779. { parse the rest too, so we can continue with error checking }
  780. getprocvardef:=tprocvardef(t.def);
  781. p:=comp_expr(true);
  782. getprocvardef:=nil;
  783. if codegenerror then
  784. begin
  785. p.free;
  786. exit;
  787. end;
  788. { let type conversion check everything needed }
  789. inserttypeconv(p,t);
  790. if codegenerror then
  791. begin
  792. p.free;
  793. exit;
  794. end;
  795. { remove typeconvn, that will normally insert a lea
  796. instruction which is not necessary for us }
  797. if p.nodetype=typeconvn then
  798. begin
  799. hp:=ttypeconvnode(p).left;
  800. ttypeconvnode(p).left:=nil;
  801. p.free;
  802. p:=hp;
  803. end;
  804. { remove addrn which we also don't need here }
  805. if p.nodetype=addrn then
  806. begin
  807. hp:=taddrnode(p).left;
  808. taddrnode(p).left:=nil;
  809. p.free;
  810. p:=hp;
  811. end;
  812. { we now need to have a loadn with a procsym }
  813. if (p.nodetype=loadn) and
  814. (tloadnode(p).symtableentry.typ=procsym) then
  815. begin
  816. curconstSegment.concat(Tai_const_symbol.createname(
  817. tprocsym(tloadnode(p).symtableentry).first_procdef.mangledname,AT_FUNCTION,0));
  818. end
  819. else
  820. Message(cg_e_illegal_expression);
  821. p.free;
  822. end;
  823. { reads a typed constant record }
  824. recorddef:
  825. begin
  826. { KAZ }
  827. if (trecorddef(t.def)=rec_tguid) and
  828. ((token=_CSTRING) or (token=_CCHAR) or (token=_ID)) then
  829. begin
  830. p:=comp_expr(true);
  831. inserttypeconv(p,cshortstringtype);
  832. if p.nodetype=stringconstn then
  833. begin
  834. s:=strpas(tstringconstnode(p).value_str);
  835. p.free;
  836. if string2guid(s,tmpguid) then
  837. begin
  838. curconstSegment.concat(Tai_const.Create_32bit(tmpguid.D1));
  839. curconstSegment.concat(Tai_const.Create_16bit(tmpguid.D2));
  840. curconstSegment.concat(Tai_const.Create_16bit(tmpguid.D3));
  841. for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
  842. curconstSegment.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
  843. end
  844. else
  845. Message(parser_e_improper_guid_syntax);
  846. end
  847. else
  848. begin
  849. p.free;
  850. Message(cg_e_illegal_expression);
  851. exit;
  852. end;
  853. end
  854. else
  855. begin
  856. consume(_LKLAMMER);
  857. sorg:='';
  858. aktpos:=0;
  859. srsym := tsym(trecorddef(t.def).symtable.symindex.first);
  860. recsym := nil;
  861. while token<>_RKLAMMER do
  862. begin
  863. s:=pattern;
  864. sorg:=orgpattern;
  865. consume(_ID);
  866. consume(_COLON);
  867. error := false;
  868. recsym := tsym(trecorddef(t.def).symtable.search(s));
  869. if not assigned(recsym) then
  870. begin
  871. Message1(sym_e_illegal_field,sorg);
  872. error := true;
  873. end;
  874. if (not error) and
  875. (not assigned(srsym) or
  876. (s <> srsym.name)) then
  877. { possible variant record (JM) }
  878. begin
  879. { All parts of a variant start at the same offset }
  880. { Also allow jumping from one variant part to another, }
  881. { as long as the offsets match }
  882. if (assigned(srsym) and
  883. (tvarsym(recsym).fieldoffset = tvarsym(srsym).fieldoffset)) or
  884. { srsym is not assigned after parsing w2 in the }
  885. { typed const in the next example: }
  886. { type tr = record case byte of }
  887. { 1: (l1,l2: dword); }
  888. { 2: (w1,w2: word); }
  889. { end; }
  890. { const r: tr = (w1:1;w2:1;l2:5); }
  891. (tvarsym(recsym).fieldoffset = aktpos) then
  892. srsym := recsym
  893. { going backwards isn't allowed in any mode }
  894. else if (tvarsym(recsym).fieldoffset<aktpos) then
  895. begin
  896. Message(parser_e_invalid_record_const);
  897. error := true;
  898. end
  899. { Delphi allows you to skip fields }
  900. else if (m_delphi in aktmodeswitches) then
  901. begin
  902. Message1(parser_w_skipped_fields_before,sorg);
  903. srsym := recsym;
  904. end
  905. { FPC and TP don't }
  906. else
  907. begin
  908. Message1(parser_e_skipped_fields_before,sorg);
  909. error := true;
  910. end;
  911. end;
  912. if error then
  913. consume_all_until(_SEMICOLON)
  914. else
  915. begin
  916. { if needed fill (alignment) }
  917. if tvarsym(srsym).fieldoffset>aktpos then
  918. for i:=1 to tvarsym(srsym).fieldoffset-aktpos do
  919. curconstSegment.concat(Tai_const.Create_8bit(0));
  920. { new position }
  921. aktpos:=tvarsym(srsym).fieldoffset+tvarsym(srsym).vartype.def.size;
  922. { read the data }
  923. readtypedconst(tvarsym(srsym).vartype,nil,writable);
  924. { keep previous field for checking whether whole }
  925. { record was initialized (JM) }
  926. recsym := srsym;
  927. { goto next field }
  928. srsym := tsym(srsym.indexnext);
  929. if token=_SEMICOLON then
  930. consume(_SEMICOLON)
  931. else break;
  932. end;
  933. end;
  934. { are there any fields left? }
  935. if assigned(srsym) and
  936. { don't complain if there only come other variant parts }
  937. { after the last initialized field }
  938. ((recsym=nil) or
  939. (tvarsym(srsym).fieldoffset > tvarsym(recsym).fieldoffset)) then
  940. Message1(parser_w_skipped_fields_after,sorg);
  941. for i:=1 to t.def.size-aktpos do
  942. curconstSegment.concat(Tai_const.Create_8bit(0));
  943. consume(_RKLAMMER);
  944. end;
  945. end;
  946. { reads a typed object }
  947. objectdef:
  948. begin
  949. if is_class_or_interface(t.def) then
  950. begin
  951. p:=comp_expr(true);
  952. if p.nodetype<>niln then
  953. begin
  954. Message(parser_e_type_const_not_possible);
  955. consume_all_until(_RKLAMMER);
  956. end
  957. else
  958. begin
  959. curconstSegment.concat(Tai_const.Create_ptr(0));
  960. end;
  961. p.free;
  962. end
  963. { for objects we allow it only if it doesn't contain a vmt }
  964. else if (oo_has_vmt in tobjectdef(t.def).objectoptions) and
  965. (m_fpc in aktmodeswitches) then
  966. Message(parser_e_type_const_not_possible)
  967. else
  968. begin
  969. consume(_LKLAMMER);
  970. aktpos:=0;
  971. while token<>_RKLAMMER do
  972. begin
  973. s:=pattern;
  974. sorg:=orgpattern;
  975. consume(_ID);
  976. consume(_COLON);
  977. srsym:=nil;
  978. obj:=tobjectdef(t.def);
  979. symt:=obj.symtable;
  980. while (srsym=nil) and assigned(symt) do
  981. begin
  982. srsym:=tsym(symt.search(s));
  983. if assigned(obj) then
  984. obj:=obj.childof;
  985. if assigned(obj) then
  986. symt:=obj.symtable
  987. else
  988. symt:=nil;
  989. end;
  990. if srsym=nil then
  991. begin
  992. Message1(sym_e_id_not_found,sorg);
  993. consume_all_until(_SEMICOLON);
  994. end
  995. else
  996. with Tvarsym(srsym) do
  997. begin
  998. { check position }
  999. if fieldoffset<aktpos then
  1000. message(parser_e_invalid_record_const);
  1001. { check in VMT needs to be added for TP mode }
  1002. with Tobjectdef(t.def) do
  1003. if not(m_fpc in aktmodeswitches) and
  1004. (oo_has_vmt in objectoptions) and
  1005. (vmt_offset<fieldoffset) then
  1006. begin
  1007. for i:=1 to vmt_offset-aktpos do
  1008. curconstsegment.concat(tai_const.create_8bit(0));
  1009. curconstsegment.concat(tai_const_symbol.createname(vmt_mangledname,AT_DATA,0));
  1010. { this is more general }
  1011. aktpos:=vmt_offset + pointer_size;
  1012. end;
  1013. { if needed fill }
  1014. if fieldoffset>aktpos then
  1015. for i:=1 to fieldoffset-aktpos do
  1016. curconstSegment.concat(Tai_const.Create_8bit(0));
  1017. { new position }
  1018. aktpos:=fieldoffset+vartype.def.size;
  1019. { read the data }
  1020. readtypedconst(vartype,nil,writable);
  1021. if token=_SEMICOLON then
  1022. consume(_SEMICOLON)
  1023. else break;
  1024. end;
  1025. end;
  1026. if not(m_fpc in aktmodeswitches) and
  1027. (oo_has_vmt in tobjectdef(t.def).objectoptions) and
  1028. (tobjectdef(t.def).vmt_offset>=aktpos) then
  1029. begin
  1030. for i:=1 to tobjectdef(t.def).vmt_offset-aktpos do
  1031. curconstsegment.concat(tai_const.create_8bit(0));
  1032. curconstsegment.concat(tai_const_symbol.createname(tobjectdef(t.def).vmt_mangledname,AT_DATA,0));
  1033. { this is more general }
  1034. aktpos:=tobjectdef(t.def).vmt_offset + pointer_size;
  1035. end;
  1036. for i:=1 to t.def.size-aktpos do
  1037. curconstSegment.concat(Tai_const.Create_8bit(0));
  1038. consume(_RKLAMMER);
  1039. end;
  1040. end;
  1041. errordef:
  1042. begin
  1043. { try to consume something useful }
  1044. if token=_LKLAMMER then
  1045. consume_all_until(_RKLAMMER)
  1046. else
  1047. consume_all_until(_SEMICOLON);
  1048. end;
  1049. else Message(parser_e_type_const_not_possible);
  1050. end;
  1051. block_type:=old_block_type;
  1052. end;
  1053. {$ifdef fpc}
  1054. {$maxfpuregisters default}
  1055. {$endif fpc}
  1056. end.
  1057. {
  1058. $Log$
  1059. Revision 1.85 2004-05-23 15:23:30 peter
  1060. * fixed qword(longint) that removed sign from the number
  1061. * removed code in the compiler that relied on wrong qword(longint)
  1062. code generation
  1063. Revision 1.84 2004/04/29 19:56:37 daniel
  1064. * Prepare compiler infrastructure for multiple ansistring types
  1065. Revision 1.83 2004/04/11 10:44:23 peter
  1066. * block_type is bt_const when parsing typed consts
  1067. Revision 1.82 2004/03/18 11:43:57 olle
  1068. * change AT_FUNCTION to AT_DATA where appropriate
  1069. Revision 1.81 2004/03/17 22:27:41 florian
  1070. * fixed handling of doubles in a native arm compiler
  1071. * fixed handling of typed double constants on arm
  1072. Revision 1.80 2004/03/02 00:36:33 olle
  1073. * big transformation of Tai_[const_]Symbol.Create[data]name*
  1074. Revision 1.79 2004/02/26 16:15:23 peter
  1075. * support @@procvar in typed consts
  1076. Revision 1.78 2004/02/07 23:28:34 daniel
  1077. * Take advantage of our new with statement optimization
  1078. Revision 1.77 2003/12/29 12:48:39 jonas
  1079. + support for currency typed constants if currency=int64. Warning: does
  1080. not work properly for extreme values if bestreal <= double
  1081. Revision 1.76 2003/12/08 22:34:24 peter
  1082. * tai_const.create_32bit changed to cardinal
  1083. Revision 1.75 2003/11/22 00:32:35 jonas
  1084. * fixed reversed "got <type 1>, expected <type 1>" error message
  1085. Revision 1.74 2003/11/12 16:05:39 florian
  1086. * assembler readers OOPed
  1087. + typed currency constants
  1088. + typed 128 bit float constants if the CPU supports it
  1089. Revision 1.73 2003/11/08 10:23:35 florian
  1090. * fixed parsing of typed widestring constants with length 1
  1091. Revision 1.72 2003/10/21 18:16:13 peter
  1092. * IncompatibleTypes() added that will include unit names when
  1093. the typenames are the same
  1094. Revision 1.71 2003/09/23 17:56:06 peter
  1095. * locals and paras are allocated in the code generation
  1096. * tvarsym.localloc contains the location of para/local when
  1097. generating code for the current procedure
  1098. Revision 1.70 2003/09/03 15:55:01 peter
  1099. * NEWRA branch merged
  1100. Revision 1.69 2003/05/09 17:47:03 peter
  1101. * self moved to hidden parameter
  1102. * removed hdisposen,hnewn,selfn
  1103. Revision 1.68 2003/04/30 20:53:32 florian
  1104. * error when address of an abstract method is taken
  1105. * fixed some x86-64 problems
  1106. * merged some more x86-64 and i386 code
  1107. Revision 1.67 2003/04/24 22:29:58 florian
  1108. * fixed a lot of PowerPC related stuff
  1109. Revision 1.66 2003/04/06 21:11:23 olle
  1110. * changed newasmsymbol to newasmsymboldata for data symbols
  1111. Revision 1.65 2003/03/17 21:42:32 peter
  1112. * allow nil initialization of dynamic array
  1113. Revision 1.64 2003/01/02 20:45:08 peter
  1114. * fix uninited var
  1115. Revision 1.63 2002/12/26 12:34:54 florian
  1116. * fixed support for type widechar consts
  1117. Revision 1.62 2002/12/07 14:15:33 carl
  1118. + add some explicit typecasts to remove some warnings
  1119. Revision 1.61 2002/11/25 18:43:33 carl
  1120. - removed the invalid if <> checking (Delphi is strange on this)
  1121. + implemented abstract warning on instance creation of class with
  1122. abstract methods.
  1123. * some error message cleanups
  1124. Revision 1.60 2002/11/25 17:43:23 peter
  1125. * splitted defbase in defutil,symutil,defcmp
  1126. * merged isconvertable and is_equal into compare_defs(_ext)
  1127. * made operator search faster by walking the list only once
  1128. Revision 1.59 2002/11/22 22:48:10 carl
  1129. * memory optimization with tconstsym (1.5%)
  1130. Revision 1.58 2002/11/09 15:31:57 carl
  1131. + align ansi/wide string constants
  1132. Revision 1.57 2002/09/06 19:58:31 carl
  1133. * start bugfix 1996
  1134. * 64-bit typed constant now work correctly and fully (bugfix 2001)
  1135. Revision 1.56 2002/09/03 16:26:27 daniel
  1136. * Make Tprocdef.defs protected
  1137. Revision 1.55 2002/08/11 14:32:27 peter
  1138. * renamed current_library to objectlibrary
  1139. Revision 1.54 2002/08/11 13:24:13 peter
  1140. * saving of asmsymbols in ppu supported
  1141. * asmsymbollist global is removed and moved into a new class
  1142. tasmlibrarydata that will hold the info of a .a file which
  1143. corresponds with a single module. Added librarydata to tmodule
  1144. to keep the library info stored for the module. In the future the
  1145. objectfiles will also be stored to the tasmlibrarydata class
  1146. * all getlabel/newasmsymbol and friends are moved to the new class
  1147. Revision 1.53 2002/07/23 12:34:30 daniel
  1148. * Readded old set code. To use it define 'oldset'. Activated by default
  1149. for ppc.
  1150. Revision 1.52 2002/07/22 11:48:04 daniel
  1151. * Sets are now internally sets.
  1152. Revision 1.51 2002/07/20 11:57:56 florian
  1153. * types.pas renamed to defbase.pas because D6 contains a types
  1154. unit so this would conflicts if D6 programms are compiled
  1155. + Willamette/SSE2 instructions to assembler added
  1156. Revision 1.50 2002/07/01 18:46:25 peter
  1157. * internal linker
  1158. * reorganized aasm layer
  1159. Revision 1.49 2002/05/18 13:34:16 peter
  1160. * readded missing revisions
  1161. Revision 1.48 2002/05/16 19:46:44 carl
  1162. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1163. + try to fix temp allocation (still in ifdef)
  1164. + generic constructor calls
  1165. + start of tassembler / tmodulebase class cleanup
  1166. Revision 1.46 2002/05/12 16:53:09 peter
  1167. * moved entry and exitcode to ncgutil and cgobj
  1168. * foreach gets extra argument for passing local data to the
  1169. iterator function
  1170. * -CR checks also class typecasts at runtime by changing them
  1171. into as
  1172. * fixed compiler to cycle with the -CR option
  1173. * fixed stabs with elf writer, finally the global variables can
  1174. be watched
  1175. * removed a lot of routines from cga unit and replaced them by
  1176. calls to cgobj
  1177. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1178. u32bit then the other is typecasted also to u32bit without giving
  1179. a rangecheck warning/error.
  1180. * fixed pascal calling method with reversing also the high tree in
  1181. the parast, detected by tcalcst3 test
  1182. Revision 1.45 2002/04/23 19:16:35 peter
  1183. * add pinline unit that inserts compiler supported functions using
  1184. one or more statements
  1185. * moved finalize and setlength from ninl to pinline
  1186. Revision 1.44 2002/04/20 21:32:24 carl
  1187. + generic FPC_CHECKPOINTER
  1188. + first parameter offset in stack now portable
  1189. * rename some constants
  1190. + move some cpu stuff to other units
  1191. - remove unused constents
  1192. * fix stacksize for some targets
  1193. * fix generic size problems which depend now on EXTEND_SIZE constant
  1194. Revision 1.43 2002/04/15 19:01:53 carl
  1195. + target_info.size_of_pointer -> pointer_Size
  1196. Revision 1.42 2002/04/04 19:06:03 peter
  1197. * removed unused units
  1198. * use tlocation.size in cg.a_*loc*() routines
  1199. Revision 1.41 2002/01/24 18:25:49 peter
  1200. * implicit result variable generation for assembler routines
  1201. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  1202. Revision 1.40 2002/01/06 21:47:32 peter
  1203. * removed getprocvar, use only getprocvardef
  1204. }