ptype.pas 26 KB

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