pdecobj.pas 30 KB

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