pdecobj.pas 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does object 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 pdecobj;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,symtype,symdef;
  23. { parses a object declaration }
  24. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  25. implementation
  26. uses
  27. cutils,cclasses,
  28. globals,verbose,systems,tokens,
  29. symconst,symbase,symsym,symtable,defbase,
  30. cgbase,
  31. node,nld,nmem,ncon,ncnv,ncal,pass_1,
  32. scanner,
  33. pbase,pexpr,pdecsub,pdecvar,ptype;
  34. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  35. { this function parses an object or class declaration }
  36. var
  37. there_is_a_destructor : boolean;
  38. classtype : tobjectdeftype;
  39. childof : tobjectdef;
  40. aktclass : tobjectdef;
  41. procedure constructor_head;
  42. begin
  43. consume(_CONSTRUCTOR);
  44. { must be at same level as in implementation }
  45. inc(lexlevel);
  46. parse_proc_head(potype_constructor);
  47. dec(lexlevel);
  48. if (cs_constructor_name in aktglobalswitches) and (aktprocsym.name<>'INIT') then
  49. Message(parser_e_constructorname_must_be_init);
  50. include(aktclass.objectoptions,oo_has_constructor);
  51. consume(_SEMICOLON);
  52. begin
  53. if is_class(aktclass) then
  54. begin
  55. { CLASS constructors return the created instance }
  56. aktprocdef.rettype.def:=aktclass;
  57. end
  58. else
  59. begin
  60. { OBJECT constructors return a boolean }
  61. aktprocdef.rettype:=booltype;
  62. end;
  63. end;
  64. end;
  65. procedure property_dec;
  66. { convert a node tree to symlist and return the last
  67. symbol }
  68. function parse_symlist(pl:tsymlist):boolean;
  69. var
  70. idx : longint;
  71. sym : tsym;
  72. def : tdef;
  73. st : tsymtable;
  74. begin
  75. parse_symlist:=true;
  76. def:=nil;
  77. if token=_ID then
  78. begin
  79. sym:=search_class_member(aktclass,pattern);
  80. if assigned(sym) then
  81. begin
  82. case sym.typ of
  83. varsym :
  84. begin
  85. pl.addsym(sl_load,sym);
  86. def:=tvarsym(sym).vartype.def;
  87. end;
  88. procsym :
  89. begin
  90. pl.addsym(sl_call,sym);
  91. end;
  92. end;
  93. end
  94. else
  95. begin
  96. Message1(parser_e_illegal_field_or_method,pattern);
  97. parse_symlist:=false;
  98. end;
  99. consume(_ID);
  100. repeat
  101. case token of
  102. _ID,
  103. _SEMICOLON :
  104. begin
  105. break;
  106. end;
  107. _POINT :
  108. begin
  109. consume(_POINT);
  110. if assigned(def) then
  111. begin
  112. st:=def.getsymtable(gs_record);
  113. if assigned(st) then
  114. begin
  115. sym:=searchsymonlyin(st,pattern);
  116. if assigned(sym) then
  117. begin
  118. pl.addsym(sl_subscript,sym);
  119. case sym.typ of
  120. varsym :
  121. def:=tvarsym(sym).vartype.def;
  122. else
  123. begin
  124. Message1(sym_e_illegal_field,pattern);
  125. parse_symlist:=false;
  126. end;
  127. end;
  128. end
  129. else
  130. begin
  131. Message1(sym_e_illegal_field,pattern);
  132. parse_symlist:=false;
  133. end;
  134. end
  135. else
  136. begin
  137. Message(cg_e_invalid_qualifier);
  138. parse_symlist:=false;
  139. end;
  140. end;
  141. consume(_ID);
  142. end;
  143. _LECKKLAMMER :
  144. begin
  145. consume(_LECKKLAMMER);
  146. repeat
  147. if def.deftype=arraydef then
  148. begin
  149. idx:=get_intconst;
  150. pl.addconst(sl_vec,idx);
  151. def:=tarraydef(def).elementtype.def;
  152. end
  153. else
  154. begin
  155. Message(cg_e_invalid_qualifier);
  156. parse_symlist:=false;
  157. end;
  158. until not try_to_consume(_COMMA);
  159. consume(_RECKKLAMMER);
  160. end;
  161. else
  162. begin
  163. Message(parser_e_ill_property_access_sym);
  164. parse_symlist:=false;
  165. break;
  166. end;
  167. end;
  168. until false;
  169. end
  170. else
  171. begin
  172. Message(parser_e_ill_property_access_sym);
  173. parse_symlist:=false;
  174. end;
  175. pl.def:=def;
  176. end;
  177. var
  178. sym : tsym;
  179. propertyparas : tparalinkedlist;
  180. { returns the matching procedure to access a property }
  181. { function get_procdef : tprocdef;
  182. var
  183. p : pprocdeflist;
  184. begin
  185. get_procdef:=nil;
  186. p:=tprocsym(sym).defs;
  187. while assigned(p) do
  188. begin
  189. if equal_paras(p^.def.para,propertyparas,cp_value_equal_const) or
  190. convertable_paras(p^.def.para,propertyparas,cp_value_equal_const) then
  191. begin
  192. get_procdef:=p^.def;
  193. exit;
  194. end;
  195. p:=p^.next;
  196. end;
  197. end;}
  198. var
  199. hp2,datacoll : tparaitem;
  200. p : tpropertysym;
  201. overriden : tsym;
  202. hs : string;
  203. varspez : tvarspez;
  204. sc : tidstringlist;
  205. s : string;
  206. tt : ttype;
  207. declarepos : tfileposinfo;
  208. pp : Tprocdef;
  209. pd : tprocdef;
  210. pt : tnode;
  211. propname : stringid;
  212. begin
  213. { check for a class }
  214. aktprocsym:=nil;
  215. aktprocdef:=nil;
  216. if not((is_class_or_interface(aktclass)) or
  217. ((m_delphi in aktmodeswitches) and (is_object(aktclass)))) then
  218. Message(parser_e_syntax_error);
  219. consume(_PROPERTY);
  220. propertyparas:=TParaLinkedList.Create;
  221. datacoll:=nil;
  222. if token=_ID then
  223. begin
  224. p:=tpropertysym.create(orgpattern);
  225. propname:=pattern;
  226. consume(_ID);
  227. { property parameters ? }
  228. if token=_LECKKLAMMER then
  229. begin
  230. if (sp_published in current_object_option) then
  231. Message(parser_e_cant_publish_that_property);
  232. { create a list of the parameters in propertyparas }
  233. consume(_LECKKLAMMER);
  234. inc(testcurobject);
  235. repeat
  236. if token=_VAR then
  237. begin
  238. consume(_VAR);
  239. varspez:=vs_var;
  240. end
  241. else if token=_CONST then
  242. begin
  243. consume(_CONST);
  244. varspez:=vs_const;
  245. end
  246. else if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  247. begin
  248. consume(_OUT);
  249. varspez:=vs_out;
  250. end
  251. else varspez:=vs_value;
  252. sc:=consume_idlist;
  253. {$ifdef fixLeaksOnError}
  254. strContStack.push(sc);
  255. {$endif fixLeaksOnError}
  256. if token=_COLON then
  257. begin
  258. consume(_COLON);
  259. if token=_ARRAY then
  260. begin
  261. {
  262. if (varspez<>vs_const) and
  263. (varspez<>vs_var) then
  264. begin
  265. varspez:=vs_const;
  266. Message(parser_e_illegal_open_parameter);
  267. end;
  268. }
  269. consume(_ARRAY);
  270. consume(_OF);
  271. { define range and type of range }
  272. tt.setdef(tarraydef.create(0,-1,s32bittype));
  273. { define field type }
  274. single_type(tarraydef(tt.def).elementtype,s,false);
  275. end
  276. else
  277. single_type(tt,s,false);
  278. end
  279. else
  280. tt:=cformaltype;
  281. repeat
  282. s:=sc.get(declarepos);
  283. if s='' then
  284. break;
  285. hp2:=TParaItem.create;
  286. hp2.paratyp:=varspez;
  287. hp2.paratype:=tt;
  288. propertyparas.insert(hp2);
  289. until false;
  290. {$ifdef fixLeaksOnError}
  291. if strContStack.pop <> sc then
  292. writeln('problem with strContStack in ptype');
  293. {$endif fixLeaksOnError}
  294. sc.free;
  295. until not try_to_consume(_SEMICOLON);
  296. dec(testcurobject);
  297. consume(_RECKKLAMMER);
  298. { the parser need to know if a property has parameters, the
  299. index parameter doesn't count (PFV) }
  300. if not(propertyparas.empty) then
  301. include(p.propoptions,ppo_hasparameters);
  302. end;
  303. { overriden property ? }
  304. { force property interface, if there is a property parameter }
  305. if (token=_COLON) or not(propertyparas.empty) then
  306. begin
  307. consume(_COLON);
  308. single_type(p.proptype,hs,false);
  309. if (idtoken=_INDEX) then
  310. begin
  311. consume(_INDEX);
  312. pt:=comp_expr(true);
  313. if is_constnode(pt) and
  314. is_ordinal(pt.resulttype.def) and
  315. (not is_64bitint(pt.resulttype.def)) then
  316. p.index:=tordconstnode(pt).value
  317. else
  318. begin
  319. Message(parser_e_invalid_property_index_value);
  320. p.index:=0;
  321. end;
  322. p.indextype.setdef(pt.resulttype.def);
  323. include(p.propoptions,ppo_indexed);
  324. { concat a longint to the para template }
  325. hp2:=TParaItem.Create;
  326. hp2.paratyp:=vs_value;
  327. hp2.paratype:=p.indextype;
  328. propertyparas.insert(hp2);
  329. pt.free;
  330. end;
  331. end
  332. else
  333. begin
  334. { do an property override }
  335. overriden:=search_class_member(aktclass,propname);
  336. if assigned(overriden) and (overriden.typ=propertysym) then
  337. begin
  338. p.dooverride(tpropertysym(overriden));
  339. end
  340. else
  341. begin
  342. p.proptype:=generrortype;
  343. message(parser_e_no_property_found_to_override);
  344. end;
  345. end;
  346. if (sp_published in current_object_option) and
  347. not(p.proptype.def.is_publishable) then
  348. Message(parser_e_cant_publish_that_property);
  349. { create data defcoll to allow correct parameter checks }
  350. datacoll:=TParaItem.Create;
  351. datacoll.paratyp:=vs_value;
  352. datacoll.paratype:=p.proptype;
  353. if try_to_consume(_READ) then
  354. begin
  355. p.readaccess.clear;
  356. if parse_symlist(p.readaccess) then
  357. begin
  358. sym:=p.readaccess.firstsym^.sym;
  359. case sym.typ of
  360. procsym :
  361. begin
  362. pd:=Tprocsym(sym).search_procdef_bypara(propertyparas,true);
  363. if not(assigned(pd)) or
  364. not(is_equal(pd.rettype.def,p.proptype.def)) then
  365. Message(parser_e_ill_property_access_sym);
  366. p.readaccess.setdef(pd);
  367. end;
  368. varsym :
  369. begin
  370. if CheckTypes(p.readaccess.def,p.proptype.def) then
  371. begin
  372. { property parameters are allowed if this is
  373. an indexed property, because the index is then
  374. the parameter.
  375. Note: In the help of Kylix it is written
  376. that it isn't allowed, but the compiler accepts it (PFV) }
  377. if (ppo_hasparameters in p.propoptions) then
  378. Message(parser_e_ill_property_access_sym);
  379. end;
  380. end;
  381. else
  382. Message(parser_e_ill_property_access_sym);
  383. end;
  384. end;
  385. end;
  386. if try_to_consume(_WRITE) then
  387. begin
  388. p.writeaccess.clear;
  389. if parse_symlist(p.writeaccess) then
  390. begin
  391. sym:=p.writeaccess.firstsym^.sym;
  392. case sym.typ of
  393. procsym :
  394. begin
  395. { insert data entry to check access method }
  396. propertyparas.insert(datacoll);
  397. pd:=Tprocsym(sym).search_procdef_bypara(propertyparas,true);
  398. { ... and remove it }
  399. propertyparas.remove(datacoll);
  400. if not(assigned(pd)) then
  401. Message(parser_e_ill_property_access_sym);
  402. p.writeaccess.setdef(pd);
  403. end;
  404. varsym :
  405. begin
  406. if CheckTypes(p.writeaccess.def,p.proptype.def) then
  407. begin
  408. { property parameters are allowed if this is
  409. an indexed property, because the index is then
  410. the parameter.
  411. Note: In the help of Kylix it is written
  412. that it isn't allowed, but the compiler accepts it (PFV) }
  413. if (ppo_hasparameters in p.propoptions) then
  414. Message(parser_e_ill_property_access_sym);
  415. end;
  416. end;
  417. else
  418. Message(parser_e_ill_property_access_sym);
  419. end;
  420. end;
  421. end;
  422. include(p.propoptions,ppo_stored);
  423. if try_to_consume(_STORED) then
  424. begin
  425. p.storedaccess.clear;
  426. case token of
  427. _ID:
  428. begin
  429. { in the case that idtoken=_DEFAULT }
  430. { we have to do nothing except }
  431. { setting ppo_stored, it's the same }
  432. { as stored true }
  433. if idtoken<>_DEFAULT then
  434. begin
  435. if parse_symlist(p.storedaccess) then
  436. begin
  437. sym:=p.storedaccess.firstsym^.sym;
  438. case sym.typ of
  439. procsym :
  440. begin
  441. pp:=Tprocsym(sym).search_procdef_nopara_boolret;
  442. if assigned(pp) then
  443. p.storedaccess.setdef(pp)
  444. else
  445. message(parser_e_ill_property_storage_sym);
  446. end;
  447. varsym :
  448. begin
  449. if (ppo_hasparameters in p.propoptions) or
  450. not(is_boolean(p.storedaccess.def)) then
  451. Message(parser_e_stored_property_must_be_boolean);
  452. end;
  453. else
  454. Message(parser_e_ill_property_access_sym);
  455. end;
  456. end;
  457. end;
  458. end;
  459. _FALSE:
  460. begin
  461. consume(_FALSE);
  462. exclude(p.propoptions,ppo_stored);
  463. end;
  464. _TRUE:
  465. consume(_TRUE);
  466. end;
  467. end;
  468. if try_to_consume(_DEFAULT) then
  469. begin
  470. if not(is_ordinal(p.proptype.def) or
  471. is_64bitint(p.proptype.def) or
  472. ((p.proptype.def.deftype=setdef) and
  473. (tsetdef(p.proptype.def).settype=smallset))) or
  474. ((p.proptype.def.deftype=arraydef) and
  475. (ppo_indexed in p.propoptions)) or
  476. (ppo_hasparameters in p.propoptions) then
  477. Message(parser_e_property_cant_have_a_default_value);
  478. { Get the result of the default, the firstpass is
  479. needed to support values like -1 }
  480. pt:=comp_expr(true);
  481. if (p.proptype.def.deftype=setdef) and
  482. (pt.nodetype=arrayconstructorn) then
  483. begin
  484. arrayconstructor_to_set(pt);
  485. do_resulttypepass(pt);
  486. end;
  487. inserttypeconv(pt,p.proptype);
  488. if not(is_constnode(pt)) then
  489. Message(parser_e_property_default_value_must_const);
  490. if pt.nodetype=setconstn then
  491. p.default:=plongint(tsetconstnode(pt).value_set)^
  492. else
  493. p.default:=tordconstnode(pt).value;
  494. pt.free;
  495. end
  496. else if try_to_consume(_NODEFAULT) then
  497. begin
  498. p.default:=0;
  499. end;
  500. symtablestack.insert(p);
  501. { default property ? }
  502. consume(_SEMICOLON);
  503. if try_to_consume(_DEFAULT) then
  504. begin
  505. { overriding a default propertyp is allowed
  506. p2:=search_default_property(aktclass);
  507. if assigned(p2) then
  508. message1(parser_e_only_one_default_property,
  509. tobjectdef(p2.owner.defowner)^.objrealname^)
  510. else
  511. }
  512. begin
  513. include(p.propoptions,ppo_defaultproperty);
  514. if propertyparas.empty then
  515. message(parser_e_property_need_paras);
  516. end;
  517. consume(_SEMICOLON);
  518. end;
  519. { clean up }
  520. if assigned(datacoll) then
  521. datacoll.free;
  522. end
  523. else
  524. begin
  525. consume(_ID);
  526. consume(_SEMICOLON);
  527. end;
  528. propertyparas.free;
  529. end;
  530. procedure destructor_head;
  531. begin
  532. consume(_DESTRUCTOR);
  533. inc(lexlevel);
  534. parse_proc_head(potype_destructor);
  535. dec(lexlevel);
  536. if (cs_constructor_name in aktglobalswitches) and (aktprocsym.name<>'DONE') then
  537. Message(parser_e_destructorname_must_be_done);
  538. include(aktclass.objectoptions,oo_has_destructor);
  539. consume(_SEMICOLON);
  540. if not(aktprocdef.Para.empty) then
  541. if (m_fpc in aktmodeswitches) then
  542. Message(parser_e_no_paras_for_destructor);
  543. { no return value }
  544. aktprocdef.rettype:=voidtype;
  545. end;
  546. var
  547. hs : string;
  548. pcrd : tclassrefdef;
  549. tt : ttype;
  550. old_object_option : tsymoptions;
  551. oldprocinfo : tprocinfo;
  552. oldprocsym : tprocsym;
  553. oldprocdef : tprocdef;
  554. oldparse_only : boolean;
  555. storetypecanbeforward : boolean;
  556. procedure setclassattributes;
  557. begin
  558. { publishable }
  559. if classtype in [odt_interfacecom,odt_class] then
  560. begin
  561. aktclass.objecttype:=classtype;
  562. if (cs_generate_rtti in aktlocalswitches) or
  563. (assigned(aktclass.childof) and
  564. (oo_can_have_published in aktclass.childof.objectoptions)) then
  565. begin
  566. include(aktclass.objectoptions,oo_can_have_published);
  567. { in "publishable" classes the default access type is published }
  568. current_object_option:=[sp_published];
  569. end;
  570. end;
  571. end;
  572. procedure setclassparent;
  573. begin
  574. if assigned(fd) then
  575. aktclass:=fd
  576. else
  577. aktclass:=tobjectdef.create(classtype,n,nil);
  578. { is the current class tobject? }
  579. { so you could define your own tobject }
  580. if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_class) and (upper(n)='TOBJECT') then
  581. class_tobject:=aktclass
  582. else if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  583. interface_iunknown:=aktclass
  584. else
  585. begin
  586. case classtype of
  587. odt_class:
  588. childof:=class_tobject;
  589. odt_interfacecom:
  590. childof:=interface_iunknown;
  591. end;
  592. if (oo_is_forward in childof.objectoptions) then
  593. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  594. aktclass.set_parent(childof);
  595. end;
  596. end;
  597. procedure setinterfacemethodoptions;
  598. var
  599. i: longint;
  600. defs: TIndexArray;
  601. pd: tprocdef;
  602. begin
  603. include(aktclass.objectoptions,oo_has_virtual);
  604. defs:=aktclass.symtable.defindex;
  605. for i:=1 to defs.count do
  606. begin
  607. pd:=tprocdef(defs.search(i));
  608. if pd.deftype=procdef then
  609. begin
  610. pd.extnumber:=aktclass.lastvtableindex;
  611. inc(aktclass.lastvtableindex);
  612. include(pd.procoptions,po_virtualmethod);
  613. pd.forwarddef:=false;
  614. end;
  615. end;
  616. end;
  617. function readobjecttype : boolean;
  618. begin
  619. readobjecttype:=true;
  620. { distinguish classes and objects }
  621. case token of
  622. _OBJECT:
  623. begin
  624. classtype:=odt_object;
  625. consume(_OBJECT)
  626. end;
  627. _CPPCLASS:
  628. begin
  629. classtype:=odt_cppclass;
  630. consume(_CPPCLASS);
  631. end;
  632. _INTERFACE:
  633. begin
  634. if aktinterfacetype=it_interfacecom then
  635. classtype:=odt_interfacecom
  636. else {it_interfacecorba}
  637. classtype:=odt_interfacecorba;
  638. consume(_INTERFACE);
  639. { forward declaration }
  640. if not(assigned(fd)) and (token=_SEMICOLON) then
  641. begin
  642. { also anonym objects aren't allow (o : object a : longint; end;) }
  643. if n='' then
  644. Message(parser_f_no_anonym_objects);
  645. aktclass:=tobjectdef.create(classtype,n,nil);
  646. if (cs_compilesystem in aktmoduleswitches) and
  647. (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  648. interface_iunknown:=aktclass;
  649. include(aktclass.objectoptions,oo_is_forward);
  650. object_dec:=aktclass;
  651. typecanbeforward:=storetypecanbeforward;
  652. readobjecttype:=false;
  653. exit;
  654. end;
  655. end;
  656. _CLASS:
  657. begin
  658. classtype:=odt_class;
  659. consume(_CLASS);
  660. if not(assigned(fd)) and
  661. (token=_OF) and
  662. { Delphi only allows class of in type blocks.
  663. Note that when parsing the type of a variable declaration
  664. the blocktype is bt_type so the check for typecanbeforward
  665. is also necessary (PFV) }
  666. (((block_type=bt_type) and typecanbeforward) or
  667. not(m_delphi in aktmodeswitches)) then
  668. begin
  669. { a hack, but it's easy to handle }
  670. { class reference type }
  671. consume(_OF);
  672. single_type(tt,hs,typecanbeforward);
  673. { accept hp1, if is a forward def or a class }
  674. if (tt.def.deftype=forwarddef) or
  675. is_class(tt.def) then
  676. begin
  677. pcrd:=tclassrefdef.create(tt);
  678. object_dec:=pcrd;
  679. end
  680. else
  681. begin
  682. object_dec:=generrortype.def;
  683. Message1(type_e_class_type_expected,generrortype.def.typename);
  684. end;
  685. typecanbeforward:=storetypecanbeforward;
  686. readobjecttype:=false;
  687. exit;
  688. end
  689. { forward class }
  690. else if not(assigned(fd)) and (token=_SEMICOLON) then
  691. begin
  692. { also anonym objects aren't allow (o : object a : longint; end;) }
  693. if n='' then
  694. Message(parser_f_no_anonym_objects);
  695. aktclass:=tobjectdef.create(odt_class,n,nil);
  696. if (cs_compilesystem in aktmoduleswitches) and (upper(n)='TOBJECT') then
  697. class_tobject:=aktclass;
  698. aktclass.objecttype:=odt_class;
  699. include(aktclass.objectoptions,oo_is_forward);
  700. { all classes must have a vmt !! at offset zero }
  701. if not(oo_has_vmt in aktclass.objectoptions) then
  702. aktclass.insertvmt;
  703. object_dec:=aktclass;
  704. typecanbeforward:=storetypecanbeforward;
  705. readobjecttype:=false;
  706. exit;
  707. end;
  708. end;
  709. else
  710. begin
  711. classtype:=odt_class; { this is error but try to recover }
  712. consume(_OBJECT);
  713. end;
  714. end;
  715. end;
  716. procedure handleimplementedinterface(implintf : tobjectdef);
  717. begin
  718. if not is_interface(implintf) then
  719. begin
  720. Message1(type_e_interface_type_expected,implintf.typename);
  721. exit;
  722. end;
  723. if aktclass.implementedinterfaces.searchintf(implintf)<>-1 then
  724. Message1(sym_e_duplicate_id,implintf.name)
  725. else
  726. aktclass.implementedinterfaces.addintf(implintf);
  727. end;
  728. procedure readimplementedinterfaces;
  729. var
  730. tt : ttype;
  731. begin
  732. while try_to_consume(_COMMA) do
  733. begin
  734. id_type(tt,pattern,false);
  735. if (tt.def.deftype<>objectdef) then
  736. begin
  737. Message1(type_e_interface_type_expected,tt.def.typename);
  738. continue;
  739. end;
  740. handleimplementedinterface(tobjectdef(tt.def));
  741. end;
  742. end;
  743. procedure readinterfaceiid;
  744. var
  745. p : tnode;
  746. begin
  747. p:=comp_expr(true);
  748. if p.nodetype=stringconstn then
  749. begin
  750. stringdispose(aktclass.iidstr);
  751. aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
  752. p.free;
  753. aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
  754. if (classtype=odt_interfacecom) and not aktclass.isiidguidvalid then
  755. Message(parser_e_improper_guid_syntax);
  756. end
  757. else
  758. begin
  759. p.free;
  760. Message(cg_e_illegal_expression);
  761. end;
  762. end;
  763. procedure readparentclasses;
  764. var
  765. hp : tobjectdef;
  766. begin
  767. hp:=nil;
  768. { reads the parent class }
  769. if token=_LKLAMMER then
  770. begin
  771. consume(_LKLAMMER);
  772. id_type(tt,pattern,false);
  773. childof:=tobjectdef(tt.def);
  774. if (not assigned(childof)) or
  775. (childof.deftype<>objectdef) then
  776. begin
  777. if assigned(childof) then
  778. Message1(type_e_class_type_expected,childof.typename);
  779. childof:=nil;
  780. aktclass:=tobjectdef.create(classtype,n,nil);
  781. end
  782. else
  783. begin
  784. { a mix of class, interfaces, objects and cppclasses
  785. isn't allowed }
  786. case classtype of
  787. odt_class:
  788. if not(is_class(childof)) then
  789. begin
  790. if is_interface(childof) then
  791. begin
  792. { we insert the interface after the child
  793. is set, see below
  794. }
  795. hp:=childof;
  796. childof:=class_tobject;
  797. end
  798. else
  799. Message(parser_e_mix_of_classes_and_objects);
  800. end;
  801. odt_interfacecorba,
  802. odt_interfacecom:
  803. if not(is_interface(childof)) then
  804. Message(parser_e_mix_of_classes_and_objects);
  805. odt_cppclass:
  806. if not(is_cppclass(childof)) then
  807. Message(parser_e_mix_of_classes_and_objects);
  808. odt_object:
  809. if not(is_object(childof)) then
  810. Message(parser_e_mix_of_classes_and_objects);
  811. end;
  812. { the forward of the child must be resolved to get
  813. correct field addresses }
  814. if assigned(fd) then
  815. begin
  816. if (oo_is_forward in childof.objectoptions) then
  817. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  818. aktclass:=fd;
  819. { we must inherit several options !!
  820. this was missing !!
  821. all is now done in set_parent
  822. including symtable datasize setting PM }
  823. fd.set_parent(childof);
  824. end
  825. else
  826. aktclass:=tobjectdef.create(classtype,n,childof);
  827. if aktclass.objecttype=odt_class then
  828. begin
  829. if assigned(hp) then
  830. handleimplementedinterface(hp);
  831. readimplementedinterfaces;
  832. end;
  833. end;
  834. consume(_RKLAMMER);
  835. end
  836. { if no parent class, then a class get tobject as parent }
  837. else if classtype in [odt_class,odt_interfacecom] then
  838. setclassparent
  839. else
  840. aktclass:=tobjectdef.create(classtype,n,nil);
  841. { read GUID }
  842. if (classtype in [odt_interfacecom,odt_interfacecorba]) and
  843. try_to_consume(_LECKKLAMMER) then
  844. begin
  845. readinterfaceiid;
  846. consume(_RECKKLAMMER);
  847. end;
  848. end;
  849. procedure chkcpp;
  850. begin
  851. if is_cppclass(aktclass) then
  852. begin
  853. aktprocdef.proccalloption:=pocall_cppdecl;
  854. aktprocdef.setmangledname(
  855. target_info.Cprefix+aktprocdef.cplusplusmangledname);
  856. end;
  857. end;
  858. begin
  859. {Nowadays aktprocsym may already have a value, so we need to save
  860. it.}
  861. oldprocdef:=aktprocdef;
  862. oldprocsym:=aktprocsym;
  863. old_object_option:=current_object_option;
  864. { forward is resolved }
  865. if assigned(fd) then
  866. exclude(fd.objectoptions,oo_is_forward);
  867. { objects and class types can't be declared local }
  868. if not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) then
  869. Message(parser_e_no_local_objects);
  870. storetypecanbeforward:=typecanbeforward;
  871. { for tp7 don't allow forward types }
  872. if (m_tp7 in aktmodeswitches) then
  873. typecanbeforward:=false;
  874. if not(readobjecttype) then
  875. exit;
  876. { also anonym objects aren't allow (o : object a : longint; end;) }
  877. if n='' then
  878. Message(parser_f_no_anonym_objects);
  879. { read list of parent classes }
  880. readparentclasses;
  881. { default access is public }
  882. there_is_a_destructor:=false;
  883. current_object_option:=[sp_public];
  884. { set class flags and inherits published }
  885. setclassattributes;
  886. aktobjectdef:=aktclass;
  887. aktclass.symtable.next:=symtablestack;
  888. symtablestack:=aktclass.symtable;
  889. testcurobject:=1;
  890. curobjectname:=Upper(n);
  891. { new procinfo }
  892. oldprocinfo:=procinfo;
  893. procinfo:=cprocinfo.create;
  894. procinfo._class:=aktclass;
  895. { short class declaration ? }
  896. if (classtype<>odt_class) or (token<>_SEMICOLON) then
  897. begin
  898. { Parse componenten }
  899. repeat
  900. case token of
  901. _ID :
  902. begin
  903. case idtoken of
  904. _PRIVATE :
  905. begin
  906. if is_interface(aktclass) then
  907. Message(parser_e_no_access_specifier_in_interfaces);
  908. consume(_PRIVATE);
  909. current_object_option:=[sp_private];
  910. include(aktclass.objectoptions,oo_has_private);
  911. end;
  912. _PROTECTED :
  913. begin
  914. if is_interface(aktclass) then
  915. Message(parser_e_no_access_specifier_in_interfaces);
  916. consume(_PROTECTED);
  917. current_object_option:=[sp_protected];
  918. include(aktclass.objectoptions,oo_has_protected);
  919. end;
  920. _PUBLIC :
  921. begin
  922. if is_interface(aktclass) then
  923. Message(parser_e_no_access_specifier_in_interfaces);
  924. consume(_PUBLIC);
  925. current_object_option:=[sp_public];
  926. end;
  927. _PUBLISHED :
  928. begin
  929. { we've to check for a pushlished section in non- }
  930. { publishable classes later, if a real declaration }
  931. { this is the way, delphi does it }
  932. if is_interface(aktclass) then
  933. Message(parser_e_no_access_specifier_in_interfaces);
  934. consume(_PUBLISHED);
  935. current_object_option:=[sp_published];
  936. end;
  937. else
  938. begin
  939. if is_interface(aktclass) then
  940. Message(parser_e_no_vars_in_interfaces);
  941. if (sp_published in current_object_option) and
  942. not(oo_can_have_published in aktclass.objectoptions) then
  943. Message(parser_e_cant_have_published);
  944. read_var_decs(false,true,false);
  945. end;
  946. end;
  947. end;
  948. _PROPERTY :
  949. begin
  950. property_dec;
  951. end;
  952. _PROCEDURE,
  953. _FUNCTION,
  954. _CLASS :
  955. begin
  956. if (sp_published in current_object_option) and
  957. not(oo_can_have_published in aktclass.objectoptions) then
  958. Message(parser_e_cant_have_published);
  959. oldparse_only:=parse_only;
  960. parse_only:=true;
  961. parse_proc_dec;
  962. { this is for error recovery as well as forward }
  963. { interface mappings, i.e. mapping to a method }
  964. { which isn't declared yet }
  965. if assigned(aktprocsym) then
  966. begin
  967. parse_object_proc_directives(aktprocsym);
  968. { add definition to procsym }
  969. proc_add_definition(aktprocsym,aktprocdef);
  970. { add procdef options to objectdef options }
  971. if (po_msgint in aktprocdef.procoptions) then
  972. include(aktclass.objectoptions,oo_has_msgint);
  973. if (po_msgstr in aktprocdef.procoptions) then
  974. include(aktclass.objectoptions,oo_has_msgstr);
  975. if (po_virtualmethod in aktprocdef.procoptions) then
  976. include(aktclass.objectoptions,oo_has_virtual);
  977. chkcpp;
  978. end;
  979. parse_only:=oldparse_only;
  980. end;
  981. _CONSTRUCTOR :
  982. begin
  983. if (sp_published in current_object_option) and
  984. not(oo_can_have_published in aktclass.objectoptions) then
  985. Message(parser_e_cant_have_published);
  986. if not(sp_public in current_object_option) then
  987. Message(parser_w_constructor_should_be_public);
  988. if is_interface(aktclass) then
  989. Message(parser_e_no_con_des_in_interfaces);
  990. oldparse_only:=parse_only;
  991. parse_only:=true;
  992. constructor_head;
  993. parse_object_proc_directives(aktprocsym);
  994. { add definition to procsym }
  995. proc_add_definition(aktprocsym,aktprocdef);
  996. { add procdef options to objectdef options }
  997. if (po_virtualmethod in aktprocdef.procoptions) then
  998. include(aktclass.objectoptions,oo_has_virtual);
  999. chkcpp;
  1000. parse_only:=oldparse_only;
  1001. end;
  1002. _DESTRUCTOR :
  1003. begin
  1004. if (sp_published in current_object_option) and
  1005. not(oo_can_have_published in aktclass.objectoptions) then
  1006. Message(parser_e_cant_have_published);
  1007. if there_is_a_destructor then
  1008. Message(parser_n_only_one_destructor);
  1009. if is_interface(aktclass) then
  1010. Message(parser_e_no_con_des_in_interfaces);
  1011. if not(sp_public in current_object_option) then
  1012. Message(parser_w_destructor_should_be_public);
  1013. there_is_a_destructor:=true;
  1014. oldparse_only:=parse_only;
  1015. parse_only:=true;
  1016. destructor_head;
  1017. parse_object_proc_directives(aktprocsym);
  1018. { add definition to procsym }
  1019. proc_add_definition(aktprocsym,aktprocdef);
  1020. { add procdef options to objectdef options }
  1021. if (po_virtualmethod in aktprocdef.procoptions) then
  1022. include(aktclass.objectoptions,oo_has_virtual);
  1023. chkcpp;
  1024. parse_only:=oldparse_only;
  1025. end;
  1026. _END :
  1027. begin
  1028. consume(_END);
  1029. break;
  1030. end;
  1031. else
  1032. consume(_ID); { Give a ident expected message, like tp7 }
  1033. end;
  1034. until false;
  1035. end;
  1036. { generate vmt space if needed }
  1037. if not(oo_has_vmt in aktclass.objectoptions) and
  1038. (([oo_has_virtual,oo_has_constructor,oo_has_destructor]*aktclass.objectoptions<>[]) or
  1039. (classtype in [odt_class])
  1040. ) then
  1041. aktclass.insertvmt;
  1042. if is_interface(aktclass) then
  1043. setinterfacemethodoptions;
  1044. { reset }
  1045. testcurobject:=0;
  1046. curobjectname:='';
  1047. typecanbeforward:=storetypecanbeforward;
  1048. { restore old state }
  1049. symtablestack:=symtablestack.next;
  1050. aktobjectdef:=nil;
  1051. {Restore procinfo}
  1052. procinfo.free;
  1053. procinfo:=oldprocinfo;
  1054. {Restore the aktprocsym.}
  1055. aktprocsym:=oldprocsym;
  1056. aktprocdef:=oldprocdef;
  1057. current_object_option:=old_object_option;
  1058. object_dec:=aktclass;
  1059. end;
  1060. end.
  1061. {
  1062. $Log$
  1063. Revision 1.50 2002-09-03 16:26:26 daniel
  1064. * Make Tprocdef.defs protected
  1065. Revision 1.49 2002/08/17 09:23:38 florian
  1066. * first part of procinfo rewrite
  1067. Revision 1.48 2002/08/09 07:33:02 florian
  1068. * a couple of interface related fixes
  1069. Revision 1.47 2002/07/20 11:57:55 florian
  1070. * types.pas renamed to defbase.pas because D6 contains a types
  1071. unit so this would conflicts if D6 programms are compiled
  1072. + Willamette/SSE2 instructions to assembler added
  1073. Revision 1.46 2002/07/01 16:23:53 peter
  1074. * cg64 patch
  1075. * basics for currency
  1076. * asnode updates for class and interface (not finished)
  1077. Revision 1.45 2002/05/18 13:34:12 peter
  1078. * readded missing revisions
  1079. Revision 1.44 2002/05/16 19:46:42 carl
  1080. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1081. + try to fix temp allocation (still in ifdef)
  1082. + generic constructor calls
  1083. + start of tassembler / tmodulebase class cleanup
  1084. Revision 1.42 2002/05/12 16:53:08 peter
  1085. * moved entry and exitcode to ncgutil and cgobj
  1086. * foreach gets extra argument for passing local data to the
  1087. iterator function
  1088. * -CR checks also class typecasts at runtime by changing them
  1089. into as
  1090. * fixed compiler to cycle with the -CR option
  1091. * fixed stabs with elf writer, finally the global variables can
  1092. be watched
  1093. * removed a lot of routines from cga unit and replaced them by
  1094. calls to cgobj
  1095. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1096. u32bit then the other is typecasted also to u32bit without giving
  1097. a rangecheck warning/error.
  1098. * fixed pascal calling method with reversing also the high tree in
  1099. the parast, detected by tcalcst3 test
  1100. Revision 1.41 2002/04/21 19:02:04 peter
  1101. * removed newn and disposen nodes, the code is now directly
  1102. inlined from pexpr
  1103. * -an option that will write the secondpass nodes to the .s file, this
  1104. requires EXTDEBUG define to actually write the info
  1105. * fixed various internal errors and crashes due recent code changes
  1106. Revision 1.40 2002/04/19 15:46:02 peter
  1107. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  1108. in most cases and not written to the ppu
  1109. * add mangeledname_prefix() routine to generate the prefix of
  1110. manglednames depending on the current procedure, object and module
  1111. * removed static procprefix since the mangledname is now build only
  1112. on demand from tprocdef.mangledname
  1113. Revision 1.39 2002/04/04 19:06:00 peter
  1114. * removed unused units
  1115. * use tlocation.size in cg.a_*loc*() routines
  1116. Revision 1.38 2002/01/25 17:38:19 peter
  1117. * fixed default value for properties with index values
  1118. Revision 1.37 2002/01/24 18:25:48 peter
  1119. * implicit result variable generation for assembler routines
  1120. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  1121. Revision 1.36 2002/01/06 12:08:15 peter
  1122. * removed uauto from orddef, use new range_to_basetype generating
  1123. the correct ordinal type for a range
  1124. }