ptype.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  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;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;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;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. s,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;isforwarddef:boolean);
  166. var
  167. t2 : ttype;
  168. begin
  169. case token of
  170. _STRING:
  171. string_dec(tt);
  172. _FILE:
  173. begin
  174. consume(_FILE);
  175. if token=_OF then
  176. begin
  177. consume(_OF);
  178. single_type(t2,false);
  179. tt.setdef(tfiledef.createtyped(t2));
  180. end
  181. else
  182. tt:=cfiletype;
  183. end;
  184. _ID:
  185. id_type(tt,isforwarddef);
  186. else
  187. begin
  188. message(type_e_type_id_expected);
  189. tt:=generrortype;
  190. end;
  191. end;
  192. end;
  193. { reads a record declaration }
  194. function record_dec : tdef;
  195. var
  196. symtable : tsymtable;
  197. storetypecanbeforward : boolean;
  198. old_object_option : tsymoptions;
  199. begin
  200. { create recdef }
  201. symtable:=trecordsymtable.create(aktpackrecords);
  202. record_dec:=trecorddef.create(symtable);
  203. { update symtable stack }
  204. symtable.next:=symtablestack;
  205. symtablestack:=symtable;
  206. { parse record }
  207. consume(_RECORD);
  208. old_object_option:=current_object_option;
  209. current_object_option:=[sp_public];
  210. storetypecanbeforward:=typecanbeforward;
  211. { for tp7 don't allow forward types }
  212. if m_tp7 in aktmodeswitches then
  213. typecanbeforward:=false;
  214. read_var_decs(true,false,false);
  215. consume(_END);
  216. typecanbeforward:=storetypecanbeforward;
  217. current_object_option:=old_object_option;
  218. { make the record size aligned }
  219. trecordsymtable(symtablestack).addalignmentpadding;
  220. { restore symtable stack }
  221. symtablestack:=symtable.next;
  222. end;
  223. { reads a type definition and returns a pointer to it }
  224. procedure read_type(var tt : ttype;const name : stringid;parseprocvardir:boolean);
  225. var
  226. pt : tnode;
  227. tt2 : ttype;
  228. aktenumdef : tenumdef;
  229. ap : tarraydef;
  230. s : stringid;
  231. l,v : TConstExprInt;
  232. oldaktpackrecords : longint;
  233. hs : string;
  234. defpos,storepos : tfileposinfo;
  235. procedure expr_type;
  236. var
  237. pt1,pt2 : tnode;
  238. lv,hv : TConstExprInt;
  239. begin
  240. { use of current parsed object ? }
  241. if (token=_ID) and (testcurobject=2) and (curobjectname=pattern) then
  242. begin
  243. consume(_ID);
  244. tt.setdef(aktobjectdef);
  245. exit;
  246. end;
  247. { classes can be used also in classes }
  248. if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
  249. begin
  250. tt.setdef(aktobjectdef);
  251. consume(_ID);
  252. exit;
  253. end;
  254. { we can't accept a equal in type }
  255. pt1:=comp_expr(not(ignore_equal));
  256. if (token=_POINTPOINT) then
  257. begin
  258. consume(_POINTPOINT);
  259. { get high value of range }
  260. pt2:=comp_expr(not(ignore_equal));
  261. { make both the same type or give an error. This is not
  262. done when both are integer values, because typecasting
  263. between -3200..3200 will result in a signed-unsigned
  264. conflict and give a range check error (PFV) }
  265. if not(is_integer(pt1.resulttype.def) and is_integer(pt2.resulttype.def)) then
  266. inserttypeconv(pt1,pt2.resulttype);
  267. { both must be evaluated to constants now }
  268. if (pt1.nodetype=ordconstn) and
  269. (pt2.nodetype=ordconstn) then
  270. begin
  271. lv:=tordconstnode(pt1).value;
  272. hv:=tordconstnode(pt2).value;
  273. { Check bounds }
  274. if hv<lv then
  275. Message(parser_e_upper_lower_than_lower)
  276. else
  277. begin
  278. { All checks passed, create the new def }
  279. case pt1.resulttype.def.deftype of
  280. enumdef :
  281. tt.setdef(tenumdef.create_subrange(tenumdef(pt1.resulttype.def),lv,hv));
  282. orddef :
  283. begin
  284. if is_char(pt1.resulttype.def) then
  285. tt.setdef(torddef.create(uchar,lv,hv))
  286. else
  287. if is_boolean(pt1.resulttype.def) then
  288. tt.setdef(torddef.create(bool8bit,l,hv))
  289. else
  290. tt.setdef(torddef.create(range_to_basetype(lv,hv),lv,hv));
  291. end;
  292. end;
  293. end;
  294. end
  295. else
  296. Message(sym_e_error_in_type_def);
  297. pt2.free;
  298. end
  299. else
  300. begin
  301. { a simple type renaming }
  302. if (pt1.nodetype=typen) then
  303. tt:=ttypenode(pt1).resulttype
  304. else
  305. Message(sym_e_error_in_type_def);
  306. end;
  307. pt1.free;
  308. end;
  309. procedure array_dec;
  310. var
  311. lowval,
  312. highval : aint;
  313. arraytype : ttype;
  314. ht : ttype;
  315. procedure setdefdecl(const t:ttype);
  316. begin
  317. case t.def.deftype of
  318. enumdef :
  319. begin
  320. lowval:=tenumdef(t.def).min;
  321. highval:=tenumdef(t.def).max;
  322. if (m_fpc in aktmodeswitches) and
  323. (tenumdef(t.def).has_jumps) then
  324. Message(type_e_array_index_enums_with_assign_not_possible);
  325. arraytype:=t;
  326. end;
  327. orddef :
  328. begin
  329. if torddef(t.def).typ in [uchar,
  330. u8bit,u16bit,
  331. s8bit,s16bit,s32bit,
  332. {$ifdef cpu64bit}
  333. u32bit,s64bit,
  334. {$endif cpu64bit}
  335. bool8bit,bool16bit,bool32bit,
  336. uwidechar] then
  337. begin
  338. lowval:=torddef(t.def).low;
  339. highval:=torddef(t.def).high;
  340. arraytype:=t;
  341. end
  342. else
  343. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  344. end;
  345. else
  346. Message(sym_e_error_in_type_def);
  347. end;
  348. end;
  349. begin
  350. consume(_ARRAY);
  351. { open array? }
  352. if token=_LECKKLAMMER then
  353. begin
  354. consume(_LECKKLAMMER);
  355. { defaults }
  356. arraytype:=generrortype;
  357. lowval:=low(aint);
  358. highval:=high(aint);
  359. tt.reset;
  360. repeat
  361. { read the expression and check it, check apart if the
  362. declaration is an enum declaration because that needs to
  363. be parsed by readtype (PFV) }
  364. if token=_LKLAMMER then
  365. begin
  366. read_type(ht,'',true);
  367. setdefdecl(ht);
  368. end
  369. else
  370. begin
  371. pt:=expr;
  372. if pt.nodetype=typen then
  373. setdefdecl(pt.resulttype)
  374. else
  375. begin
  376. if (pt.nodetype=rangen) then
  377. begin
  378. if (trangenode(pt).left.nodetype=ordconstn) and
  379. (trangenode(pt).right.nodetype=ordconstn) then
  380. begin
  381. { make both the same type or give an error. This is not
  382. done when both are integer values, because typecasting
  383. between -3200..3200 will result in a signed-unsigned
  384. conflict and give a range check error (PFV) }
  385. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  386. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  387. lowval:=tordconstnode(trangenode(pt).left).value;
  388. highval:=tordconstnode(trangenode(pt).right).value;
  389. if highval<lowval then
  390. begin
  391. Message(parser_e_array_lower_less_than_upper_bound);
  392. highval:=lowval;
  393. end;
  394. if is_integer(trangenode(pt).left.resulttype.def) then
  395. range_to_type(lowval,highval,arraytype)
  396. else
  397. arraytype:=trangenode(pt).left.resulttype;
  398. end
  399. else
  400. Message(type_e_cant_eval_constant_expr);
  401. end
  402. else
  403. Message(sym_e_error_in_type_def)
  404. end;
  405. pt.free;
  406. end;
  407. { create arraydef }
  408. if not assigned(tt.def) then
  409. begin
  410. ap:=tarraydef.create(lowval,highval,arraytype);
  411. tt.setdef(ap);
  412. end
  413. else
  414. begin
  415. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  416. ap:=tarraydef(ap.elementtype.def);
  417. end;
  418. if token=_COMMA then
  419. consume(_COMMA)
  420. else
  421. break;
  422. until false;
  423. consume(_RECKKLAMMER);
  424. end
  425. else
  426. begin
  427. ap:=tarraydef.create(0,-1,s32inttype);
  428. ap.IsDynamicArray:=true;
  429. tt.setdef(ap);
  430. end;
  431. consume(_OF);
  432. read_type(tt2,'',true);
  433. { if no error, set element type }
  434. if assigned(ap) then
  435. ap.setelementtype(tt2);
  436. end;
  437. var
  438. p : tnode;
  439. pd : tabstractprocdef;
  440. is_func,
  441. enumdupmsg : boolean;
  442. newtype : ttypesym;
  443. begin
  444. tt.reset;
  445. case token of
  446. _STRING,_FILE:
  447. begin
  448. single_type(tt,false);
  449. end;
  450. _LKLAMMER:
  451. begin
  452. consume(_LKLAMMER);
  453. { allow negativ value_str }
  454. l:=-1;
  455. enumdupmsg:=false;
  456. aktenumdef:=tenumdef.create;
  457. repeat
  458. s:=orgpattern;
  459. defpos:=akttokenpos;
  460. consume(_ID);
  461. { only allow assigning of specific numbers under fpc mode }
  462. if not(m_tp7 in aktmodeswitches) and
  463. (
  464. { in fpc mode also allow := to be compatible
  465. with previous 1.0.x versions }
  466. ((m_fpc in aktmodeswitches) and
  467. try_to_consume(_ASSIGNMENT)) or
  468. try_to_consume(_EQUAL)
  469. ) then
  470. begin
  471. p:=comp_expr(true);
  472. if (p.nodetype=ordconstn) then
  473. begin
  474. { we expect an integer or an enum of the
  475. same type }
  476. if is_integer(p.resulttype.def) or
  477. is_char(p.resulttype.def) or
  478. equal_defs(p.resulttype.def,aktenumdef) then
  479. v:=tordconstnode(p).value
  480. else
  481. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  482. end
  483. else
  484. Message(parser_e_illegal_expression);
  485. p.free;
  486. { please leave that a note, allows type save }
  487. { declarations in the win32 units ! }
  488. if (v<=l) and (not enumdupmsg) then
  489. begin
  490. Message(parser_n_duplicate_enum);
  491. enumdupmsg:=true;
  492. end;
  493. l:=v;
  494. end
  495. else
  496. inc(l);
  497. storepos:=akttokenpos;
  498. akttokenpos:=defpos;
  499. constsymtable.insert(tenumsym.create(s,aktenumdef,l));
  500. akttokenpos:=storepos;
  501. until not try_to_consume(_COMMA);
  502. tt.setdef(aktenumdef);
  503. consume(_RKLAMMER);
  504. end;
  505. _ARRAY:
  506. begin
  507. array_dec;
  508. end;
  509. _SET:
  510. begin
  511. consume(_SET);
  512. consume(_OF);
  513. read_type(tt2,'',true);
  514. if assigned(tt2.def) then
  515. begin
  516. case tt2.def.deftype of
  517. { don't forget that min can be negativ PM }
  518. enumdef :
  519. if tenumdef(tt2.def).min>=0 then
  520. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  521. else
  522. Message(sym_e_ill_type_decl_set);
  523. orddef :
  524. begin
  525. case torddef(tt2.def).typ of
  526. uchar :
  527. tt.setdef(tsetdef.create(tt2,255));
  528. u8bit,u16bit,u32bit,
  529. s8bit,s16bit,s32bit :
  530. begin
  531. if (torddef(tt2.def).low>=0) then
  532. tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
  533. else
  534. Message(sym_e_ill_type_decl_set);
  535. end;
  536. else
  537. Message(sym_e_ill_type_decl_set);
  538. end;
  539. end;
  540. else
  541. Message(sym_e_ill_type_decl_set);
  542. end;
  543. end
  544. else
  545. tt:=generrortype;
  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
  563. begin
  564. oldaktpackrecords:=aktpackrecords;
  565. aktpackrecords:=1;
  566. if token in [_CLASS,_OBJECT] then
  567. tt.setdef(object_dec(name,nil))
  568. else
  569. tt.setdef(record_dec);
  570. aktpackrecords:=oldaktpackrecords;
  571. end;
  572. end;
  573. _CLASS,
  574. _CPPCLASS,
  575. _INTERFACE,
  576. _OBJECT:
  577. begin
  578. tt.setdef(object_dec(name,nil));
  579. end;
  580. _PROCEDURE,
  581. _FUNCTION:
  582. begin
  583. is_func:=(token=_FUNCTION);
  584. consume(token);
  585. pd:=tprocvardef.create(normal_function_level);
  586. if token=_LKLAMMER then
  587. parse_parameter_dec(pd);
  588. if is_func then
  589. begin
  590. consume(_COLON);
  591. single_type(pd.rettype,false);
  592. end;
  593. if token=_OF then
  594. begin
  595. consume(_OF);
  596. consume(_OBJECT);
  597. include(pd.procoptions,po_methodpointer);
  598. end;
  599. tt.def:=pd;
  600. { possible proc directives }
  601. if parseprocvardir then
  602. begin
  603. if check_proc_directive(true) then
  604. begin
  605. newtype:=ttypesym.create('unnamed',tt);
  606. parse_var_proc_directives(tsym(newtype));
  607. newtype.restype.def:=nil;
  608. tt.def.typesym:=nil;
  609. newtype.free;
  610. end;
  611. { Add implicit hidden parameters and function result }
  612. handle_calling_convention(pd);
  613. end;
  614. end;
  615. else
  616. expr_type;
  617. end;
  618. if tt.def=nil then
  619. tt:=generrortype;
  620. end;
  621. end.
  622. {
  623. $Log$
  624. Revision 1.74 2005-02-01 08:46:13 michael
  625. * Patch from peter: fix macpas anonymous function procvar
  626. Revision 1.73 2005/01/19 22:19:41 peter
  627. * unit mapping rewrite
  628. * new derefmap added
  629. Revision 1.72 2005/01/04 16:39:12 peter
  630. * allow enum with jumps as array index in delphi mode
  631. Revision 1.71 2004/11/16 20:32:41 peter
  632. * fixes for win32 mangledname
  633. Revision 1.70 2004/11/15 23:35:31 peter
  634. * tparaitem removed, use tparavarsym instead
  635. * parameter order is now calculated from paranr value in tparavarsym
  636. Revision 1.69 2004/11/01 23:30:11 peter
  637. * support > 32bit accesses for x86_64
  638. * rewrote array size checking to support 64bit
  639. Revision 1.68 2004/06/20 08:55:30 florian
  640. * logs truncated
  641. Revision 1.67 2004/06/16 20:07:09 florian
  642. * dwarf branch merged
  643. Revision 1.66.2.1 2004/04/28 19:55:52 peter
  644. * new warning for ordinal-pointer when size is different
  645. * fixed some cg_e_ messages to the correct section type_e_ or parser_e_
  646. Revision 1.66 2004/03/29 14:44:10 peter
  647. * fixes to previous constant integer commit
  648. Revision 1.65 2004/03/23 22:34:49 peter
  649. * constants ordinals now always have a type assigned
  650. * integer constants have the smallest type, unsigned prefered over
  651. signed
  652. Revision 1.64 2004/02/03 22:32:54 peter
  653. * renamed xNNbittype to xNNinttype
  654. * renamed registers32 to registersint
  655. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  656. }