pdecobj.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Does object 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 pdecobj;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype,symtype,symdef;
  22. { parses a object declaration }
  23. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  24. implementation
  25. uses
  26. cutils,cclasses,
  27. globals,verbose,systems,tokens,
  28. symconst,symbase,symsym,
  29. node,nld,nmem,ncon,ncnv,ncal,
  30. scanner,
  31. pbase,pexpr,pdecsub,pdecvar,ptype
  32. ;
  33. const
  34. { Please leave this here, this module should NOT use
  35. these variables.
  36. Declaring it as string here results in an error when compiling (PFV) }
  37. current_procinfo = 'error';
  38. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  39. { this function parses an object or class declaration }
  40. var
  41. there_is_a_destructor : boolean;
  42. classtype : tobjectdeftype;
  43. childof : tobjectdef;
  44. aktclass : tobjectdef;
  45. function constructor_head:tprocdef;
  46. var
  47. pd : tprocdef;
  48. begin
  49. consume(_CONSTRUCTOR);
  50. { must be at same level as in implementation }
  51. parse_proc_head(aktclass,potype_constructor,pd);
  52. if not assigned(pd) then
  53. begin
  54. consume(_SEMICOLON);
  55. exit;
  56. end;
  57. if (cs_constructor_name in aktglobalswitches) and
  58. (pd.procsym.name<>'INIT') then
  59. Message(parser_e_constructorname_must_be_init);
  60. consume(_SEMICOLON);
  61. include(aktclass.objectoptions,oo_has_constructor);
  62. { Set return type, class constructors return the
  63. created instance, object constructors return boolean }
  64. if is_class(pd._class) then
  65. pd.rettype.setdef(pd._class)
  66. else
  67. pd.rettype:=booltype;
  68. constructor_head:=pd;
  69. end;
  70. procedure property_dec;
  71. var
  72. p : tpropertysym;
  73. begin
  74. { check for a class }
  75. if not((is_class_or_interface(aktclass)) or
  76. (not(m_tp7 in aktmodeswitches) and (is_object(aktclass)))) then
  77. Message(parser_e_syntax_error);
  78. consume(_PROPERTY);
  79. p:=read_property_dec(aktclass);
  80. consume(_SEMICOLON);
  81. if try_to_consume(_DEFAULT) then
  82. begin
  83. if oo_has_default_property in aktclass.objectoptions then
  84. message(parser_e_only_one_default_property);
  85. include(aktclass.objectoptions,oo_has_default_property);
  86. include(p.propoptions,ppo_defaultproperty);
  87. if not(ppo_hasparameters in p.propoptions) then
  88. message(parser_e_property_need_paras);
  89. consume(_SEMICOLON);
  90. end;
  91. { hint directives, these can be separated by semicolons here,
  92. that needs to be handled here with a loop (PFV) }
  93. while try_consume_hintdirective(p.symoptions) do
  94. Consume(_SEMICOLON);
  95. end;
  96. function destructor_head:tprocdef;
  97. var
  98. pd : tprocdef;
  99. begin
  100. consume(_DESTRUCTOR);
  101. parse_proc_head(aktclass,potype_destructor,pd);
  102. if not assigned(pd) then
  103. begin
  104. consume(_SEMICOLON);
  105. exit;
  106. end;
  107. if (cs_constructor_name in aktglobalswitches) and
  108. (pd.procsym.name<>'DONE') then
  109. Message(parser_e_destructorname_must_be_done);
  110. if not(pd.maxparacount=0) and
  111. (m_fpc in aktmodeswitches) then
  112. Message(parser_e_no_paras_for_destructor);
  113. consume(_SEMICOLON);
  114. include(aktclass.objectoptions,oo_has_destructor);
  115. { no return value }
  116. pd.rettype:=voidtype;
  117. destructor_head:=pd;
  118. end;
  119. var
  120. pcrd : tclassrefdef;
  121. tt : ttype;
  122. old_object_option : tsymoptions;
  123. oldparse_only : boolean;
  124. storetypecanbeforward : boolean;
  125. procedure setclassattributes;
  126. begin
  127. { publishable }
  128. if classtype in [odt_interfacecom,odt_class] then
  129. begin
  130. aktclass.objecttype:=classtype;
  131. if (cs_generate_rtti in aktlocalswitches) or
  132. (assigned(aktclass.childof) and
  133. (oo_can_have_published in aktclass.childof.objectoptions)) then
  134. begin
  135. include(aktclass.objectoptions,oo_can_have_published);
  136. { in "publishable" classes the default access type is published }
  137. current_object_option:=[sp_published];
  138. end;
  139. end;
  140. end;
  141. procedure setclassparent;
  142. begin
  143. if assigned(fd) then
  144. aktclass:=fd
  145. else
  146. aktclass:=tobjectdef.create(classtype,n,nil);
  147. { is the current class tobject? }
  148. { so you could define your own tobject }
  149. if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_class) and (upper(n)='TOBJECT') then
  150. class_tobject:=aktclass
  151. else if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  152. interface_iunknown:=aktclass
  153. else
  154. begin
  155. case classtype of
  156. odt_class:
  157. childof:=class_tobject;
  158. odt_interfacecom:
  159. childof:=interface_iunknown;
  160. end;
  161. if (oo_is_forward in childof.objectoptions) then
  162. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  163. aktclass.set_parent(childof);
  164. end;
  165. end;
  166. procedure setinterfacemethodoptions;
  167. var
  168. i: longint;
  169. defs: TIndexArray;
  170. pd: tdef;
  171. begin
  172. include(aktclass.objectoptions,oo_has_virtual);
  173. defs:=aktclass.symtable.defindex;
  174. for i:=1 to defs.count do
  175. begin
  176. pd:=tdef(defs.search(i));
  177. if pd.deftype=procdef then
  178. begin
  179. tprocdef(pd).extnumber:=aktclass.lastvtableindex;
  180. inc(aktclass.lastvtableindex);
  181. include(tprocdef(pd).procoptions,po_virtualmethod);
  182. tprocdef(pd).forwarddef:=false;
  183. end;
  184. end;
  185. end;
  186. function readobjecttype : boolean;
  187. begin
  188. readobjecttype:=true;
  189. { distinguish classes and objects }
  190. case token of
  191. _OBJECT:
  192. begin
  193. classtype:=odt_object;
  194. consume(_OBJECT)
  195. end;
  196. _CPPCLASS:
  197. begin
  198. classtype:=odt_cppclass;
  199. consume(_CPPCLASS);
  200. end;
  201. _INTERFACE:
  202. begin
  203. { need extra check here since interface is a keyword
  204. in all pascal modes }
  205. if not(m_class in aktmodeswitches) then
  206. Message(parser_f_need_objfpc_or_delphi_mode);
  207. if aktinterfacetype=it_interfacecom then
  208. classtype:=odt_interfacecom
  209. else {it_interfacecorba}
  210. classtype:=odt_interfacecorba;
  211. consume(_INTERFACE);
  212. { forward declaration }
  213. if not(assigned(fd)) and (token=_SEMICOLON) then
  214. begin
  215. { also anonym objects aren't allow (o : object a : longint; end;) }
  216. if n='' then
  217. Message(parser_f_no_anonym_objects);
  218. aktclass:=tobjectdef.create(classtype,n,nil);
  219. if (cs_compilesystem in aktmoduleswitches) and
  220. (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  221. interface_iunknown:=aktclass;
  222. include(aktclass.objectoptions,oo_is_forward);
  223. object_dec:=aktclass;
  224. typecanbeforward:=storetypecanbeforward;
  225. readobjecttype:=false;
  226. exit;
  227. end;
  228. end;
  229. _CLASS:
  230. begin
  231. classtype:=odt_class;
  232. consume(_CLASS);
  233. if not(assigned(fd)) and
  234. (token=_OF) and
  235. { Delphi only allows class of in type blocks.
  236. Note that when parsing the type of a variable declaration
  237. the blocktype is bt_type so the check for typecanbeforward
  238. is also necessary (PFV) }
  239. (((block_type=bt_type) and typecanbeforward) or
  240. not(m_delphi in aktmodeswitches)) then
  241. begin
  242. { a hack, but it's easy to handle }
  243. { class reference type }
  244. consume(_OF);
  245. single_type(tt,typecanbeforward);
  246. { accept hp1, if is a forward def or a class }
  247. if (tt.def.deftype=forwarddef) or
  248. is_class(tt.def) then
  249. begin
  250. pcrd:=tclassrefdef.create(tt);
  251. object_dec:=pcrd;
  252. end
  253. else
  254. begin
  255. object_dec:=generrortype.def;
  256. Message1(type_e_class_type_expected,generrortype.def.typename);
  257. end;
  258. typecanbeforward:=storetypecanbeforward;
  259. readobjecttype:=false;
  260. exit;
  261. end
  262. { forward class }
  263. else if not(assigned(fd)) and (token=_SEMICOLON) then
  264. begin
  265. { also anonym objects aren't allow (o : object a : longint; end;) }
  266. if n='' then
  267. Message(parser_f_no_anonym_objects);
  268. aktclass:=tobjectdef.create(odt_class,n,nil);
  269. if (cs_compilesystem in aktmoduleswitches) and (upper(n)='TOBJECT') then
  270. class_tobject:=aktclass;
  271. aktclass.objecttype:=odt_class;
  272. include(aktclass.objectoptions,oo_is_forward);
  273. { all classes must have a vmt !! at offset zero }
  274. if not(oo_has_vmt in aktclass.objectoptions) then
  275. aktclass.insertvmt;
  276. object_dec:=aktclass;
  277. typecanbeforward:=storetypecanbeforward;
  278. readobjecttype:=false;
  279. exit;
  280. end;
  281. end;
  282. else
  283. begin
  284. classtype:=odt_class; { this is error but try to recover }
  285. consume(_OBJECT);
  286. end;
  287. end;
  288. end;
  289. procedure handleimplementedinterface(implintf : tobjectdef);
  290. begin
  291. if not is_interface(implintf) then
  292. begin
  293. Message1(type_e_interface_type_expected,implintf.typename);
  294. exit;
  295. end;
  296. if aktclass.implementedinterfaces.searchintf(implintf)<>-1 then
  297. Message1(sym_e_duplicate_id,implintf.name)
  298. else
  299. begin
  300. { allocate and prepare the GUID only if the class
  301. implements some interfaces.
  302. }
  303. if aktclass.implementedinterfaces.count = 0 then
  304. aktclass.prepareguid;
  305. aktclass.implementedinterfaces.addintf(implintf);
  306. end;
  307. end;
  308. procedure readimplementedinterfaces;
  309. var
  310. tt : ttype;
  311. begin
  312. while try_to_consume(_COMMA) do
  313. begin
  314. id_type(tt,false);
  315. if (tt.def.deftype<>objectdef) then
  316. begin
  317. Message1(type_e_interface_type_expected,tt.def.typename);
  318. continue;
  319. end;
  320. handleimplementedinterface(tobjectdef(tt.def));
  321. end;
  322. end;
  323. procedure readinterfaceiid;
  324. var
  325. p : tnode;
  326. valid : boolean;
  327. begin
  328. p:=comp_expr(true);
  329. if p.nodetype=stringconstn then
  330. begin
  331. stringdispose(aktclass.iidstr);
  332. aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
  333. p.free;
  334. valid:=string2guid(aktclass.iidstr^,aktclass.iidguid^);
  335. if (classtype=odt_interfacecom) and not assigned(aktclass.iidguid) and not valid then
  336. Message(parser_e_improper_guid_syntax);
  337. end
  338. else
  339. begin
  340. p.free;
  341. Message(parser_e_illegal_expression);
  342. end;
  343. end;
  344. procedure readparentclasses;
  345. var
  346. hp : tobjectdef;
  347. begin
  348. hp:=nil;
  349. { reads the parent class }
  350. if try_to_consume(_LKLAMMER) then
  351. begin
  352. id_type(tt,false);
  353. childof:=tobjectdef(tt.def);
  354. if (not assigned(childof)) or
  355. (childof.deftype<>objectdef) then
  356. begin
  357. if assigned(childof) then
  358. Message1(type_e_class_type_expected,childof.typename);
  359. childof:=nil;
  360. aktclass:=tobjectdef.create(classtype,n,nil);
  361. end
  362. else
  363. begin
  364. { a mix of class, interfaces, objects and cppclasses
  365. isn't allowed }
  366. case classtype of
  367. odt_class:
  368. if not(is_class(childof)) then
  369. begin
  370. if is_interface(childof) then
  371. begin
  372. { we insert the interface after the child
  373. is set, see below
  374. }
  375. hp:=childof;
  376. childof:=class_tobject;
  377. end
  378. else
  379. Message(parser_e_mix_of_classes_and_objects);
  380. end;
  381. odt_interfacecorba,
  382. odt_interfacecom:
  383. if not(is_interface(childof)) then
  384. Message(parser_e_mix_of_classes_and_objects);
  385. odt_cppclass:
  386. if not(is_cppclass(childof)) then
  387. Message(parser_e_mix_of_classes_and_objects);
  388. odt_object:
  389. if not(is_object(childof)) then
  390. Message(parser_e_mix_of_classes_and_objects);
  391. end;
  392. { the forward of the child must be resolved to get
  393. correct field addresses }
  394. if assigned(fd) then
  395. begin
  396. if (oo_is_forward in childof.objectoptions) then
  397. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  398. aktclass:=fd;
  399. { we must inherit several options !!
  400. this was missing !!
  401. all is now done in set_parent
  402. including symtable datasize setting PM }
  403. fd.set_parent(childof);
  404. end
  405. else
  406. aktclass:=tobjectdef.create(classtype,n,childof);
  407. if aktclass.objecttype=odt_class then
  408. begin
  409. if assigned(hp) then
  410. handleimplementedinterface(hp);
  411. readimplementedinterfaces;
  412. end;
  413. end;
  414. consume(_RKLAMMER);
  415. end
  416. { if no parent class, then a class get tobject as parent }
  417. else if classtype in [odt_class,odt_interfacecom] then
  418. setclassparent
  419. else
  420. aktclass:=tobjectdef.create(classtype,n,nil);
  421. { read GUID }
  422. if (classtype in [odt_interfacecom,odt_interfacecorba]) and
  423. try_to_consume(_LECKKLAMMER) then
  424. begin
  425. readinterfaceiid;
  426. consume(_RECKKLAMMER);
  427. end;
  428. end;
  429. procedure chkcpp(pd:tprocdef);
  430. begin
  431. if is_cppclass(pd._class) then
  432. begin
  433. pd.proccalloption:=pocall_cppdecl;
  434. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  435. end;
  436. end;
  437. var
  438. pd : tprocdef;
  439. dummysymoptions : tsymoptions;
  440. begin
  441. old_object_option:=current_object_option;
  442. { forward is resolved }
  443. if assigned(fd) then
  444. exclude(fd.objectoptions,oo_is_forward);
  445. { objects and class types can't be declared local }
  446. if not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) then
  447. Message(parser_e_no_local_objects);
  448. storetypecanbeforward:=typecanbeforward;
  449. { for tp7 don't allow forward types }
  450. if (m_tp7 in aktmodeswitches) then
  451. typecanbeforward:=false;
  452. if not(readobjecttype) then
  453. exit;
  454. { also anonym objects aren't allow (o : object a : longint; end;) }
  455. if n='' then
  456. Message(parser_f_no_anonym_objects);
  457. { read list of parent classes }
  458. readparentclasses;
  459. { default access is public }
  460. there_is_a_destructor:=false;
  461. current_object_option:=[sp_public];
  462. { set class flags and inherits published }
  463. setclassattributes;
  464. aktobjectdef:=aktclass;
  465. aktclass.symtable.next:=symtablestack;
  466. symtablestack:=aktclass.symtable;
  467. testcurobject:=1;
  468. curobjectname:=Upper(n);
  469. { short class declaration ? }
  470. if (classtype<>odt_class) or (token<>_SEMICOLON) then
  471. begin
  472. { Parse componenten }
  473. repeat
  474. case token of
  475. _ID :
  476. begin
  477. case idtoken of
  478. _PRIVATE :
  479. begin
  480. if is_interface(aktclass) then
  481. Message(parser_e_no_access_specifier_in_interfaces);
  482. consume(_PRIVATE);
  483. current_object_option:=[sp_private];
  484. include(aktclass.objectoptions,oo_has_private);
  485. end;
  486. _PROTECTED :
  487. begin
  488. if is_interface(aktclass) then
  489. Message(parser_e_no_access_specifier_in_interfaces);
  490. consume(_PROTECTED);
  491. current_object_option:=[sp_protected];
  492. include(aktclass.objectoptions,oo_has_protected);
  493. end;
  494. _PUBLIC :
  495. begin
  496. if is_interface(aktclass) then
  497. Message(parser_e_no_access_specifier_in_interfaces);
  498. consume(_PUBLIC);
  499. current_object_option:=[sp_public];
  500. end;
  501. _PUBLISHED :
  502. begin
  503. { we've to check for a pushlished section in non- }
  504. { publishable classes later, if a real declaration }
  505. { this is the way, delphi does it }
  506. if is_interface(aktclass) then
  507. Message(parser_e_no_access_specifier_in_interfaces);
  508. consume(_PUBLISHED);
  509. current_object_option:=[sp_published];
  510. end;
  511. _STRICT :
  512. begin
  513. if is_interface(aktclass) then
  514. Message(parser_e_no_access_specifier_in_interfaces);
  515. consume(_STRICT);
  516. if token=_ID then
  517. begin
  518. case idtoken of
  519. _PRIVATE:
  520. begin
  521. consume(_PRIVATE);
  522. current_object_option:=[sp_strictprivate];
  523. include(aktclass.objectoptions,oo_has_strictprivate);
  524. end;
  525. _PROTECTED:
  526. begin
  527. consume(_PROTECTED);
  528. current_object_option:=[sp_strictprotected];
  529. include(aktclass.objectoptions,oo_has_strictprotected);
  530. end;
  531. else
  532. message(parser_e_protected_or_private_expected);
  533. end;
  534. end
  535. else
  536. message(parser_e_protected_or_private_expected);
  537. end;
  538. else
  539. begin
  540. if is_interface(aktclass) then
  541. Message(parser_e_no_vars_in_interfaces);
  542. if (sp_published in current_object_option) and
  543. not(oo_can_have_published in aktclass.objectoptions) then
  544. Message(parser_e_cant_have_published);
  545. read_var_decs([vd_object]);
  546. end;
  547. end;
  548. end;
  549. _PROPERTY :
  550. begin
  551. property_dec;
  552. end;
  553. _PROCEDURE,
  554. _FUNCTION,
  555. _CLASS :
  556. begin
  557. if (sp_published in current_object_option) and
  558. not(oo_can_have_published in aktclass.objectoptions) then
  559. Message(parser_e_cant_have_published);
  560. oldparse_only:=parse_only;
  561. parse_only:=true;
  562. pd:=parse_proc_dec(aktclass);
  563. { this is for error recovery as well as forward }
  564. { interface mappings, i.e. mapping to a method }
  565. { which isn't declared yet }
  566. if assigned(pd) then
  567. begin
  568. parse_object_proc_directives(pd);
  569. { all Macintosh Object Pascal methods are virtual. }
  570. { this can't be a class method, because macpas mode }
  571. { has no m_class }
  572. if (m_mac in aktmodeswitches) then
  573. include(pd.procoptions,po_virtualmethod);
  574. handle_calling_convention(pd);
  575. { add definition to procsym }
  576. proc_add_definition(pd);
  577. { add procdef options to objectdef options }
  578. if (po_msgint in pd.procoptions) then
  579. include(aktclass.objectoptions,oo_has_msgint);
  580. if (po_msgstr in pd.procoptions) then
  581. include(aktclass.objectoptions,oo_has_msgstr);
  582. if (po_virtualmethod in pd.procoptions) then
  583. include(aktclass.objectoptions,oo_has_virtual);
  584. chkcpp(pd);
  585. end;
  586. { Support hint directives }
  587. dummysymoptions:=[];
  588. while try_consume_hintdirective(dummysymoptions) do
  589. Consume(_SEMICOLON);
  590. if assigned(pd) then
  591. pd.symoptions:=pd.symoptions+dummysymoptions;
  592. parse_only:=oldparse_only;
  593. end;
  594. _CONSTRUCTOR :
  595. begin
  596. if (sp_published in current_object_option) and
  597. not(oo_can_have_published in aktclass.objectoptions) then
  598. Message(parser_e_cant_have_published);
  599. if not(sp_public in current_object_option) and
  600. not(sp_published in current_object_option) then
  601. Message(parser_w_constructor_should_be_public);
  602. if is_interface(aktclass) then
  603. Message(parser_e_no_con_des_in_interfaces);
  604. oldparse_only:=parse_only;
  605. parse_only:=true;
  606. pd:=constructor_head;
  607. parse_object_proc_directives(pd);
  608. handle_calling_convention(pd);
  609. { add definition to procsym }
  610. proc_add_definition(pd);
  611. { add procdef options to objectdef options }
  612. if (po_virtualmethod in pd.procoptions) then
  613. include(aktclass.objectoptions,oo_has_virtual);
  614. chkcpp(pd);
  615. { Support hint directives }
  616. dummysymoptions:=[];
  617. while try_consume_hintdirective(dummysymoptions) do
  618. Consume(_SEMICOLON);
  619. if assigned(pd) then
  620. pd.symoptions:=pd.symoptions+dummysymoptions;
  621. parse_only:=oldparse_only;
  622. end;
  623. _DESTRUCTOR :
  624. begin
  625. if (sp_published in current_object_option) and
  626. not(oo_can_have_published in aktclass.objectoptions) then
  627. Message(parser_e_cant_have_published);
  628. if there_is_a_destructor then
  629. Message(parser_n_only_one_destructor);
  630. if is_interface(aktclass) then
  631. Message(parser_e_no_con_des_in_interfaces);
  632. if not(sp_public in current_object_option) then
  633. Message(parser_w_destructor_should_be_public);
  634. there_is_a_destructor:=true;
  635. oldparse_only:=parse_only;
  636. parse_only:=true;
  637. pd:=destructor_head;
  638. parse_object_proc_directives(pd);
  639. handle_calling_convention(pd);
  640. { add definition to procsym }
  641. proc_add_definition(pd);
  642. { add procdef options to objectdef options }
  643. if (po_virtualmethod in pd.procoptions) then
  644. include(aktclass.objectoptions,oo_has_virtual);
  645. chkcpp(pd);
  646. { Support hint directives }
  647. dummysymoptions:=[];
  648. while try_consume_hintdirective(dummysymoptions) do
  649. Consume(_SEMICOLON);
  650. if assigned(pd) then
  651. pd.symoptions:=pd.symoptions+dummysymoptions;
  652. parse_only:=oldparse_only;
  653. end;
  654. _END :
  655. begin
  656. consume(_END);
  657. break;
  658. end;
  659. else
  660. consume(_ID); { Give a ident expected message, like tp7 }
  661. end;
  662. until false;
  663. end;
  664. { generate vmt space if needed }
  665. if not(oo_has_vmt in aktclass.objectoptions) and
  666. (([oo_has_virtual,oo_has_constructor,oo_has_destructor]*aktclass.objectoptions<>[]) or
  667. (classtype in [odt_class])
  668. ) then
  669. aktclass.insertvmt;
  670. if is_interface(aktclass) then
  671. setinterfacemethodoptions;
  672. { reset }
  673. testcurobject:=0;
  674. curobjectname:='';
  675. typecanbeforward:=storetypecanbeforward;
  676. { restore old state }
  677. symtablestack:=symtablestack.next;
  678. aktobjectdef:=nil;
  679. current_object_option:=old_object_option;
  680. object_dec:=aktclass;
  681. end;
  682. end.