ptype.pas 32 KB

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