ptconst.pas 56 KB

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