ptype.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  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,
  22. symtype,symdef,symbase;
  23. const
  24. { forward types should only be possible inside a TYPE statement }
  25. typecanbeforward : boolean = false;
  26. var
  27. { hack, which allows to use the current parsed }
  28. { object type as function argument type }
  29. testcurobject : byte;
  30. { reads a type identifier }
  31. procedure id_type(var def : tdef;isforwarddef:boolean);
  32. { reads a string, file type or a type identifier }
  33. procedure single_type(var def:tdef;isforwarddef:boolean);
  34. { reads any type declaration, where the resulting type will get name as type identifier }
  35. procedure read_named_type(var def:tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  36. { reads any type declaration }
  37. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  38. { generate persistent type information like VMT, RTTI and inittables }
  39. procedure write_persistent_type_info(st:tsymtable);
  40. implementation
  41. uses
  42. { common }
  43. cutils,
  44. { global }
  45. globals,tokens,verbose,constexp,
  46. systems,
  47. { target }
  48. paramgr,
  49. { symtable }
  50. symconst,symsym,symtable,
  51. defutil,defcmp,
  52. { pass 1 }
  53. node,ncgrtti,nobj,
  54. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  55. { parser }
  56. scanner,
  57. pbase,pexpr,pdecsub,pdecvar,pdecobj;
  58. procedure generate_specialization(var pt1:tnode;const name:string);
  59. var
  60. st : TSymtable;
  61. pt2 : tnode;
  62. first,
  63. err : boolean;
  64. i : longint;
  65. sym : tsym;
  66. genericdef : tstoreddef;
  67. generictype : ttypesym;
  68. generictypelist : TFPObjectList;
  69. begin
  70. { retrieve generic def that we are going to replace }
  71. genericdef:=tstoreddef(pt1.resultdef);
  72. pt1.resultdef:=nil;
  73. if not(df_generic in genericdef.defoptions) then
  74. begin
  75. Message(parser_e_special_onlygenerics);
  76. pt1.resultdef:=generrordef;
  77. { recover }
  78. consume(_LSHARPBRACKET);
  79. repeat
  80. pt2:=factor(false);
  81. pt2.free;
  82. until not try_to_consume(_COMMA);
  83. consume(_RSHARPBRACKET);
  84. exit;
  85. end;
  86. consume(_LSHARPBRACKET);
  87. block_type:=bt_specialize;
  88. { Parse generic parameters, for each undefineddef in the symtable of
  89. the genericdef we need to have a new def }
  90. err:=false;
  91. first:=true;
  92. generictypelist:=TFPObjectList.create(false);
  93. case genericdef.typ of
  94. procdef :
  95. st:=genericdef.GetSymtable(gs_para);
  96. objectdef,
  97. recorddef :
  98. st:=genericdef.GetSymtable(gs_record);
  99. end;
  100. if not assigned(st) then
  101. internalerror(200511182);
  102. for i:=0 to st.SymList.Count-1 do
  103. begin
  104. sym:=tsym(st.SymList[i]);
  105. if (sym.typ=typesym) and
  106. (ttypesym(sym).typedef.typ=undefineddef) then
  107. begin
  108. if not first then
  109. consume(_COMMA)
  110. else
  111. first:=false;
  112. pt2:=factor(false);
  113. if pt2.nodetype=typen then
  114. begin
  115. if df_generic in pt2.resultdef.defoptions then
  116. Message(parser_e_no_generics_as_params);
  117. generictype:=ttypesym.create(sym.realname,pt2.resultdef);
  118. generictypelist.add(generictype);
  119. end
  120. else
  121. begin
  122. Message(type_e_type_id_expected);
  123. err:=true;
  124. end;
  125. pt2.free;
  126. end;
  127. end;
  128. { force correct error location if too much type parameters are passed }
  129. if token<>_RSHARPBRACKET then
  130. consume(_RSHARPBRACKET);
  131. { Reparse the original type definition }
  132. if not err then
  133. begin
  134. if not assigned(genericdef.generictokenbuf) then
  135. internalerror(200511171);
  136. current_scanner.startreplaytokens(genericdef.generictokenbuf);
  137. read_named_type(pt1.resultdef,name,genericdef,generictypelist,false);
  138. { Consume the semicolon if it is also recorded }
  139. try_to_consume(_SEMICOLON);
  140. end;
  141. generictypelist.free;
  142. consume(_RSHARPBRACKET);
  143. end;
  144. procedure id_type(var def : tdef;isforwarddef:boolean);
  145. { reads a type definition }
  146. { to a appropriating tdef, s gets the name of }
  147. { the type to allow name mangling }
  148. var
  149. is_unit_specific : boolean;
  150. pos : tfileposinfo;
  151. srsym : tsym;
  152. srsymtable : TSymtable;
  153. s,sorg : TIDString;
  154. begin
  155. s:=pattern;
  156. sorg:=orgpattern;
  157. pos:=current_tokenpos;
  158. { use of current parsed object:
  159. - classes can be used also in classes
  160. - objects can be parameters }
  161. if assigned(aktobjectdef) and
  162. (aktobjectdef.objname^=pattern) and
  163. (
  164. (testcurobject=2) or
  165. is_class_or_interface(aktobjectdef)
  166. )then
  167. begin
  168. consume(_ID);
  169. def:=aktobjectdef;
  170. exit;
  171. end;
  172. { Use the special searchsym_type that ignores records,objects and
  173. parameters }
  174. searchsym_type(s,srsym,srsymtable);
  175. { handle unit specification like System.Writeln }
  176. is_unit_specific:=try_consume_unitsym(srsym,srsymtable);
  177. consume(_ID);
  178. { Types are first defined with an error def before assigning
  179. the real type so check if it's an errordef. if so then
  180. give an error. Only check for typesyms in the current symbol
  181. table as forwarddef are not resolved directly }
  182. if assigned(srsym) and
  183. (srsym.typ=typesym) and
  184. (ttypesym(srsym).typedef.typ=errordef) then
  185. begin
  186. Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
  187. def:=generrordef;
  188. exit;
  189. end;
  190. { are we parsing a possible forward def ? }
  191. if isforwarddef and
  192. not(is_unit_specific) then
  193. begin
  194. def:=tforwarddef.create(s,pos);
  195. exit;
  196. end;
  197. { unknown sym ? }
  198. if not assigned(srsym) then
  199. begin
  200. Message1(sym_e_id_not_found,sorg);
  201. def:=generrordef;
  202. exit;
  203. end;
  204. { type sym ? }
  205. if (srsym.typ<>typesym) then
  206. begin
  207. Message(type_e_type_id_expected);
  208. def:=generrordef;
  209. exit;
  210. end;
  211. { Give an error when referring to an errordef }
  212. if (ttypesym(srsym).typedef.typ=errordef) then
  213. begin
  214. Message(sym_e_error_in_type_def);
  215. def:=generrordef;
  216. exit;
  217. end;
  218. def:=ttypesym(srsym).typedef;
  219. end;
  220. procedure single_type(var def:tdef;isforwarddef:boolean);
  221. var
  222. t2 : tdef;
  223. again : boolean;
  224. begin
  225. repeat
  226. again:=false;
  227. case token of
  228. _STRING:
  229. string_dec(def);
  230. _FILE:
  231. begin
  232. consume(_FILE);
  233. if try_to_consume(_OF) then
  234. begin
  235. single_type(t2,false);
  236. def:=tfiledef.createtyped(t2);
  237. end
  238. else
  239. def:=cfiletype;
  240. end;
  241. _ID:
  242. begin
  243. if try_to_consume(_SPECIALIZE) then
  244. begin
  245. if block_type<>bt_type then
  246. Message(parser_f_no_anonymous_specializations);
  247. block_type:=bt_specialize;
  248. again:=true;
  249. end
  250. else
  251. id_type(def,isforwarddef);
  252. end;
  253. else
  254. begin
  255. message(type_e_type_id_expected);
  256. def:=generrordef;
  257. end;
  258. end;
  259. until not again;
  260. end;
  261. { reads a record declaration }
  262. function record_dec : tdef;
  263. var
  264. recst : trecordsymtable;
  265. storetypecanbeforward : boolean;
  266. old_object_option : tsymoptions;
  267. begin
  268. { create recdef }
  269. recst:=trecordsymtable.create(current_settings.packrecords);
  270. record_dec:=trecorddef.create(recst);
  271. { insert in symtablestack }
  272. symtablestack.push(recst);
  273. { parse record }
  274. consume(_RECORD);
  275. old_object_option:=current_object_option;
  276. current_object_option:=[sp_public];
  277. storetypecanbeforward:=typecanbeforward;
  278. { for tp7 don't allow forward types }
  279. if m_tp7 in current_settings.modeswitches then
  280. typecanbeforward:=false;
  281. read_record_fields([vd_record]);
  282. consume(_END);
  283. typecanbeforward:=storetypecanbeforward;
  284. current_object_option:=old_object_option;
  285. { make the record size aligned }
  286. recst.addalignmentpadding;
  287. { restore symtable stack }
  288. symtablestack.pop(recst);
  289. if trecorddef(record_dec).is_packed and
  290. record_dec.needs_inittable then
  291. Message(type_e_no_packed_inittable);
  292. end;
  293. { reads a type definition and returns a pointer to it }
  294. procedure read_named_type(var def : tdef;const name : TIDString;genericdef:tstoreddef;genericlist:TFPObjectList;parseprocvardir:boolean);
  295. var
  296. pt : tnode;
  297. tt2 : tdef;
  298. aktenumdef : tenumdef;
  299. s : TIDString;
  300. l,v : TConstExprInt;
  301. oldpackrecords : longint;
  302. defpos,storepos : tfileposinfo;
  303. procedure expr_type;
  304. var
  305. pt1,pt2 : tnode;
  306. lv,hv : TConstExprInt;
  307. old_block_type : tblock_type;
  308. begin
  309. old_block_type:=block_type;
  310. { use of current parsed object:
  311. - classes can be used also in classes
  312. - objects can be parameters }
  313. if (token=_ID) and
  314. assigned(aktobjectdef) and
  315. (aktobjectdef.objname^=pattern) and
  316. (
  317. (testcurobject=2) or
  318. is_class_or_interface(aktobjectdef)
  319. )then
  320. begin
  321. consume(_ID);
  322. def:=aktobjectdef;
  323. exit;
  324. end;
  325. { Generate a specialization? }
  326. if try_to_consume(_SPECIALIZE) then
  327. begin
  328. if name='' then
  329. Message(parser_f_no_anonymous_specializations);
  330. block_type:=bt_specialize;
  331. end;
  332. { we can't accept a equal in type }
  333. pt1:=comp_expr(false);
  334. if (block_type<>bt_specialize) and
  335. try_to_consume(_POINTPOINT) then
  336. begin
  337. { get high value of range }
  338. pt2:=comp_expr(false);
  339. { make both the same type or give an error. This is not
  340. done when both are integer values, because typecasting
  341. between -3200..3200 will result in a signed-unsigned
  342. conflict and give a range check error (PFV) }
  343. if not(is_integer(pt1.resultdef) and is_integer(pt2.resultdef)) then
  344. inserttypeconv(pt1,pt2.resultdef);
  345. { both must be evaluated to constants now }
  346. if (pt1.nodetype=ordconstn) and
  347. (pt2.nodetype=ordconstn) then
  348. begin
  349. lv:=tordconstnode(pt1).value;
  350. hv:=tordconstnode(pt2).value;
  351. { Check bounds }
  352. if hv<lv then
  353. message(parser_e_upper_lower_than_lower)
  354. else if (lv.signed and (lv.svalue<0)) and (not hv.signed and (hv.uvalue>qword(high(int64)))) then
  355. message(type_e_cant_eval_constant_expr)
  356. else
  357. begin
  358. { All checks passed, create the new def }
  359. case pt1.resultdef.typ of
  360. enumdef :
  361. def:=tenumdef.create_subrange(tenumdef(pt1.resultdef),lv.svalue,hv.svalue);
  362. orddef :
  363. begin
  364. if is_char(pt1.resultdef) then
  365. def:=torddef.create(uchar,lv,hv)
  366. else
  367. if is_boolean(pt1.resultdef) then
  368. def:=torddef.create(bool8bit,lv,hv)
  369. else if is_signed(pt1.resultdef) then
  370. def:=torddef.create(range_to_basetype(lv,hv),lv,hv)
  371. else
  372. def:=torddef.create(range_to_basetype(lv,hv),lv,hv);
  373. end;
  374. end;
  375. end;
  376. end
  377. else
  378. Message(sym_e_error_in_type_def);
  379. pt2.free;
  380. end
  381. else
  382. begin
  383. { a simple type renaming or generic specialization }
  384. if (pt1.nodetype=typen) then
  385. begin
  386. if (block_type=bt_specialize) then
  387. generate_specialization(pt1,name);
  388. def:=ttypenode(pt1).resultdef;
  389. if (block_type<>bt_specialize) and (df_generic in def.defoptions) then
  390. begin
  391. Message(parser_e_no_generics_as_types);
  392. def:=generrordef;
  393. end;
  394. end
  395. else
  396. Message(sym_e_error_in_type_def);
  397. end;
  398. pt1.free;
  399. block_type:=old_block_type;
  400. end;
  401. procedure set_dec;
  402. begin
  403. consume(_SET);
  404. consume(_OF);
  405. read_anon_type(tt2,true);
  406. if assigned(tt2) then
  407. begin
  408. case tt2.typ of
  409. { don't forget that min can be negativ PM }
  410. enumdef :
  411. if (tenumdef(tt2).min>=0) and
  412. (tenumdef(tt2).max<=255) then
  413. // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  414. def:=tsetdef.create(tt2,tenumdef(tt2).min,tenumdef(tt2).max)
  415. else
  416. Message(sym_e_ill_type_decl_set);
  417. orddef :
  418. begin
  419. if (torddef(tt2).ordtype<>uvoid) and
  420. (torddef(tt2).ordtype<>uwidechar) and
  421. (torddef(tt2).low>=0) then
  422. // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  423. if Torddef(tt2).high>int64(high(byte)) then
  424. message(sym_e_ill_type_decl_set)
  425. else
  426. def:=tsetdef.create(tt2,torddef(tt2).low.svalue,torddef(tt2).high.svalue)
  427. else
  428. Message(sym_e_ill_type_decl_set);
  429. end;
  430. else
  431. Message(sym_e_ill_type_decl_set);
  432. end;
  433. end
  434. else
  435. def:=generrordef;
  436. end;
  437. procedure array_dec(is_packed: boolean);
  438. var
  439. lowval,
  440. highval : TConstExprInt;
  441. indexdef : tdef;
  442. hdef : tdef;
  443. arrdef : tarraydef;
  444. procedure setdefdecl(def:tdef);
  445. begin
  446. case def.typ of
  447. enumdef :
  448. begin
  449. lowval:=tenumdef(def).min;
  450. highval:=tenumdef(def).max;
  451. if (m_fpc in current_settings.modeswitches) and
  452. (tenumdef(def).has_jumps) then
  453. Message(type_e_array_index_enums_with_assign_not_possible);
  454. indexdef:=def;
  455. end;
  456. orddef :
  457. begin
  458. if torddef(def).ordtype in [uchar,
  459. u8bit,u16bit,
  460. s8bit,s16bit,s32bit,
  461. {$ifdef cpu64bit}
  462. u32bit,s64bit,
  463. {$endif cpu64bit}
  464. bool8bit,bool16bit,bool32bit,bool64bit,
  465. uwidechar] then
  466. begin
  467. lowval:=torddef(def).low;
  468. highval:=torddef(def).high;
  469. indexdef:=def;
  470. end
  471. else
  472. Message1(parser_e_type_cant_be_used_in_array_index,def.GetTypeName);
  473. end;
  474. else
  475. Message(sym_e_error_in_type_def);
  476. end;
  477. end;
  478. begin
  479. arrdef:=nil;
  480. consume(_ARRAY);
  481. { open array? }
  482. if try_to_consume(_LECKKLAMMER) then
  483. begin
  484. { defaults }
  485. indexdef:=generrordef;
  486. lowval:=int64(low(aint));
  487. highval:=high(aint);
  488. repeat
  489. { read the expression and check it, check apart if the
  490. declaration is an enum declaration because that needs to
  491. be parsed by readtype (PFV) }
  492. if token=_LKLAMMER then
  493. begin
  494. read_anon_type(hdef,true);
  495. setdefdecl(hdef);
  496. end
  497. else
  498. begin
  499. pt:=expr;
  500. if pt.nodetype=typen then
  501. setdefdecl(pt.resultdef)
  502. else
  503. begin
  504. if (pt.nodetype=rangen) then
  505. begin
  506. if (trangenode(pt).left.nodetype=ordconstn) and
  507. (trangenode(pt).right.nodetype=ordconstn) then
  508. begin
  509. { make both the same type or give an error. This is not
  510. done when both are integer values, because typecasting
  511. between -3200..3200 will result in a signed-unsigned
  512. conflict and give a range check error (PFV) }
  513. if not(is_integer(trangenode(pt).left.resultdef) and is_integer(trangenode(pt).left.resultdef)) then
  514. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resultdef);
  515. lowval:=tordconstnode(trangenode(pt).left).value;
  516. highval:=tordconstnode(trangenode(pt).right).value;
  517. if highval<lowval then
  518. begin
  519. Message(parser_e_array_lower_less_than_upper_bound);
  520. highval:=lowval;
  521. end
  522. else if (lowval<int64(low(aint))) or
  523. (highval > high(aint)) then
  524. begin
  525. Message(parser_e_array_range_out_of_bounds);
  526. lowval :=0;
  527. highval:=0;
  528. end;
  529. if is_integer(trangenode(pt).left.resultdef) then
  530. range_to_type(lowval,highval,indexdef)
  531. else
  532. indexdef:=trangenode(pt).left.resultdef;
  533. end
  534. else
  535. Message(type_e_cant_eval_constant_expr);
  536. end
  537. else
  538. Message(sym_e_error_in_type_def)
  539. end;
  540. pt.free;
  541. end;
  542. { if the array is already created add the new arrray
  543. as element of the existing array, otherwise create a new array }
  544. if assigned(arrdef) then
  545. begin
  546. arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  547. arrdef:=tarraydef(arrdef.elementdef);
  548. end
  549. else
  550. begin
  551. arrdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  552. def:=arrdef;
  553. end;
  554. if is_packed then
  555. include(arrdef.arrayoptions,ado_IsBitPacked);
  556. if token=_COMMA then
  557. consume(_COMMA)
  558. else
  559. break;
  560. until false;
  561. consume(_RECKKLAMMER);
  562. end
  563. else
  564. begin
  565. if is_packed then
  566. Message(parser_e_packed_dynamic_open_array);
  567. arrdef:=tarraydef.create(0,-1,s32inttype);
  568. include(arrdef.arrayoptions,ado_IsDynamicArray);
  569. def:=arrdef;
  570. end;
  571. consume(_OF);
  572. read_anon_type(tt2,true);
  573. { set element type of the last array definition }
  574. if assigned(arrdef) then
  575. begin
  576. arrdef.elementdef:=tt2;
  577. if is_packed and
  578. tt2.needs_inittable then
  579. Message(type_e_no_packed_inittable);
  580. end;
  581. end;
  582. var
  583. p : tnode;
  584. pd : tabstractprocdef;
  585. is_func,
  586. enumdupmsg, first : boolean;
  587. newtype : ttypesym;
  588. oldlocalswitches : tlocalswitches;
  589. bitpacking: boolean;
  590. begin
  591. def:=nil;
  592. case token of
  593. _STRING,_FILE:
  594. begin
  595. single_type(def,false);
  596. end;
  597. _LKLAMMER:
  598. begin
  599. consume(_LKLAMMER);
  600. first := true;
  601. { allow negativ value_str }
  602. l:=int64(-1);
  603. enumdupmsg:=false;
  604. aktenumdef:=tenumdef.create;
  605. repeat
  606. s:=orgpattern;
  607. defpos:=current_tokenpos;
  608. consume(_ID);
  609. { only allow assigning of specific numbers under fpc mode }
  610. if not(m_tp7 in current_settings.modeswitches) and
  611. (
  612. { in fpc mode also allow := to be compatible
  613. with previous 1.0.x versions }
  614. ((m_fpc in current_settings.modeswitches) and
  615. try_to_consume(_ASSIGNMENT)) or
  616. try_to_consume(_EQUAL)
  617. ) then
  618. begin
  619. oldlocalswitches:=current_settings.localswitches;
  620. include(current_settings.localswitches,cs_allow_enum_calc);
  621. p:=comp_expr(true);
  622. current_settings.localswitches:=oldlocalswitches;
  623. if (p.nodetype=ordconstn) then
  624. begin
  625. { we expect an integer or an enum of the
  626. same type }
  627. if is_integer(p.resultdef) or
  628. is_char(p.resultdef) or
  629. equal_defs(p.resultdef,aktenumdef) then
  630. v:=tordconstnode(p).value
  631. else
  632. IncompatibleTypes(p.resultdef,s32inttype);
  633. end
  634. else
  635. Message(parser_e_illegal_expression);
  636. p.free;
  637. { please leave that a note, allows type save }
  638. { declarations in the win32 units ! }
  639. if (not first) and (v<=l) and (not enumdupmsg) then
  640. begin
  641. Message(parser_n_duplicate_enum);
  642. enumdupmsg:=true;
  643. end;
  644. l:=v;
  645. end
  646. else
  647. inc(l.svalue);
  648. first := false;
  649. storepos:=current_tokenpos;
  650. current_tokenpos:=defpos;
  651. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l.svalue));
  652. current_tokenpos:=storepos;
  653. until not try_to_consume(_COMMA);
  654. def:=aktenumdef;
  655. consume(_RKLAMMER);
  656. end;
  657. _ARRAY:
  658. begin
  659. array_dec(false);
  660. end;
  661. _SET:
  662. begin
  663. set_dec;
  664. end;
  665. _CARET:
  666. begin
  667. consume(_CARET);
  668. single_type(tt2,typecanbeforward);
  669. def:=tpointerdef.create(tt2);
  670. end;
  671. _RECORD:
  672. begin
  673. def:=record_dec;
  674. end;
  675. _PACKED,
  676. _BITPACKED:
  677. begin
  678. bitpacking :=
  679. (cs_bitpacking in current_settings.localswitches) or
  680. (token = _BITPACKED);
  681. consume(token);
  682. if token=_ARRAY then
  683. array_dec(bitpacking)
  684. else if token=_SET then
  685. set_dec
  686. else
  687. begin
  688. oldpackrecords:=current_settings.packrecords;
  689. if (not bitpacking) or
  690. (token in [_CLASS,_OBJECT]) then
  691. current_settings.packrecords:=1
  692. else
  693. current_settings.packrecords:=bit_alignment;
  694. if token in [_CLASS,_OBJECT] then
  695. def:=object_dec(name,genericdef,genericlist,nil)
  696. else
  697. def:=record_dec;
  698. current_settings.packrecords:=oldpackrecords;
  699. end;
  700. end;
  701. _DISPINTERFACE,
  702. _CLASS,
  703. _CPPCLASS,
  704. _INTERFACE,
  705. _OBJECT:
  706. begin
  707. def:=object_dec(name,genericdef,genericlist,nil);
  708. end;
  709. _PROCEDURE,
  710. _FUNCTION:
  711. begin
  712. is_func:=(token=_FUNCTION);
  713. consume(token);
  714. pd:=tprocvardef.create(normal_function_level);
  715. if token=_LKLAMMER then
  716. parse_parameter_dec(pd);
  717. if is_func then
  718. begin
  719. consume(_COLON);
  720. single_type(pd.returndef,false);
  721. end;
  722. if token=_OF then
  723. begin
  724. consume(_OF);
  725. consume(_OBJECT);
  726. include(pd.procoptions,po_methodpointer);
  727. end;
  728. def:=pd;
  729. { possible proc directives }
  730. if parseprocvardir then
  731. begin
  732. if check_proc_directive(true) then
  733. begin
  734. newtype:=ttypesym.create('unnamed',def);
  735. parse_var_proc_directives(tsym(newtype));
  736. newtype.typedef:=nil;
  737. def.typesym:=nil;
  738. newtype.free;
  739. end;
  740. { Add implicit hidden parameters and function result }
  741. handle_calling_convention(pd);
  742. end;
  743. end;
  744. else
  745. expr_type;
  746. end;
  747. if def=nil then
  748. def:=generrordef;
  749. end;
  750. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  751. begin
  752. read_named_type(def,'',nil,nil,parseprocvardir);
  753. end;
  754. procedure write_persistent_type_info(st:tsymtable);
  755. var
  756. i : longint;
  757. def : tdef;
  758. vmtwriter : TVMTWriter;
  759. begin
  760. for i:=0 to st.DefList.Count-1 do
  761. begin
  762. def:=tdef(st.DefList[i]);
  763. case def.typ of
  764. recorddef :
  765. write_persistent_type_info(trecorddef(def).symtable);
  766. objectdef :
  767. begin
  768. write_persistent_type_info(tobjectdef(def).symtable);
  769. { Write also VMT }
  770. if not(ds_vmt_written in def.defstates) and
  771. not(oo_is_forward in tobjectdef(def).objectoptions) then
  772. begin
  773. vmtwriter:=TVMTWriter.create(tobjectdef(def));
  774. if is_interface(tobjectdef(def)) then
  775. vmtwriter.writeinterfaceids;
  776. if (oo_has_vmt in tobjectdef(def).objectoptions) then
  777. vmtwriter.writevmt;
  778. vmtwriter.free;
  779. include(def.defstates,ds_vmt_written);
  780. end;
  781. end;
  782. procdef :
  783. begin
  784. if assigned(tprocdef(def).localst) and
  785. (tprocdef(def).localst.symtabletype=localsymtable) then
  786. write_persistent_type_info(tprocdef(def).localst);
  787. if assigned(tprocdef(def).parast) then
  788. write_persistent_type_info(tprocdef(def).parast);
  789. end;
  790. end;
  791. { generate always persistent tables for types in the interface so it can
  792. be reused in other units and give always the same pointer location. }
  793. { Init }
  794. if (
  795. assigned(def.typesym) and
  796. (st.symtabletype=globalsymtable)
  797. ) or
  798. def.needs_inittable or
  799. (ds_init_table_used in def.defstates) then
  800. RTTIWriter.write_rtti(def,initrtti);
  801. { RTTI }
  802. if (
  803. assigned(def.typesym) and
  804. (st.symtabletype=globalsymtable)
  805. ) or
  806. (ds_rtti_table_used in def.defstates) then
  807. RTTIWriter.write_rtti(def,fullrtti);
  808. end;
  809. end;
  810. end.