ptype.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  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 array_dec;
  392. var
  393. lowval,
  394. highval : aint;
  395. arraytype : ttype;
  396. ht : ttype;
  397. procedure setdefdecl(const t:ttype);
  398. begin
  399. case t.def.deftype of
  400. enumdef :
  401. begin
  402. lowval:=tenumdef(t.def).min;
  403. highval:=tenumdef(t.def).max;
  404. if (m_fpc in aktmodeswitches) and
  405. (tenumdef(t.def).has_jumps) then
  406. Message(type_e_array_index_enums_with_assign_not_possible);
  407. arraytype:=t;
  408. end;
  409. orddef :
  410. begin
  411. if torddef(t.def).typ in [uchar,
  412. u8bit,u16bit,
  413. s8bit,s16bit,s32bit,
  414. {$ifdef cpu64bit}
  415. u32bit,s64bit,
  416. {$endif cpu64bit}
  417. bool8bit,bool16bit,bool32bit,
  418. uwidechar] then
  419. begin
  420. lowval:=torddef(t.def).low;
  421. highval:=torddef(t.def).high;
  422. arraytype:=t;
  423. end
  424. else
  425. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  426. end;
  427. else
  428. Message(sym_e_error_in_type_def);
  429. end;
  430. end;
  431. begin
  432. consume(_ARRAY);
  433. { open array? }
  434. if token=_LECKKLAMMER then
  435. begin
  436. consume(_LECKKLAMMER);
  437. { defaults }
  438. arraytype:=generrortype;
  439. lowval:=low(aint);
  440. highval:=high(aint);
  441. tt.reset;
  442. repeat
  443. { read the expression and check it, check apart if the
  444. declaration is an enum declaration because that needs to
  445. be parsed by readtype (PFV) }
  446. if token=_LKLAMMER then
  447. begin
  448. read_anon_type(ht,true);
  449. setdefdecl(ht);
  450. end
  451. else
  452. begin
  453. pt:=expr;
  454. if pt.nodetype=typen then
  455. setdefdecl(pt.resulttype)
  456. else
  457. begin
  458. if (pt.nodetype=rangen) then
  459. begin
  460. if (trangenode(pt).left.nodetype=ordconstn) and
  461. (trangenode(pt).right.nodetype=ordconstn) then
  462. begin
  463. { make both the same type or give an error. This is not
  464. done when both are integer values, because typecasting
  465. between -3200..3200 will result in a signed-unsigned
  466. conflict and give a range check error (PFV) }
  467. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  468. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  469. lowval:=tordconstnode(trangenode(pt).left).value;
  470. highval:=tordconstnode(trangenode(pt).right).value;
  471. if highval<lowval then
  472. begin
  473. Message(parser_e_array_lower_less_than_upper_bound);
  474. highval:=lowval;
  475. end;
  476. if is_integer(trangenode(pt).left.resulttype.def) then
  477. range_to_type(lowval,highval,arraytype)
  478. else
  479. arraytype:=trangenode(pt).left.resulttype;
  480. end
  481. else
  482. Message(type_e_cant_eval_constant_expr);
  483. end
  484. else
  485. Message(sym_e_error_in_type_def)
  486. end;
  487. pt.free;
  488. end;
  489. { create arraydef }
  490. if not assigned(tt.def) then
  491. begin
  492. ap:=tarraydef.create(lowval,highval,arraytype);
  493. tt.setdef(ap);
  494. end
  495. else
  496. begin
  497. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  498. ap:=tarraydef(ap.elementtype.def);
  499. end;
  500. if token=_COMMA then
  501. consume(_COMMA)
  502. else
  503. break;
  504. until false;
  505. consume(_RECKKLAMMER);
  506. end
  507. else
  508. begin
  509. ap:=tarraydef.create(0,-1,s32inttype);
  510. include(ap.arrayoptions,ado_IsDynamicArray);
  511. tt.setdef(ap);
  512. end;
  513. consume(_OF);
  514. read_anon_type(tt2,true);
  515. { if no error, set element type }
  516. if assigned(ap) then
  517. ap.setelementtype(tt2);
  518. end;
  519. var
  520. p : tnode;
  521. pd : tabstractprocdef;
  522. is_func,
  523. enumdupmsg : boolean;
  524. newtype : ttypesym;
  525. oldlocalswitches : tlocalswitches;
  526. begin
  527. tt.reset;
  528. case token of
  529. _STRING,_FILE:
  530. begin
  531. single_type(tt,false);
  532. end;
  533. _LKLAMMER:
  534. begin
  535. consume(_LKLAMMER);
  536. { allow negativ value_str }
  537. l:=-1;
  538. enumdupmsg:=false;
  539. aktenumdef:=tenumdef.create;
  540. repeat
  541. s:=orgpattern;
  542. defpos:=akttokenpos;
  543. consume(_ID);
  544. { only allow assigning of specific numbers under fpc mode }
  545. if not(m_tp7 in aktmodeswitches) and
  546. (
  547. { in fpc mode also allow := to be compatible
  548. with previous 1.0.x versions }
  549. ((m_fpc in aktmodeswitches) and
  550. try_to_consume(_ASSIGNMENT)) or
  551. try_to_consume(_EQUAL)
  552. ) then
  553. begin
  554. oldlocalswitches:=aktlocalswitches;
  555. include(aktlocalswitches,cs_allow_enum_calc);
  556. p:=comp_expr(true);
  557. aktlocalswitches:=oldlocalswitches;
  558. if (p.nodetype=ordconstn) then
  559. begin
  560. { we expect an integer or an enum of the
  561. same type }
  562. if is_integer(p.resulttype.def) or
  563. is_char(p.resulttype.def) or
  564. equal_defs(p.resulttype.def,aktenumdef) then
  565. v:=tordconstnode(p).value
  566. else
  567. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  568. end
  569. else
  570. Message(parser_e_illegal_expression);
  571. p.free;
  572. { please leave that a note, allows type save }
  573. { declarations in the win32 units ! }
  574. if (v<=l) and (not enumdupmsg) then
  575. begin
  576. Message(parser_n_duplicate_enum);
  577. enumdupmsg:=true;
  578. end;
  579. l:=v;
  580. end
  581. else
  582. inc(l);
  583. storepos:=akttokenpos;
  584. akttokenpos:=defpos;
  585. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l));
  586. akttokenpos:=storepos;
  587. until not try_to_consume(_COMMA);
  588. tt.setdef(aktenumdef);
  589. consume(_RKLAMMER);
  590. end;
  591. _ARRAY:
  592. begin
  593. array_dec;
  594. end;
  595. _SET:
  596. begin
  597. consume(_SET);
  598. consume(_OF);
  599. read_anon_type(tt2,true);
  600. if assigned(tt2.def) then
  601. begin
  602. case tt2.def.deftype of
  603. { don't forget that min can be negativ PM }
  604. enumdef :
  605. if tenumdef(tt2.def).min>=0 then
  606. // !! tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  607. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  608. else
  609. Message(sym_e_ill_type_decl_set);
  610. orddef :
  611. begin
  612. if (torddef(tt2.def).typ<>uvoid) and
  613. (torddef(tt2.def).low>=0) then
  614. // !! tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  615. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  616. else
  617. Message(sym_e_ill_type_decl_set);
  618. end;
  619. else
  620. Message(sym_e_ill_type_decl_set);
  621. end;
  622. end
  623. else
  624. tt:=generrortype;
  625. end;
  626. _CARET:
  627. begin
  628. consume(_CARET);
  629. single_type(tt2,typecanbeforward);
  630. tt.setdef(tpointerdef.create(tt2));
  631. end;
  632. _RECORD:
  633. begin
  634. tt.setdef(record_dec);
  635. end;
  636. _PACKED:
  637. begin
  638. consume(_PACKED);
  639. if token=_ARRAY then
  640. array_dec
  641. else
  642. begin
  643. oldaktpackrecords:=aktpackrecords;
  644. aktpackrecords:=1;
  645. if token in [_CLASS,_OBJECT] then
  646. tt.setdef(object_dec(name,genericdef,genericlist,nil))
  647. else
  648. tt.setdef(record_dec);
  649. aktpackrecords:=oldaktpackrecords;
  650. end;
  651. end;
  652. _CLASS,
  653. _CPPCLASS,
  654. _INTERFACE,
  655. _OBJECT:
  656. begin
  657. tt.setdef(object_dec(name,genericdef,genericlist,nil));
  658. end;
  659. _PROCEDURE,
  660. _FUNCTION:
  661. begin
  662. is_func:=(token=_FUNCTION);
  663. consume(token);
  664. pd:=tprocvardef.create(normal_function_level);
  665. if token=_LKLAMMER then
  666. parse_parameter_dec(pd);
  667. if is_func then
  668. begin
  669. consume(_COLON);
  670. single_type(pd.rettype,false);
  671. end;
  672. if token=_OF then
  673. begin
  674. consume(_OF);
  675. consume(_OBJECT);
  676. include(pd.procoptions,po_methodpointer);
  677. end;
  678. tt.def:=pd;
  679. { possible proc directives }
  680. if parseprocvardir then
  681. begin
  682. if check_proc_directive(true) then
  683. begin
  684. newtype:=ttypesym.create('unnamed',tt);
  685. parse_var_proc_directives(tsym(newtype));
  686. newtype.restype.def:=nil;
  687. tt.def.typesym:=nil;
  688. newtype.free;
  689. end;
  690. { Add implicit hidden parameters and function result }
  691. handle_calling_convention(pd);
  692. end;
  693. end;
  694. else
  695. expr_type;
  696. end;
  697. if tt.def=nil then
  698. tt:=generrortype;
  699. end;
  700. procedure read_anon_type(var tt : ttype;parseprocvardir:boolean);
  701. begin
  702. read_named_type(tt,'',nil,nil,parseprocvardir);
  703. end;
  704. end.