ptype.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  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,symtype;
  22. const
  23. { forward types should only be possible inside a TYPE statement }
  24. typecanbeforward : boolean = false;
  25. var
  26. { hack, which allows to use the current parsed }
  27. { object type as function argument type }
  28. testcurobject : byte;
  29. { reads a string, file type or a type id and returns a name and }
  30. { tdef }
  31. procedure single_type(var tt:ttype;isforwarddef:boolean);
  32. procedure read_type(var tt:ttype;const name : stringid;parseprocvardir:boolean);
  33. { reads a type definition }
  34. { to a appropriating tdef, s gets the name of }
  35. { the type to allow name mangling }
  36. procedure id_type(var tt : ttype;isforwarddef:boolean);
  37. implementation
  38. uses
  39. { common }
  40. cutils,
  41. { global }
  42. globals,tokens,verbose,
  43. systems,
  44. { target }
  45. paramgr,
  46. { symtable }
  47. symconst,symbase,symdef,symsym,symtable,
  48. defutil,defcmp,
  49. { pass 1 }
  50. node,
  51. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  52. { parser }
  53. scanner,
  54. pbase,pexpr,pdecsub,pdecvar,pdecobj;
  55. procedure id_type(var tt : ttype;isforwarddef:boolean);
  56. { reads a type definition }
  57. { to a appropriating tdef, s gets the name of }
  58. { the type to allow name mangling }
  59. var
  60. is_unit_specific : boolean;
  61. pos : tfileposinfo;
  62. srsym : tsym;
  63. srsymtable : tsymtable;
  64. s,sorg : stringid;
  65. begin
  66. s:=pattern;
  67. sorg:=orgpattern;
  68. pos:=akttokenpos;
  69. { use of current parsed object:
  70. - classes can be used also in classes
  71. - objects can be parameters }
  72. if (token=_ID) and
  73. assigned(aktobjectdef) and
  74. (aktobjectdef.objname^=pattern) and
  75. (
  76. (testcurobject=2) or
  77. is_class_or_interface(aktobjectdef)
  78. )then
  79. begin
  80. consume(_ID);
  81. tt.setdef(aktobjectdef);
  82. exit;
  83. end;
  84. { try to load the symbol to see if it's a unitsym. Use the
  85. special searchsym_type that ignores records,objects and
  86. parameters }
  87. is_unit_specific:=false;
  88. searchsym_type(s,srsym,srsymtable);
  89. consume(_ID);
  90. if assigned(srsym) and
  91. (srsym.typ=unitsym) then
  92. begin
  93. is_unit_specific:=true;
  94. consume(_POINT);
  95. if not(srsym.owner.symtabletype in [staticsymtable,globalsymtable]) then
  96. internalerror(200501155);
  97. { only allow unit.symbol access if the name was
  98. found in the current module }
  99. if srsym.owner.iscurrentunit then
  100. begin
  101. srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
  102. pos:=akttokenpos;
  103. s:=pattern;
  104. end
  105. else
  106. srsym:=nil;
  107. consume(_ID);
  108. end;
  109. { Types are first defined with an error def before assigning
  110. the real type so check if it's an errordef. if so then
  111. give an error. Only check for typesyms in the current symbol
  112. table as forwarddef are not resolved directly }
  113. if assigned(srsym) and
  114. (srsym.typ=typesym) and
  115. (srsym.owner=symtablestack) and
  116. (ttypesym(srsym).restype.def.deftype=errordef) then
  117. begin
  118. Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
  119. tt:=generrortype;
  120. exit;
  121. end;
  122. { are we parsing a possible forward def ? }
  123. if isforwarddef and
  124. not(is_unit_specific) then
  125. begin
  126. tt.setdef(tforwarddef.create(s,pos));
  127. exit;
  128. end;
  129. { unknown sym ? }
  130. if not assigned(srsym) then
  131. begin
  132. Message1(sym_e_id_not_found,sorg);
  133. tt:=generrortype;
  134. exit;
  135. end;
  136. { type sym ? }
  137. if (srsym.typ<>typesym) then
  138. begin
  139. Message(type_e_type_id_expected);
  140. tt:=generrortype;
  141. exit;
  142. end;
  143. { Give an error when referring to an errordef }
  144. if (ttypesym(srsym).restype.def.deftype=errordef) then
  145. begin
  146. Message(sym_e_error_in_type_def);
  147. tt:=generrortype;
  148. exit;
  149. end;
  150. { Use the definitions for current unit, because
  151. they can be refered from the parameters and symbols are not
  152. loaded at that time. Only write the definition when the
  153. symbol is the real owner of the definition (not a redefine) }
  154. if (ttypesym(srsym).owner.symtabletype in [staticsymtable,globalsymtable]) and
  155. ttypesym(srsym).owner.iscurrentunit and
  156. (
  157. (ttypesym(srsym).restype.def.typesym=nil) or
  158. (srsym=ttypesym(srsym).restype.def.typesym)
  159. ) then
  160. tt.setdef(ttypesym(srsym).restype.def)
  161. else
  162. tt.setsym(srsym);
  163. end;
  164. procedure single_type(var tt:ttype;isforwarddef:boolean);
  165. var
  166. t2 : ttype;
  167. begin
  168. case token of
  169. _STRING:
  170. string_dec(tt);
  171. _FILE:
  172. begin
  173. consume(_FILE);
  174. if token=_OF then
  175. begin
  176. consume(_OF);
  177. single_type(t2,false);
  178. tt.setdef(tfiledef.createtyped(t2));
  179. end
  180. else
  181. tt:=cfiletype;
  182. end;
  183. _ID:
  184. id_type(tt,isforwarddef);
  185. else
  186. begin
  187. message(type_e_type_id_expected);
  188. tt:=generrortype;
  189. end;
  190. end;
  191. end;
  192. { reads a record declaration }
  193. function record_dec : tdef;
  194. var
  195. symtable : tsymtable;
  196. storetypecanbeforward : boolean;
  197. old_object_option : tsymoptions;
  198. begin
  199. { create recdef }
  200. symtable:=trecordsymtable.create(aktpackrecords);
  201. record_dec:=trecorddef.create(symtable);
  202. { update symtable stack }
  203. symtable.next:=symtablestack;
  204. symtablestack:=symtable;
  205. { parse record }
  206. consume(_RECORD);
  207. old_object_option:=current_object_option;
  208. current_object_option:=[sp_public];
  209. storetypecanbeforward:=typecanbeforward;
  210. { for tp7 don't allow forward types }
  211. if m_tp7 in aktmodeswitches then
  212. typecanbeforward:=false;
  213. read_var_decs(true,false,false);
  214. consume(_END);
  215. typecanbeforward:=storetypecanbeforward;
  216. current_object_option:=old_object_option;
  217. { make the record size aligned }
  218. trecordsymtable(symtablestack).addalignmentpadding;
  219. { restore symtable stack }
  220. symtablestack:=symtable.next;
  221. end;
  222. { reads a type definition and returns a pointer to it }
  223. procedure read_type(var tt : ttype;const name : stringid;parseprocvardir:boolean);
  224. var
  225. pt : tnode;
  226. tt2 : ttype;
  227. aktenumdef : tenumdef;
  228. ap : tarraydef;
  229. s : stringid;
  230. l,v : TConstExprInt;
  231. oldaktpackrecords : longint;
  232. defpos,storepos : tfileposinfo;
  233. procedure expr_type;
  234. var
  235. pt1,pt2 : tnode;
  236. lv,hv : TConstExprInt;
  237. begin
  238. { use of current parsed object:
  239. - classes can be used also in classes
  240. - objects can be parameters }
  241. if (token=_ID) and
  242. assigned(aktobjectdef) and
  243. (aktobjectdef.objname^=pattern) and
  244. (
  245. (testcurobject=2) or
  246. is_class_or_interface(aktobjectdef)
  247. )then
  248. begin
  249. consume(_ID);
  250. tt.setdef(aktobjectdef);
  251. exit;
  252. end;
  253. { we can't accept a equal in type }
  254. pt1:=comp_expr(not(ignore_equal));
  255. if (token=_POINTPOINT) then
  256. begin
  257. consume(_POINTPOINT);
  258. { get high value of range }
  259. pt2:=comp_expr(not(ignore_equal));
  260. { make both the same type or give an error. This is not
  261. done when both are integer values, because typecasting
  262. between -3200..3200 will result in a signed-unsigned
  263. conflict and give a range check error (PFV) }
  264. if not(is_integer(pt1.resulttype.def) and is_integer(pt2.resulttype.def)) then
  265. inserttypeconv(pt1,pt2.resulttype);
  266. { both must be evaluated to constants now }
  267. if (pt1.nodetype=ordconstn) and
  268. (pt2.nodetype=ordconstn) then
  269. begin
  270. lv:=tordconstnode(pt1).value;
  271. hv:=tordconstnode(pt2).value;
  272. { Check bounds }
  273. if hv<lv then
  274. Message(parser_e_upper_lower_than_lower)
  275. else
  276. begin
  277. { All checks passed, create the new def }
  278. case pt1.resulttype.def.deftype of
  279. enumdef :
  280. tt.setdef(tenumdef.create_subrange(tenumdef(pt1.resulttype.def),lv,hv));
  281. orddef :
  282. begin
  283. if is_char(pt1.resulttype.def) then
  284. tt.setdef(torddef.create(uchar,lv,hv))
  285. else
  286. if is_boolean(pt1.resulttype.def) then
  287. tt.setdef(torddef.create(bool8bit,lv,hv))
  288. else
  289. tt.setdef(torddef.create(range_to_basetype(lv,hv),lv,hv));
  290. end;
  291. end;
  292. end;
  293. end
  294. else
  295. Message(sym_e_error_in_type_def);
  296. pt2.free;
  297. end
  298. else
  299. begin
  300. { a simple type renaming }
  301. if (pt1.nodetype=typen) then
  302. tt:=ttypenode(pt1).resulttype
  303. else
  304. Message(sym_e_error_in_type_def);
  305. end;
  306. pt1.free;
  307. end;
  308. procedure set_dec;
  309. begin
  310. consume(_SET);
  311. consume(_OF);
  312. read_type(tt2,'',true);
  313. if assigned(tt2.def) then
  314. begin
  315. case tt2.def.deftype of
  316. { don't forget that min can be negativ PM }
  317. enumdef :
  318. if tenumdef(tt2.def).min>=0 then
  319. // !! tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  320. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  321. else
  322. Message(sym_e_ill_type_decl_set);
  323. orddef :
  324. begin
  325. if (torddef(tt2.def).typ<>uvoid) and
  326. (torddef(tt2.def).low>=0) then
  327. // !! tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  328. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  329. else
  330. Message(sym_e_ill_type_decl_set);
  331. end;
  332. else
  333. Message(sym_e_ill_type_decl_set);
  334. end;
  335. end
  336. else
  337. tt:=generrortype;
  338. end;
  339. procedure array_dec;
  340. var
  341. lowval,
  342. highval : aint;
  343. arraytype : ttype;
  344. ht : ttype;
  345. procedure setdefdecl(const t:ttype);
  346. begin
  347. case t.def.deftype of
  348. enumdef :
  349. begin
  350. lowval:=tenumdef(t.def).min;
  351. highval:=tenumdef(t.def).max;
  352. if (m_fpc in aktmodeswitches) and
  353. (tenumdef(t.def).has_jumps) then
  354. Message(type_e_array_index_enums_with_assign_not_possible);
  355. arraytype:=t;
  356. end;
  357. orddef :
  358. begin
  359. if torddef(t.def).typ in [uchar,
  360. u8bit,u16bit,
  361. s8bit,s16bit,s32bit,
  362. {$ifdef cpu64bit}
  363. u32bit,s64bit,
  364. {$endif cpu64bit}
  365. bool8bit,bool16bit,bool32bit,bool64bit,
  366. uwidechar] then
  367. begin
  368. lowval:=torddef(t.def).low;
  369. highval:=torddef(t.def).high;
  370. arraytype:=t;
  371. end
  372. else
  373. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  374. end;
  375. else
  376. Message(sym_e_error_in_type_def);
  377. end;
  378. end;
  379. begin
  380. consume(_ARRAY);
  381. { open array? }
  382. if token=_LECKKLAMMER then
  383. begin
  384. consume(_LECKKLAMMER);
  385. { defaults }
  386. arraytype:=generrortype;
  387. lowval:=low(aint);
  388. highval:=high(aint);
  389. tt.reset;
  390. repeat
  391. { read the expression and check it, check apart if the
  392. declaration is an enum declaration because that needs to
  393. be parsed by readtype (PFV) }
  394. if token=_LKLAMMER then
  395. begin
  396. read_type(ht,'',true);
  397. setdefdecl(ht);
  398. end
  399. else
  400. begin
  401. pt:=expr;
  402. if pt.nodetype=typen then
  403. setdefdecl(pt.resulttype)
  404. else
  405. begin
  406. if (pt.nodetype=rangen) then
  407. begin
  408. if (trangenode(pt).left.nodetype=ordconstn) and
  409. (trangenode(pt).right.nodetype=ordconstn) then
  410. begin
  411. { make both the same type or give an error. This is not
  412. done when both are integer values, because typecasting
  413. between -3200..3200 will result in a signed-unsigned
  414. conflict and give a range check error (PFV) }
  415. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  416. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  417. lowval:=tordconstnode(trangenode(pt).left).value;
  418. highval:=tordconstnode(trangenode(pt).right).value;
  419. if highval<lowval then
  420. begin
  421. Message(parser_e_array_lower_less_than_upper_bound);
  422. highval:=lowval;
  423. end;
  424. if is_integer(trangenode(pt).left.resulttype.def) then
  425. range_to_type(lowval,highval,arraytype)
  426. else
  427. arraytype:=trangenode(pt).left.resulttype;
  428. end
  429. else
  430. Message(type_e_cant_eval_constant_expr);
  431. end
  432. else
  433. Message(sym_e_error_in_type_def)
  434. end;
  435. pt.free;
  436. end;
  437. { create arraydef }
  438. if not assigned(tt.def) then
  439. begin
  440. ap:=tarraydef.create(lowval,highval,arraytype);
  441. tt.setdef(ap);
  442. end
  443. else
  444. begin
  445. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  446. ap:=tarraydef(ap.elementtype.def);
  447. end;
  448. if token=_COMMA then
  449. consume(_COMMA)
  450. else
  451. break;
  452. until false;
  453. consume(_RECKKLAMMER);
  454. end
  455. else
  456. begin
  457. ap:=tarraydef.create(0,-1,s32inttype);
  458. ap.IsDynamicArray:=true;
  459. tt.setdef(ap);
  460. end;
  461. consume(_OF);
  462. read_type(tt2,'',true);
  463. { if no error, set element type }
  464. if assigned(ap) then
  465. ap.setelementtype(tt2);
  466. end;
  467. var
  468. p : tnode;
  469. pd : tabstractprocdef;
  470. is_func,
  471. enumdupmsg : boolean;
  472. newtype : ttypesym;
  473. oldlocalswitches : tlocalswitches;
  474. begin
  475. tt.reset;
  476. case token of
  477. _STRING,_FILE:
  478. begin
  479. single_type(tt,false);
  480. end;
  481. _LKLAMMER:
  482. begin
  483. consume(_LKLAMMER);
  484. { allow negativ value_str }
  485. l:=-1;
  486. enumdupmsg:=false;
  487. aktenumdef:=tenumdef.create;
  488. repeat
  489. s:=orgpattern;
  490. defpos:=akttokenpos;
  491. consume(_ID);
  492. { only allow assigning of specific numbers under fpc mode }
  493. if not(m_tp7 in aktmodeswitches) and
  494. (
  495. { in fpc mode also allow := to be compatible
  496. with previous 1.0.x versions }
  497. ((m_fpc in aktmodeswitches) and
  498. try_to_consume(_ASSIGNMENT)) or
  499. try_to_consume(_EQUAL)
  500. ) then
  501. begin
  502. oldlocalswitches:=aktlocalswitches;
  503. include(aktlocalswitches,cs_allow_enum_calc);
  504. p:=comp_expr(true);
  505. aktlocalswitches:=oldlocalswitches;
  506. if (p.nodetype=ordconstn) then
  507. begin
  508. { we expect an integer or an enum of the
  509. same type }
  510. if is_integer(p.resulttype.def) or
  511. is_char(p.resulttype.def) or
  512. equal_defs(p.resulttype.def,aktenumdef) then
  513. v:=tordconstnode(p).value
  514. else
  515. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  516. end
  517. else
  518. Message(parser_e_illegal_expression);
  519. p.free;
  520. { please leave that a note, allows type save }
  521. { declarations in the win32 units ! }
  522. if (v<=l) and (not enumdupmsg) then
  523. begin
  524. Message(parser_n_duplicate_enum);
  525. enumdupmsg:=true;
  526. end;
  527. l:=v;
  528. end
  529. else
  530. inc(l);
  531. storepos:=akttokenpos;
  532. akttokenpos:=defpos;
  533. constsymtable.insert(tenumsym.create(s,aktenumdef,l));
  534. akttokenpos:=storepos;
  535. until not try_to_consume(_COMMA);
  536. tt.setdef(aktenumdef);
  537. consume(_RKLAMMER);
  538. end;
  539. _ARRAY:
  540. begin
  541. array_dec;
  542. end;
  543. _SET:
  544. begin
  545. set_dec;
  546. end;
  547. _CARET:
  548. begin
  549. consume(_CARET);
  550. single_type(tt2,typecanbeforward);
  551. tt.setdef(tpointerdef.create(tt2));
  552. end;
  553. _RECORD:
  554. begin
  555. tt.setdef(record_dec);
  556. end;
  557. _PACKED:
  558. begin
  559. consume(_PACKED);
  560. if token=_ARRAY then
  561. array_dec
  562. else if token=_SET then
  563. set_dec
  564. else
  565. begin
  566. oldaktpackrecords:=aktpackrecords;
  567. aktpackrecords:=1;
  568. if token in [_CLASS,_OBJECT] then
  569. tt.setdef(object_dec(name,nil))
  570. else
  571. tt.setdef(record_dec);
  572. aktpackrecords:=oldaktpackrecords;
  573. end;
  574. end;
  575. _CLASS,
  576. _CPPCLASS,
  577. _INTERFACE,
  578. _OBJECT:
  579. begin
  580. tt.setdef(object_dec(name,nil));
  581. end;
  582. _PROCEDURE,
  583. _FUNCTION:
  584. begin
  585. is_func:=(token=_FUNCTION);
  586. consume(token);
  587. pd:=tprocvardef.create(normal_function_level);
  588. if token=_LKLAMMER then
  589. parse_parameter_dec(pd);
  590. if is_func then
  591. begin
  592. consume(_COLON);
  593. single_type(pd.rettype,false);
  594. end;
  595. if token=_OF then
  596. begin
  597. consume(_OF);
  598. consume(_OBJECT);
  599. include(pd.procoptions,po_methodpointer);
  600. end;
  601. tt.def:=pd;
  602. { possible proc directives }
  603. if parseprocvardir then
  604. begin
  605. if check_proc_directive(true) then
  606. begin
  607. newtype:=ttypesym.create('unnamed',tt);
  608. parse_var_proc_directives(tsym(newtype));
  609. newtype.restype.def:=nil;
  610. tt.def.typesym:=nil;
  611. newtype.free;
  612. end;
  613. { Add implicit hidden parameters and function result }
  614. handle_calling_convention(pd);
  615. end;
  616. end;
  617. else
  618. expr_type;
  619. end;
  620. if tt.def=nil then
  621. tt:=generrortype;
  622. end;
  623. end.