ptconst.pas 57 KB

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