ptype.pas 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  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,
  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. block_type:=bt_specialize;
  243. again:=true;
  244. end
  245. else
  246. id_type(def,isforwarddef);
  247. end;
  248. else
  249. begin
  250. message(type_e_type_id_expected);
  251. def:=generrordef;
  252. end;
  253. end;
  254. until not again;
  255. end;
  256. { reads a record declaration }
  257. function record_dec : tdef;
  258. var
  259. recst : trecordsymtable;
  260. storetypecanbeforward : boolean;
  261. old_object_option : tsymoptions;
  262. begin
  263. { create recdef }
  264. recst:=trecordsymtable.create(current_settings.packrecords);
  265. record_dec:=trecorddef.create(recst);
  266. { insert in symtablestack }
  267. symtablestack.push(recst);
  268. { parse record }
  269. consume(_RECORD);
  270. old_object_option:=current_object_option;
  271. current_object_option:=[sp_public];
  272. storetypecanbeforward:=typecanbeforward;
  273. { for tp7 don't allow forward types }
  274. if m_tp7 in current_settings.modeswitches then
  275. typecanbeforward:=false;
  276. read_record_fields([vd_record]);
  277. consume(_END);
  278. typecanbeforward:=storetypecanbeforward;
  279. current_object_option:=old_object_option;
  280. { make the record size aligned }
  281. recst.addalignmentpadding;
  282. { restore symtable stack }
  283. symtablestack.pop(recst);
  284. if trecorddef(record_dec).is_packed and
  285. record_dec.needs_inittable then
  286. Message(type_e_no_packed_inittable);
  287. end;
  288. { reads a type definition and returns a pointer to it }
  289. procedure read_named_type(var def : tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  290. var
  291. pt : tnode;
  292. tt2 : tdef;
  293. aktenumdef : tenumdef;
  294. s : TIDString;
  295. l,v : TConstExprInt;
  296. oldpackrecords : longint;
  297. defpos,storepos : tfileposinfo;
  298. procedure expr_type;
  299. var
  300. pt1,pt2 : tnode;
  301. lv,hv : TConstExprInt;
  302. old_block_type : tblock_type;
  303. begin
  304. old_block_type:=block_type;
  305. { use of current parsed object:
  306. - classes can be used also in classes
  307. - objects can be parameters }
  308. if (token=_ID) and
  309. assigned(aktobjectdef) and
  310. (aktobjectdef.objname^=pattern) and
  311. (
  312. (testcurobject=2) or
  313. is_class_or_interface(aktobjectdef)
  314. )then
  315. begin
  316. consume(_ID);
  317. def:=aktobjectdef;
  318. exit;
  319. end;
  320. { Generate a specialization? }
  321. if try_to_consume(_SPECIALIZE) then
  322. block_type:=bt_specialize;
  323. { we can't accept a equal in type }
  324. pt1:=comp_expr(not(ignore_equal));
  325. if (block_type<>bt_specialize) and
  326. try_to_consume(_POINTPOINT) then
  327. begin
  328. { get high value of range }
  329. pt2:=comp_expr(not(ignore_equal));
  330. { make both the same type or give an error. This is not
  331. done when both are integer values, because typecasting
  332. between -3200..3200 will result in a signed-unsigned
  333. conflict and give a range check error (PFV) }
  334. if not(is_integer(pt1.resultdef) and is_integer(pt2.resultdef)) then
  335. inserttypeconv(pt1,pt2.resultdef);
  336. { both must be evaluated to constants now }
  337. if (pt1.nodetype=ordconstn) and
  338. (pt2.nodetype=ordconstn) then
  339. begin
  340. lv:=tordconstnode(pt1).value;
  341. hv:=tordconstnode(pt2).value;
  342. { Check bounds }
  343. if hv<lv then
  344. Message(parser_e_upper_lower_than_lower)
  345. else
  346. begin
  347. { All checks passed, create the new def }
  348. case pt1.resultdef.typ of
  349. enumdef :
  350. def:=tenumdef.create_subrange(tenumdef(pt1.resultdef),lv,hv);
  351. orddef :
  352. begin
  353. if is_char(pt1.resultdef) then
  354. def:=torddef.create(uchar,lv,hv)
  355. else
  356. if is_boolean(pt1.resultdef) then
  357. def:=torddef.create(bool8bit,lv,hv)
  358. else
  359. def:=torddef.create(range_to_basetype(lv,hv),lv,hv);
  360. end;
  361. end;
  362. end;
  363. end
  364. else
  365. Message(sym_e_error_in_type_def);
  366. pt2.free;
  367. end
  368. else
  369. begin
  370. { a simple type renaming or generic specialization }
  371. if (pt1.nodetype=typen) then
  372. begin
  373. if (block_type=bt_specialize) then
  374. generate_specialization(pt1,name);
  375. def:=ttypenode(pt1).resultdef;
  376. end
  377. else
  378. Message(sym_e_error_in_type_def);
  379. end;
  380. pt1.free;
  381. block_type:=old_block_type;
  382. end;
  383. procedure set_dec;
  384. begin
  385. consume(_SET);
  386. consume(_OF);
  387. read_anon_type(tt2,true);
  388. if assigned(tt2) then
  389. begin
  390. case tt2.typ of
  391. { don't forget that min can be negativ PM }
  392. enumdef :
  393. if tenumdef(tt2).min>=0 then
  394. // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  395. def:=tsetdef.create(tt2,tenumdef(tt2).max)
  396. else
  397. Message(sym_e_ill_type_decl_set);
  398. orddef :
  399. begin
  400. if (torddef(tt2).ordtype<>uvoid) and
  401. (torddef(tt2).low>=0) then
  402. // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  403. def:=tsetdef.create(tt2,torddef(tt2).high)
  404. else
  405. Message(sym_e_ill_type_decl_set);
  406. end;
  407. else
  408. Message(sym_e_ill_type_decl_set);
  409. end;
  410. end
  411. else
  412. def:=generrordef;
  413. end;
  414. procedure array_dec(is_packed: boolean);
  415. var
  416. lowval,
  417. highval : TConstExprInt;
  418. indexdef : tdef;
  419. hdef : tdef;
  420. arrdef : tarraydef;
  421. procedure setdefdecl(def:tdef);
  422. begin
  423. case def.typ of
  424. enumdef :
  425. begin
  426. lowval:=tenumdef(def).min;
  427. highval:=tenumdef(def).max;
  428. if (m_fpc in current_settings.modeswitches) and
  429. (tenumdef(def).has_jumps) then
  430. Message(type_e_array_index_enums_with_assign_not_possible);
  431. indexdef:=def;
  432. end;
  433. orddef :
  434. begin
  435. if torddef(def).ordtype in [uchar,
  436. u8bit,u16bit,
  437. s8bit,s16bit,s32bit,
  438. {$ifdef cpu64bit}
  439. u32bit,s64bit,
  440. {$endif cpu64bit}
  441. bool8bit,bool16bit,bool32bit,bool64bit,
  442. uwidechar] then
  443. begin
  444. lowval:=torddef(def).low;
  445. highval:=torddef(def).high;
  446. indexdef:=def;
  447. end
  448. else
  449. Message1(parser_e_type_cant_be_used_in_array_index,def.GetTypeName);
  450. end;
  451. else
  452. Message(sym_e_error_in_type_def);
  453. end;
  454. end;
  455. begin
  456. arrdef:=nil;
  457. consume(_ARRAY);
  458. { open array? }
  459. if try_to_consume(_LECKKLAMMER) then
  460. begin
  461. { defaults }
  462. indexdef:=generrordef;
  463. lowval:=low(aint);
  464. highval:=high(aint);
  465. repeat
  466. { read the expression and check it, check apart if the
  467. declaration is an enum declaration because that needs to
  468. be parsed by readtype (PFV) }
  469. if token=_LKLAMMER then
  470. begin
  471. read_anon_type(hdef,true);
  472. setdefdecl(hdef);
  473. end
  474. else
  475. begin
  476. pt:=expr;
  477. if pt.nodetype=typen then
  478. setdefdecl(pt.resultdef)
  479. else
  480. begin
  481. if (pt.nodetype=rangen) then
  482. begin
  483. if (trangenode(pt).left.nodetype=ordconstn) and
  484. (trangenode(pt).right.nodetype=ordconstn) then
  485. begin
  486. { make both the same type or give an error. This is not
  487. done when both are integer values, because typecasting
  488. between -3200..3200 will result in a signed-unsigned
  489. conflict and give a range check error (PFV) }
  490. if not(is_integer(trangenode(pt).left.resultdef) and is_integer(trangenode(pt).left.resultdef)) then
  491. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resultdef);
  492. lowval:=tordconstnode(trangenode(pt).left).value;
  493. highval:=tordconstnode(trangenode(pt).right).value;
  494. if highval<lowval then
  495. begin
  496. Message(parser_e_array_lower_less_than_upper_bound);
  497. highval:=lowval;
  498. end
  499. else if (lowval < low(aint)) or
  500. (highval > high(aint)) then
  501. begin
  502. Message(parser_e_array_range_out_of_bounds);
  503. lowval :=0;
  504. highval:=0;
  505. end;
  506. if is_integer(trangenode(pt).left.resultdef) then
  507. range_to_type(lowval,highval,indexdef)
  508. else
  509. indexdef:=trangenode(pt).left.resultdef;
  510. end
  511. else
  512. Message(type_e_cant_eval_constant_expr);
  513. end
  514. else
  515. Message(sym_e_error_in_type_def)
  516. end;
  517. pt.free;
  518. end;
  519. { if the array is already created add the new arrray
  520. as element of the existing array, otherwise create a new array }
  521. if assigned(arrdef) then
  522. begin
  523. arrdef.elementdef:=tarraydef.create(lowval,highval,indexdef);
  524. arrdef:=tarraydef(arrdef.elementdef);
  525. end
  526. else
  527. begin
  528. arrdef:=tarraydef.create(lowval,highval,indexdef);
  529. def:=arrdef;
  530. end;
  531. if is_packed then
  532. include(arrdef.arrayoptions,ado_IsBitPacked);
  533. if token=_COMMA then
  534. consume(_COMMA)
  535. else
  536. break;
  537. until false;
  538. consume(_RECKKLAMMER);
  539. end
  540. else
  541. begin
  542. if is_packed then
  543. Message(parser_e_packed_dynamic_open_array);
  544. arrdef:=tarraydef.create(0,-1,s32inttype);
  545. include(arrdef.arrayoptions,ado_IsDynamicArray);
  546. def:=arrdef;
  547. end;
  548. consume(_OF);
  549. read_anon_type(tt2,true);
  550. { set element type of the last array definition }
  551. if assigned(arrdef) then
  552. begin
  553. arrdef.elementdef:=tt2;
  554. if is_packed and
  555. tt2.needs_inittable then
  556. Message(type_e_no_packed_inittable);
  557. end;
  558. end;
  559. var
  560. p : tnode;
  561. pd : tabstractprocdef;
  562. is_func,
  563. enumdupmsg, first : boolean;
  564. newtype : ttypesym;
  565. oldlocalswitches : tlocalswitches;
  566. bitpacking: boolean;
  567. begin
  568. def:=nil;
  569. case token of
  570. _STRING,_FILE:
  571. begin
  572. single_type(def,false);
  573. end;
  574. _LKLAMMER:
  575. begin
  576. consume(_LKLAMMER);
  577. first := true;
  578. { allow negativ value_str }
  579. l:=-1;
  580. enumdupmsg:=false;
  581. aktenumdef:=tenumdef.create;
  582. repeat
  583. s:=orgpattern;
  584. defpos:=current_tokenpos;
  585. consume(_ID);
  586. { only allow assigning of specific numbers under fpc mode }
  587. if not(m_tp7 in current_settings.modeswitches) and
  588. (
  589. { in fpc mode also allow := to be compatible
  590. with previous 1.0.x versions }
  591. ((m_fpc in current_settings.modeswitches) and
  592. try_to_consume(_ASSIGNMENT)) or
  593. try_to_consume(_EQUAL)
  594. ) then
  595. begin
  596. oldlocalswitches:=current_settings.localswitches;
  597. include(current_settings.localswitches,cs_allow_enum_calc);
  598. p:=comp_expr(true);
  599. current_settings.localswitches:=oldlocalswitches;
  600. if (p.nodetype=ordconstn) then
  601. begin
  602. { we expect an integer or an enum of the
  603. same type }
  604. if is_integer(p.resultdef) or
  605. is_char(p.resultdef) or
  606. equal_defs(p.resultdef,aktenumdef) then
  607. v:=tordconstnode(p).value
  608. else
  609. IncompatibleTypes(p.resultdef,s32inttype);
  610. end
  611. else
  612. Message(parser_e_illegal_expression);
  613. p.free;
  614. { please leave that a note, allows type save }
  615. { declarations in the win32 units ! }
  616. if (not first) and (v<=l) and (not enumdupmsg) then
  617. begin
  618. Message(parser_n_duplicate_enum);
  619. enumdupmsg:=true;
  620. end;
  621. l:=v;
  622. end
  623. else
  624. inc(l);
  625. first := false;
  626. storepos:=current_tokenpos;
  627. current_tokenpos:=defpos;
  628. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l));
  629. current_tokenpos:=storepos;
  630. until not try_to_consume(_COMMA);
  631. def:=aktenumdef;
  632. consume(_RKLAMMER);
  633. end;
  634. _ARRAY:
  635. begin
  636. array_dec(false);
  637. end;
  638. _SET:
  639. begin
  640. set_dec;
  641. end;
  642. _CARET:
  643. begin
  644. consume(_CARET);
  645. single_type(tt2,typecanbeforward);
  646. def:=tpointerdef.create(tt2);
  647. end;
  648. _RECORD:
  649. begin
  650. def:=record_dec;
  651. end;
  652. _PACKED,
  653. _BITPACKED:
  654. begin
  655. bitpacking :=
  656. (cs_bitpacking in current_settings.localswitches) or
  657. (token = _BITPACKED);
  658. consume(token);
  659. if token=_ARRAY then
  660. array_dec(bitpacking)
  661. else if token=_SET then
  662. set_dec
  663. else
  664. begin
  665. oldpackrecords:=current_settings.packrecords;
  666. if (not bitpacking) or
  667. (token in [_CLASS,_OBJECT]) then
  668. current_settings.packrecords:=1
  669. else
  670. current_settings.packrecords:=bit_alignment;
  671. if token in [_CLASS,_OBJECT] then
  672. def:=object_dec(name,genericdef,genericlist,nil)
  673. else
  674. def:=record_dec;
  675. current_settings.packrecords:=oldpackrecords;
  676. end;
  677. end;
  678. _DISPINTERFACE,
  679. _CLASS,
  680. _CPPCLASS,
  681. _INTERFACE,
  682. _OBJECT:
  683. begin
  684. def:=object_dec(name,genericdef,genericlist,nil);
  685. end;
  686. _PROCEDURE,
  687. _FUNCTION:
  688. begin
  689. is_func:=(token=_FUNCTION);
  690. consume(token);
  691. pd:=tprocvardef.create(normal_function_level);
  692. if token=_LKLAMMER then
  693. parse_parameter_dec(pd);
  694. if is_func then
  695. begin
  696. consume(_COLON);
  697. single_type(pd.returndef,false);
  698. end;
  699. if token=_OF then
  700. begin
  701. consume(_OF);
  702. consume(_OBJECT);
  703. include(pd.procoptions,po_methodpointer);
  704. end;
  705. def:=pd;
  706. { possible proc directives }
  707. if parseprocvardir then
  708. begin
  709. if check_proc_directive(true) then
  710. begin
  711. newtype:=ttypesym.create('unnamed',def);
  712. parse_var_proc_directives(tsym(newtype));
  713. newtype.typedef:=nil;
  714. def.typesym:=nil;
  715. newtype.free;
  716. end;
  717. { Add implicit hidden parameters and function result }
  718. handle_calling_convention(pd);
  719. end;
  720. end;
  721. else
  722. expr_type;
  723. end;
  724. if def=nil then
  725. def:=generrordef;
  726. end;
  727. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  728. begin
  729. read_named_type(def,'',nil,nil,parseprocvardir);
  730. end;
  731. procedure write_persistent_type_info(st:tsymtable);
  732. var
  733. i : longint;
  734. def : tdef;
  735. vmtwriter : TVMTWriter;
  736. begin
  737. for i:=0 to st.DefList.Count-1 do
  738. begin
  739. def:=tdef(st.DefList[i]);
  740. if df_deleted in def.defoptions then
  741. continue;
  742. case def.typ of
  743. recorddef :
  744. write_persistent_type_info(trecorddef(def).symtable);
  745. objectdef :
  746. begin
  747. write_persistent_type_info(tobjectdef(def).symtable);
  748. { Write also VMT }
  749. if not(ds_vmt_written in def.defstates) and
  750. not(oo_is_forward in tobjectdef(def).objectoptions) then
  751. begin
  752. vmtwriter:=TVMTWriter.create(tobjectdef(def));
  753. if is_interface(tobjectdef(def)) then
  754. vmtwriter.writeinterfaceids;
  755. if (oo_has_vmt in tobjectdef(def).objectoptions) then
  756. vmtwriter.writevmt;
  757. vmtwriter.free;
  758. include(def.defstates,ds_vmt_written);
  759. end;
  760. end;
  761. procdef :
  762. begin
  763. if assigned(tprocdef(def).localst) and
  764. (tprocdef(def).localst.symtabletype=localsymtable) then
  765. write_persistent_type_info(tprocdef(def).localst);
  766. if assigned(tprocdef(def).parast) then
  767. write_persistent_type_info(tprocdef(def).parast);
  768. end;
  769. end;
  770. { generate always persistent tables for types in the interface so it can
  771. be reused in other units and give always the same pointer location. }
  772. { Init }
  773. if (
  774. assigned(def.typesym) and
  775. (st.symtabletype=globalsymtable)
  776. ) or
  777. def.needs_inittable or
  778. (ds_init_table_used in def.defstates) then
  779. RTTIWriter.write_rtti(def,initrtti);
  780. { RTTI }
  781. if (
  782. assigned(def.typesym) and
  783. (st.symtabletype=globalsymtable)
  784. ) or
  785. (ds_rtti_table_used in def.defstates) then
  786. RTTIWriter.write_rtti(def,fullrtti);
  787. end;
  788. end;
  789. end.