ptype.pas 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  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,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 if (lv.signed and (lv.svalue<0)) and (not hv.signed and (hv.uvalue>qword(high(int64)))) then
  452. message(type_e_cant_eval_constant_expr)
  453. else
  454. begin
  455. { All checks passed, create the new def }
  456. case pt1.resultdef.typ of
  457. enumdef :
  458. def:=tenumdef.create_subrange(tenumdef(pt1.resultdef),lv.svalue,hv.svalue);
  459. orddef :
  460. begin
  461. if is_char(pt1.resultdef) then
  462. def:=torddef.create(uchar,lv,hv)
  463. else
  464. if is_boolean(pt1.resultdef) then
  465. def:=torddef.create(bool8bit,lv,hv)
  466. else if is_signed(pt1.resultdef) then
  467. def:=torddef.create(range_to_basetype(lv,hv),lv,hv)
  468. else
  469. def:=torddef.create(range_to_basetype(lv,hv),lv,hv);
  470. end;
  471. end;
  472. end;
  473. end
  474. else
  475. Message(sym_e_error_in_type_def);
  476. pt2.free;
  477. end
  478. else
  479. begin
  480. { a simple type renaming or generic specialization }
  481. if (pt1.nodetype=typen) then
  482. begin
  483. def:=ttypenode(pt1).resultdef;
  484. if dospecialize then
  485. generate_specialization(def)
  486. else
  487. begin
  488. if (df_generic in def.defoptions) then
  489. begin
  490. Message(parser_e_no_generics_as_types);
  491. def:=generrordef;
  492. end;
  493. end;
  494. end
  495. else
  496. Message(sym_e_error_in_type_def);
  497. end;
  498. pt1.free;
  499. block_type:=old_block_type;
  500. end;
  501. procedure set_dec;
  502. begin
  503. consume(_SET);
  504. consume(_OF);
  505. read_anon_type(tt2,true);
  506. if assigned(tt2) then
  507. begin
  508. case tt2.typ of
  509. { don't forget that min can be negativ PM }
  510. enumdef :
  511. if (tenumdef(tt2).min>=0) and
  512. (tenumdef(tt2).max<=255) then
  513. // !! def:=tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  514. def:=tsetdef.create(tt2,tenumdef(tt2).min,tenumdef(tt2).max)
  515. else
  516. Message(sym_e_ill_type_decl_set);
  517. orddef :
  518. begin
  519. if (torddef(tt2).ordtype<>uvoid) and
  520. (torddef(tt2).ordtype<>uwidechar) and
  521. (torddef(tt2).low>=0) then
  522. // !! def:=tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  523. if Torddef(tt2).high>int64(high(byte)) then
  524. message(sym_e_ill_type_decl_set)
  525. else
  526. def:=tsetdef.create(tt2,torddef(tt2).low.svalue,torddef(tt2).high.svalue)
  527. else
  528. Message(sym_e_ill_type_decl_set);
  529. end;
  530. else
  531. Message(sym_e_ill_type_decl_set);
  532. end;
  533. end
  534. else
  535. def:=generrordef;
  536. end;
  537. procedure array_dec(is_packed: boolean);
  538. var
  539. lowval,
  540. highval : TConstExprInt;
  541. indexdef : tdef;
  542. hdef : tdef;
  543. arrdef : tarraydef;
  544. procedure setdefdecl(def:tdef);
  545. begin
  546. case def.typ of
  547. enumdef :
  548. begin
  549. lowval:=tenumdef(def).min;
  550. highval:=tenumdef(def).max;
  551. if (m_fpc in current_settings.modeswitches) and
  552. (tenumdef(def).has_jumps) then
  553. Message(type_e_array_index_enums_with_assign_not_possible);
  554. indexdef:=def;
  555. end;
  556. orddef :
  557. begin
  558. if torddef(def).ordtype in [uchar,
  559. u8bit,u16bit,
  560. s8bit,s16bit,s32bit,
  561. {$ifdef cpu64bit}
  562. u32bit,s64bit,
  563. {$endif cpu64bit}
  564. bool8bit,bool16bit,bool32bit,bool64bit,
  565. uwidechar] then
  566. begin
  567. lowval:=torddef(def).low;
  568. highval:=torddef(def).high;
  569. indexdef:=def;
  570. end
  571. else
  572. Message1(parser_e_type_cant_be_used_in_array_index,def.GetTypeName);
  573. end;
  574. else
  575. Message(sym_e_error_in_type_def);
  576. end;
  577. end;
  578. begin
  579. arrdef:=nil;
  580. consume(_ARRAY);
  581. { open array? }
  582. if try_to_consume(_LECKKLAMMER) then
  583. begin
  584. { defaults }
  585. indexdef:=generrordef;
  586. lowval:=int64(low(aint));
  587. highval:=high(aint);
  588. repeat
  589. { read the expression and check it, check apart if the
  590. declaration is an enum declaration because that needs to
  591. be parsed by readtype (PFV) }
  592. if token=_LKLAMMER then
  593. begin
  594. read_anon_type(hdef,true);
  595. setdefdecl(hdef);
  596. end
  597. else
  598. begin
  599. pt:=expr;
  600. if pt.nodetype=typen then
  601. setdefdecl(pt.resultdef)
  602. else
  603. begin
  604. if (pt.nodetype=rangen) then
  605. begin
  606. if (trangenode(pt).left.nodetype=ordconstn) and
  607. (trangenode(pt).right.nodetype=ordconstn) then
  608. begin
  609. { make both the same type or give an error. This is not
  610. done when both are integer values, because typecasting
  611. between -3200..3200 will result in a signed-unsigned
  612. conflict and give a range check error (PFV) }
  613. if not(is_integer(trangenode(pt).left.resultdef) and is_integer(trangenode(pt).left.resultdef)) then
  614. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resultdef);
  615. lowval:=tordconstnode(trangenode(pt).left).value;
  616. highval:=tordconstnode(trangenode(pt).right).value;
  617. if highval<lowval then
  618. begin
  619. Message(parser_e_array_lower_less_than_upper_bound);
  620. highval:=lowval;
  621. end
  622. else if (lowval<int64(low(aint))) or
  623. (highval > high(aint)) then
  624. begin
  625. Message(parser_e_array_range_out_of_bounds);
  626. lowval :=0;
  627. highval:=0;
  628. end;
  629. if is_integer(trangenode(pt).left.resultdef) then
  630. range_to_type(lowval,highval,indexdef)
  631. else
  632. indexdef:=trangenode(pt).left.resultdef;
  633. end
  634. else
  635. Message(type_e_cant_eval_constant_expr);
  636. end
  637. else
  638. Message(sym_e_error_in_type_def)
  639. end;
  640. pt.free;
  641. end;
  642. { if the array is already created add the new arrray
  643. as element of the existing array, otherwise create a new array }
  644. if assigned(arrdef) then
  645. begin
  646. arrdef.elementdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  647. arrdef:=tarraydef(arrdef.elementdef);
  648. end
  649. else
  650. begin
  651. arrdef:=tarraydef.create(lowval.svalue,highval.svalue,indexdef);
  652. def:=arrdef;
  653. end;
  654. if is_packed then
  655. include(arrdef.arrayoptions,ado_IsBitPacked);
  656. if token=_COMMA then
  657. consume(_COMMA)
  658. else
  659. break;
  660. until false;
  661. consume(_RECKKLAMMER);
  662. end
  663. else
  664. begin
  665. if is_packed then
  666. Message(parser_e_packed_dynamic_open_array);
  667. arrdef:=tarraydef.create(0,-1,s32inttype);
  668. include(arrdef.arrayoptions,ado_IsDynamicArray);
  669. def:=arrdef;
  670. end;
  671. consume(_OF);
  672. read_anon_type(tt2,true);
  673. { set element type of the last array definition }
  674. if assigned(arrdef) then
  675. begin
  676. arrdef.elementdef:=tt2;
  677. if is_packed and
  678. tt2.needs_inittable then
  679. Message(type_e_no_packed_inittable);
  680. end;
  681. end;
  682. var
  683. p : tnode;
  684. pd : tabstractprocdef;
  685. is_func,
  686. enumdupmsg, first : boolean;
  687. newtype : ttypesym;
  688. oldlocalswitches : tlocalswitches;
  689. bitpacking: boolean;
  690. begin
  691. def:=nil;
  692. case token of
  693. _STRING,_FILE:
  694. begin
  695. single_type(def,false);
  696. end;
  697. _LKLAMMER:
  698. begin
  699. consume(_LKLAMMER);
  700. first := true;
  701. { allow negativ value_str }
  702. l:=int64(-1);
  703. enumdupmsg:=false;
  704. aktenumdef:=tenumdef.create;
  705. repeat
  706. s:=orgpattern;
  707. defpos:=current_tokenpos;
  708. consume(_ID);
  709. { only allow assigning of specific numbers under fpc mode }
  710. if not(m_tp7 in current_settings.modeswitches) and
  711. (
  712. { in fpc mode also allow := to be compatible
  713. with previous 1.0.x versions }
  714. ((m_fpc in current_settings.modeswitches) and
  715. try_to_consume(_ASSIGNMENT)) or
  716. try_to_consume(_EQUAL)
  717. ) then
  718. begin
  719. oldlocalswitches:=current_settings.localswitches;
  720. include(current_settings.localswitches,cs_allow_enum_calc);
  721. p:=comp_expr(true);
  722. current_settings.localswitches:=oldlocalswitches;
  723. if (p.nodetype=ordconstn) then
  724. begin
  725. { we expect an integer or an enum of the
  726. same type }
  727. if is_integer(p.resultdef) or
  728. is_char(p.resultdef) or
  729. equal_defs(p.resultdef,aktenumdef) then
  730. v:=tordconstnode(p).value
  731. else
  732. IncompatibleTypes(p.resultdef,s32inttype);
  733. end
  734. else
  735. Message(parser_e_illegal_expression);
  736. p.free;
  737. { please leave that a note, allows type save }
  738. { declarations in the win32 units ! }
  739. if (not first) and (v<=l) and (not enumdupmsg) then
  740. begin
  741. Message(parser_n_duplicate_enum);
  742. enumdupmsg:=true;
  743. end;
  744. l:=v;
  745. end
  746. else
  747. inc(l.svalue);
  748. first := false;
  749. storepos:=current_tokenpos;
  750. current_tokenpos:=defpos;
  751. tstoredsymtable(aktenumdef.owner).insert(tenumsym.create(s,aktenumdef,l.svalue));
  752. current_tokenpos:=storepos;
  753. until not try_to_consume(_COMMA);
  754. def:=aktenumdef;
  755. consume(_RKLAMMER);
  756. end;
  757. _ARRAY:
  758. begin
  759. array_dec(false);
  760. end;
  761. _SET:
  762. begin
  763. set_dec;
  764. end;
  765. _CARET:
  766. begin
  767. consume(_CARET);
  768. single_type(tt2,typecanbeforward);
  769. def:=tpointerdef.create(tt2);
  770. end;
  771. _RECORD:
  772. begin
  773. def:=record_dec;
  774. end;
  775. _PACKED,
  776. _BITPACKED:
  777. begin
  778. bitpacking :=
  779. (cs_bitpacking in current_settings.localswitches) or
  780. (token = _BITPACKED);
  781. consume(token);
  782. if token=_ARRAY then
  783. array_dec(bitpacking)
  784. else if token=_SET then
  785. set_dec
  786. else
  787. begin
  788. oldpackrecords:=current_settings.packrecords;
  789. if (not bitpacking) or
  790. (token in [_CLASS,_OBJECT]) then
  791. current_settings.packrecords:=1
  792. else
  793. current_settings.packrecords:=bit_alignment;
  794. if token in [_CLASS,_OBJECT] then
  795. def:=object_dec(name,genericdef,genericlist,nil)
  796. else
  797. def:=record_dec;
  798. current_settings.packrecords:=oldpackrecords;
  799. end;
  800. end;
  801. _DISPINTERFACE,
  802. _CLASS,
  803. _CPPCLASS,
  804. _INTERFACE,
  805. _OBJECT:
  806. begin
  807. def:=object_dec(name,genericdef,genericlist,nil);
  808. end;
  809. _PROCEDURE,
  810. _FUNCTION:
  811. begin
  812. is_func:=(token=_FUNCTION);
  813. consume(token);
  814. pd:=tprocvardef.create(normal_function_level);
  815. if token=_LKLAMMER then
  816. parse_parameter_dec(pd);
  817. if is_func then
  818. begin
  819. consume(_COLON);
  820. single_type(pd.returndef,false);
  821. end;
  822. if token=_OF then
  823. begin
  824. consume(_OF);
  825. consume(_OBJECT);
  826. include(pd.procoptions,po_methodpointer);
  827. end;
  828. def:=pd;
  829. { possible proc directives }
  830. if parseprocvardir then
  831. begin
  832. if check_proc_directive(true) then
  833. begin
  834. newtype:=ttypesym.create('unnamed',def);
  835. parse_var_proc_directives(tsym(newtype));
  836. newtype.typedef:=nil;
  837. def.typesym:=nil;
  838. newtype.free;
  839. end;
  840. { Add implicit hidden parameters and function result }
  841. handle_calling_convention(pd);
  842. end;
  843. end;
  844. else
  845. expr_type;
  846. end;
  847. if def=nil then
  848. def:=generrordef;
  849. end;
  850. procedure read_anon_type(var def : tdef;parseprocvardir:boolean);
  851. begin
  852. read_named_type(def,'',nil,nil,parseprocvardir);
  853. end;
  854. procedure write_persistent_type_info(st:tsymtable);
  855. var
  856. i : longint;
  857. def : tdef;
  858. vmtwriter : TVMTWriter;
  859. begin
  860. for i:=0 to st.DefList.Count-1 do
  861. begin
  862. def:=tdef(st.DefList[i]);
  863. case def.typ of
  864. recorddef :
  865. write_persistent_type_info(trecorddef(def).symtable);
  866. objectdef :
  867. begin
  868. { Skip generics and forward defs }
  869. if (df_generic in def.defoptions) or
  870. (oo_is_forward in tobjectdef(def).objectoptions) then
  871. continue;
  872. write_persistent_type_info(tobjectdef(def).symtable);
  873. { Write also VMT if not done yet }
  874. if not(ds_vmt_written in def.defstates) then
  875. begin
  876. vmtwriter:=TVMTWriter.create(tobjectdef(def));
  877. if is_interface(tobjectdef(def)) then
  878. vmtwriter.writeinterfaceids;
  879. if (oo_has_vmt in tobjectdef(def).objectoptions) then
  880. vmtwriter.writevmt;
  881. vmtwriter.free;
  882. include(def.defstates,ds_vmt_written);
  883. end;
  884. end;
  885. procdef :
  886. begin
  887. if assigned(tprocdef(def).localst) and
  888. (tprocdef(def).localst.symtabletype=localsymtable) then
  889. write_persistent_type_info(tprocdef(def).localst);
  890. if assigned(tprocdef(def).parast) then
  891. write_persistent_type_info(tprocdef(def).parast);
  892. end;
  893. end;
  894. { generate always persistent tables for types in the interface so it can
  895. be reused in other units and give always the same pointer location. }
  896. { Init }
  897. if (
  898. assigned(def.typesym) and
  899. (st.symtabletype=globalsymtable)
  900. ) or
  901. def.needs_inittable or
  902. (ds_init_table_used in def.defstates) then
  903. RTTIWriter.write_rtti(def,initrtti);
  904. { RTTI }
  905. if (
  906. assigned(def.typesym) and
  907. (st.symtabletype=globalsymtable)
  908. ) or
  909. (ds_rtti_table_used in def.defstates) then
  910. RTTIWriter.write_rtti(def,fullrtti);
  911. end;
  912. end;
  913. end.