pdecobj.pas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  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. if (token=_COLON) then
  89. begin
  90. Message(parser_e_field_not_allowed_here);
  91. consume_all_until(_SEMICOLON);
  92. end;
  93. consume(_SEMICOLON);
  94. end;
  95. { hint directives, these can be separated by semicolons here,
  96. that needs to be handled here with a loop (PFV) }
  97. while try_consume_hintdirective(p.symoptions) do
  98. Consume(_SEMICOLON);
  99. end;
  100. function destructor_head:tprocdef;
  101. var
  102. pd : tprocdef;
  103. begin
  104. result:=nil;
  105. consume(_DESTRUCTOR);
  106. parse_proc_head(current_objectdef,potype_destructor,pd);
  107. if not assigned(pd) then
  108. begin
  109. consume(_SEMICOLON);
  110. exit;
  111. end;
  112. if (cs_constructor_name in current_settings.globalswitches) and
  113. (pd.procsym.name<>'DONE') then
  114. Message(parser_e_destructorname_must_be_done);
  115. if not(pd.maxparacount=0) and
  116. (m_fpc in current_settings.modeswitches) then
  117. Message(parser_e_no_paras_for_destructor);
  118. consume(_SEMICOLON);
  119. include(current_objectdef.objectoptions,oo_has_destructor);
  120. { no return value }
  121. pd.returndef:=voidtype;
  122. result:=pd;
  123. end;
  124. procedure setinterfacemethodoptions;
  125. var
  126. i : longint;
  127. def : tdef;
  128. begin
  129. include(current_objectdef.objectoptions,oo_has_virtual);
  130. for i:=0 to current_objectdef.symtable.DefList.count-1 do
  131. begin
  132. def:=tdef(current_objectdef.symtable.DefList[i]);
  133. if assigned(def) and
  134. (def.typ=procdef) then
  135. begin
  136. include(tprocdef(def).procoptions,po_virtualmethod);
  137. tprocdef(def).forwarddef:=false;
  138. end;
  139. end;
  140. end;
  141. procedure setobjcclassmethodoptions;
  142. var
  143. i : longint;
  144. def : tdef;
  145. begin
  146. for i:=0 to current_objectdef.symtable.DefList.count-1 do
  147. begin
  148. def:=tdef(current_objectdef.symtable.DefList[i]);
  149. if assigned(def) and
  150. (def.typ=procdef) then
  151. begin
  152. include(tprocdef(def).procoptions,po_virtualmethod);
  153. end;
  154. end;
  155. end;
  156. procedure handleImplementedInterface(intfdef : tobjectdef);
  157. begin
  158. if not is_interface(intfdef) then
  159. begin
  160. Message1(type_e_interface_type_expected,intfdef.typename);
  161. exit;
  162. end;
  163. if current_objectdef.find_implemented_interface(intfdef)<>nil then
  164. Message1(sym_e_duplicate_id,intfdef.objname^)
  165. else
  166. begin
  167. { allocate and prepare the GUID only if the class
  168. implements some interfaces. }
  169. if current_objectdef.ImplementedInterfaces.count = 0 then
  170. current_objectdef.prepareguid;
  171. current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef));
  172. end;
  173. end;
  174. procedure handleImplementedProtocol(intfdef : tobjectdef);
  175. begin
  176. if not is_objcprotocol(intfdef) then
  177. begin
  178. Message1(type_e_protocol_type_expected,intfdef.typename);
  179. exit;
  180. end;
  181. if current_objectdef.find_implemented_interface(intfdef)<>nil then
  182. Message1(sym_e_duplicate_id,intfdef.objname^)
  183. else
  184. begin
  185. current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef));
  186. end;
  187. end;
  188. procedure readImplementedInterfacesAndProtocols(intf: boolean);
  189. var
  190. hdef : tdef;
  191. begin
  192. while try_to_consume(_COMMA) do
  193. begin
  194. id_type(hdef,false);
  195. if (hdef.typ<>objectdef) then
  196. begin
  197. if intf then
  198. Message1(type_e_interface_type_expected,hdef.typename)
  199. else
  200. Message1(type_e_protocol_type_expected,hdef.typename);
  201. continue;
  202. end;
  203. if intf then
  204. handleImplementedInterface(tobjectdef(hdef))
  205. else
  206. handleImplementedProtocol(tobjectdef(hdef));
  207. end;
  208. end;
  209. procedure readinterfaceiid;
  210. var
  211. p : tnode;
  212. valid : boolean;
  213. begin
  214. p:=comp_expr(true);
  215. if p.nodetype=stringconstn then
  216. begin
  217. stringdispose(current_objectdef.iidstr);
  218. current_objectdef.iidstr:=stringdup(strpas(tstringconstnode(p).value_str));
  219. valid:=string2guid(current_objectdef.iidstr^,current_objectdef.iidguid^);
  220. if (current_objectdef.objecttype in [odt_interfacecom,odt_dispinterface]) and
  221. not valid then
  222. Message(parser_e_improper_guid_syntax);
  223. include(current_objectdef.objectoptions,oo_has_valid_guid);
  224. end
  225. else
  226. Message(parser_e_illegal_expression);
  227. p.free;
  228. end;
  229. procedure parse_parent_classes;
  230. var
  231. intfchildof,
  232. childof : tobjectdef;
  233. hdef : tdef;
  234. hasparentdefined : boolean;
  235. begin
  236. childof:=nil;
  237. intfchildof:=nil;
  238. hasparentdefined:=false;
  239. { reads the parent class }
  240. if try_to_consume(_LKLAMMER) then
  241. begin
  242. { use single_type instead of id_type for specialize support }
  243. single_type(hdef,false,false);
  244. if (not assigned(hdef)) or
  245. (hdef.typ<>objectdef) then
  246. begin
  247. if assigned(hdef) then
  248. Message1(type_e_class_type_expected,hdef.typename);
  249. end
  250. else
  251. begin
  252. childof:=tobjectdef(hdef);
  253. { a mix of class, interfaces, objects and cppclasses
  254. isn't allowed }
  255. case current_objectdef.objecttype of
  256. odt_class:
  257. if not(is_class(childof)) then
  258. begin
  259. if is_interface(childof) then
  260. begin
  261. { we insert the interface after the child
  262. is set, see below
  263. }
  264. intfchildof:=childof;
  265. childof:=class_tobject;
  266. end
  267. else
  268. Message(parser_e_mix_of_classes_and_objects);
  269. end;
  270. odt_interfacecorba,
  271. odt_interfacecom:
  272. begin
  273. if not(is_interface(childof)) then
  274. Message(parser_e_mix_of_classes_and_objects);
  275. current_objectdef.objecttype:=childof.objecttype;
  276. current_objectdef.objecttype:=current_objectdef.objecttype;
  277. end;
  278. odt_cppclass:
  279. if not(is_cppclass(childof)) then
  280. Message(parser_e_mix_of_classes_and_objects);
  281. odt_objcclass:
  282. if not(is_objcclass(childof)) then
  283. begin
  284. if is_objcprotocol(childof) then
  285. begin
  286. intfchildof:=childof;
  287. childof:=nil;
  288. CGMessage(parser_h_no_objc_parent);
  289. end
  290. else
  291. Message(parser_e_mix_of_classes_and_objects);
  292. end;
  293. odt_objcprotocol:
  294. if not(is_objcprotocol(childof)) then
  295. Message(parser_e_mix_of_classes_and_objects);
  296. odt_object:
  297. if not(is_object(childof)) then
  298. Message(parser_e_mix_of_classes_and_objects);
  299. odt_dispinterface:
  300. Message(parser_e_dispinterface_cant_have_parent);
  301. end;
  302. end;
  303. hasparentdefined:=true;
  304. end;
  305. { no generic as parents }
  306. if assigned(childof) and
  307. (df_generic in childof.defoptions) then
  308. begin
  309. Message(parser_e_no_generics_as_types);
  310. childof:=nil;
  311. end;
  312. { if no parent class, then a class get tobject as parent }
  313. if not assigned(childof) then
  314. begin
  315. case current_objectdef.objecttype of
  316. odt_class:
  317. if current_objectdef<>class_tobject then
  318. childof:=class_tobject;
  319. odt_interfacecom:
  320. if current_objectdef<>interface_iunknown then
  321. childof:=interface_iunknown;
  322. odt_objcclass:
  323. CGMessage(parser_h_no_objc_parent);
  324. end;
  325. end;
  326. if assigned(childof) then
  327. begin
  328. { Forbid not completly defined objects to be used as parents. This will
  329. also prevent circular loops of classes, because we set the forward flag
  330. at the start of the new definition and will reset it below after the
  331. parent has been set }
  332. if not(oo_is_forward in childof.objectoptions) then
  333. current_objectdef.set_parent(childof)
  334. else
  335. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^);
  336. end;
  337. { remove forward flag, is resolved }
  338. exclude(current_objectdef.objectoptions,oo_is_forward);
  339. if hasparentdefined then
  340. begin
  341. if current_objectdef.objecttype in [odt_class,odt_objcclass] then
  342. begin
  343. if assigned(intfchildof) then
  344. if current_objectdef.objecttype=odt_class then
  345. handleImplementedInterface(intfchildof)
  346. else
  347. handleImplementedProtocol(intfchildof);
  348. readImplementedInterfacesAndProtocols(current_objectdef.objecttype=odt_class);
  349. end;
  350. consume(_RKLAMMER);
  351. end;
  352. end;
  353. procedure parse_guid;
  354. begin
  355. { read GUID }
  356. if (current_objectdef.objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) and
  357. try_to_consume(_LECKKLAMMER) then
  358. begin
  359. readinterfaceiid;
  360. consume(_RECKKLAMMER);
  361. end
  362. else if (current_objectdef.objecttype=odt_dispinterface) then
  363. message(parser_e_dispinterface_needs_a_guid);
  364. end;
  365. procedure insert_generic_parameter_types(genericdef:tstoreddef;genericlist:TFPObjectList);
  366. var
  367. i : longint;
  368. generictype : ttypesym;
  369. begin
  370. current_objectdef.genericdef:=genericdef;
  371. if not assigned(genericlist) then
  372. exit;
  373. for i:=0 to genericlist.count-1 do
  374. begin
  375. generictype:=ttypesym(genericlist[i]);
  376. if generictype.typedef.typ=undefineddef then
  377. include(current_objectdef.defoptions,df_generic)
  378. else
  379. include(current_objectdef.defoptions,df_specialization);
  380. symtablestack.top.insert(generictype);
  381. end;
  382. end;
  383. procedure parse_object_members;
  384. procedure chkobjc(pd: tprocdef);
  385. begin
  386. if is_objc_class_or_protocol(pd._class) then
  387. begin
  388. include(pd.procoptions,po_objc);
  389. end;
  390. end;
  391. procedure chkcpp(pd:tprocdef);
  392. begin
  393. if is_cppclass(pd._class) then
  394. begin
  395. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  396. end;
  397. end;
  398. procedure maybe_parse_hint_directives(pd:tprocdef);
  399. var
  400. dummysymoptions : tsymoptions;
  401. begin
  402. dummysymoptions:=[];
  403. while try_consume_hintdirective(dummysymoptions) do
  404. Consume(_SEMICOLON);
  405. if assigned(pd) then
  406. pd.symoptions:=pd.symoptions+dummysymoptions;
  407. end;
  408. var
  409. pd : tprocdef;
  410. has_destructor,
  411. oldparse_only,
  412. old_parse_generic : boolean;
  413. object_member_blocktype : tblock_type;
  414. fields_allowed: boolean;
  415. begin
  416. { empty class declaration ? }
  417. if (current_objectdef.objecttype in [odt_class,odt_objcclass]) and
  418. (token=_SEMICOLON) then
  419. exit;
  420. old_parse_generic:=parse_generic;
  421. parse_generic:=(df_generic in current_objectdef.defoptions);
  422. { in "publishable" classes the default access type is published }
  423. if (oo_can_have_published in current_objectdef.objectoptions) then
  424. current_objectdef.symtable.currentvisibility:=vis_published
  425. else
  426. current_objectdef.symtable.currentvisibility:=vis_public;
  427. testcurobject:=1;
  428. has_destructor:=false;
  429. fields_allowed:=true;
  430. object_member_blocktype:=bt_general;
  431. repeat
  432. case token of
  433. _TYPE :
  434. begin
  435. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  436. Message(parser_e_type_and_var_only_in_generics);
  437. consume(_TYPE);
  438. object_member_blocktype:=bt_type;
  439. end;
  440. _VAR :
  441. begin
  442. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  443. Message(parser_e_type_and_var_only_in_generics);
  444. consume(_VAR);
  445. object_member_blocktype:=bt_general;
  446. end;
  447. _ID :
  448. begin
  449. if is_objcprotocol(current_objectdef) and
  450. ((idtoken=_REQUIRED) or
  451. (idtoken=_OPTIONAL)) then
  452. begin
  453. current_objectdef.symtable.currentlyoptional:=(idtoken=_OPTIONAL);
  454. consume(idtoken)
  455. end
  456. else case idtoken of
  457. _PRIVATE :
  458. begin
  459. if is_interface(current_objectdef) or
  460. is_objcprotocol(current_objectdef) then
  461. Message(parser_e_no_access_specifier_in_interfaces);
  462. consume(_PRIVATE);
  463. current_objectdef.symtable.currentvisibility:=vis_private;
  464. include(current_objectdef.objectoptions,oo_has_private);
  465. fields_allowed:=true;
  466. end;
  467. _PROTECTED :
  468. begin
  469. if is_interface(current_objectdef) or
  470. is_objcprotocol(current_objectdef) then
  471. Message(parser_e_no_access_specifier_in_interfaces);
  472. consume(_PROTECTED);
  473. current_objectdef.symtable.currentvisibility:=vis_protected;
  474. include(current_objectdef.objectoptions,oo_has_protected);
  475. fields_allowed:=true;
  476. end;
  477. _PUBLIC :
  478. begin
  479. if is_interface(current_objectdef) or
  480. is_objcprotocol(current_objectdef) then
  481. Message(parser_e_no_access_specifier_in_interfaces);
  482. consume(_PUBLIC);
  483. current_objectdef.symtable.currentvisibility:=vis_public;
  484. fields_allowed:=true;
  485. end;
  486. _PUBLISHED :
  487. begin
  488. { we've to check for a pushlished section in non- }
  489. { publishable classes later, if a real declaration }
  490. { this is the way, delphi does it }
  491. if is_interface(current_objectdef) or
  492. is_objcprotocol(current_objectdef) then
  493. Message(parser_e_no_access_specifier_in_interfaces);
  494. { Objective-C classes do not support "published",
  495. as basically everything is published. }
  496. if is_objc_class_or_protocol(current_objectdef) then
  497. Message(parser_e_no_objc_published);
  498. consume(_PUBLISHED);
  499. current_objectdef.symtable.currentvisibility:=vis_published;
  500. fields_allowed:=true;
  501. end;
  502. _STRICT :
  503. begin
  504. if is_interface(current_objectdef) or
  505. is_objcprotocol(current_objectdef) then
  506. Message(parser_e_no_access_specifier_in_interfaces);
  507. consume(_STRICT);
  508. if token=_ID then
  509. begin
  510. case idtoken of
  511. _PRIVATE:
  512. begin
  513. consume(_PRIVATE);
  514. current_objectdef.symtable.currentvisibility:=vis_strictprivate;
  515. include(current_objectdef.objectoptions,oo_has_strictprivate);
  516. end;
  517. _PROTECTED:
  518. begin
  519. consume(_PROTECTED);
  520. current_objectdef.symtable.currentvisibility:=vis_strictprotected;
  521. include(current_objectdef.objectoptions,oo_has_strictprotected);
  522. end;
  523. else
  524. message(parser_e_protected_or_private_expected);
  525. end;
  526. end
  527. else
  528. message(parser_e_protected_or_private_expected);
  529. fields_allowed:=true;
  530. end;
  531. else
  532. begin
  533. if object_member_blocktype=bt_general then
  534. begin
  535. if is_interface(current_objectdef) or
  536. is_objcprotocol(current_objectdef) then
  537. Message(parser_e_no_vars_in_interfaces);
  538. if (current_objectdef.symtable.currentvisibility=vis_published) and
  539. not(oo_can_have_published in current_objectdef.objectoptions) then
  540. Message(parser_e_cant_have_published);
  541. if (not fields_allowed) then
  542. Message(parser_e_field_not_allowed_here);
  543. read_record_fields([vd_object])
  544. end
  545. else
  546. types_dec;
  547. end;
  548. end;
  549. end;
  550. _PROPERTY :
  551. begin
  552. property_dec;
  553. fields_allowed:=false;
  554. end;
  555. _PROCEDURE,
  556. _FUNCTION,
  557. _CLASS :
  558. begin
  559. if (current_objectdef.symtable.currentvisibility=vis_published) and
  560. not(oo_can_have_published in current_objectdef.objectoptions) then
  561. Message(parser_e_cant_have_published);
  562. oldparse_only:=parse_only;
  563. parse_only:=true;
  564. pd:=parse_proc_dec(current_objectdef);
  565. { this is for error recovery as well as forward }
  566. { interface mappings, i.e. mapping to a method }
  567. { which isn't declared yet }
  568. if assigned(pd) then
  569. begin
  570. parse_object_proc_directives(pd);
  571. { all Macintosh Object Pascal methods are virtual. }
  572. { this can't be a class method, because macpas mode }
  573. { has no m_class }
  574. if (m_mac in current_settings.modeswitches) then
  575. include(pd.procoptions,po_virtualmethod);
  576. handle_calling_convention(pd);
  577. { add definition to procsym }
  578. proc_add_definition(pd);
  579. { add procdef options to objectdef options }
  580. if (po_msgint in pd.procoptions) then
  581. include(current_objectdef.objectoptions,oo_has_msgint);
  582. if (po_msgstr in pd.procoptions) then
  583. include(current_objectdef.objectoptions,oo_has_msgstr);
  584. if (po_virtualmethod in pd.procoptions) then
  585. include(current_objectdef.objectoptions,oo_has_virtual);
  586. chkcpp(pd);
  587. chkobjc(pd);
  588. end;
  589. maybe_parse_hint_directives(pd);
  590. parse_only:=oldparse_only;
  591. fields_allowed:=false;
  592. end;
  593. _CONSTRUCTOR :
  594. begin
  595. if (current_objectdef.symtable.currentvisibility=vis_published) and
  596. not(oo_can_have_published in current_objectdef.objectoptions) then
  597. Message(parser_e_cant_have_published);
  598. if not(current_objectdef.symtable.currentvisibility in [vis_public,vis_published]) then
  599. Message(parser_w_constructor_should_be_public);
  600. if is_interface(current_objectdef) then
  601. Message(parser_e_no_con_des_in_interfaces);
  602. { Objective-C does not know the concept of a constructor }
  603. if is_objc_class_or_protocol(current_objectdef) then
  604. Message(parser_e_objc_no_constructor_destructor);
  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(current_objectdef.objectoptions,oo_has_virtual);
  615. chkcpp(pd);
  616. maybe_parse_hint_directives(pd);
  617. parse_only:=oldparse_only;
  618. fields_allowed:=false;
  619. end;
  620. _DESTRUCTOR :
  621. begin
  622. if (current_objectdef.symtable.currentvisibility=vis_published) and
  623. not(oo_can_have_published in current_objectdef.objectoptions) then
  624. Message(parser_e_cant_have_published);
  625. if has_destructor then
  626. Message(parser_n_only_one_destructor);
  627. has_destructor:=true;
  628. if is_interface(current_objectdef) then
  629. Message(parser_e_no_con_des_in_interfaces);
  630. if (current_objectdef.symtable.currentvisibility<>vis_public) then
  631. Message(parser_w_destructor_should_be_public);
  632. { Objective-C does not know the concept of a destructor }
  633. if is_objc_class_or_protocol(current_objectdef) then
  634. Message(parser_e_objc_no_constructor_destructor);
  635. oldparse_only:=parse_only;
  636. parse_only:=true;
  637. pd:=destructor_head;
  638. parse_object_proc_directives(pd);
  639. handle_calling_convention(pd);
  640. { add definition to procsym }
  641. proc_add_definition(pd);
  642. { add procdef options to objectdef options }
  643. if (po_virtualmethod in pd.procoptions) then
  644. include(current_objectdef.objectoptions,oo_has_virtual);
  645. chkcpp(pd);
  646. maybe_parse_hint_directives(pd);
  647. parse_only:=oldparse_only;
  648. fields_allowed:=false;
  649. end;
  650. _END :
  651. begin
  652. consume(_END);
  653. break;
  654. end;
  655. else
  656. consume(_ID); { Give a ident expected message, like tp7 }
  657. end;
  658. until false;
  659. { restore }
  660. testcurobject:=0;
  661. parse_generic:=old_parse_generic;
  662. end;
  663. function object_dec(objecttype:tobjecttyp;const n:tidstring;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef) : tobjectdef;
  664. var
  665. old_current_objectdef : tobjectdef;
  666. begin
  667. old_current_objectdef:=current_objectdef;
  668. current_objectdef:=nil;
  669. { objects and class types can't be declared local }
  670. if not(symtablestack.top.symtabletype in [globalsymtable,staticsymtable]) and
  671. not assigned(genericlist) then
  672. Message(parser_e_no_local_objects);
  673. { reuse forward objectdef? }
  674. if assigned(fd) then
  675. begin
  676. if fd.objecttype<>objecttype then
  677. begin
  678. Message(parser_e_forward_mismatch);
  679. { recover }
  680. current_objectdef:=tobjectdef.create(current_objectdef.objecttype,n,nil);
  681. include(current_objectdef.objectoptions,oo_is_forward);
  682. end
  683. else
  684. current_objectdef:=fd
  685. end
  686. else
  687. begin
  688. { anonym objects aren't allow (o : object a : longint; end;) }
  689. if n='' then
  690. Message(parser_f_no_anonym_objects);
  691. { create new class }
  692. current_objectdef:=tobjectdef.create(objecttype,n,nil);
  693. { include always the forward flag, it'll be removed after the parent class have been
  694. added. This is to prevent circular childof loops }
  695. include(current_objectdef.objectoptions,oo_is_forward);
  696. if (cs_compilesystem in current_settings.moduleswitches) then
  697. begin
  698. case current_objectdef.objecttype of
  699. odt_interfacecom :
  700. if (current_objectdef.objname^='IUNKNOWN') then
  701. interface_iunknown:=current_objectdef;
  702. odt_class :
  703. if (current_objectdef.objname^='TOBJECT') then
  704. class_tobject:=current_objectdef;
  705. end;
  706. end;
  707. if (current_module.modulename^='OBJCBASE') then
  708. begin
  709. case current_objectdef.objecttype of
  710. odt_objcclass:
  711. if (current_objectdef.objname^='Protocol') then
  712. objc_protocoltype:=current_objectdef;
  713. end;
  714. end;
  715. end;
  716. { set published flag in $M+ mode, it can also be inherited and will
  717. be added when the parent class set with tobjectdef.set_parent (PFV) }
  718. if (cs_generate_rtti in current_settings.localswitches) and
  719. (current_objectdef.objecttype in [odt_interfacecom,odt_class]) then
  720. include(current_objectdef.objectoptions,oo_can_have_published);
  721. { forward def? }
  722. if not assigned(fd) and
  723. (token=_SEMICOLON) then
  724. begin
  725. { add to the list of definitions to check that the forward
  726. is resolved. this is required for delphi mode }
  727. current_module.checkforwarddefs.add(current_objectdef);
  728. end
  729. else
  730. begin
  731. { parse list of parent classes }
  732. parse_parent_classes;
  733. { parse optional GUID for interfaces }
  734. parse_guid;
  735. { parse and insert object members }
  736. symtablestack.push(current_objectdef.symtable);
  737. insert_generic_parameter_types(genericdef,genericlist);
  738. parse_object_members;
  739. symtablestack.pop(current_objectdef.symtable);
  740. end;
  741. { generate vmt space if needed }
  742. if not(oo_has_vmt in current_objectdef.objectoptions) and
  743. (
  744. ([oo_has_virtual,oo_has_constructor,oo_has_destructor]*current_objectdef.objectoptions<>[]) or
  745. (current_objectdef.objecttype in [odt_class])
  746. ) then
  747. current_objectdef.insertvmt;
  748. { for implemented classes with a vmt check if there is a constructor }
  749. if (oo_has_vmt in current_objectdef.objectoptions) and
  750. not(oo_is_forward in current_objectdef.objectoptions) and
  751. not(oo_has_constructor in current_objectdef.objectoptions) and
  752. not is_objc_class_or_protocol(current_objectdef) then
  753. Message1(parser_w_virtual_without_constructor,current_objectdef.objrealname^);
  754. if is_interface(current_objectdef) or
  755. is_objcprotocol(current_objectdef) then
  756. setinterfacemethodoptions
  757. else if is_objcclass(current_objectdef) then
  758. setobjcclassmethodoptions;
  759. { return defined objectdef }
  760. result:=current_objectdef;
  761. { restore old state }
  762. current_objectdef:=old_current_objectdef;
  763. end;
  764. end.