pdecobj.pas 31 KB

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