ptype.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  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([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. - 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 array_dec;
  309. var
  310. lowval,
  311. highval : aint;
  312. arraytype : ttype;
  313. ht : ttype;
  314. procedure setdefdecl(const t:ttype);
  315. begin
  316. case t.def.deftype of
  317. enumdef :
  318. begin
  319. lowval:=tenumdef(t.def).min;
  320. highval:=tenumdef(t.def).max;
  321. if (m_fpc in aktmodeswitches) and
  322. (tenumdef(t.def).has_jumps) then
  323. Message(type_e_array_index_enums_with_assign_not_possible);
  324. arraytype:=t;
  325. end;
  326. orddef :
  327. begin
  328. if torddef(t.def).typ in [uchar,
  329. u8bit,u16bit,
  330. s8bit,s16bit,s32bit,
  331. {$ifdef cpu64bit}
  332. u32bit,s64bit,
  333. {$endif cpu64bit}
  334. bool8bit,bool16bit,bool32bit,
  335. uwidechar] then
  336. begin
  337. lowval:=torddef(t.def).low;
  338. highval:=torddef(t.def).high;
  339. arraytype:=t;
  340. end
  341. else
  342. Message1(parser_e_type_cant_be_used_in_array_index,t.def.gettypename);
  343. end;
  344. else
  345. Message(sym_e_error_in_type_def);
  346. end;
  347. end;
  348. begin
  349. consume(_ARRAY);
  350. { open array? }
  351. if token=_LECKKLAMMER then
  352. begin
  353. consume(_LECKKLAMMER);
  354. { defaults }
  355. arraytype:=generrortype;
  356. lowval:=low(aint);
  357. highval:=high(aint);
  358. tt.reset;
  359. repeat
  360. { read the expression and check it, check apart if the
  361. declaration is an enum declaration because that needs to
  362. be parsed by readtype (PFV) }
  363. if token=_LKLAMMER then
  364. begin
  365. read_type(ht,'',true);
  366. setdefdecl(ht);
  367. end
  368. else
  369. begin
  370. pt:=expr;
  371. if pt.nodetype=typen then
  372. setdefdecl(pt.resulttype)
  373. else
  374. begin
  375. if (pt.nodetype=rangen) then
  376. begin
  377. if (trangenode(pt).left.nodetype=ordconstn) and
  378. (trangenode(pt).right.nodetype=ordconstn) then
  379. begin
  380. { make both the same type or give an error. This is not
  381. done when both are integer values, because typecasting
  382. between -3200..3200 will result in a signed-unsigned
  383. conflict and give a range check error (PFV) }
  384. if not(is_integer(trangenode(pt).left.resulttype.def) and is_integer(trangenode(pt).left.resulttype.def)) then
  385. inserttypeconv(trangenode(pt).left,trangenode(pt).right.resulttype);
  386. lowval:=tordconstnode(trangenode(pt).left).value;
  387. highval:=tordconstnode(trangenode(pt).right).value;
  388. if highval<lowval then
  389. begin
  390. Message(parser_e_array_lower_less_than_upper_bound);
  391. highval:=lowval;
  392. end;
  393. if is_integer(trangenode(pt).left.resulttype.def) then
  394. range_to_type(lowval,highval,arraytype)
  395. else
  396. arraytype:=trangenode(pt).left.resulttype;
  397. end
  398. else
  399. Message(type_e_cant_eval_constant_expr);
  400. end
  401. else
  402. Message(sym_e_error_in_type_def)
  403. end;
  404. pt.free;
  405. end;
  406. { create arraydef }
  407. if not assigned(tt.def) then
  408. begin
  409. ap:=tarraydef.create(lowval,highval,arraytype);
  410. tt.setdef(ap);
  411. end
  412. else
  413. begin
  414. ap.elementtype.setdef(tarraydef.create(lowval,highval,arraytype));
  415. ap:=tarraydef(ap.elementtype.def);
  416. end;
  417. if token=_COMMA then
  418. consume(_COMMA)
  419. else
  420. break;
  421. until false;
  422. consume(_RECKKLAMMER);
  423. end
  424. else
  425. begin
  426. ap:=tarraydef.create(0,-1,s32inttype);
  427. ap.IsDynamicArray:=true;
  428. tt.setdef(ap);
  429. end;
  430. consume(_OF);
  431. read_type(tt2,'',true);
  432. { if no error, set element type }
  433. if assigned(ap) then
  434. ap.setelementtype(tt2);
  435. end;
  436. var
  437. p : tnode;
  438. pd : tabstractprocdef;
  439. is_func,
  440. enumdupmsg : boolean;
  441. newtype : ttypesym;
  442. oldlocalswitches : tlocalswitches;
  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. oldlocalswitches:=aktlocalswitches;
  472. include(aktlocalswitches,cs_allow_enum_calc);
  473. p:=comp_expr(true);
  474. aktlocalswitches:=oldlocalswitches;
  475. if (p.nodetype=ordconstn) then
  476. begin
  477. { we expect an integer or an enum of the
  478. same type }
  479. if is_integer(p.resulttype.def) or
  480. is_char(p.resulttype.def) or
  481. equal_defs(p.resulttype.def,aktenumdef) then
  482. v:=tordconstnode(p).value
  483. else
  484. IncompatibleTypes(p.resulttype.def,s32inttype.def);
  485. end
  486. else
  487. Message(parser_e_illegal_expression);
  488. p.free;
  489. { please leave that a note, allows type save }
  490. { declarations in the win32 units ! }
  491. if (v<=l) and (not enumdupmsg) then
  492. begin
  493. Message(parser_n_duplicate_enum);
  494. enumdupmsg:=true;
  495. end;
  496. l:=v;
  497. end
  498. else
  499. inc(l);
  500. storepos:=akttokenpos;
  501. akttokenpos:=defpos;
  502. constsymtable.insert(tenumsym.create(s,aktenumdef,l));
  503. akttokenpos:=storepos;
  504. until not try_to_consume(_COMMA);
  505. tt.setdef(aktenumdef);
  506. consume(_RKLAMMER);
  507. end;
  508. _ARRAY:
  509. begin
  510. array_dec;
  511. end;
  512. _SET:
  513. begin
  514. consume(_SET);
  515. consume(_OF);
  516. read_type(tt2,'',true);
  517. if assigned(tt2.def) then
  518. begin
  519. case tt2.def.deftype of
  520. { don't forget that min can be negativ PM }
  521. enumdef :
  522. if tenumdef(tt2.def).min>=0 then
  523. // !! tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
  524. tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
  525. else
  526. Message(sym_e_ill_type_decl_set);
  527. orddef :
  528. begin
  529. if (torddef(tt2.def).typ<>uvoid) and
  530. (torddef(tt2.def).low>=0) then
  531. // !! tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
  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. tt:=generrortype;
  542. end;
  543. _CARET:
  544. begin
  545. consume(_CARET);
  546. single_type(tt2,typecanbeforward);
  547. tt.setdef(tpointerdef.create(tt2));
  548. end;
  549. _RECORD:
  550. begin
  551. tt.setdef(record_dec);
  552. end;
  553. _PACKED:
  554. begin
  555. consume(_PACKED);
  556. if token=_ARRAY then
  557. array_dec
  558. else
  559. begin
  560. oldaktpackrecords:=aktpackrecords;
  561. aktpackrecords:=1;
  562. if token in [_CLASS,_OBJECT] then
  563. tt.setdef(object_dec(name,nil))
  564. else
  565. tt.setdef(record_dec);
  566. aktpackrecords:=oldaktpackrecords;
  567. end;
  568. end;
  569. _CLASS,
  570. _CPPCLASS,
  571. _INTERFACE,
  572. _OBJECT:
  573. begin
  574. tt.setdef(object_dec(name,nil));
  575. end;
  576. _PROCEDURE,
  577. _FUNCTION:
  578. begin
  579. is_func:=(token=_FUNCTION);
  580. consume(token);
  581. pd:=tprocvardef.create(normal_function_level);
  582. if token=_LKLAMMER then
  583. parse_parameter_dec(pd);
  584. if is_func then
  585. begin
  586. consume(_COLON);
  587. single_type(pd.rettype,false);
  588. end;
  589. if token=_OF then
  590. begin
  591. consume(_OF);
  592. consume(_OBJECT);
  593. include(pd.procoptions,po_methodpointer);
  594. end;
  595. tt.def:=pd;
  596. { possible proc directives }
  597. if parseprocvardir then
  598. begin
  599. if check_proc_directive(true) then
  600. begin
  601. newtype:=ttypesym.create('unnamed',tt);
  602. parse_var_proc_directives(tsym(newtype));
  603. newtype.restype.def:=nil;
  604. tt.def.typesym:=nil;
  605. newtype.free;
  606. end;
  607. { Add implicit hidden parameters and function result }
  608. handle_calling_convention(pd);
  609. end;
  610. end;
  611. else
  612. expr_type;
  613. end;
  614. if tt.def=nil then
  615. tt:=generrortype;
  616. end;
  617. end.