ptype.pas 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Does parsing types for Free Pascal
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit ptype;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,cclasses,
  22. symtype,symdef,symbase;
  23. const
  24. { forward types should only be possible inside a TYPE statement }
  25. typecanbeforward : boolean = false;
  26. var
  27. { hack, which allows to use the current parsed }
  28. { object type as function argument type }
  29. testcurobject : byte;
  30. { reads a type identifier }
  31. procedure id_type(var def : tdef;isforwarddef:boolean);
  32. { reads a string, file type or a type identifier }
  33. procedure single_type(var def:tdef;isforwarddef:boolean);
  34. { reads any type declaration, where the resulting type will get name as type identifier }
  35. procedure read_named_type(var def:tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  36. { reads any type declaration }
  37. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  38. { generate persistent type information like VMT, RTTI and inittables }
  39. procedure write_persistent_type_info(st:tsymtable);
  40. implementation
  41. uses
  42. { common }
  43. cutils,
  44. { global }
  45. globals,tokens,verbose,constexp,
  46. systems,
  47. { target }
  48. paramgr,
  49. { symtable }
  50. symconst,symsym,symtable,
  51. defutil,defcmp,
  52. { pass 1 }
  53. node,ncgrtti,nobj,
  54. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  55. { parser }
  56. scanner,
  57. pbase,pexpr,pdecsub,pdecvar,pdecobj;
  58. procedure generate_specialization(var pt1:tnode;const name:string);
  59. var
  60. st : TSymtable;
  61. pt2 : tnode;
  62. first,
  63. err : boolean;
  64. i : longint;
  65. sym : tsym;
  66. genericdef : tstoreddef;
  67. generictype : ttypesym;
  68. generictypelist : TFPObjectList;
  69. begin
  70. { retrieve generic def that we are going to replace }
  71. genericdef:=tstoreddef(pt1.resultdef);
  72. pt1.resultdef:=nil;
  73. if not(df_generic in genericdef.defoptions) then
  74. begin
  75. Message(parser_e_special_onlygenerics);
  76. pt1.resultdef:=generrordef;
  77. { recover }
  78. consume(_LSHARPBRACKET);
  79. repeat
  80. pt2:=factor(false);
  81. pt2.free;
  82. until not try_to_consume(_COMMA);
  83. consume(_RSHARPBRACKET);
  84. exit;
  85. end;
  86. consume(_LSHARPBRACKET);
  87. block_type:=bt_specialize;
  88. { Parse generic parameters, for each undefineddef in the symtable of
  89. the genericdef we need to have a new def }
  90. err:=false;
  91. first:=true;
  92. generictypelist:=TFPObjectList.create(false);
  93. case genericdef.typ of
  94. procdef :
  95. st:=genericdef.GetSymtable(gs_para);
  96. objectdef,
  97. recorddef :
  98. st:=genericdef.GetSymtable(gs_record);
  99. end;
  100. if not assigned(st) then
  101. internalerror(200511182);
  102. for i:=0 to st.SymList.Count-1 do
  103. begin
  104. sym:=tsym(st.SymList[i]);
  105. if (sym.typ=typesym) and
  106. (ttypesym(sym).typedef.typ=undefineddef) then
  107. begin
  108. if not first then
  109. consume(_COMMA)
  110. else
  111. first:=false;
  112. pt2:=factor(false);
  113. if pt2.nodetype=typen then
  114. begin
  115. if df_generic in pt2.resultdef.defoptions then
  116. Message(parser_e_no_generics_as_params);
  117. generictype:=ttypesym.create(sym.realname,pt2.resultdef);
  118. generictypelist.add(generictype);
  119. end
  120. else
  121. begin
  122. Message(type_e_type_id_expected);
  123. err:=true;
  124. end;
  125. pt2.free;
  126. end;
  127. end;
  128. { Reparse the original type definition }
  129. if not err then
  130. begin
  131. if not assigned(genericdef.generictokenbuf) then
  132. internalerror(200511171);
  133. current_scanner.startreplaytokens(genericdef.generictokenbuf);
  134. read_named_type(pt1.resultdef,name,genericdef,generictypelist,false);
  135. { Consume the semicolon if it is also recorded }
  136. try_to_consume(_SEMICOLON);
  137. end;
  138. generictypelist.free;
  139. consume(_RSHARPBRACKET);
  140. end;
  141. procedure id_type(var def : tdef;isforwarddef:boolean);
  142. { reads a type definition }
  143. { to a appropriating tdef, s gets the name of }
  144. { the type to allow name mangling }
  145. var
  146. is_unit_specific : boolean;
  147. pos : tfileposinfo;
  148. srsym : tsym;
  149. srsymtable : TSymtable;
  150. s,sorg : TIDString;
  151. begin
  152. s:=pattern;
  153. sorg:=orgpattern;
  154. pos:=current_tokenpos;
  155. { use of current parsed object:
  156. - classes can be used also in classes
  157. - objects can be parameters }
  158. if assigned(aktobjectdef) and
  159. (aktobjectdef.objname^=pattern) and
  160. (
  161. (testcurobject=2) or
  162. is_class_or_interface(aktobjectdef)
  163. )then
  164. begin
  165. consume(_ID);
  166. def:=aktobjectdef;
  167. exit;
  168. end;
  169. { Use the special searchsym_type that ignores records,objects and
  170. parameters }
  171. searchsym_type(s,srsym,srsymtable);
  172. { handle unit specification like System.Writeln }
  173. is_unit_specific:=try_consume_unitsym(srsym,srsymtable);
  174. consume(_ID);
  175. { Types are first defined with an error def before assigning
  176. the real type so check if it's an errordef. if so then
  177. give an error. Only check for typesyms in the current symbol
  178. table as forwarddef are not resolved directly }
  179. if assigned(srsym) and
  180. (srsym.typ=typesym) and
  181. (ttypesym(srsym).typedef.typ=errordef) then
  182. begin
  183. Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
  184. def:=generrordef;
  185. exit;
  186. end;
  187. { are we parsing a possible forward def ? }
  188. if isforwarddef and
  189. not(is_unit_specific) then
  190. begin
  191. def:=tforwarddef.create(s,pos);
  192. exit;
  193. end;
  194. { unknown sym ? }
  195. if not assigned(srsym) then
  196. begin
  197. Message1(sym_e_id_not_found,sorg);
  198. def:=generrordef;
  199. exit;
  200. end;
  201. { type sym ? }
  202. if (srsym.typ<>typesym) then
  203. begin
  204. Message(type_e_type_id_expected);
  205. def:=generrordef;
  206. exit;
  207. end;
  208. { Give an error when referring to an errordef }
  209. if (ttypesym(srsym).typedef.typ=errordef) then
  210. begin
  211. Message(sym_e_error_in_type_def);
  212. def:=generrordef;
  213. exit;
  214. end;
  215. def:=ttypesym(srsym).typedef;
  216. end;
  217. procedure single_type(var def:tdef;isforwarddef:boolean);
  218. var
  219. t2 : tdef;
  220. again : boolean;
  221. begin
  222. repeat
  223. again:=false;
  224. case token of
  225. _STRING:
  226. string_dec(def);
  227. _FILE:
  228. begin
  229. consume(_FILE);
  230. if try_to_consume(_OF) then
  231. begin
  232. single_type(t2,false);
  233. def:=tfiledef.createtyped(t2);
  234. end
  235. else
  236. def:=cfiletype;
  237. end;
  238. _ID:
  239. begin
  240. if try_to_consume(_SPECIALIZE) then
  241. begin
  242. if block_type<>bt_type then
  243. Message(parser_f_no_anonymous_specializations);
  244. block_type:=bt_specialize;
  245. again:=true;
  246. end
  247. else
  248. id_type(def,isforwarddef);
  249. end;
  250. else
  251. begin
  252. message(type_e_type_id_expected);
  253. def:=generrordef;
  254. end;
  255. end;
  256. until not again;
  257. end;
  258. { reads a record declaration }
  259. function record_dec : tdef;
  260. var
  261. recst : trecordsymtable;
  262. storetypecanbeforward : boolean;
  263. old_object_option : tsymoptions;
  264. begin
  265. { create recdef }
  266. recst:=trecordsymtable.create(current_settings.packrecords);
  267. record_dec:=trecorddef.create(recst);
  268. { insert in symtablestack }
  269. symtablestack.push(recst);
  270. { parse record }
  271. consume(_RECORD);
  272. old_object_option:=current_object_option;
  273. current_object_option:=[sp_public];
  274. storetypecanbeforward:=typecanbeforward;
  275. { for tp7 don't allow forward types }
  276. if m_tp7 in current_settings.modeswitches then
  277. typecanbeforward:=false;
  278. read_record_fields([vd_record]);
  279. consume(_END);
  280. typecanbeforward:=storetypecanbeforward;
  281. current_object_option:=old_object_option;
  282. { make the record size aligned }
  283. recst.addalignmentpadding;
  284. { restore symtable stack }
  285. symtablestack.pop(recst);
  286. if trecorddef(record_dec).is_packed and
  287. record_dec.needs_inittable then
  288. Message(type_e_no_packed_inittable);
  289. end;
  290. { reads a type definition and returns a pointer to it }
  291. procedure read_named_type(var def : tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  292. var
  293. pt : tnode;
  294. tt2 : tdef;
  295. aktenumdef : tenumdef;
  296. s : TIDString;
  297. l,v : TConstExprInt;
  298. oldpackrecords : longint;
  299. defpos,storepos : tfileposinfo;
  300. procedure expr_type;
  301. var
  302. pt1,pt2 : tnode;
  303. lv,hv : TConstExprInt;
  304. old_block_type : tblock_type;
  305. begin
  306. old_block_type:=block_type;
  307. { use of current parsed object:
  308. - classes can be used also in classes
  309. - objects can be parameters }
  310. if (token=_ID) and
  311. assigned(aktobjectdef) and
  312. (aktobjectdef.objname^=pattern) and
  313. (
  314. (testcurobject=2) or
  315. is_class_or_interface(aktobjectdef)
  316. )then
  317. begin
  318. consume(_ID);
  319. def:=aktobjectdef;
  320. exit;
  321. end;
  322. { Generate a specialization? }
  323. if try_to_consume(_SPECIALIZE) then
  324. begin
  325. if name='' then
  326. Message(parser_f_no_anonymous_specializations);
  327. block_type:=bt_specialize;
  328. end;
  329. { we can't accept a equal in type }
  330. pt1:=comp_expr(false);
  331. if (block_type<>bt_specialize) and
  332. try_to_consume(_POINTPOINT) then
  333. begin
  334. { get high value of range }
  335. pt2:=comp_expr(false);
  336. { make both the same type or give an error. This is not
  337. done when both are integer values, because typecasting
  338. between -3200..3200 will result in a signed-unsigned
  339. conflict and give a range check error (PFV) }
  340. if not(is_integer(pt1.resultdef) and is_integer(pt2.resultdef)) then
  341. inserttypeconv(pt1,pt2.resultdef);
  342. { both must be evaluated to constants now }
  343. if (pt1.nodetype=ordconstn) and
  344. (pt2.nodetype=ordconstn) then
  345. begin
  346. lv:=tordconstnode(pt1).value;
  347. hv:=tordconstnode(pt2).value;
  348. { Check bounds }
  349. if hv<lv then
  350. message(parser_e_upper_lower_than_lower)
  351. else if (lv.signed and (lv.svalue<0)) and (not hv.signed and (hv.uvalue>qword(high(int64)))) then
  352. message(type_e_cant_eval_constant_expr)
  353. else
  354. begin
  355. { All checks passed, create the new def }
  356. case pt1.resultdef.typ of
  357. enumdef :
  358. def:=tenumdef.create_subrange(tenumdef(pt1.resultdef),lv.svalue,hv.svalue);
  359. orddef :
  360. begin
  361. if is_char(pt1.resultdef) then
  362. def:=torddef.create(uchar,lv,hv)
  363. else
  364. if is_boolean(pt1.resultdef) then
  365. def:=torddef.create(bool8bit,lv,hv)
  366. else if is_signed(pt1.resultdef) then
  367. def:=torddef.create(range_to_basetype(lv,hv),lv,hv)
  368. else
  369. def:=torddef.create(range_to_basetype(lv,hv),lv,hv);
  370. end;
  371. end;
  372. end;
  373. end
  374. else
  375. Message(sym_e_error_in_type_def);
  376. pt2.free;
  377. end
  378. else
  379. begin
  380. { a simple type renaming or generic specialization }
  381. if (pt1.nodetype=typen) then
  382. begin
  383. if (block_type=bt_specialize) then
  384. generate_specialization(pt1,name);
  385. def:=ttypenode(pt1).resultdef;
  386. end
  387. else
  388. Message(sym_e_error_in_type_def);
  389. end;
  390. pt1.free;
  391. block_type:=old_block_type;
  392. end;
  393. procedure set_dec;
  394. begin
  395. consume(_SET);
  396. consume(_OF);
  397. read_anon_type(tt2,true);
  398. if assigned(tt2) then
  399. begin
  400. case tt2.typ of
  401. { don't forget that min can be negativ PM }
  402. enumdef :
  403. if tenumdef(tt2).min>=0 then
  404. // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  405. def:=tsetdef.create(tt2,tenumdef(tt2).max)
  406. else
  407. Message(sym_e_ill_type_decl_set);
  408. orddef :
  409. begin
  410. if (torddef(tt2).ordtype<>uvoid) and
  411. (torddef(tt2).low>=0) then
  412. // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  413. if Torddef(tt2).high>int64(high(longint)) then
  414. message(sym_e_ill_type_decl_set)
  415. else
  416. def:=tsetdef.create(tt2,torddef(tt2).high.svalue)
  417. else
  418. Message(sym_e_ill_type_decl_set);
  419. end;
  420. else
  421. Message(sym_e_ill_type_decl_set);
  422. end;
  423. end
  424. else
  425. def:=generrordef;
  426. end;
  427. procedure array_dec(is_packed: boolean);
  428. var
  429. lowval,
  430. highval : TConstExprInt;
  431. indexdef : tdef;
  432. hdef : tdef;
  433. arrdef : tarraydef;
  434. procedure setdefdecl(def:tdef);
  435. begin
  436. case def.typ of
  437. enumdef :
  438. begin
  439. lowval:=tenumdef(def).min;
  440. highval:=tenumdef(def).max;
  441. if (m_fpc in current_settings.modeswitches) and
  442. (tenumdef(def).has_jumps) then
  443. Message(type_e_array_index_enums_with_assign_not_possible);
  444. indexdef:=def;
  445. end;
  446. orddef :
  447. begin
  448. if torddef(def).ordtype in [uchar,
  449. u8bit,u16bit,
  450. s8bit,s16bit,s32bit,
  451. {$ifdef cpu64bit}
  452. u32bit,s64bit,
  453. {$endif cpu64bit}
  454. bool8bit,bool16bit,bool32bit,bool64bit,
  455. uwidechar] then
  456. begin
  457. lowval:=torddef(def).low;
  458. highval:=torddef(def).high;
  459. indexdef:=def;
  460. end
  461. else
  462. Message1(parser_e_type_cant_be_used_in_array_index,def.GetTypeName);
  463. end;
  464. else
  465. Message(sym_e_error_in_type_def);
  466. end;
  467. end;
  468. begin
  469. arrdef:=nil;
  470. consume(_ARRAY);
  471. { open array? }
  472. if try_to_consume(_LECKKLAMMER) then
  473. begin
  474. { defaults }
  475. indexdef:=generrordef;
  476. lowval:=int64(low(aint));
  477. highval:=high(aint);
  478. repeat
  479. { read the expression and check it, check apart if the
  480. declaration is an enum declaration because that needs to
  481. be parsed by readtype (PFV) }
  482. if token=_LKLAMMER then
  483. begin
  484. read_anon_type(hdef,true);
  485. setdefdecl(hdef);
  486. end
  487. else
  488. begin
  489. pt:=expr;
  490. if pt.nodetype=typen then
  491. setdefdecl(pt.resultdef)
  492. else
  493. begin
  494. if (pt.nodetype=rangen) then
  495. begin
  496. if (trangenode(pt).left.nodetype=ordconstn) and
  497. (trangenode(pt).right.nodetype=ordconstn) then
  498. begin
  499. { make both the same type or give an error. This is not
  500. done when both are integer values, because typecasting
  501. between -3200..3200 will result in a signed-unsigned
  502. conflict and give a range check error (PFV) }
  503. if not(is_integer(trangenode(pt).left.resultdef) and is_integer(trangenode(pt).left.resultdef)) then
  504. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resultdef);
  505. lowval:=tordconstnode(trangenode(pt).left).value;
  506. highval:=tordconstnode(trangenode(pt).right).value;
  507. if highval<lowval then
  508. begin
  509. Message(parser_e_array_lower_less_than_upper_bound);
  510. highval:=lowval;
  511. end
  512. else if (lowval<int64(low(aint))) or
  513. (highval > high(aint)) then
  514. begin
  515. Message(parser_e_array_range_out_of_bounds);
  516. lowval :=0;
  517. highval:=0;
  518. end;
  519. if is_integer(trangenode(pt).left.resultdef) then
  520. range_to_type(lowval,highval,indexdef)
  521. else
  522. indexdef:=trangenode(pt).left.resultdef;
  523. end
  524. else
  525. Message(type_e_cant_eval_constant_expr);
  526. end
  527. else
  528. Message(sym_e_error_in_type_def)
  529. end;
  530. pt.free;
  531. end;
  532. { if the array is already created add the new arrray
  533. as element of the existing array, otherwise create a new array }
  534. if assigned(arrdef) then
  535. begin
  536. arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  537. arrdef:=tarraydef(arrdef.elementdef);
  538. end
  539. else
  540. begin
  541. arrdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  542. def:=arrdef;
  543. end;
  544. if is_packed then
  545. include(arrdef.arrayoptions,ado_IsBitPacked);
  546. if token=_COMMA then
  547. consume(_COMMA)
  548. else
  549. break;
  550. until false;
  551. consume(_RECKKLAMMER);
  552. end
  553. else
  554. begin
  555. if is_packed then
  556. Message(parser_e_packed_dynamic_open_array);
  557. arrdef:=tarraydef.create(0,-1,s32inttype);
  558. include(arrdef.arrayoptions,ado_IsDynamicArray);
  559. def:=arrdef;
  560. end;
  561. consume(_OF);
  562. read_anon_type(tt2,true);
  563. { set element type of the last array definition }
  564. if assigned(arrdef) then
  565. begin
  566. arrdef.elementdef:=tt2;
  567. if is_packed and
  568. tt2.needs_inittable then
  569. Message(type_e_no_packed_inittable);
  570. end;
  571. end;
  572. var
  573. p : tnode;
  574. pd : tabstractprocdef;
  575. is_func,
  576. enumdupmsg, first : boolean;
  577. newtype : ttypesym;
  578. oldlocalswitches : tlocalswitches;
  579. bitpacking: boolean;
  580. begin
  581. def:=nil;
  582. case token of
  583. _STRING,_FILE:
  584. begin
  585. single_type(def,false);
  586. end;
  587. _LKLAMMER:
  588. begin
  589. consume(_LKLAMMER);
  590. first := true;
  591. { allow negativ value_str }
  592. l:=int64(-1);
  593. enumdupmsg:=false;
  594. aktenumdef:=tenumdef.create;
  595. repeat
  596. s:=orgpattern;
  597. defpos:=current_tokenpos;
  598. consume(_ID);
  599. { only allow assigning of specific numbers under fpc mode }
  600. if not(m_tp7 in current_settings.modeswitches) and
  601. (
  602. { in fpc mode also allow := to be compatible
  603. with previous 1.0.x versions }
  604. ((m_fpc in current_settings.modeswitches) and
  605. try_to_consume(_ASSIGNMENT)) or
  606. try_to_consume(_EQUAL)
  607. ) then
  608. begin
  609. oldlocalswitches:=current_settings.localswitches;
  610. include(current_settings.localswitches,cs_allow_enum_calc);
  611. p:=comp_expr(true);
  612. current_settings.localswitches:=oldlocalswitches;
  613. if (p.nodetype=ordconstn) then
  614. begin
  615. { we expect an integer or an enum of the
  616. same type }
  617. if is_integer(p.resultdef) or
  618. is_char(p.resultdef) or
  619. equal_defs(p.resultdef,aktenumdef) then
  620. v:=tordconstnode(p).value
  621. else
  622. IncompatibleTypes(p.resultdef,s32inttype);
  623. end
  624. else
  625. Message(parser_e_illegal_expression);
  626. p.free;
  627. { please leave that a note, allows type save }
  628. { declarations in the win32 units ! }
  629. if (not first) and (v<=l) and (not enumdupmsg) then
  630. begin
  631. Message(parser_n_duplicate_enum);
  632. enumdupmsg:=true;
  633. end;
  634. l:=v;
  635. end
  636. else
  637. inc(l.svalue);
  638. first := false;
  639. storepos:=current_tokenpos;
  640. current_tokenpos:=defpos;
  641. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l.svalue));
  642. current_tokenpos:=storepos;
  643. until not try_to_consume(_COMMA);
  644. def:=aktenumdef;
  645. consume(_RKLAMMER);
  646. end;
  647. _ARRAY:
  648. begin
  649. array_dec(false);
  650. end;
  651. _SET:
  652. begin
  653. set_dec;
  654. end;
  655. _CARET:
  656. begin
  657. consume(_CARET);
  658. single_type(tt2,typecanbeforward);
  659. def:=tpointerdef.create(tt2);
  660. end;
  661. _RECORD:
  662. begin
  663. def:=record_dec;
  664. end;
  665. _PACKED,
  666. _BITPACKED:
  667. begin
  668. bitpacking :=
  669. (cs_bitpacking in current_settings.localswitches) or
  670. (token = _BITPACKED);
  671. consume(token);
  672. if token=_ARRAY then
  673. array_dec(bitpacking)
  674. else if token=_SET then
  675. set_dec
  676. else
  677. begin
  678. oldpackrecords:=current_settings.packrecords;
  679. if (not bitpacking) or
  680. (token in [_CLASS,_OBJECT]) then
  681. current_settings.packrecords:=1
  682. else
  683. current_settings.packrecords:=bit_alignment;
  684. if token in [_CLASS,_OBJECT] then
  685. def:=object_dec(name,genericdef,genericlist,nil)
  686. else
  687. def:=record_dec;
  688. current_settings.packrecords:=oldpackrecords;
  689. end;
  690. end;
  691. _DISPINTERFACE,
  692. _CLASS,
  693. _CPPCLASS,
  694. _INTERFACE,
  695. _OBJECT:
  696. begin
  697. def:=object_dec(name,genericdef,genericlist,nil);
  698. end;
  699. _PROCEDURE,
  700. _FUNCTION:
  701. begin
  702. is_func:=(token=_FUNCTION);
  703. consume(token);
  704. pd:=tprocvardef.create(normal_function_level);
  705. if token=_LKLAMMER then
  706. parse_parameter_dec(pd);
  707. if is_func then
  708. begin
  709. consume(_COLON);
  710. single_type(pd.returndef,false);
  711. end;
  712. if token=_OF then
  713. begin
  714. consume(_OF);
  715. consume(_OBJECT);
  716. include(pd.procoptions,po_methodpointer);
  717. end;
  718. def:=pd;
  719. { possible proc directives }
  720. if parseprocvardir then
  721. begin
  722. if check_proc_directive(true) then
  723. begin
  724. newtype:=ttypesym.create('unnamed',def);
  725. parse_var_proc_directives(tsym(newtype));
  726. newtype.typedef:=nil;
  727. def.typesym:=nil;
  728. newtype.free;
  729. end;
  730. { Add implicit hidden parameters and function result }
  731. handle_calling_convention(pd);
  732. end;
  733. end;
  734. else
  735. expr_type;
  736. end;
  737. if def=nil then
  738. def:=generrordef;
  739. end;
  740. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  741. begin
  742. read_named_type(def,'',nil,nil,parseprocvardir);
  743. end;
  744. procedure write_persistent_type_info(st:tsymtable);
  745. var
  746. i : longint;
  747. def : tdef;
  748. vmtwriter : TVMTWriter;
  749. begin
  750. for i:=0 to st.DefList.Count-1 do
  751. begin
  752. def:=tdef(st.DefList[i]);
  753. case def.typ of
  754. recorddef :
  755. write_persistent_type_info(trecorddef(def).symtable);
  756. objectdef :
  757. begin
  758. write_persistent_type_info(tobjectdef(def).symtable);
  759. { Write also VMT }
  760. if not(ds_vmt_written in def.defstates) and
  761. not(oo_is_forward in tobjectdef(def).objectoptions) then
  762. begin
  763. vmtwriter:=TVMTWriter.create(tobjectdef(def));
  764. if is_interface(tobjectdef(def)) then
  765. vmtwriter.writeinterfaceids;
  766. if (oo_has_vmt in tobjectdef(def).objectoptions) then
  767. vmtwriter.writevmt;
  768. vmtwriter.free;
  769. include(def.defstates,ds_vmt_written);
  770. end;
  771. end;
  772. procdef :
  773. begin
  774. if assigned(tprocdef(def).localst) and
  775. (tprocdef(def).localst.symtabletype=localsymtable) then
  776. write_persistent_type_info(tprocdef(def).localst);
  777. if assigned(tprocdef(def).parast) then
  778. write_persistent_type_info(tprocdef(def).parast);
  779. end;
  780. end;
  781. { generate always persistent tables for types in the interface so it can
  782. be reused in other units and give always the same pointer location. }
  783. { Init }
  784. if (
  785. assigned(def.typesym) and
  786. (st.symtabletype=globalsymtable)
  787. ) or
  788. def.needs_inittable or
  789. (ds_init_table_used in def.defstates) then
  790. RTTIWriter.write_rtti(def,initrtti);
  791. { RTTI }
  792. if (
  793. assigned(def.typesym) and
  794. (st.symtabletype=globalsymtable)
  795. ) or
  796. (ds_rtti_table_used in def.defstates) then
  797. RTTIWriter.write_rtti(def,fullrtti);
  798. end;
  799. end;
  800. end.