ptype.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  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. end;
  294. { reads a type definition and returns a pointer to it }
  295. procedure read_named_type(var tt : ttype;const name : stringid;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  296. var
  297. pt : tnode;
  298. tt2 : ttype;
  299. aktenumdef : tenumdef;
  300. ap : tarraydef;
  301. s : stringid;
  302. l,v : TConstExprInt;
  303. oldaktpackrecords : longint;
  304. defpos,storepos : tfileposinfo;
  305. procedure expr_type;
  306. var
  307. pt1,pt2 : tnode;
  308. lv,hv : TConstExprInt;
  309. old_block_type : tblock_type;
  310. begin
  311. old_block_type:=block_type;
  312. { use of current parsed object:
  313. - classes can be used also in classes
  314. - objects can be parameters }
  315. if (token=_ID) and
  316. assigned(aktobjectdef) and
  317. (aktobjectdef.objname^=pattern) and
  318. (
  319. (testcurobject=2) or
  320. is_class_or_interface(aktobjectdef)
  321. )then
  322. begin
  323. consume(_ID);
  324. tt.setdef(aktobjectdef);
  325. exit;
  326. end;
  327. { Generate a specialization? }
  328. if try_to_consume(_SPECIALIZE) then
  329. block_type:=bt_specialize;
  330. { we can't accept a equal in type }
  331. pt1:=comp_expr(not(ignore_equal));
  332. if (block_type<>bt_specialize) and
  333. try_to_consume(_POINTPOINT) then
  334. begin
  335. { get high value of range }
  336. pt2:=comp_expr(not(ignore_equal));
  337. { make both the same type or give an error. This is not
  338. done when both are integer values, because typecasting
  339. between -3200..3200 will result in a signed-unsigned
  340. conflict and give a range check error (PFV) }
  341. if not(is_integer(pt1.resulttype.def) and is_integer(pt2.resulttype.def)) then
  342. inserttypeconv(pt1,pt2.resulttype);
  343. { both must be evaluated to constants now }
  344. if (pt1.nodetype=ordconstn) and
  345. (pt2.nodetype=ordconstn) then
  346. begin
  347. lv:=tordconstnode(pt1).value;
  348. hv:=tordconstnode(pt2).value;
  349. { Check bounds }
  350. if hv<lv then
  351. Message(parser_e_upper_lower_than_lower)
  352. else
  353. begin
  354. { All checks passed, create the new def }
  355. case pt1.resulttype.def.deftype of
  356. enumdef :
  357. tt.setdef(tenumdef.create_subrange(tenumdef(pt1.resulttype.def),lv,hv));
  358. orddef :
  359. begin
  360. if is_char(pt1.resulttype.def) then
  361. tt.setdef(torddef.create(uchar,lv,hv))
  362. else
  363. if is_boolean(pt1.resulttype.def) then
  364. tt.setdef(torddef.create(bool8bit,lv,hv))
  365. else
  366. tt.setdef(torddef.create(range_to_basetype(lv,hv),lv,hv));
  367. end;
  368. end;
  369. end;
  370. end
  371. else
  372. Message(sym_e_error_in_type_def);
  373. pt2.free;
  374. end
  375. else
  376. begin
  377. { a simple type renaming or generic specialization }
  378. if (pt1.nodetype=typen) then
  379. begin
  380. if (block_type=bt_specialize) then
  381. generate_specialization(pt1,name);
  382. tt:=ttypenode(pt1).resulttype;
  383. end
  384. else
  385. Message(sym_e_error_in_type_def);
  386. end;
  387. pt1.free;
  388. block_type:=old_block_type;
  389. end;
  390. procedure set_dec;
  391. begin
  392. consume(_SET);
  393. consume(_OF);
  394. read_anon_type(tt2,true);
  395. if assigned(tt2.def) then
  396. begin
  397. case tt2.def.deftype of
  398. { don't forget that min can be negativ PM }
  399. enumdef :
  400. if tenumdef(tt2.def).min>=0 then
  401. // !! tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  402. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  403. else
  404. Message(sym_e_ill_type_decl_set);
  405. orddef :
  406. begin
  407. if (torddef(tt2.def).typ<>uvoid) and
  408. (torddef(tt2.def).low>=0) then
  409. // !! tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  410. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  411. else
  412. Message(sym_e_ill_type_decl_set);
  413. end;
  414. else
  415. Message(sym_e_ill_type_decl_set);
  416. end;
  417. end
  418. else
  419. tt:=generrortype;
  420. end;
  421. procedure array_dec(is_packed: boolean);
  422. var
  423. lowval,
  424. highval : TConstExprInt;
  425. arraytype : ttype;
  426. ht : ttype;
  427. procedure setdefdecl(const t:ttype);
  428. begin
  429. case t.def.deftype of
  430. enumdef :
  431. begin
  432. lowval:=tenumdef(t.def).min;
  433. highval:=tenumdef(t.def).max;
  434. if (m_fpc in aktmodeswitches) and
  435. (tenumdef(t.def).has_jumps) then
  436. Message(type_e_array_index_enums_with_assign_not_possible);
  437. arraytype:=t;
  438. end;
  439. orddef :
  440. begin
  441. if torddef(t.def).typ in [uchar,
  442. u8bit,u16bit,
  443. s8bit,s16bit,s32bit,
  444. {$ifdef cpu64bit}
  445. u32bit,s64bit,
  446. {$endif cpu64bit}
  447. bool8bit,bool16bit,bool32bit,bool64bit,
  448. uwidechar] then
  449. begin
  450. lowval:=torddef(t.def).low;
  451. highval:=torddef(t.def).high;
  452. arraytype:=t;
  453. end
  454. else
  455. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  456. end;
  457. else
  458. Message(sym_e_error_in_type_def);
  459. end;
  460. end;
  461. begin
  462. consume(_ARRAY);
  463. { open array? }
  464. if token=_LECKKLAMMER then
  465. begin
  466. consume(_LECKKLAMMER);
  467. { defaults }
  468. arraytype:=generrortype;
  469. lowval:=low(aint);
  470. highval:=high(aint);
  471. tt.reset;
  472. repeat
  473. { read the expression and check it, check apart if the
  474. declaration is an enum declaration because that needs to
  475. be parsed by readtype (PFV) }
  476. if token=_LKLAMMER then
  477. begin
  478. read_anon_type(ht,true);
  479. setdefdecl(ht);
  480. end
  481. else
  482. begin
  483. pt:=expr;
  484. if pt.nodetype=typen then
  485. setdefdecl(pt.resulttype)
  486. else
  487. begin
  488. if (pt.nodetype=rangen) then
  489. begin
  490. if (trangenode(pt).left.nodetype=ordconstn) and
  491. (trangenode(pt).right.nodetype=ordconstn) then
  492. begin
  493. { make both the same type or give an error. This is not
  494. done when both are integer values, because typecasting
  495. between -3200..3200 will result in a signed-unsigned
  496. conflict and give a range check error (PFV) }
  497. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  498. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  499. lowval:=tordconstnode(trangenode(pt).left).value;
  500. highval:=tordconstnode(trangenode(pt).right).value;
  501. if highval<lowval then
  502. begin
  503. Message(parser_e_array_lower_less_than_upper_bound);
  504. highval:=lowval;
  505. end
  506. else if (lowval < low(aint)) or
  507. (highval > high(aint)) then
  508. begin
  509. Message(parser_e_array_range_out_of_bounds);
  510. lowval :=0;
  511. highval:=0;
  512. end;
  513. if is_integer(trangenode(pt).left.resulttype.def) then
  514. range_to_type(lowval,highval,arraytype)
  515. else
  516. arraytype:=trangenode(pt).left.resulttype;
  517. end
  518. else
  519. Message(type_e_cant_eval_constant_expr);
  520. end
  521. else
  522. Message(sym_e_error_in_type_def)
  523. end;
  524. pt.free;
  525. end;
  526. { create arraydef }
  527. if not assigned(tt.def) then
  528. begin
  529. ap:=tarraydef.create(lowval,highval,arraytype);
  530. tt.setdef(ap);
  531. end
  532. else
  533. begin
  534. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  535. ap:=tarraydef(ap.elementtype.def);
  536. end;
  537. if is_packed then
  538. include(ap.arrayoptions,ado_IsBitPacked);
  539. if token=_COMMA then
  540. consume(_COMMA)
  541. else
  542. break;
  543. until false;
  544. consume(_RECKKLAMMER);
  545. end
  546. else
  547. begin
  548. if is_packed then
  549. Message(parser_e_packed_dynamic_open_array);
  550. ap:=tarraydef.create(0,-1,s32inttype);
  551. include(ap.arrayoptions,ado_IsDynamicArray);
  552. tt.setdef(ap);
  553. end;
  554. consume(_OF);
  555. read_anon_type(tt2,true);
  556. { if no error, set element type }
  557. if assigned(ap) then
  558. begin
  559. ap.setelementtype(tt2);
  560. if is_packed and
  561. tt2.def.needs_inittable then
  562. Message(type_e_no_packed_inittable);
  563. end;
  564. end;
  565. var
  566. p : tnode;
  567. pd : tabstractprocdef;
  568. is_func,
  569. enumdupmsg, first : boolean;
  570. newtype : ttypesym;
  571. oldlocalswitches : tlocalswitches;
  572. bitpacking: boolean;
  573. begin
  574. tt.reset;
  575. case token of
  576. _STRING,_FILE:
  577. begin
  578. single_type(tt,false);
  579. end;
  580. _LKLAMMER:
  581. begin
  582. consume(_LKLAMMER);
  583. first := true;
  584. { allow negativ value_str }
  585. l:=-1;
  586. enumdupmsg:=false;
  587. aktenumdef:=tenumdef.create;
  588. repeat
  589. s:=orgpattern;
  590. defpos:=akttokenpos;
  591. consume(_ID);
  592. { only allow assigning of specific numbers under fpc mode }
  593. if not(m_tp7 in aktmodeswitches) and
  594. (
  595. { in fpc mode also allow := to be compatible
  596. with previous 1.0.x versions }
  597. ((m_fpc in aktmodeswitches) and
  598. try_to_consume(_ASSIGNMENT)) or
  599. try_to_consume(_EQUAL)
  600. ) then
  601. begin
  602. oldlocalswitches:=aktlocalswitches;
  603. include(aktlocalswitches,cs_allow_enum_calc);
  604. p:=comp_expr(true);
  605. aktlocalswitches:=oldlocalswitches;
  606. if (p.nodetype=ordconstn) then
  607. begin
  608. { we expect an integer or an enum of the
  609. same type }
  610. if is_integer(p.resulttype.def) or
  611. is_char(p.resulttype.def) or
  612. equal_defs(p.resulttype.def,aktenumdef) then
  613. v:=tordconstnode(p).value
  614. else
  615. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  616. end
  617. else
  618. Message(parser_e_illegal_expression);
  619. p.free;
  620. { please leave that a note, allows type save }
  621. { declarations in the win32 units ! }
  622. if (not first) and (v<=l) and (not enumdupmsg) then
  623. begin
  624. Message(parser_n_duplicate_enum);
  625. enumdupmsg:=true;
  626. end;
  627. l:=v;
  628. end
  629. else
  630. inc(l);
  631. first := false;
  632. storepos:=akttokenpos;
  633. akttokenpos:=defpos;
  634. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l));
  635. akttokenpos:=storepos;
  636. until not try_to_consume(_COMMA);
  637. tt.setdef(aktenumdef);
  638. consume(_RKLAMMER);
  639. end;
  640. _ARRAY:
  641. begin
  642. array_dec(false);
  643. end;
  644. _SET:
  645. begin
  646. set_dec;
  647. end;
  648. _CARET:
  649. begin
  650. consume(_CARET);
  651. single_type(tt2,typecanbeforward);
  652. tt.setdef(tpointerdef.create(tt2));
  653. end;
  654. _RECORD:
  655. begin
  656. tt.setdef(record_dec);
  657. end;
  658. _PACKED,
  659. _BITPACKED:
  660. begin
  661. bitpacking :=
  662. (cs_bitpacking in aktlocalswitches) or
  663. (token = _BITPACKED);
  664. consume(token);
  665. if token=_ARRAY then
  666. array_dec(bitpacking)
  667. else if token=_SET then
  668. set_dec
  669. else
  670. begin
  671. oldaktpackrecords:=aktpackrecords;
  672. aktpackrecords:=1;
  673. if token in [_CLASS,_OBJECT] then
  674. tt.setdef(object_dec(name,genericdef,genericlist,nil))
  675. else
  676. tt.setdef(record_dec);
  677. aktpackrecords:=oldaktpackrecords;
  678. end;
  679. end;
  680. _DISPINTERFACE,
  681. _CLASS,
  682. _CPPCLASS,
  683. _INTERFACE,
  684. _OBJECT:
  685. begin
  686. tt.setdef(object_dec(name,genericdef,genericlist,nil));
  687. end;
  688. _PROCEDURE,
  689. _FUNCTION:
  690. begin
  691. is_func:=(token=_FUNCTION);
  692. consume(token);
  693. pd:=tprocvardef.create(normal_function_level);
  694. if token=_LKLAMMER then
  695. parse_parameter_dec(pd);
  696. if is_func then
  697. begin
  698. consume(_COLON);
  699. single_type(pd.rettype,false);
  700. end;
  701. if token=_OF then
  702. begin
  703. consume(_OF);
  704. consume(_OBJECT);
  705. include(pd.procoptions,po_methodpointer);
  706. end;
  707. tt.def:=pd;
  708. { possible proc directives }
  709. if parseprocvardir then
  710. begin
  711. if check_proc_directive(true) then
  712. begin
  713. newtype:=ttypesym.create('unnamed',tt);
  714. parse_var_proc_directives(tsym(newtype));
  715. newtype.restype.def:=nil;
  716. tt.def.typesym:=nil;
  717. newtype.free;
  718. end;
  719. { Add implicit hidden parameters and function result }
  720. handle_calling_convention(pd);
  721. end;
  722. end;
  723. else
  724. expr_type;
  725. end;
  726. if tt.def=nil then
  727. tt:=generrortype;
  728. end;
  729. procedure read_anon_type(var tt : ttype;parseprocvardir:boolean);
  730. begin
  731. read_named_type(tt,'',nil,nil,parseprocvardir);
  732. end;
  733. end.