pdecobj.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  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. _DISPINTERFACE:
  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. classtype:=odt_dispinterface;
  208. consume(_DISPINTERFACE);
  209. { no forward declaration }
  210. if not(assigned(fd)) and (token=_SEMICOLON) then
  211. begin
  212. { also anonym objects aren't allow (o : object a : longint; end;) }
  213. if n='' then
  214. Message(parser_f_no_anonym_objects);
  215. aktclass:=tobjectdef.create(classtype,n,nil);
  216. include(aktclass.objectoptions,oo_is_forward);
  217. object_dec:=aktclass;
  218. typecanbeforward:=storetypecanbeforward;
  219. readobjecttype:=false;
  220. exit;
  221. end;
  222. end;
  223. _INTERFACE:
  224. begin
  225. { need extra check here since interface is a keyword
  226. in all pascal modes }
  227. if not(m_class in aktmodeswitches) then
  228. Message(parser_f_need_objfpc_or_delphi_mode);
  229. if aktinterfacetype=it_interfacecom then
  230. classtype:=odt_interfacecom
  231. else {it_interfacecorba}
  232. classtype:=odt_interfacecorba;
  233. consume(_INTERFACE);
  234. { forward declaration }
  235. if not(assigned(fd)) and (token=_SEMICOLON) then
  236. begin
  237. { also anonym objects aren't allow (o : object a : longint; end;) }
  238. if n='' then
  239. Message(parser_f_no_anonym_objects);
  240. aktclass:=tobjectdef.create(classtype,n,nil);
  241. if (cs_compilesystem in aktmoduleswitches) and
  242. (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  243. interface_iunknown:=aktclass;
  244. include(aktclass.objectoptions,oo_is_forward);
  245. object_dec:=aktclass;
  246. typecanbeforward:=storetypecanbeforward;
  247. readobjecttype:=false;
  248. exit;
  249. end;
  250. end;
  251. _CLASS:
  252. begin
  253. classtype:=odt_class;
  254. consume(_CLASS);
  255. if not(assigned(fd)) and
  256. (token=_OF) and
  257. { Delphi only allows class of in type blocks.
  258. Note that when parsing the type of a variable declaration
  259. the blocktype is bt_type so the check for typecanbeforward
  260. is also necessary (PFV) }
  261. (((block_type=bt_type) and typecanbeforward) or
  262. not(m_delphi in aktmodeswitches)) then
  263. begin
  264. { a hack, but it's easy to handle }
  265. { class reference type }
  266. consume(_OF);
  267. single_type(tt,typecanbeforward);
  268. { accept hp1, if is a forward def or a class }
  269. if (tt.def.deftype=forwarddef) or
  270. is_class(tt.def) then
  271. begin
  272. pcrd:=tclassrefdef.create(tt);
  273. object_dec:=pcrd;
  274. end
  275. else
  276. begin
  277. object_dec:=generrortype.def;
  278. Message1(type_e_class_type_expected,generrortype.def.typename);
  279. end;
  280. typecanbeforward:=storetypecanbeforward;
  281. readobjecttype:=false;
  282. exit;
  283. end
  284. { forward class }
  285. else if not(assigned(fd)) and (token=_SEMICOLON) then
  286. begin
  287. { also anonym objects aren't allow (o : object a : longint; end;) }
  288. if n='' then
  289. Message(parser_f_no_anonym_objects);
  290. aktclass:=tobjectdef.create(odt_class,n,nil);
  291. if (cs_compilesystem in aktmoduleswitches) and (upper(n)='TOBJECT') then
  292. class_tobject:=aktclass;
  293. aktclass.objecttype:=odt_class;
  294. include(aktclass.objectoptions,oo_is_forward);
  295. { all classes must have a vmt !! at offset zero }
  296. if not(oo_has_vmt in aktclass.objectoptions) then
  297. aktclass.insertvmt;
  298. object_dec:=aktclass;
  299. typecanbeforward:=storetypecanbeforward;
  300. readobjecttype:=false;
  301. exit;
  302. end;
  303. end;
  304. else
  305. begin
  306. classtype:=odt_class; { this is error but try to recover }
  307. consume(_OBJECT);
  308. end;
  309. end;
  310. end;
  311. procedure handleimplementedinterface(implintf : tobjectdef);
  312. begin
  313. if not is_interface(implintf) then
  314. begin
  315. Message1(type_e_interface_type_expected,implintf.typename);
  316. exit;
  317. end;
  318. if aktclass.implementedinterfaces.searchintf(implintf)<>-1 then
  319. Message1(sym_e_duplicate_id,implintf.name)
  320. else
  321. begin
  322. { allocate and prepare the GUID only if the class
  323. implements some interfaces.
  324. }
  325. if aktclass.implementedinterfaces.count = 0 then
  326. aktclass.prepareguid;
  327. aktclass.implementedinterfaces.addintf(implintf);
  328. end;
  329. end;
  330. procedure readimplementedinterfaces;
  331. var
  332. tt : ttype;
  333. begin
  334. while try_to_consume(_COMMA) do
  335. begin
  336. id_type(tt,false);
  337. if (tt.def.deftype<>objectdef) then
  338. begin
  339. Message1(type_e_interface_type_expected,tt.def.typename);
  340. continue;
  341. end;
  342. handleimplementedinterface(tobjectdef(tt.def));
  343. end;
  344. end;
  345. procedure readinterfaceiid;
  346. var
  347. p : tnode;
  348. valid : boolean;
  349. begin
  350. p:=comp_expr(true);
  351. if p.nodetype=stringconstn then
  352. begin
  353. stringdispose(aktclass.iidstr);
  354. aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
  355. p.free;
  356. valid:=string2guid(aktclass.iidstr^,aktclass.iidguid^);
  357. if (classtype=odt_interfacecom) and not assigned(aktclass.iidguid) and not valid then
  358. Message(parser_e_improper_guid_syntax);
  359. end
  360. else
  361. begin
  362. p.free;
  363. Message(parser_e_illegal_expression);
  364. end;
  365. end;
  366. procedure readparentclasses;
  367. var
  368. hp : tobjectdef;
  369. begin
  370. hp:=nil;
  371. { reads the parent class }
  372. if try_to_consume(_LKLAMMER) then
  373. begin
  374. id_type(tt,false);
  375. childof:=tobjectdef(tt.def);
  376. if (not assigned(childof)) or
  377. (childof.deftype<>objectdef) then
  378. begin
  379. if assigned(childof) then
  380. Message1(type_e_class_type_expected,childof.typename);
  381. childof:=nil;
  382. aktclass:=tobjectdef.create(classtype,n,nil);
  383. end
  384. else
  385. begin
  386. { a mix of class, interfaces, objects and cppclasses
  387. isn't allowed }
  388. case classtype of
  389. odt_class:
  390. if not(is_class(childof)) then
  391. begin
  392. if is_interface(childof) then
  393. begin
  394. { we insert the interface after the child
  395. is set, see below
  396. }
  397. hp:=childof;
  398. childof:=class_tobject;
  399. end
  400. else
  401. Message(parser_e_mix_of_classes_and_objects);
  402. end;
  403. odt_interfacecorba,
  404. odt_interfacecom:
  405. if not(is_interface(childof)) then
  406. Message(parser_e_mix_of_classes_and_objects);
  407. odt_cppclass:
  408. if not(is_cppclass(childof)) then
  409. Message(parser_e_mix_of_classes_and_objects);
  410. odt_object:
  411. if not(is_object(childof)) then
  412. Message(parser_e_mix_of_classes_and_objects);
  413. odt_dispinterface:
  414. Message(parser_e_dispinterface_cant_have_parent);
  415. end;
  416. { the forward of the child must be resolved to get
  417. correct field addresses }
  418. if assigned(fd) then
  419. begin
  420. if (oo_is_forward in childof.objectoptions) then
  421. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  422. aktclass:=fd;
  423. { we must inherit several options !!
  424. this was missing !!
  425. all is now done in set_parent
  426. including symtable datasize setting PM }
  427. fd.set_parent(childof);
  428. end
  429. else
  430. aktclass:=tobjectdef.create(classtype,n,childof);
  431. if aktclass.objecttype=odt_class then
  432. begin
  433. if assigned(hp) then
  434. handleimplementedinterface(hp);
  435. readimplementedinterfaces;
  436. end;
  437. end;
  438. consume(_RKLAMMER);
  439. end
  440. { if no parent class, then a class get tobject as parent }
  441. else if classtype in [odt_class,odt_interfacecom] then
  442. setclassparent
  443. else
  444. aktclass:=tobjectdef.create(classtype,n,nil);
  445. { read GUID }
  446. if (classtype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) and
  447. try_to_consume(_LECKKLAMMER) then
  448. begin
  449. readinterfaceiid;
  450. consume(_RECKKLAMMER);
  451. end
  452. else if (classtype=odt_dispinterface) then
  453. message(parser_e_dispinterface_needs_a_guid);
  454. end;
  455. procedure chkcpp(pd:tprocdef);
  456. begin
  457. if is_cppclass(pd._class) then
  458. begin
  459. pd.proccalloption:=pocall_cppdecl;
  460. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  461. end;
  462. end;
  463. var
  464. pd : tprocdef;
  465. dummysymoptions : tsymoptions;
  466. begin
  467. old_object_option:=current_object_option;
  468. { forward is resolved }
  469. if assigned(fd) then
  470. exclude(fd.objectoptions,oo_is_forward);
  471. { objects and class types can't be declared local }
  472. if not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) then
  473. Message(parser_e_no_local_objects);
  474. storetypecanbeforward:=typecanbeforward;
  475. { for tp7 don't allow forward types }
  476. if (m_tp7 in aktmodeswitches) then
  477. typecanbeforward:=false;
  478. if not(readobjecttype) then
  479. exit;
  480. { also anonym objects aren't allow (o : object a : longint; end;) }
  481. if n='' then
  482. Message(parser_f_no_anonym_objects);
  483. { read list of parent classes }
  484. readparentclasses;
  485. { default access is public }
  486. there_is_a_destructor:=false;
  487. current_object_option:=[sp_public];
  488. { set class flags and inherits published }
  489. setclassattributes;
  490. aktobjectdef:=aktclass;
  491. aktclass.symtable.next:=symtablestack;
  492. symtablestack:=aktclass.symtable;
  493. testcurobject:=1;
  494. curobjectname:=Upper(n);
  495. { short class declaration ? }
  496. if (classtype<>odt_class) or (token<>_SEMICOLON) then
  497. begin
  498. { Parse componenten }
  499. repeat
  500. case token of
  501. _ID :
  502. begin
  503. case idtoken of
  504. _PRIVATE :
  505. begin
  506. if is_interface(aktclass) then
  507. Message(parser_e_no_access_specifier_in_interfaces);
  508. consume(_PRIVATE);
  509. current_object_option:=[sp_private];
  510. include(aktclass.objectoptions,oo_has_private);
  511. end;
  512. _PROTECTED :
  513. begin
  514. if is_interface(aktclass) then
  515. Message(parser_e_no_access_specifier_in_interfaces);
  516. consume(_PROTECTED);
  517. current_object_option:=[sp_protected];
  518. include(aktclass.objectoptions,oo_has_protected);
  519. end;
  520. _PUBLIC :
  521. begin
  522. if is_interface(aktclass) then
  523. Message(parser_e_no_access_specifier_in_interfaces);
  524. consume(_PUBLIC);
  525. current_object_option:=[sp_public];
  526. end;
  527. _PUBLISHED :
  528. begin
  529. { we've to check for a pushlished section in non- }
  530. { publishable classes later, if a real declaration }
  531. { this is the way, delphi does it }
  532. if is_interface(aktclass) then
  533. Message(parser_e_no_access_specifier_in_interfaces);
  534. consume(_PUBLISHED);
  535. current_object_option:=[sp_published];
  536. end;
  537. _STRICT :
  538. begin
  539. if is_interface(aktclass) then
  540. Message(parser_e_no_access_specifier_in_interfaces);
  541. consume(_STRICT);
  542. if token=_ID then
  543. begin
  544. case idtoken of
  545. _PRIVATE:
  546. begin
  547. consume(_PRIVATE);
  548. current_object_option:=[sp_strictprivate];
  549. include(aktclass.objectoptions,oo_has_strictprivate);
  550. end;
  551. _PROTECTED:
  552. begin
  553. consume(_PROTECTED);
  554. current_object_option:=[sp_strictprotected];
  555. include(aktclass.objectoptions,oo_has_strictprotected);
  556. end;
  557. else
  558. message(parser_e_protected_or_private_expected);
  559. end;
  560. end
  561. else
  562. message(parser_e_protected_or_private_expected);
  563. end;
  564. else
  565. begin
  566. if is_interface(aktclass) then
  567. Message(parser_e_no_vars_in_interfaces);
  568. if (sp_published in current_object_option) and
  569. not(oo_can_have_published in aktclass.objectoptions) then
  570. Message(parser_e_cant_have_published);
  571. read_var_decs([vd_object]);
  572. end;
  573. end;
  574. end;
  575. _PROPERTY :
  576. begin
  577. property_dec;
  578. end;
  579. _PROCEDURE,
  580. _FUNCTION,
  581. _CLASS :
  582. begin
  583. if (sp_published in current_object_option) and
  584. not(oo_can_have_published in aktclass.objectoptions) then
  585. Message(parser_e_cant_have_published);
  586. oldparse_only:=parse_only;
  587. parse_only:=true;
  588. pd:=parse_proc_dec(aktclass);
  589. { this is for error recovery as well as forward }
  590. { interface mappings, i.e. mapping to a method }
  591. { which isn't declared yet }
  592. if assigned(pd) then
  593. begin
  594. parse_object_proc_directives(pd);
  595. { all Macintosh Object Pascal methods are virtual. }
  596. { this can't be a class method, because macpas mode }
  597. { has no m_class }
  598. if (m_mac in aktmodeswitches) then
  599. include(pd.procoptions,po_virtualmethod);
  600. handle_calling_convention(pd);
  601. { add definition to procsym }
  602. proc_add_definition(pd);
  603. { add procdef options to objectdef options }
  604. if (po_msgint in pd.procoptions) then
  605. include(aktclass.objectoptions,oo_has_msgint);
  606. if (po_msgstr in pd.procoptions) then
  607. include(aktclass.objectoptions,oo_has_msgstr);
  608. if (po_virtualmethod in pd.procoptions) then
  609. include(aktclass.objectoptions,oo_has_virtual);
  610. chkcpp(pd);
  611. end;
  612. { Support hint directives }
  613. dummysymoptions:=[];
  614. while try_consume_hintdirective(dummysymoptions) do
  615. Consume(_SEMICOLON);
  616. if assigned(pd) then
  617. pd.symoptions:=pd.symoptions+dummysymoptions;
  618. parse_only:=oldparse_only;
  619. end;
  620. _CONSTRUCTOR :
  621. begin
  622. if (sp_published in current_object_option) and
  623. not(oo_can_have_published in aktclass.objectoptions) then
  624. Message(parser_e_cant_have_published);
  625. if not(sp_public in current_object_option) and
  626. not(sp_published in current_object_option) then
  627. Message(parser_w_constructor_should_be_public);
  628. if is_interface(aktclass) then
  629. Message(parser_e_no_con_des_in_interfaces);
  630. oldparse_only:=parse_only;
  631. parse_only:=true;
  632. pd:=constructor_head;
  633. parse_object_proc_directives(pd);
  634. handle_calling_convention(pd);
  635. { add definition to procsym }
  636. proc_add_definition(pd);
  637. { add procdef options to objectdef options }
  638. if (po_virtualmethod in pd.procoptions) then
  639. include(aktclass.objectoptions,oo_has_virtual);
  640. chkcpp(pd);
  641. { Support hint directives }
  642. dummysymoptions:=[];
  643. while try_consume_hintdirective(dummysymoptions) do
  644. Consume(_SEMICOLON);
  645. if assigned(pd) then
  646. pd.symoptions:=pd.symoptions+dummysymoptions;
  647. parse_only:=oldparse_only;
  648. end;
  649. _DESTRUCTOR :
  650. begin
  651. if (sp_published in current_object_option) and
  652. not(oo_can_have_published in aktclass.objectoptions) then
  653. Message(parser_e_cant_have_published);
  654. if there_is_a_destructor then
  655. Message(parser_n_only_one_destructor);
  656. if is_interface(aktclass) then
  657. Message(parser_e_no_con_des_in_interfaces);
  658. if not(sp_public in current_object_option) then
  659. Message(parser_w_destructor_should_be_public);
  660. there_is_a_destructor:=true;
  661. oldparse_only:=parse_only;
  662. parse_only:=true;
  663. pd:=destructor_head;
  664. parse_object_proc_directives(pd);
  665. handle_calling_convention(pd);
  666. { add definition to procsym }
  667. proc_add_definition(pd);
  668. { add procdef options to objectdef options }
  669. if (po_virtualmethod in pd.procoptions) then
  670. include(aktclass.objectoptions,oo_has_virtual);
  671. chkcpp(pd);
  672. { Support hint directives }
  673. dummysymoptions:=[];
  674. while try_consume_hintdirective(dummysymoptions) do
  675. Consume(_SEMICOLON);
  676. if assigned(pd) then
  677. pd.symoptions:=pd.symoptions+dummysymoptions;
  678. parse_only:=oldparse_only;
  679. end;
  680. _END :
  681. begin
  682. consume(_END);
  683. break;
  684. end;
  685. else
  686. consume(_ID); { Give a ident expected message, like tp7 }
  687. end;
  688. until false;
  689. end;
  690. { generate vmt space if needed }
  691. if not(oo_has_vmt in aktclass.objectoptions) and
  692. (([oo_has_virtual,oo_has_constructor,oo_has_destructor]*aktclass.objectoptions<>[]) or
  693. (classtype in [odt_class])
  694. ) then
  695. aktclass.insertvmt;
  696. if is_interface(aktclass) then
  697. setinterfacemethodoptions;
  698. { reset }
  699. testcurobject:=0;
  700. curobjectname:='';
  701. typecanbeforward:=storetypecanbeforward;
  702. { restore old state }
  703. symtablestack:=symtablestack.next;
  704. aktobjectdef:=nil;
  705. current_object_option:=old_object_option;
  706. object_dec:=aktclass;
  707. end;
  708. end.