ptype.pas 29 KB

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