ptype.pas 34 KB

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