pdecobj.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737
  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. cclasses,
  22. globtype,symconst,symtype,symdef;
  23. { parses a object declaration }
  24. function object_dec(objecttype:tobjecttyp;const n:tidstring;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef) : tobjectdef;
  25. implementation
  26. uses
  27. cutils,
  28. globals,verbose,systems,tokens,
  29. symbase,symsym,symtable,
  30. node,nld,nmem,ncon,ncnv,ncal,
  31. fmodule,scanner,
  32. pbase,pexpr,pdecsub,pdecvar,ptype,pdecl
  33. ;
  34. const
  35. { Please leave this here, this module should NOT use
  36. these variables.
  37. Declaring it as string here results in an error when compiling (PFV) }
  38. current_procinfo = 'error';
  39. function constructor_head:tprocdef;
  40. var
  41. pd : tprocdef;
  42. begin
  43. result:=nil;
  44. consume(_CONSTRUCTOR);
  45. { must be at same level as in implementation }
  46. parse_proc_head(current_objectdef,potype_constructor,pd);
  47. if not assigned(pd) then
  48. begin
  49. consume(_SEMICOLON);
  50. exit;
  51. end;
  52. if (cs_constructor_name in current_settings.globalswitches) and
  53. (pd.procsym.name<>'INIT') then
  54. Message(parser_e_constructorname_must_be_init);
  55. consume(_SEMICOLON);
  56. include(current_objectdef.objectoptions,oo_has_constructor);
  57. { Set return type, class constructors return the
  58. created instance, object constructors return boolean }
  59. if is_class(pd._class) then
  60. pd.returndef:=pd._class
  61. else
  62. {$ifdef CPU64bitaddr}
  63. pd.returndef:=bool64type;
  64. {$else CPU64bitaddr}
  65. pd.returndef:=bool32type;
  66. {$endif CPU64bitaddr}
  67. result:=pd;
  68. end;
  69. procedure property_dec;
  70. var
  71. p : tpropertysym;
  72. begin
  73. { check for a class }
  74. if not((is_class_or_interface_or_dispinterface(current_objectdef)) or
  75. (not(m_tp7 in current_settings.modeswitches) and (is_object(current_objectdef)))) then
  76. Message(parser_e_syntax_error);
  77. consume(_PROPERTY);
  78. p:=read_property_dec(current_objectdef);
  79. consume(_SEMICOLON);
  80. if try_to_consume(_DEFAULT) then
  81. begin
  82. if oo_has_default_property in current_objectdef.objectoptions then
  83. message(parser_e_only_one_default_property);
  84. include(current_objectdef.objectoptions,oo_has_default_property);
  85. include(p.propoptions,ppo_defaultproperty);
  86. if not(ppo_hasparameters in p.propoptions) then
  87. message(parser_e_property_need_paras);
  88. consume(_SEMICOLON);
  89. end;
  90. { hint directives, these can be separated by semicolons here,
  91. that needs to be handled here with a loop (PFV) }
  92. while try_consume_hintdirective(p.symoptions) do
  93. Consume(_SEMICOLON);
  94. end;
  95. function destructor_head:tprocdef;
  96. var
  97. pd : tprocdef;
  98. begin
  99. result:=nil;
  100. consume(_DESTRUCTOR);
  101. parse_proc_head(current_objectdef,potype_destructor,pd);
  102. if not assigned(pd) then
  103. begin
  104. consume(_SEMICOLON);
  105. exit;
  106. end;
  107. if (cs_constructor_name in current_settings.globalswitches) 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 current_settings.modeswitches) then
  112. Message(parser_e_no_paras_for_destructor);
  113. consume(_SEMICOLON);
  114. include(current_objectdef.objectoptions,oo_has_destructor);
  115. { no return value }
  116. pd.returndef:=voidtype;
  117. result:=pd;
  118. end;
  119. procedure setinterfacemethodoptions;
  120. var
  121. i : longint;
  122. def : tdef;
  123. begin
  124. include(current_objectdef.objectoptions,oo_has_virtual);
  125. for i:=0 to current_objectdef.symtable.DefList.count-1 do
  126. begin
  127. def:=tdef(current_objectdef.symtable.DefList[i]);
  128. if assigned(def) and
  129. (def.typ=procdef) then
  130. begin
  131. include(tprocdef(def).procoptions,po_virtualmethod);
  132. tprocdef(def).forwarddef:=false;
  133. end;
  134. end;
  135. end;
  136. procedure handleImplementedInterface(intfdef : tobjectdef);
  137. begin
  138. if not is_interface(intfdef) then
  139. begin
  140. Message1(type_e_interface_type_expected,intfdef.typename);
  141. exit;
  142. end;
  143. if current_objectdef.find_implemented_interface(intfdef)<>nil then
  144. Message1(sym_e_duplicate_id,intfdef.objname^)
  145. else
  146. begin
  147. { allocate and prepare the GUID only if the class
  148. implements some interfaces. }
  149. if current_objectdef.ImplementedInterfaces.count = 0 then
  150. current_objectdef.prepareguid;
  151. current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef));
  152. end;
  153. end;
  154. procedure readImplementedInterfaces;
  155. var
  156. hdef : tdef;
  157. begin
  158. while try_to_consume(_COMMA) do
  159. begin
  160. id_type(hdef,false);
  161. if (hdef.typ<>objectdef) then
  162. begin
  163. Message1(type_e_interface_type_expected,hdef.typename);
  164. continue;
  165. end;
  166. handleImplementedInterface(tobjectdef(hdef));
  167. end;
  168. end;
  169. procedure readinterfaceiid;
  170. var
  171. p : tnode;
  172. valid : boolean;
  173. begin
  174. p:=comp_expr(true);
  175. if p.nodetype=stringconstn then
  176. begin
  177. stringdispose(current_objectdef.iidstr);
  178. current_objectdef.iidstr:=stringdup(strpas(tstringconstnode(p).value_str));
  179. valid:=string2guid(current_objectdef.iidstr^,current_objectdef.iidguid^);
  180. if (current_objectdef.objecttype in [odt_interfacecom,odt_dispinterface]) and
  181. not assigned(current_objectdef.iidguid) and
  182. not valid then
  183. Message(parser_e_improper_guid_syntax);
  184. include(current_objectdef.objectoptions,oo_has_valid_guid);
  185. end
  186. else
  187. Message(parser_e_illegal_expression);
  188. p.free;
  189. end;
  190. procedure parse_parent_classes;
  191. var
  192. intfchildof,
  193. childof : tobjectdef;
  194. hdef : tdef;
  195. hasparentdefined : boolean;
  196. begin
  197. childof:=nil;
  198. intfchildof:=nil;
  199. hasparentdefined:=false;
  200. { reads the parent class }
  201. if try_to_consume(_LKLAMMER) then
  202. begin
  203. { use single_type instead of id_type for specialize support }
  204. single_type(hdef,false);
  205. if (not assigned(hdef)) or
  206. (hdef.typ<>objectdef) then
  207. begin
  208. if assigned(hdef) then
  209. Message1(type_e_class_type_expected,hdef.typename);
  210. end
  211. else
  212. begin
  213. childof:=tobjectdef(hdef);
  214. { a mix of class, interfaces, objects and cppclasses
  215. isn't allowed }
  216. case current_objectdef.objecttype of
  217. odt_class:
  218. if not(is_class(childof)) then
  219. begin
  220. if is_interface(childof) then
  221. begin
  222. { we insert the interface after the child
  223. is set, see below
  224. }
  225. intfchildof:=childof;
  226. childof:=class_tobject;
  227. end
  228. else
  229. Message(parser_e_mix_of_classes_and_objects);
  230. end;
  231. odt_interfacecorba,
  232. odt_interfacecom:
  233. begin
  234. if not(is_interface(childof)) then
  235. Message(parser_e_mix_of_classes_and_objects);
  236. current_objectdef.objecttype:=childof.objecttype;
  237. current_objectdef.objecttype:=current_objectdef.objecttype;
  238. end;
  239. odt_cppclass:
  240. if not(is_cppclass(childof)) then
  241. Message(parser_e_mix_of_classes_and_objects);
  242. odt_object:
  243. if not(is_object(childof)) then
  244. Message(parser_e_mix_of_classes_and_objects);
  245. odt_dispinterface:
  246. Message(parser_e_dispinterface_cant_have_parent);
  247. end;
  248. end;
  249. hasparentdefined:=true;
  250. end;
  251. { no generic as parents }
  252. if assigned(childof) and
  253. (df_generic in childof.defoptions) then
  254. begin
  255. Message(parser_e_no_generics_as_types);
  256. childof:=nil;
  257. end;
  258. { if no parent class, then a class get tobject as parent }
  259. if not assigned(childof) then
  260. begin
  261. case current_objectdef.objecttype of
  262. odt_class:
  263. if current_objectdef<>class_tobject then
  264. childof:=class_tobject;
  265. odt_interfacecom:
  266. if current_objectdef<>interface_iunknown then
  267. childof:=interface_iunknown;
  268. end;
  269. end;
  270. if assigned(childof) then
  271. begin
  272. { Forbid not completly defined objects to be used as parents. This will
  273. also prevent circular loops of classes, because we set the forward flag
  274. at the start of the new definition and will reset it below after the
  275. parent has been set }
  276. if not(oo_is_forward in childof.objectoptions) then
  277. current_objectdef.set_parent(childof)
  278. else
  279. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  280. end;
  281. { remove forward flag, is resolved }
  282. exclude(current_objectdef.objectoptions,oo_is_forward);
  283. if hasparentdefined then
  284. begin
  285. if current_objectdef.objecttype=odt_class then
  286. begin
  287. if assigned(intfchildof) then
  288. handleImplementedInterface(intfchildof);
  289. readImplementedInterfaces;
  290. end;
  291. consume(_RKLAMMER);
  292. end;
  293. end;
  294. procedure parse_guid;
  295. begin
  296. { read GUID }
  297. if (current_objectdef.objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) and
  298. try_to_consume(_LECKKLAMMER) then
  299. begin
  300. readinterfaceiid;
  301. consume(_RECKKLAMMER);
  302. end
  303. else if (current_objectdef.objecttype=odt_dispinterface) then
  304. message(parser_e_dispinterface_needs_a_guid);
  305. end;
  306. procedure insert_generic_parameter_types(genericdef:tstoreddef;genericlist:TFPObjectList);
  307. var
  308. i : longint;
  309. generictype : ttypesym;
  310. begin
  311. current_objectdef.genericdef:=genericdef;
  312. if not assigned(genericlist) then
  313. exit;
  314. for i:=0 to genericlist.count-1 do
  315. begin
  316. generictype:=ttypesym(genericlist[i]);
  317. if generictype.typedef.typ=undefineddef then
  318. include(current_objectdef.defoptions,df_generic)
  319. else
  320. include(current_objectdef.defoptions,df_specialization);
  321. symtablestack.top.insert(generictype);
  322. end;
  323. end;
  324. procedure parse_object_members;
  325. procedure chkcpp(pd:tprocdef);
  326. begin
  327. if is_cppclass(pd._class) then
  328. begin
  329. pd.proccalloption:=pocall_cppdecl;
  330. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  331. end;
  332. end;
  333. procedure maybe_parse_hint_directives(pd:tprocdef);
  334. var
  335. dummysymoptions : tsymoptions;
  336. begin
  337. dummysymoptions:=[];
  338. while try_consume_hintdirective(dummysymoptions) do
  339. Consume(_SEMICOLON);
  340. if assigned(pd) then
  341. pd.symoptions:=pd.symoptions+dummysymoptions;
  342. end;
  343. var
  344. pd : tprocdef;
  345. has_destructor,
  346. oldparse_only,
  347. old_parse_generic : boolean;
  348. object_member_blocktype : tblock_type;
  349. begin
  350. { empty class declaration ? }
  351. if (current_objectdef.objecttype=odt_class) and
  352. (token=_SEMICOLON) then
  353. exit;
  354. old_parse_generic:=parse_generic;
  355. parse_generic:=(df_generic in current_objectdef.defoptions);
  356. { in "publishable" classes the default access type is published }
  357. if (oo_can_have_published in current_objectdef.objectoptions) then
  358. current_objectdef.symtable.currentvisibility:=vis_published
  359. else
  360. current_objectdef.symtable.currentvisibility:=vis_public;
  361. testcurobject:=1;
  362. has_destructor:=false;
  363. object_member_blocktype:=bt_general;
  364. repeat
  365. case token of
  366. _TYPE :
  367. begin
  368. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  369. Message(parser_e_type_and_var_only_in_generics);
  370. consume(_TYPE);
  371. object_member_blocktype:=bt_type;
  372. end;
  373. _VAR :
  374. begin
  375. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  376. Message(parser_e_type_and_var_only_in_generics);
  377. consume(_VAR);
  378. object_member_blocktype:=bt_general;
  379. end;
  380. _ID :
  381. begin
  382. case idtoken of
  383. _PRIVATE :
  384. begin
  385. if is_interface(current_objectdef) then
  386. Message(parser_e_no_access_specifier_in_interfaces);
  387. consume(_PRIVATE);
  388. current_objectdef.symtable.currentvisibility:=vis_private;
  389. include(current_objectdef.objectoptions,oo_has_private);
  390. end;
  391. _PROTECTED :
  392. begin
  393. if is_interface(current_objectdef) then
  394. Message(parser_e_no_access_specifier_in_interfaces);
  395. consume(_PROTECTED);
  396. current_objectdef.symtable.currentvisibility:=vis_protected;
  397. include(current_objectdef.objectoptions,oo_has_protected);
  398. end;
  399. _PUBLIC :
  400. begin
  401. if is_interface(current_objectdef) then
  402. Message(parser_e_no_access_specifier_in_interfaces);
  403. consume(_PUBLIC);
  404. current_objectdef.symtable.currentvisibility:=vis_public;
  405. end;
  406. _PUBLISHED :
  407. begin
  408. { we've to check for a pushlished section in non- }
  409. { publishable classes later, if a real declaration }
  410. { this is the way, delphi does it }
  411. if is_interface(current_objectdef) then
  412. Message(parser_e_no_access_specifier_in_interfaces);
  413. consume(_PUBLISHED);
  414. current_objectdef.symtable.currentvisibility:=vis_published;
  415. end;
  416. _STRICT :
  417. begin
  418. if is_interface(current_objectdef) then
  419. Message(parser_e_no_access_specifier_in_interfaces);
  420. consume(_STRICT);
  421. if token=_ID then
  422. begin
  423. case idtoken of
  424. _PRIVATE:
  425. begin
  426. consume(_PRIVATE);
  427. current_objectdef.symtable.currentvisibility:=vis_strictprivate;
  428. include(current_objectdef.objectoptions,oo_has_strictprivate);
  429. end;
  430. _PROTECTED:
  431. begin
  432. consume(_PROTECTED);
  433. current_objectdef.symtable.currentvisibility:=vis_strictprotected;
  434. include(current_objectdef.objectoptions,oo_has_strictprotected);
  435. end;
  436. else
  437. message(parser_e_protected_or_private_expected);
  438. end;
  439. end
  440. else
  441. message(parser_e_protected_or_private_expected);
  442. end;
  443. else
  444. begin
  445. if object_member_blocktype=bt_general then
  446. begin
  447. if is_interface(current_objectdef) then
  448. Message(parser_e_no_vars_in_interfaces);
  449. if (current_objectdef.symtable.currentvisibility=vis_published) and
  450. not(oo_can_have_published in current_objectdef.objectoptions) then
  451. Message(parser_e_cant_have_published);
  452. read_record_fields([vd_object])
  453. end
  454. else
  455. types_dec;
  456. end;
  457. end;
  458. end;
  459. _PROPERTY :
  460. begin
  461. property_dec;
  462. end;
  463. _PROCEDURE,
  464. _FUNCTION,
  465. _CLASS :
  466. begin
  467. if (current_objectdef.symtable.currentvisibility=vis_published) and
  468. not(oo_can_have_published in current_objectdef.objectoptions) then
  469. Message(parser_e_cant_have_published);
  470. oldparse_only:=parse_only;
  471. parse_only:=true;
  472. pd:=parse_proc_dec(current_objectdef);
  473. { this is for error recovery as well as forward }
  474. { interface mappings, i.e. mapping to a method }
  475. { which isn't declared yet }
  476. if assigned(pd) then
  477. begin
  478. parse_object_proc_directives(pd);
  479. { all Macintosh Object Pascal methods are virtual. }
  480. { this can't be a class method, because macpas mode }
  481. { has no m_class }
  482. if (m_mac in current_settings.modeswitches) then
  483. include(pd.procoptions,po_virtualmethod);
  484. handle_calling_convention(pd);
  485. { add definition to procsym }
  486. proc_add_definition(pd);
  487. { add procdef options to objectdef options }
  488. if (po_msgint in pd.procoptions) then
  489. include(current_objectdef.objectoptions,oo_has_msgint);
  490. if (po_msgstr in pd.procoptions) then
  491. include(current_objectdef.objectoptions,oo_has_msgstr);
  492. if (po_virtualmethod in pd.procoptions) then
  493. include(current_objectdef.objectoptions,oo_has_virtual);
  494. chkcpp(pd);
  495. end;
  496. maybe_parse_hint_directives(pd);
  497. parse_only:=oldparse_only;
  498. end;
  499. _CONSTRUCTOR :
  500. begin
  501. if (current_objectdef.symtable.currentvisibility=vis_published) and
  502. not(oo_can_have_published in current_objectdef.objectoptions) then
  503. Message(parser_e_cant_have_published);
  504. if not(current_objectdef.symtable.currentvisibility in [vis_public,vis_published]) then
  505. Message(parser_w_constructor_should_be_public);
  506. if is_interface(current_objectdef) then
  507. Message(parser_e_no_con_des_in_interfaces);
  508. oldparse_only:=parse_only;
  509. parse_only:=true;
  510. pd:=constructor_head;
  511. parse_object_proc_directives(pd);
  512. handle_calling_convention(pd);
  513. { add definition to procsym }
  514. proc_add_definition(pd);
  515. { add procdef options to objectdef options }
  516. if (po_virtualmethod in pd.procoptions) then
  517. include(current_objectdef.objectoptions,oo_has_virtual);
  518. chkcpp(pd);
  519. maybe_parse_hint_directives(pd);
  520. parse_only:=oldparse_only;
  521. end;
  522. _DESTRUCTOR :
  523. begin
  524. if (current_objectdef.symtable.currentvisibility=vis_published) and
  525. not(oo_can_have_published in current_objectdef.objectoptions) then
  526. Message(parser_e_cant_have_published);
  527. if has_destructor then
  528. Message(parser_n_only_one_destructor);
  529. has_destructor:=true;
  530. if is_interface(current_objectdef) then
  531. Message(parser_e_no_con_des_in_interfaces);
  532. if (current_objectdef.symtable.currentvisibility<>vis_public) then
  533. Message(parser_w_destructor_should_be_public);
  534. oldparse_only:=parse_only;
  535. parse_only:=true;
  536. pd:=destructor_head;
  537. parse_object_proc_directives(pd);
  538. handle_calling_convention(pd);
  539. { add definition to procsym }
  540. proc_add_definition(pd);
  541. { add procdef options to objectdef options }
  542. if (po_virtualmethod in pd.procoptions) then
  543. include(current_objectdef.objectoptions,oo_has_virtual);
  544. chkcpp(pd);
  545. maybe_parse_hint_directives(pd);
  546. parse_only:=oldparse_only;
  547. end;
  548. _END :
  549. begin
  550. consume(_END);
  551. break;
  552. end;
  553. else
  554. consume(_ID); { Give a ident expected message, like tp7 }
  555. end;
  556. until false;
  557. { restore }
  558. testcurobject:=0;
  559. parse_generic:=old_parse_generic;
  560. end;
  561. function object_dec(objecttype:tobjecttyp;const n:tidstring;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef) : tobjectdef;
  562. var
  563. old_current_objectdef : tobjectdef;
  564. begin
  565. old_current_objectdef:=current_objectdef;
  566. current_objectdef:=nil;
  567. { objects and class types can't be declared local }
  568. if not(symtablestack.top.symtabletype in [globalsymtable,staticsymtable]) and
  569. not assigned(genericlist) then
  570. Message(parser_e_no_local_objects);
  571. { reuse forward objectdef? }
  572. if assigned(fd) then
  573. begin
  574. if fd.objecttype<>objecttype then
  575. begin
  576. Message(parser_e_forward_mismatch);
  577. { recover }
  578. current_objectdef:=tobjectdef.create(current_objectdef.objecttype,n,nil);
  579. include(current_objectdef.objectoptions,oo_is_forward);
  580. end
  581. else
  582. current_objectdef:=fd
  583. end
  584. else
  585. begin
  586. { anonym objects aren't allow (o : object a : longint; end;) }
  587. if n='' then
  588. Message(parser_f_no_anonym_objects);
  589. { create new class }
  590. current_objectdef:=tobjectdef.create(objecttype,n,nil);
  591. { include always the forward flag, it'll be removed after the parent class have been
  592. added. This is to prevent circular childof loops }
  593. include(current_objectdef.objectoptions,oo_is_forward);
  594. if (cs_compilesystem in current_settings.moduleswitches) then
  595. begin
  596. case current_objectdef.objecttype of
  597. odt_interfacecom :
  598. if (current_objectdef.objname^='IUNKNOWN') then
  599. interface_iunknown:=current_objectdef;
  600. odt_class :
  601. if (current_objectdef.objname^='TOBJECT') then
  602. class_tobject:=current_objectdef;
  603. end;
  604. end;
  605. end;
  606. { set published flag in $M+ mode, it can also be inherited and will
  607. be added when the parent class set with tobjectdef.set_parent (PFV) }
  608. if (cs_generate_rtti in current_settings.localswitches) and
  609. (current_objectdef.objecttype in [odt_interfacecom,odt_class]) then
  610. include(current_objectdef.objectoptions,oo_can_have_published);
  611. { forward def? }
  612. if not assigned(fd) and
  613. (token=_SEMICOLON) then
  614. begin
  615. { add to the list of definitions to check that the forward
  616. is resolved. this is required for delphi mode }
  617. current_module.checkforwarddefs.add(current_objectdef);
  618. end
  619. else
  620. begin
  621. { parse list of parent classes }
  622. parse_parent_classes;
  623. { parse optional GUID for interfaces }
  624. parse_guid;
  625. { parse and insert object members }
  626. symtablestack.push(current_objectdef.symtable);
  627. insert_generic_parameter_types(genericdef,genericlist);
  628. parse_object_members;
  629. symtablestack.pop(current_objectdef.symtable);
  630. end;
  631. { generate vmt space if needed }
  632. if not(oo_has_vmt in current_objectdef.objectoptions) and
  633. (
  634. ([oo_has_virtual,oo_has_constructor,oo_has_destructor]*current_objectdef.objectoptions<>[]) or
  635. (current_objectdef.objecttype in [odt_class])
  636. ) then
  637. current_objectdef.insertvmt;
  638. if (oo_has_vmt in current_objectdef.objectoptions) and
  639. not(oo_has_constructor in current_objectdef.objectoptions) then
  640. Message1(parser_w_virtual_without_constructor,current_objectdef.objrealname^);
  641. if is_interface(current_objectdef) then
  642. setinterfacemethodoptions;
  643. { return defined objectdef }
  644. result:=current_objectdef;
  645. { restore old state }
  646. current_objectdef:=old_current_objectdef;
  647. end;
  648. end.