ptype.pas 28 KB

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