ptype.pas 24 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. curobjectname : stringid;
  30. { reads a string, file type or a type id and returns a name and }
  31. { tdef }
  32. procedure single_type(var tt:ttype;isforwarddef:boolean);
  33. procedure read_type(var tt:ttype;const name : stringid;parseprocvardir:boolean);
  34. { reads a type definition }
  35. { to a appropriating tdef, s gets the name of }
  36. { the type to allow name mangling }
  37. procedure id_type(var tt : ttype;isforwarddef:boolean);
  38. implementation
  39. uses
  40. { common }
  41. cutils,
  42. { global }
  43. globals,tokens,verbose,
  44. systems,
  45. { target }
  46. paramgr,
  47. { symtable }
  48. symconst,symbase,symdef,symsym,symtable,
  49. defutil,defcmp,
  50. { pass 1 }
  51. node,
  52. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  53. { parser }
  54. scanner,
  55. pbase,pexpr,pdecsub,pdecvar,pdecobj;
  56. procedure id_type(var tt : ttype;isforwarddef:boolean);
  57. { reads a type definition }
  58. { to a appropriating tdef, s gets the name of }
  59. { the type to allow name mangling }
  60. var
  61. is_unit_specific : boolean;
  62. pos : tfileposinfo;
  63. srsym : tsym;
  64. srsymtable : tsymtable;
  65. s,sorg : stringid;
  66. begin
  67. s:=pattern;
  68. sorg:=orgpattern;
  69. pos:=akttokenpos;
  70. { classes can be used also in classes }
  71. if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
  72. begin
  73. tt.setdef(aktobjectdef);
  74. consume(_ID);
  75. exit;
  76. end;
  77. { objects can be parameters }
  78. if (testcurobject=2) and (curobjectname=pattern) then
  79. begin
  80. tt.setdef(aktobjectdef);
  81. consume(_ID);
  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([vd_record]);
  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. if (token=_ID) and (testcurobject=2) and (curobjectname=pattern) then
  240. begin
  241. consume(_ID);
  242. tt.setdef(aktobjectdef);
  243. exit;
  244. end;
  245. { classes can be used also in classes }
  246. if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
  247. begin
  248. tt.setdef(aktobjectdef);
  249. consume(_ID);
  250. exit;
  251. end;
  252. { we can't accept a equal in type }
  253. pt1:=comp_expr(not(ignore_equal));
  254. if (token=_POINTPOINT) then
  255. begin
  256. consume(_POINTPOINT);
  257. { get high value of range }
  258. pt2:=comp_expr(not(ignore_equal));
  259. { make both the same type or give an error. This is not
  260. done when both are integer values, because typecasting
  261. between -3200..3200 will result in a signed-unsigned
  262. conflict and give a range check error (PFV) }
  263. if not(is_integer(pt1.resulttype.def) and is_integer(pt2.resulttype.def)) then
  264. inserttypeconv(pt1,pt2.resulttype);
  265. { both must be evaluated to constants now }
  266. if (pt1.nodetype=ordconstn) and
  267. (pt2.nodetype=ordconstn) then
  268. begin
  269. lv:=tordconstnode(pt1).value;
  270. hv:=tordconstnode(pt2).value;
  271. { Check bounds }
  272. if hv<lv then
  273. Message(parser_e_upper_lower_than_lower)
  274. else
  275. begin
  276. { All checks passed, create the new def }
  277. case pt1.resulttype.def.deftype of
  278. enumdef :
  279. tt.setdef(tenumdef.create_subrange(tenumdef(pt1.resulttype.def),lv,hv));
  280. orddef :
  281. begin
  282. if is_char(pt1.resulttype.def) then
  283. tt.setdef(torddef.create(uchar,lv,hv))
  284. else
  285. if is_boolean(pt1.resulttype.def) then
  286. tt.setdef(torddef.create(bool8bit,l,hv))
  287. else
  288. tt.setdef(torddef.create(range_to_basetype(lv,hv),lv,hv));
  289. end;
  290. end;
  291. end;
  292. end
  293. else
  294. Message(sym_e_error_in_type_def);
  295. pt2.free;
  296. end
  297. else
  298. begin
  299. { a simple type renaming }
  300. if (pt1.nodetype=typen) then
  301. tt:=ttypenode(pt1).resulttype
  302. else
  303. Message(sym_e_error_in_type_def);
  304. end;
  305. pt1.free;
  306. end;
  307. procedure array_dec;
  308. var
  309. lowval,
  310. highval : aint;
  311. arraytype : ttype;
  312. ht : ttype;
  313. procedure setdefdecl(const t:ttype);
  314. begin
  315. case t.def.deftype of
  316. enumdef :
  317. begin
  318. lowval:=tenumdef(t.def).min;
  319. highval:=tenumdef(t.def).max;
  320. if (m_fpc in aktmodeswitches) and
  321. (tenumdef(t.def).has_jumps) then
  322. Message(type_e_array_index_enums_with_assign_not_possible);
  323. arraytype:=t;
  324. end;
  325. orddef :
  326. begin
  327. if torddef(t.def).typ in [uchar,
  328. u8bit,u16bit,
  329. s8bit,s16bit,s32bit,
  330. {$ifdef cpu64bit}
  331. u32bit,s64bit,
  332. {$endif cpu64bit}
  333. bool8bit,bool16bit,bool32bit,
  334. uwidechar] then
  335. begin
  336. lowval:=torddef(t.def).low;
  337. highval:=torddef(t.def).high;
  338. arraytype:=t;
  339. end
  340. else
  341. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  342. end;
  343. else
  344. Message(sym_e_error_in_type_def);
  345. end;
  346. end;
  347. begin
  348. consume(_ARRAY);
  349. { open array? }
  350. if token=_LECKKLAMMER then
  351. begin
  352. consume(_LECKKLAMMER);
  353. { defaults }
  354. arraytype:=generrortype;
  355. lowval:=low(aint);
  356. highval:=high(aint);
  357. tt.reset;
  358. repeat
  359. { read the expression and check it, check apart if the
  360. declaration is an enum declaration because that needs to
  361. be parsed by readtype (PFV) }
  362. if token=_LKLAMMER then
  363. begin
  364. read_type(ht,'',true);
  365. setdefdecl(ht);
  366. end
  367. else
  368. begin
  369. pt:=expr;
  370. if pt.nodetype=typen then
  371. setdefdecl(pt.resulttype)
  372. else
  373. begin
  374. if (pt.nodetype=rangen) then
  375. begin
  376. if (trangenode(pt).left.nodetype=ordconstn) and
  377. (trangenode(pt).right.nodetype=ordconstn) then
  378. begin
  379. { make both the same type or give an error. This is not
  380. done when both are integer values, because typecasting
  381. between -3200..3200 will result in a signed-unsigned
  382. conflict and give a range check error (PFV) }
  383. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  384. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  385. lowval:=tordconstnode(trangenode(pt).left).value;
  386. highval:=tordconstnode(trangenode(pt).right).value;
  387. if highval<lowval then
  388. begin
  389. Message(parser_e_array_lower_less_than_upper_bound);
  390. highval:=lowval;
  391. end;
  392. if is_integer(trangenode(pt).left.resulttype.def) then
  393. range_to_type(lowval,highval,arraytype)
  394. else
  395. arraytype:=trangenode(pt).left.resulttype;
  396. end
  397. else
  398. Message(type_e_cant_eval_constant_expr);
  399. end
  400. else
  401. Message(sym_e_error_in_type_def)
  402. end;
  403. pt.free;
  404. end;
  405. { create arraydef }
  406. if not assigned(tt.def) then
  407. begin
  408. ap:=tarraydef.create(lowval,highval,arraytype);
  409. tt.setdef(ap);
  410. end
  411. else
  412. begin
  413. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  414. ap:=tarraydef(ap.elementtype.def);
  415. end;
  416. if token=_COMMA then
  417. consume(_COMMA)
  418. else
  419. break;
  420. until false;
  421. consume(_RECKKLAMMER);
  422. end
  423. else
  424. begin
  425. ap:=tarraydef.create(0,-1,s32inttype);
  426. ap.IsDynamicArray:=true;
  427. tt.setdef(ap);
  428. end;
  429. consume(_OF);
  430. read_type(tt2,'',true);
  431. { if no error, set element type }
  432. if assigned(ap) then
  433. ap.setelementtype(tt2);
  434. end;
  435. var
  436. p : tnode;
  437. pd : tabstractprocdef;
  438. is_func,
  439. enumdupmsg : boolean;
  440. newtype : ttypesym;
  441. oldlocalswitches : tlocalswitches;
  442. begin
  443. tt.reset;
  444. case token of
  445. _STRING,_FILE:
  446. begin
  447. single_type(tt,false);
  448. end;
  449. _LKLAMMER:
  450. begin
  451. consume(_LKLAMMER);
  452. { allow negativ value_str }
  453. l:=-1;
  454. enumdupmsg:=false;
  455. aktenumdef:=tenumdef.create;
  456. repeat
  457. s:=orgpattern;
  458. defpos:=akttokenpos;
  459. consume(_ID);
  460. { only allow assigning of specific numbers under fpc mode }
  461. if not(m_tp7 in aktmodeswitches) and
  462. (
  463. { in fpc mode also allow := to be compatible
  464. with previous 1.0.x versions }
  465. ((m_fpc in aktmodeswitches) and
  466. try_to_consume(_ASSIGNMENT)) or
  467. try_to_consume(_EQUAL)
  468. ) then
  469. begin
  470. oldlocalswitches:=aktlocalswitches;
  471. include(aktlocalswitches,cs_allow_enum_calc);
  472. p:=comp_expr(true);
  473. aktlocalswitches:=oldlocalswitches;
  474. if (p.nodetype=ordconstn) then
  475. begin
  476. { we expect an integer or an enum of the
  477. same type }
  478. if is_integer(p.resulttype.def) or
  479. is_char(p.resulttype.def) or
  480. equal_defs(p.resulttype.def,aktenumdef) then
  481. v:=tordconstnode(p).value
  482. else
  483. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  484. end
  485. else
  486. Message(parser_e_illegal_expression);
  487. p.free;
  488. { please leave that a note, allows type save }
  489. { declarations in the win32 units ! }
  490. if (v<=l) and (not enumdupmsg) then
  491. begin
  492. Message(parser_n_duplicate_enum);
  493. enumdupmsg:=true;
  494. end;
  495. l:=v;
  496. end
  497. else
  498. inc(l);
  499. storepos:=akttokenpos;
  500. akttokenpos:=defpos;
  501. constsymtable.insert(tenumsym.create(s,aktenumdef,l));
  502. akttokenpos:=storepos;
  503. until not try_to_consume(_COMMA);
  504. tt.setdef(aktenumdef);
  505. consume(_RKLAMMER);
  506. end;
  507. _ARRAY:
  508. begin
  509. array_dec;
  510. end;
  511. _SET:
  512. begin
  513. consume(_SET);
  514. consume(_OF);
  515. read_type(tt2,'',true);
  516. if assigned(tt2.def) then
  517. begin
  518. case tt2.def.deftype of
  519. { don't forget that min can be negativ PM }
  520. enumdef :
  521. if tenumdef(tt2.def).min>=0 then
  522. // !! tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  523. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  524. else
  525. Message(sym_e_ill_type_decl_set);
  526. orddef :
  527. begin
  528. case torddef(tt2.def).typ of
  529. uchar :
  530. //!!! tt.setdef(tsetdef.create(tt2,0,255));
  531. tt.setdef(tsetdef.create(tt2,255));
  532. u8bit,u16bit,u32bit,
  533. s8bit,s16bit,s32bit :
  534. begin
  535. if (torddef(tt2.def).low>=0) then
  536. // !! tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  537. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  538. else
  539. Message(sym_e_ill_type_decl_set);
  540. end;
  541. else
  542. Message(sym_e_ill_type_decl_set);
  543. end;
  544. end;
  545. else
  546. Message(sym_e_ill_type_decl_set);
  547. end;
  548. end
  549. else
  550. tt:=generrortype;
  551. end;
  552. _CARET:
  553. begin
  554. consume(_CARET);
  555. single_type(tt2,typecanbeforward);
  556. tt.setdef(tpointerdef.create(tt2));
  557. end;
  558. _RECORD:
  559. begin
  560. tt.setdef(record_dec);
  561. end;
  562. _PACKED:
  563. begin
  564. consume(_PACKED);
  565. if token=_ARRAY then
  566. array_dec
  567. else
  568. begin
  569. oldaktpackrecords:=aktpackrecords;
  570. aktpackrecords:=1;
  571. if token in [_CLASS,_OBJECT] then
  572. tt.setdef(object_dec(name,nil))
  573. else
  574. tt.setdef(record_dec);
  575. aktpackrecords:=oldaktpackrecords;
  576. end;
  577. end;
  578. _CLASS,
  579. _CPPCLASS,
  580. _INTERFACE,
  581. _OBJECT:
  582. begin
  583. tt.setdef(object_dec(name,nil));
  584. end;
  585. _PROCEDURE,
  586. _FUNCTION:
  587. begin
  588. is_func:=(token=_FUNCTION);
  589. consume(token);
  590. pd:=tprocvardef.create(normal_function_level);
  591. if token=_LKLAMMER then
  592. parse_parameter_dec(pd);
  593. if is_func then
  594. begin
  595. consume(_COLON);
  596. single_type(pd.rettype,false);
  597. end;
  598. if token=_OF then
  599. begin
  600. consume(_OF);
  601. consume(_OBJECT);
  602. include(pd.procoptions,po_methodpointer);
  603. end;
  604. tt.def:=pd;
  605. { possible proc directives }
  606. if parseprocvardir then
  607. begin
  608. if check_proc_directive(true) then
  609. begin
  610. newtype:=ttypesym.create('unnamed',tt);
  611. parse_var_proc_directives(tsym(newtype));
  612. newtype.restype.def:=nil;
  613. tt.def.typesym:=nil;
  614. newtype.free;
  615. end;
  616. { Add implicit hidden parameters and function result }
  617. handle_calling_convention(pd);
  618. end;
  619. end;
  620. else
  621. expr_type;
  622. end;
  623. if tt.def=nil then
  624. tt:=generrortype;
  625. end;
  626. end.