ptype.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  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 def:tdef;isforwarddef:boolean);
  32. procedure read_named_type(var def:tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  33. procedure read_anon_type(var def : tdef;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 def : tdef;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. i : longint;
  63. sym : tsym;
  64. genericdef : tstoreddef;
  65. generictype : ttypesym;
  66. generictypelist : TFPObjectList;
  67. begin
  68. { retrieve generic def that we are going to replace }
  69. genericdef:=tstoreddef(pt1.resultdef);
  70. pt1.resultdef:=nil;
  71. if not(df_generic in genericdef.defoptions) then
  72. begin
  73. Comment(V_Error,'Specialization is only supported for generic types');
  74. pt1.resultdef:=generrordef;
  75. { recover }
  76. consume(_LSHARPBRACKET);
  77. repeat
  78. pt2:=factor(false);
  79. pt2.free;
  80. until not try_to_consume(_COMMA);
  81. consume(_RSHARPBRACKET);
  82. exit;
  83. end;
  84. consume(_LSHARPBRACKET);
  85. block_type:=bt_specialize;
  86. { Parse generic parameters, for each undefineddef in the symtable of
  87. the genericdef we need to have a new def }
  88. err:=false;
  89. first:=true;
  90. generictypelist:=TFPObjectList.create(false);
  91. case genericdef.typ of
  92. procdef :
  93. st:=genericdef.GetSymtable(gs_para);
  94. objectdef,
  95. recorddef :
  96. st:=genericdef.GetSymtable(gs_record);
  97. end;
  98. if not assigned(st) then
  99. internalerror(200511182);
  100. for i:=0 to st.SymList.Count-1 do
  101. begin
  102. sym:=tsym(st.SymList[i]);
  103. if (sym.typ=typesym) and
  104. (ttypesym(sym).typedef.typ=undefineddef) then
  105. begin
  106. if not first then
  107. begin
  108. consume(_COMMA);
  109. first:=false;
  110. end;
  111. pt2:=factor(false);
  112. if pt2.nodetype=typen then
  113. begin
  114. generictype:=ttypesym.create(sym.realname,pt2.resultdef);
  115. generictypelist.add(generictype);
  116. end
  117. else
  118. begin
  119. Message(type_e_type_id_expected);
  120. err:=true;
  121. end;
  122. pt2.free;
  123. end;
  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.resultdef,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 def : tdef;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 : TIDString;
  148. begin
  149. s:=pattern;
  150. sorg:=orgpattern;
  151. pos:=current_tokenpos;
  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. def:=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).typedef.typ=errordef) then
  179. begin
  180. Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
  181. def:=generrordef;
  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. def:=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. def:=generrordef;
  196. exit;
  197. end;
  198. { type sym ? }
  199. if (srsym.typ<>typesym) then
  200. begin
  201. Message(type_e_type_id_expected);
  202. def:=generrordef;
  203. exit;
  204. end;
  205. { Give an error when referring to an errordef }
  206. if (ttypesym(srsym).typedef.typ=errordef) then
  207. begin
  208. Message(sym_e_error_in_type_def);
  209. def:=generrordef;
  210. exit;
  211. end;
  212. def:=ttypesym(srsym).typedef;
  213. end;
  214. procedure single_type(var def:tdef;isforwarddef:boolean);
  215. var
  216. t2 : tdef;
  217. again : boolean;
  218. begin
  219. repeat
  220. again:=false;
  221. case token of
  222. _STRING:
  223. string_dec(def);
  224. _FILE:
  225. begin
  226. consume(_FILE);
  227. if try_to_consume(_OF) then
  228. begin
  229. single_type(t2,false);
  230. def:=tfiledef.createtyped(t2);
  231. end
  232. else
  233. def:=cfiletype;
  234. end;
  235. _ID:
  236. begin
  237. if try_to_consume(_SPECIALIZE) then
  238. begin
  239. block_type:=bt_specialize;
  240. again:=true;
  241. end
  242. else
  243. id_type(def,isforwarddef);
  244. end;
  245. else
  246. begin
  247. message(type_e_type_id_expected);
  248. def:=generrordef;
  249. end;
  250. end;
  251. until not again;
  252. end;
  253. { reads a record declaration }
  254. function record_dec : tdef;
  255. var
  256. recst : trecordsymtable;
  257. storetypecanbeforward : boolean;
  258. old_object_option : tsymoptions;
  259. begin
  260. { create recdef }
  261. recst:=trecordsymtable.create(current_settings.packrecords);
  262. record_dec:=trecorddef.create(recst);
  263. { insert in symtablestack }
  264. symtablestack.push(recst);
  265. { parse record }
  266. consume(_RECORD);
  267. old_object_option:=current_object_option;
  268. current_object_option:=[sp_public];
  269. storetypecanbeforward:=typecanbeforward;
  270. { for tp7 don't allow forward types }
  271. if m_tp7 in current_settings.modeswitches then
  272. typecanbeforward:=false;
  273. read_record_fields([vd_record]);
  274. consume(_END);
  275. typecanbeforward:=storetypecanbeforward;
  276. current_object_option:=old_object_option;
  277. { make the record size aligned }
  278. recst.addalignmentpadding;
  279. { restore symtable stack }
  280. symtablestack.pop(recst);
  281. if trecorddef(record_dec).is_packed and
  282. record_dec.needs_inittable then
  283. Message(type_e_no_packed_inittable);
  284. end;
  285. { reads a type definition and returns a pointer to it }
  286. procedure read_named_type(var def : tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  287. var
  288. pt : tnode;
  289. tt2 : tdef;
  290. aktenumdef : tenumdef;
  291. s : TIDString;
  292. l,v : TConstExprInt;
  293. oldpackrecords : longint;
  294. defpos,storepos : tfileposinfo;
  295. procedure expr_type;
  296. var
  297. pt1,pt2 : tnode;
  298. lv,hv : TConstExprInt;
  299. old_block_type : tblock_type;
  300. begin
  301. old_block_type:=block_type;
  302. { use of current parsed object:
  303. - classes can be used also in classes
  304. - objects can be parameters }
  305. if (token=_ID) and
  306. assigned(aktobjectdef) and
  307. (aktobjectdef.objname^=pattern) and
  308. (
  309. (testcurobject=2) or
  310. is_class_or_interface(aktobjectdef)
  311. )then
  312. begin
  313. consume(_ID);
  314. def:=aktobjectdef;
  315. exit;
  316. end;
  317. { Generate a specialization? }
  318. if try_to_consume(_SPECIALIZE) then
  319. block_type:=bt_specialize;
  320. { we can't accept a equal in type }
  321. pt1:=comp_expr(not(ignore_equal));
  322. if (block_type<>bt_specialize) and
  323. try_to_consume(_POINTPOINT) then
  324. begin
  325. { get high value of range }
  326. pt2:=comp_expr(not(ignore_equal));
  327. { make both the same type or give an error. This is not
  328. done when both are integer values, because typecasting
  329. between -3200..3200 will result in a signed-unsigned
  330. conflict and give a range check error (PFV) }
  331. if not(is_integer(pt1.resultdef) and is_integer(pt2.resultdef)) then
  332. inserttypeconv(pt1,pt2.resultdef);
  333. { both must be evaluated to constants now }
  334. if (pt1.nodetype=ordconstn) and
  335. (pt2.nodetype=ordconstn) then
  336. begin
  337. lv:=tordconstnode(pt1).value;
  338. hv:=tordconstnode(pt2).value;
  339. { Check bounds }
  340. if hv<lv then
  341. Message(parser_e_upper_lower_than_lower)
  342. else
  343. begin
  344. { All checks passed, create the new def }
  345. case pt1.resultdef.typ of
  346. enumdef :
  347. def:=tenumdef.create_subrange(tenumdef(pt1.resultdef),lv,hv);
  348. orddef :
  349. begin
  350. if is_char(pt1.resultdef) then
  351. def:=torddef.create(uchar,lv,hv)
  352. else
  353. if is_boolean(pt1.resultdef) then
  354. def:=torddef.create(bool8bit,lv,hv)
  355. else
  356. def:=torddef.create(range_to_basetype(lv,hv),lv,hv);
  357. end;
  358. end;
  359. end;
  360. end
  361. else
  362. Message(sym_e_error_in_type_def);
  363. pt2.free;
  364. end
  365. else
  366. begin
  367. { a simple type renaming or generic specialization }
  368. if (pt1.nodetype=typen) then
  369. begin
  370. if (block_type=bt_specialize) then
  371. generate_specialization(pt1,name);
  372. def:=ttypenode(pt1).resultdef;
  373. end
  374. else
  375. Message(sym_e_error_in_type_def);
  376. end;
  377. pt1.free;
  378. block_type:=old_block_type;
  379. end;
  380. procedure set_dec;
  381. begin
  382. consume(_SET);
  383. consume(_OF);
  384. read_anon_type(tt2,true);
  385. if assigned(tt2) then
  386. begin
  387. case tt2.typ of
  388. { don't forget that min can be negativ PM }
  389. enumdef :
  390. if tenumdef(tt2).min>=0 then
  391. // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  392. def:=tsetdef.create(tt2,tenumdef(tt2).max)
  393. else
  394. Message(sym_e_ill_type_decl_set);
  395. orddef :
  396. begin
  397. if (torddef(tt2).ordtype<>uvoid) and
  398. (torddef(tt2).low>=0) then
  399. // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  400. def:=tsetdef.create(tt2,torddef(tt2).high)
  401. else
  402. Message(sym_e_ill_type_decl_set);
  403. end;
  404. else
  405. Message(sym_e_ill_type_decl_set);
  406. end;
  407. end
  408. else
  409. def:=generrordef;
  410. end;
  411. procedure array_dec(is_packed: boolean);
  412. var
  413. lowval,
  414. highval : TConstExprInt;
  415. indexdef : tdef;
  416. hdef : tdef;
  417. arrdef : tarraydef;
  418. procedure setdefdecl(def:tdef);
  419. begin
  420. case def.typ of
  421. enumdef :
  422. begin
  423. lowval:=tenumdef(def).min;
  424. highval:=tenumdef(def).max;
  425. if (m_fpc in current_settings.modeswitches) and
  426. (tenumdef(def).has_jumps) then
  427. Message(type_e_array_index_enums_with_assign_not_possible);
  428. indexdef:=def;
  429. end;
  430. orddef :
  431. begin
  432. if torddef(def).ordtype in [uchar,
  433. u8bit,u16bit,
  434. s8bit,s16bit,s32bit,
  435. {$ifdef cpu64bit}
  436. u32bit,s64bit,
  437. {$endif cpu64bit}
  438. bool8bit,bool16bit,bool32bit,bool64bit,
  439. uwidechar] then
  440. begin
  441. lowval:=torddef(def).low;
  442. highval:=torddef(def).high;
  443. indexdef:=def;
  444. end
  445. else
  446. Message1(parser_e_type_cant_be_used_in_array_index,def.GetTypeName);
  447. end;
  448. else
  449. Message(sym_e_error_in_type_def);
  450. end;
  451. end;
  452. begin
  453. arrdef:=nil;
  454. consume(_ARRAY);
  455. { open array? }
  456. if try_to_consume(_LECKKLAMMER) then
  457. begin
  458. { defaults }
  459. indexdef:=generrordef;
  460. lowval:=low(aint);
  461. highval:=high(aint);
  462. repeat
  463. { read the expression and check it, check apart if the
  464. declaration is an enum declaration because that needs to
  465. be parsed by readtype (PFV) }
  466. if token=_LKLAMMER then
  467. begin
  468. read_anon_type(hdef,true);
  469. setdefdecl(hdef);
  470. end
  471. else
  472. begin
  473. pt:=expr;
  474. if pt.nodetype=typen then
  475. setdefdecl(pt.resultdef)
  476. else
  477. begin
  478. if (pt.nodetype=rangen) then
  479. begin
  480. if (trangenode(pt).left.nodetype=ordconstn) and
  481. (trangenode(pt).right.nodetype=ordconstn) then
  482. begin
  483. { make both the same type or give an error. This is not
  484. done when both are integer values, because typecasting
  485. between -3200..3200 will result in a signed-unsigned
  486. conflict and give a range check error (PFV) }
  487. if not(is_integer(trangenode(pt).left.resultdef) and is_integer(trangenode(pt).left.resultdef)) then
  488. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resultdef);
  489. lowval:=tordconstnode(trangenode(pt).left).value;
  490. highval:=tordconstnode(trangenode(pt).right).value;
  491. if highval<lowval then
  492. begin
  493. Message(parser_e_array_lower_less_than_upper_bound);
  494. highval:=lowval;
  495. end
  496. else if (lowval < low(aint)) or
  497. (highval > high(aint)) then
  498. begin
  499. Message(parser_e_array_range_out_of_bounds);
  500. lowval :=0;
  501. highval:=0;
  502. end;
  503. if is_integer(trangenode(pt).left.resultdef) then
  504. range_to_type(lowval,highval,indexdef)
  505. else
  506. indexdef:=trangenode(pt).left.resultdef;
  507. end
  508. else
  509. Message(type_e_cant_eval_constant_expr);
  510. end
  511. else
  512. Message(sym_e_error_in_type_def)
  513. end;
  514. pt.free;
  515. end;
  516. { if the array is already created add the new arrray
  517. as element of the existing array, otherwise create a new array }
  518. if assigned(arrdef) then
  519. begin
  520. arrdef.elementdef:=tarraydef.create(lowval,highval,indexdef);
  521. arrdef:=tarraydef(arrdef.elementdef);
  522. end
  523. else
  524. begin
  525. arrdef:=tarraydef.create(lowval,highval,indexdef);
  526. def:=arrdef;
  527. end;
  528. if is_packed then
  529. include(arrdef.arrayoptions,ado_IsBitPacked);
  530. if token=_COMMA then
  531. consume(_COMMA)
  532. else
  533. break;
  534. until false;
  535. consume(_RECKKLAMMER);
  536. end
  537. else
  538. begin
  539. if is_packed then
  540. Message(parser_e_packed_dynamic_open_array);
  541. arrdef:=tarraydef.create(0,-1,s32inttype);
  542. include(arrdef.arrayoptions,ado_IsDynamicArray);
  543. def:=arrdef;
  544. end;
  545. consume(_OF);
  546. read_anon_type(tt2,true);
  547. { set element type of the last array definition }
  548. if assigned(arrdef) then
  549. begin
  550. arrdef.elementdef:=tt2;
  551. if is_packed and
  552. tt2.needs_inittable then
  553. Message(type_e_no_packed_inittable);
  554. end;
  555. end;
  556. var
  557. p : tnode;
  558. pd : tabstractprocdef;
  559. is_func,
  560. enumdupmsg, first : boolean;
  561. newtype : ttypesym;
  562. oldlocalswitches : tlocalswitches;
  563. bitpacking: boolean;
  564. begin
  565. def:=nil;
  566. case token of
  567. _STRING,_FILE:
  568. begin
  569. single_type(def,false);
  570. end;
  571. _LKLAMMER:
  572. begin
  573. consume(_LKLAMMER);
  574. first := true;
  575. { allow negativ value_str }
  576. l:=-1;
  577. enumdupmsg:=false;
  578. aktenumdef:=tenumdef.create;
  579. repeat
  580. s:=orgpattern;
  581. defpos:=current_tokenpos;
  582. consume(_ID);
  583. { only allow assigning of specific numbers under fpc mode }
  584. if not(m_tp7 in current_settings.modeswitches) and
  585. (
  586. { in fpc mode also allow := to be compatible
  587. with previous 1.0.x versions }
  588. ((m_fpc in current_settings.modeswitches) and
  589. try_to_consume(_ASSIGNMENT)) or
  590. try_to_consume(_EQUAL)
  591. ) then
  592. begin
  593. oldlocalswitches:=current_settings.localswitches;
  594. include(current_settings.localswitches,cs_allow_enum_calc);
  595. p:=comp_expr(true);
  596. current_settings.localswitches:=oldlocalswitches;
  597. if (p.nodetype=ordconstn) then
  598. begin
  599. { we expect an integer or an enum of the
  600. same type }
  601. if is_integer(p.resultdef) or
  602. is_char(p.resultdef) or
  603. equal_defs(p.resultdef,aktenumdef) then
  604. v:=tordconstnode(p).value
  605. else
  606. IncompatibleTypes(p.resultdef,s32inttype);
  607. end
  608. else
  609. Message(parser_e_illegal_expression);
  610. p.free;
  611. { please leave that a note, allows type save }
  612. { declarations in the win32 units ! }
  613. if (not first) and (v<=l) and (not enumdupmsg) then
  614. begin
  615. Message(parser_n_duplicate_enum);
  616. enumdupmsg:=true;
  617. end;
  618. l:=v;
  619. end
  620. else
  621. inc(l);
  622. first := false;
  623. storepos:=current_tokenpos;
  624. current_tokenpos:=defpos;
  625. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l));
  626. current_tokenpos:=storepos;
  627. until not try_to_consume(_COMMA);
  628. def:=aktenumdef;
  629. consume(_RKLAMMER);
  630. end;
  631. _ARRAY:
  632. begin
  633. array_dec(false);
  634. end;
  635. _SET:
  636. begin
  637. set_dec;
  638. end;
  639. _CARET:
  640. begin
  641. consume(_CARET);
  642. single_type(tt2,typecanbeforward);
  643. def:=tpointerdef.create(tt2);
  644. end;
  645. _RECORD:
  646. begin
  647. def:=record_dec;
  648. end;
  649. _PACKED,
  650. _BITPACKED:
  651. begin
  652. bitpacking :=
  653. (cs_bitpacking in current_settings.localswitches) or
  654. (token = _BITPACKED);
  655. consume(token);
  656. if token=_ARRAY then
  657. array_dec(bitpacking)
  658. else if token=_SET then
  659. set_dec
  660. else
  661. begin
  662. oldpackrecords:=current_settings.packrecords;
  663. if (not bitpacking) or
  664. (token in [_CLASS,_OBJECT]) then
  665. current_settings.packrecords:=1
  666. else
  667. current_settings.packrecords:=bit_alignment;
  668. if token in [_CLASS,_OBJECT] then
  669. def:=object_dec(name,genericdef,genericlist,nil)
  670. else
  671. def:=record_dec;
  672. current_settings.packrecords:=oldpackrecords;
  673. end;
  674. end;
  675. _DISPINTERFACE,
  676. _CLASS,
  677. _CPPCLASS,
  678. _INTERFACE,
  679. _OBJECT:
  680. begin
  681. def:=object_dec(name,genericdef,genericlist,nil);
  682. end;
  683. _PROCEDURE,
  684. _FUNCTION:
  685. begin
  686. is_func:=(token=_FUNCTION);
  687. consume(token);
  688. pd:=tprocvardef.create(normal_function_level);
  689. if token=_LKLAMMER then
  690. parse_parameter_dec(pd);
  691. if is_func then
  692. begin
  693. consume(_COLON);
  694. single_type(pd.returndef,false);
  695. end;
  696. if token=_OF then
  697. begin
  698. consume(_OF);
  699. consume(_OBJECT);
  700. include(pd.procoptions,po_methodpointer);
  701. end;
  702. def:=pd;
  703. { possible proc directives }
  704. if parseprocvardir then
  705. begin
  706. if check_proc_directive(true) then
  707. begin
  708. newtype:=ttypesym.create('unnamed',def);
  709. parse_var_proc_directives(tsym(newtype));
  710. newtype.typedef:=nil;
  711. def.typesym:=nil;
  712. newtype.free;
  713. end;
  714. { Add implicit hidden parameters and function result }
  715. handle_calling_convention(pd);
  716. end;
  717. end;
  718. else
  719. expr_type;
  720. end;
  721. if def=nil then
  722. def:=generrordef;
  723. end;
  724. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  725. begin
  726. read_named_type(def,'',nil,nil,parseprocvardir);
  727. end;
  728. end.