pdecobj.pas 28 KB

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