pdecobj.pas 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  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. { none of the explicit calling conventions should be allowed }
  389. if (po_hascallingconvention in pd.procoptions) then
  390. internalerror(2009032501);
  391. pd.proccalloption:=pocall_cdecl;
  392. include(pd.procoptions,po_objc);
  393. end;
  394. end;
  395. procedure chkcpp(pd:tprocdef);
  396. begin
  397. if is_cppclass(pd._class) then
  398. begin
  399. pd.proccalloption:=pocall_cppdecl;
  400. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  401. end;
  402. end;
  403. procedure maybe_parse_hint_directives(pd:tprocdef);
  404. var
  405. dummysymoptions : tsymoptions;
  406. begin
  407. dummysymoptions:=[];
  408. while try_consume_hintdirective(dummysymoptions) do
  409. Consume(_SEMICOLON);
  410. if assigned(pd) then
  411. pd.symoptions:=pd.symoptions+dummysymoptions;
  412. end;
  413. var
  414. pd : tprocdef;
  415. has_destructor,
  416. oldparse_only,
  417. old_parse_generic : boolean;
  418. object_member_blocktype : tblock_type;
  419. fields_allowed: boolean;
  420. begin
  421. { empty class declaration ? }
  422. if (current_objectdef.objecttype in [odt_class,odt_objcclass]) and
  423. (token=_SEMICOLON) then
  424. exit;
  425. old_parse_generic:=parse_generic;
  426. parse_generic:=(df_generic in current_objectdef.defoptions);
  427. { in "publishable" classes the default access type is published }
  428. if (oo_can_have_published in current_objectdef.objectoptions) then
  429. current_objectdef.symtable.currentvisibility:=vis_published
  430. else
  431. current_objectdef.symtable.currentvisibility:=vis_public;
  432. testcurobject:=1;
  433. has_destructor:=false;
  434. fields_allowed:=true;
  435. object_member_blocktype:=bt_general;
  436. repeat
  437. case token of
  438. _TYPE :
  439. begin
  440. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  441. Message(parser_e_type_and_var_only_in_generics);
  442. consume(_TYPE);
  443. object_member_blocktype:=bt_type;
  444. end;
  445. _VAR :
  446. begin
  447. if ([df_generic,df_specialization]*current_objectdef.defoptions)=[] then
  448. Message(parser_e_type_and_var_only_in_generics);
  449. consume(_VAR);
  450. object_member_blocktype:=bt_general;
  451. end;
  452. _ID :
  453. begin
  454. if is_objcprotocol(current_objectdef) and
  455. ((idtoken=_REQUIRED) or
  456. (idtoken=_OPTIONAL)) then
  457. begin
  458. current_objectdef.symtable.currentlyoptional:=(idtoken=_OPTIONAL);
  459. consume(idtoken)
  460. end
  461. else case idtoken of
  462. _PRIVATE :
  463. begin
  464. if is_interface(current_objectdef) or
  465. is_objcprotocol(current_objectdef) then
  466. Message(parser_e_no_access_specifier_in_interfaces);
  467. consume(_PRIVATE);
  468. current_objectdef.symtable.currentvisibility:=vis_private;
  469. include(current_objectdef.objectoptions,oo_has_private);
  470. fields_allowed:=true;
  471. end;
  472. _PROTECTED :
  473. begin
  474. if is_interface(current_objectdef) or
  475. is_objcprotocol(current_objectdef) then
  476. Message(parser_e_no_access_specifier_in_interfaces);
  477. consume(_PROTECTED);
  478. current_objectdef.symtable.currentvisibility:=vis_protected;
  479. include(current_objectdef.objectoptions,oo_has_protected);
  480. fields_allowed:=true;
  481. end;
  482. _PUBLIC :
  483. begin
  484. if is_interface(current_objectdef) or
  485. is_objcprotocol(current_objectdef) then
  486. Message(parser_e_no_access_specifier_in_interfaces);
  487. consume(_PUBLIC);
  488. current_objectdef.symtable.currentvisibility:=vis_public;
  489. fields_allowed:=true;
  490. end;
  491. _PUBLISHED :
  492. begin
  493. { we've to check for a pushlished section in non- }
  494. { publishable classes later, if a real declaration }
  495. { this is the way, delphi does it }
  496. if is_interface(current_objectdef) or
  497. is_objcprotocol(current_objectdef) then
  498. Message(parser_e_no_access_specifier_in_interfaces);
  499. { Objective-C classes do not support "published",
  500. as basically everything is published. }
  501. if is_objc_class_or_protocol(current_objectdef) then
  502. Message(parser_e_no_objc_published);
  503. consume(_PUBLISHED);
  504. current_objectdef.symtable.currentvisibility:=vis_published;
  505. fields_allowed:=true;
  506. end;
  507. _STRICT :
  508. begin
  509. if is_interface(current_objectdef) or
  510. is_objcprotocol(current_objectdef) then
  511. Message(parser_e_no_access_specifier_in_interfaces);
  512. consume(_STRICT);
  513. if token=_ID then
  514. begin
  515. case idtoken of
  516. _PRIVATE:
  517. begin
  518. consume(_PRIVATE);
  519. current_objectdef.symtable.currentvisibility:=vis_strictprivate;
  520. include(current_objectdef.objectoptions,oo_has_strictprivate);
  521. end;
  522. _PROTECTED:
  523. begin
  524. consume(_PROTECTED);
  525. current_objectdef.symtable.currentvisibility:=vis_strictprotected;
  526. include(current_objectdef.objectoptions,oo_has_strictprotected);
  527. end;
  528. else
  529. message(parser_e_protected_or_private_expected);
  530. end;
  531. end
  532. else
  533. message(parser_e_protected_or_private_expected);
  534. fields_allowed:=true;
  535. end;
  536. else
  537. begin
  538. if object_member_blocktype=bt_general then
  539. begin
  540. if is_interface(current_objectdef) or
  541. is_objcprotocol(current_objectdef) then
  542. Message(parser_e_no_vars_in_interfaces);
  543. if (current_objectdef.symtable.currentvisibility=vis_published) and
  544. not(oo_can_have_published in current_objectdef.objectoptions) then
  545. Message(parser_e_cant_have_published);
  546. if (not fields_allowed) then
  547. Message(parser_e_field_not_allowed_here);
  548. read_record_fields([vd_object])
  549. end
  550. else
  551. types_dec;
  552. end;
  553. end;
  554. end;
  555. _PROPERTY :
  556. begin
  557. property_dec;
  558. fields_allowed:=false;
  559. end;
  560. _PROCEDURE,
  561. _FUNCTION,
  562. _CLASS :
  563. begin
  564. if (current_objectdef.symtable.currentvisibility=vis_published) and
  565. not(oo_can_have_published in current_objectdef.objectoptions) then
  566. Message(parser_e_cant_have_published);
  567. oldparse_only:=parse_only;
  568. parse_only:=true;
  569. pd:=parse_proc_dec(current_objectdef);
  570. { this is for error recovery as well as forward }
  571. { interface mappings, i.e. mapping to a method }
  572. { which isn't declared yet }
  573. if assigned(pd) then
  574. begin
  575. parse_object_proc_directives(pd);
  576. { all Macintosh Object Pascal methods are virtual. }
  577. { this can't be a class method, because macpas mode }
  578. { has no m_class }
  579. if (m_mac in current_settings.modeswitches) then
  580. include(pd.procoptions,po_virtualmethod);
  581. handle_calling_convention(pd);
  582. { add definition to procsym }
  583. proc_add_definition(pd);
  584. { add procdef options to objectdef options }
  585. if (po_msgint in pd.procoptions) then
  586. include(current_objectdef.objectoptions,oo_has_msgint);
  587. if (po_msgstr in pd.procoptions) then
  588. include(current_objectdef.objectoptions,oo_has_msgstr);
  589. if (po_virtualmethod in pd.procoptions) then
  590. include(current_objectdef.objectoptions,oo_has_virtual);
  591. chkcpp(pd);
  592. chkobjc(pd);
  593. end;
  594. maybe_parse_hint_directives(pd);
  595. parse_only:=oldparse_only;
  596. fields_allowed:=false;
  597. end;
  598. _CONSTRUCTOR :
  599. begin
  600. if (current_objectdef.symtable.currentvisibility=vis_published) and
  601. not(oo_can_have_published in current_objectdef.objectoptions) then
  602. Message(parser_e_cant_have_published);
  603. if not(current_objectdef.symtable.currentvisibility in [vis_public,vis_published]) then
  604. Message(parser_w_constructor_should_be_public);
  605. if is_interface(current_objectdef) then
  606. Message(parser_e_no_con_des_in_interfaces);
  607. { Objective-C does not know the concept of a constructor }
  608. if is_objc_class_or_protocol(current_objectdef) then
  609. Message(parser_e_objc_no_constructor_destructor);
  610. oldparse_only:=parse_only;
  611. parse_only:=true;
  612. pd:=constructor_head;
  613. parse_object_proc_directives(pd);
  614. handle_calling_convention(pd);
  615. { add definition to procsym }
  616. proc_add_definition(pd);
  617. { add procdef options to objectdef options }
  618. if (po_virtualmethod in pd.procoptions) then
  619. include(current_objectdef.objectoptions,oo_has_virtual);
  620. chkcpp(pd);
  621. maybe_parse_hint_directives(pd);
  622. parse_only:=oldparse_only;
  623. fields_allowed:=false;
  624. end;
  625. _DESTRUCTOR :
  626. begin
  627. if (current_objectdef.symtable.currentvisibility=vis_published) and
  628. not(oo_can_have_published in current_objectdef.objectoptions) then
  629. Message(parser_e_cant_have_published);
  630. if has_destructor then
  631. Message(parser_n_only_one_destructor);
  632. has_destructor:=true;
  633. if is_interface(current_objectdef) then
  634. Message(parser_e_no_con_des_in_interfaces);
  635. if (current_objectdef.symtable.currentvisibility<>vis_public) then
  636. Message(parser_w_destructor_should_be_public);
  637. { Objective-C does not know the concept of a destructor }
  638. if is_objc_class_or_protocol(current_objectdef) then
  639. Message(parser_e_objc_no_constructor_destructor);
  640. oldparse_only:=parse_only;
  641. parse_only:=true;
  642. pd:=destructor_head;
  643. parse_object_proc_directives(pd);
  644. handle_calling_convention(pd);
  645. { add definition to procsym }
  646. proc_add_definition(pd);
  647. { add procdef options to objectdef options }
  648. if (po_virtualmethod in pd.procoptions) then
  649. include(current_objectdef.objectoptions,oo_has_virtual);
  650. chkcpp(pd);
  651. maybe_parse_hint_directives(pd);
  652. parse_only:=oldparse_only;
  653. fields_allowed:=false;
  654. end;
  655. _END :
  656. begin
  657. consume(_END);
  658. break;
  659. end;
  660. else
  661. consume(_ID); { Give a ident expected message, like tp7 }
  662. end;
  663. until false;
  664. { restore }
  665. testcurobject:=0;
  666. parse_generic:=old_parse_generic;
  667. end;
  668. function object_dec(objecttype:tobjecttyp;const n:tidstring;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef) : tobjectdef;
  669. var
  670. old_current_objectdef : tobjectdef;
  671. begin
  672. old_current_objectdef:=current_objectdef;
  673. current_objectdef:=nil;
  674. { objects and class types can't be declared local }
  675. if not(symtablestack.top.symtabletype in [globalsymtable,staticsymtable]) and
  676. not assigned(genericlist) then
  677. Message(parser_e_no_local_objects);
  678. { reuse forward objectdef? }
  679. if assigned(fd) then
  680. begin
  681. if fd.objecttype<>objecttype then
  682. begin
  683. Message(parser_e_forward_mismatch);
  684. { recover }
  685. current_objectdef:=tobjectdef.create(current_objectdef.objecttype,n,nil);
  686. include(current_objectdef.objectoptions,oo_is_forward);
  687. end
  688. else
  689. current_objectdef:=fd
  690. end
  691. else
  692. begin
  693. { anonym objects aren't allow (o : object a : longint; end;) }
  694. if n='' then
  695. Message(parser_f_no_anonym_objects);
  696. { create new class }
  697. current_objectdef:=tobjectdef.create(objecttype,n,nil);
  698. { include always the forward flag, it'll be removed after the parent class have been
  699. added. This is to prevent circular childof loops }
  700. include(current_objectdef.objectoptions,oo_is_forward);
  701. if (cs_compilesystem in current_settings.moduleswitches) then
  702. begin
  703. case current_objectdef.objecttype of
  704. odt_interfacecom :
  705. if (current_objectdef.objname^='IUNKNOWN') then
  706. interface_iunknown:=current_objectdef;
  707. odt_class :
  708. if (current_objectdef.objname^='TOBJECT') then
  709. class_tobject:=current_objectdef;
  710. end;
  711. end;
  712. if (current_module.modulename^='OBJCBASE') then
  713. begin
  714. case current_objectdef.objecttype of
  715. odt_objcclass:
  716. if (current_objectdef.objname^='Protocol') then
  717. objc_protocoltype:=current_objectdef;
  718. end;
  719. end;
  720. end;
  721. { set published flag in $M+ mode, it can also be inherited and will
  722. be added when the parent class set with tobjectdef.set_parent (PFV) }
  723. if (cs_generate_rtti in current_settings.localswitches) and
  724. (current_objectdef.objecttype in [odt_interfacecom,odt_class]) then
  725. include(current_objectdef.objectoptions,oo_can_have_published);
  726. { forward def? }
  727. if not assigned(fd) and
  728. (token=_SEMICOLON) then
  729. begin
  730. { add to the list of definitions to check that the forward
  731. is resolved. this is required for delphi mode }
  732. current_module.checkforwarddefs.add(current_objectdef);
  733. end
  734. else
  735. begin
  736. { parse list of parent classes }
  737. parse_parent_classes;
  738. { parse optional GUID for interfaces }
  739. parse_guid;
  740. { parse and insert object members }
  741. symtablestack.push(current_objectdef.symtable);
  742. insert_generic_parameter_types(genericdef,genericlist);
  743. parse_object_members;
  744. symtablestack.pop(current_objectdef.symtable);
  745. end;
  746. { generate vmt space if needed }
  747. if not(oo_has_vmt in current_objectdef.objectoptions) and
  748. (
  749. ([oo_has_virtual,oo_has_constructor,oo_has_destructor]*current_objectdef.objectoptions<>[]) or
  750. (current_objectdef.objecttype in [odt_class])
  751. ) then
  752. current_objectdef.insertvmt;
  753. { for implemented classes with a vmt check if there is a constructor }
  754. if (oo_has_vmt in current_objectdef.objectoptions) and
  755. not(oo_is_forward in current_objectdef.objectoptions) and
  756. not(oo_has_constructor in current_objectdef.objectoptions) then
  757. Message1(parser_w_virtual_without_constructor,current_objectdef.objrealname^);
  758. if is_interface(current_objectdef) or
  759. is_objcprotocol(current_objectdef) then
  760. setinterfacemethodoptions
  761. else if is_objcclass(current_objectdef) then
  762. setobjcclassmethodoptions;
  763. { return defined objectdef }
  764. result:=current_objectdef;
  765. { restore old state }
  766. current_objectdef:=old_current_objectdef;
  767. end;
  768. end.