ptype.pas 25 KB

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