ptype.pas 27 KB

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