pdecobj.pas 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545
  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;objsym:tsym;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef;helpertype:thelpertype) : tobjectdef;
  25. { parses a (class) method declaration }
  26. function method_dec(astruct: tabstractrecorddef; is_classdef: boolean): tprocdef;
  27. function class_constructor_head(astruct: tabstractrecorddef):tprocdef;
  28. function class_destructor_head(astruct: tabstractrecorddef):tprocdef;
  29. function constructor_head:tprocdef;
  30. function destructor_head:tprocdef;
  31. procedure struct_property_dec(is_classproperty:boolean);
  32. implementation
  33. uses
  34. sysutils,cutils,
  35. globals,verbose,systems,tokens,
  36. symbase,symsym,symtable,symcreat,defcmp,
  37. node,nld,nmem,ncon,ncnv,ncal,
  38. fmodule,scanner,
  39. pbase,pexpr,pdecsub,pdecvar,ptype,pdecl,pgenutil,ppu,
  40. {$ifdef jvm}
  41. pjvm,
  42. {$endif}
  43. parabase
  44. ;
  45. const
  46. { Please leave this here, this module should NOT use
  47. these variables.
  48. Declaring it as string here results in an error when compiling (PFV) }
  49. current_procinfo = 'error';
  50. var
  51. current_objectdef : tobjectdef absolute current_structdef;
  52. procedure constr_destr_finish_head(pd: tprocdef; const astruct: tabstractrecorddef);
  53. begin
  54. case astruct.typ of
  55. recorddef:
  56. parse_record_proc_directives(pd);
  57. objectdef:
  58. parse_object_proc_directives(pd);
  59. else
  60. internalerror(2011040502);
  61. end;
  62. handle_calling_convention(pd);
  63. { add definition to procsym }
  64. proc_add_definition(pd);
  65. { add procdef options to objectdef options }
  66. if (po_virtualmethod in pd.procoptions) then
  67. include(astruct.objectoptions,oo_has_virtual);
  68. maybe_parse_hint_directives(pd);
  69. end;
  70. function class_constructor_head(astruct: tabstractrecorddef):tprocdef;
  71. var
  72. pd : tprocdef;
  73. begin
  74. result:=nil;
  75. consume(_CONSTRUCTOR);
  76. { must be at same level as in implementation }
  77. parse_proc_head(current_structdef,potype_class_constructor,pd);
  78. if not assigned(pd) then
  79. begin
  80. consume(_SEMICOLON);
  81. exit;
  82. end;
  83. pd.calcparas;
  84. if (pd.maxparacount>0) then
  85. Message(parser_e_no_paras_for_class_constructor);
  86. consume(_SEMICOLON);
  87. include(astruct.objectoptions,oo_has_class_constructor);
  88. current_module.flags:=current_module.flags or uf_classinits;
  89. { no return value }
  90. pd.returndef:=voidtype;
  91. constr_destr_finish_head(pd,astruct);
  92. result:=pd;
  93. end;
  94. function constructor_head:tprocdef;
  95. var
  96. pd : tprocdef;
  97. begin
  98. result:=nil;
  99. consume(_CONSTRUCTOR);
  100. { must be at same level as in implementation }
  101. parse_proc_head(current_structdef,potype_constructor,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<>'INIT') then
  109. Message(parser_e_constructorname_must_be_init);
  110. consume(_SEMICOLON);
  111. include(current_structdef.objectoptions,oo_has_constructor);
  112. { Set return type, class and record constructors return the
  113. created instance, helper types return the extended type,
  114. object constructors return boolean }
  115. if is_class(pd.struct) or
  116. is_record(pd.struct) or
  117. is_javaclass(pd.struct) then
  118. pd.returndef:=pd.struct
  119. else
  120. if is_objectpascal_helper(pd.struct) then
  121. pd.returndef:=tobjectdef(pd.struct).extendeddef
  122. else
  123. {$ifdef CPU64bitaddr}
  124. pd.returndef:=bool64type;
  125. {$else CPU64bitaddr}
  126. pd.returndef:=bool32type;
  127. {$endif CPU64bitaddr}
  128. constr_destr_finish_head(pd,pd.struct);
  129. result:=pd;
  130. end;
  131. procedure struct_property_dec(is_classproperty:boolean);
  132. var
  133. p : tpropertysym;
  134. begin
  135. { check for a class, record or helper }
  136. if not((is_class_or_interface_or_dispinterface(current_structdef) or is_record(current_structdef) or
  137. is_objectpascal_helper(current_structdef) or is_java_class_or_interface(current_structdef)) or
  138. (not(m_tp7 in current_settings.modeswitches) and (is_object(current_structdef)))) then
  139. Message(parser_e_syntax_error);
  140. consume(_PROPERTY);
  141. p:=read_property_dec(is_classproperty,current_structdef);
  142. consume(_SEMICOLON);
  143. if try_to_consume(_DEFAULT) then
  144. begin
  145. if oo_has_default_property in current_structdef.objectoptions then
  146. message(parser_e_only_one_default_property);
  147. include(current_structdef.objectoptions,oo_has_default_property);
  148. include(p.propoptions,ppo_defaultproperty);
  149. if not(ppo_hasparameters in p.propoptions) then
  150. message(parser_e_property_need_paras);
  151. if (token=_COLON) then
  152. begin
  153. Message(parser_e_field_not_allowed_here);
  154. consume_all_until(_SEMICOLON);
  155. end;
  156. consume(_SEMICOLON);
  157. end;
  158. { parse possible enumerator modifier }
  159. if try_to_consume(_ENUMERATOR) then
  160. begin
  161. if (token = _ID) then
  162. begin
  163. if pattern='CURRENT' then
  164. begin
  165. if oo_has_enumerator_current in current_structdef.objectoptions then
  166. message(parser_e_only_one_enumerator_current);
  167. if not p.propaccesslist[palt_read].empty then
  168. begin
  169. include(current_structdef.objectoptions,oo_has_enumerator_current);
  170. include(p.propoptions,ppo_enumerator_current);
  171. end
  172. else
  173. Message(parser_e_enumerator_current_is_not_valid) // property has no reader
  174. end
  175. else
  176. Message1(parser_e_invalid_enumerator_identifier, pattern);
  177. consume(token);
  178. end
  179. else
  180. Message(parser_e_enumerator_identifier_required);
  181. consume(_SEMICOLON);
  182. end;
  183. { hint directives, these can be separated by semicolons here,
  184. that needs to be handled here with a loop (PFV) }
  185. while try_consume_hintdirective(p.symoptions,p.deprecatedmsg) do
  186. Consume(_SEMICOLON);
  187. end;
  188. function class_destructor_head(astruct: tabstractrecorddef):tprocdef;
  189. var
  190. pd : tprocdef;
  191. begin
  192. result:=nil;
  193. consume(_DESTRUCTOR);
  194. parse_proc_head(current_structdef,potype_class_destructor,pd);
  195. if not assigned(pd) then
  196. begin
  197. consume(_SEMICOLON);
  198. exit;
  199. end;
  200. pd.calcparas;
  201. if (pd.maxparacount>0) then
  202. Message(parser_e_no_paras_for_class_destructor);
  203. consume(_SEMICOLON);
  204. include(astruct.objectoptions,oo_has_class_destructor);
  205. current_module.flags:=current_module.flags or uf_classinits;
  206. { no return value }
  207. pd.returndef:=voidtype;
  208. constr_destr_finish_head(pd,astruct);
  209. result:=pd;
  210. end;
  211. function destructor_head:tprocdef;
  212. var
  213. pd : tprocdef;
  214. begin
  215. result:=nil;
  216. consume(_DESTRUCTOR);
  217. parse_proc_head(current_structdef,potype_destructor,pd);
  218. if not assigned(pd) then
  219. begin
  220. consume(_SEMICOLON);
  221. exit;
  222. end;
  223. if (cs_constructor_name in current_settings.globalswitches) and
  224. (pd.procsym.name<>'DONE') then
  225. Message(parser_e_destructorname_must_be_done);
  226. pd.calcparas;
  227. if not(pd.maxparacount=0) and
  228. (m_fpc in current_settings.modeswitches) then
  229. Message(parser_e_no_paras_for_destructor);
  230. consume(_SEMICOLON);
  231. include(current_structdef.objectoptions,oo_has_destructor);
  232. include(current_structdef.objectoptions,oo_has_new_destructor);
  233. { no return value }
  234. pd.returndef:=voidtype;
  235. constr_destr_finish_head(pd,pd.struct);
  236. result:=pd;
  237. end;
  238. procedure setinterfacemethodoptions;
  239. var
  240. i : longint;
  241. def : tdef;
  242. begin
  243. include(current_structdef.objectoptions,oo_has_virtual);
  244. for i:=0 to current_structdef.symtable.DefList.count-1 do
  245. begin
  246. def:=tdef(current_structdef.symtable.DefList[i]);
  247. if assigned(def) and
  248. (def.typ=procdef) then
  249. begin
  250. include(tprocdef(def).procoptions,po_virtualmethod);
  251. tprocdef(def).forwarddef:=false;
  252. end;
  253. end;
  254. end;
  255. procedure setobjcclassmethodoptions;
  256. var
  257. i : longint;
  258. def : tdef;
  259. begin
  260. for i:=0 to current_structdef.symtable.DefList.count-1 do
  261. begin
  262. def:=tdef(current_structdef.symtable.DefList[i]);
  263. if assigned(def) and
  264. (def.typ=procdef) then
  265. begin
  266. include(tprocdef(def).procoptions,po_virtualmethod);
  267. end;
  268. end;
  269. end;
  270. procedure handleImplementedInterface(intfdef : tobjectdef);
  271. begin
  272. if not is_interface(intfdef) then
  273. begin
  274. Message1(type_e_interface_type_expected,intfdef.typename);
  275. exit;
  276. end;
  277. if current_objectdef.find_implemented_interface(intfdef)<>nil then
  278. Message1(sym_e_duplicate_id,intfdef.objname^)
  279. else
  280. begin
  281. { allocate and prepare the GUID only if the class
  282. implements some interfaces. }
  283. if current_objectdef.ImplementedInterfaces.count = 0 then
  284. current_objectdef.prepareguid;
  285. current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef));
  286. end;
  287. end;
  288. procedure handleImplementedProtocolOrJavaIntf(intfdef : tobjectdef);
  289. begin
  290. intfdef:=find_real_class_definition(intfdef,false);
  291. case current_objectdef.objecttype of
  292. odt_objcclass,
  293. odt_objccategory,
  294. odt_objcprotocol:
  295. if not is_objcprotocol(intfdef) then
  296. begin
  297. Message1(type_e_protocol_type_expected,intfdef.typename);
  298. exit;
  299. end;
  300. odt_javaclass,
  301. odt_interfacejava:
  302. if not is_javainterface(intfdef) then
  303. begin
  304. Message1(type_e_interface_type_expected,intfdef.typename);
  305. exit
  306. end;
  307. else
  308. internalerror(2011010807);
  309. end;
  310. if ([oo_is_forward,oo_is_formal] * intfdef.objectoptions <> []) then
  311. begin
  312. Message1(parser_e_forward_intf_declaration_must_be_resolved,intfdef.objrealname^);
  313. exit;
  314. end;
  315. if current_objectdef.find_implemented_interface(intfdef)<>nil then
  316. Message1(sym_e_duplicate_id,intfdef.objname^)
  317. else
  318. begin
  319. current_objectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef));
  320. end;
  321. end;
  322. procedure readImplementedInterfacesAndProtocols(intf: boolean);
  323. var
  324. hdef : tdef;
  325. begin
  326. while try_to_consume(_COMMA) do
  327. begin
  328. { use single_type instead of id_type for specialize support }
  329. single_type(hdef,[stoAllowSpecialization,stoParseClassParent]);
  330. if (hdef.typ<>objectdef) then
  331. begin
  332. if intf then
  333. Message1(type_e_interface_type_expected,hdef.typename)
  334. else
  335. Message1(type_e_protocol_type_expected,hdef.typename);
  336. continue;
  337. end;
  338. if intf then
  339. handleImplementedInterface(tobjectdef(hdef))
  340. else
  341. handleImplementedProtocolOrJavaIntf(tobjectdef(hdef));
  342. end;
  343. end;
  344. procedure readinterfaceiid;
  345. var
  346. p : tnode;
  347. valid : boolean;
  348. begin
  349. p:=comp_expr(true,false);
  350. if p.nodetype=stringconstn then
  351. begin
  352. stringdispose(current_objectdef.iidstr);
  353. current_objectdef.iidstr:=stringdup(strpas(tstringconstnode(p).value_str));
  354. valid:=string2guid(current_objectdef.iidstr^,current_objectdef.iidguid^);
  355. if (current_objectdef.objecttype in [odt_interfacecom,odt_dispinterface]) and
  356. not valid then
  357. Message(parser_e_improper_guid_syntax);
  358. include(current_structdef.objectoptions,oo_has_valid_guid);
  359. end
  360. else
  361. Message(parser_e_illegal_expression);
  362. p.free;
  363. end;
  364. procedure get_cpp_or_java_class_external_status(od: tobjectdef);
  365. var
  366. hs: string;
  367. begin
  368. { C++ classes can be external -> all methods inside are external
  369. (defined at the class level instead of per method, so that you cannot
  370. define some methods as external and some not)
  371. }
  372. if try_to_consume(_EXTERNAL) then
  373. begin
  374. hs:='';
  375. if token in [_CSTRING,_CWSTRING,_CCHAR,_CWCHAR] then
  376. begin
  377. { Always add library prefix and suffix to create an uniform name }
  378. hs:=get_stringconst;
  379. if ExtractFileExt(hs)='' then
  380. hs:=ChangeFileExt(hs,target_info.sharedlibext);
  381. if Copy(hs,1,length(target_info.sharedlibprefix))<>target_info.sharedlibprefix then
  382. hs:=target_info.sharedlibprefix+hs;
  383. end;
  384. if hs<>'' then
  385. begin
  386. { the JVM expects java/lang/Object rather than java.lang.Object }
  387. if target_info.system in systems_jvm then
  388. Replace(hs,'.','/');
  389. stringdispose(od.import_lib);
  390. od.import_lib:=stringdup(hs);
  391. end;
  392. { check if we shall use another name for the class }
  393. if try_to_consume(_NAME) then
  394. od.objextname:=stringdup(get_stringconst)
  395. else
  396. od.objextname:=stringdup(od.objrealname^);
  397. include(od.objectoptions,oo_is_external);
  398. end
  399. else
  400. begin
  401. od.objextname:=stringdup(od.objrealname^);
  402. end;
  403. end;
  404. procedure get_objc_class_or_protocol_external_status(od: tobjectdef);
  405. begin
  406. { Objective-C classes can be external -> all messages inside are
  407. external (defined at the class level instead of per method, so
  408. that you cannot define some methods as external and some not)
  409. }
  410. if try_to_consume(_EXTERNAL) then
  411. begin
  412. if try_to_consume(_NAME) then
  413. od.objextname:=stringdup(get_stringconst)
  414. else
  415. { the external name doesn't matter for formally declared
  416. classes, and allowing to specify one would mean that we would
  417. have to check it for consistency with the actual definition
  418. later on }
  419. od.objextname:=stringdup(od.objrealname^);
  420. include(od.objectoptions,oo_is_external);
  421. end
  422. else
  423. od.objextname:=stringdup(od.objrealname^);
  424. end;
  425. procedure parse_object_options;
  426. var
  427. gotexternal: boolean;
  428. begin
  429. case current_objectdef.objecttype of
  430. odt_object,odt_class,
  431. odt_javaclass:
  432. begin
  433. gotexternal:=false;
  434. while true do
  435. begin
  436. if try_to_consume(_ABSTRACT) then
  437. include(current_structdef.objectoptions,oo_is_abstract)
  438. else
  439. if try_to_consume(_SEALED) then
  440. include(current_structdef.objectoptions,oo_is_sealed)
  441. else if (current_objectdef.objecttype=odt_javaclass) and
  442. (token=_ID) and
  443. (idtoken=_EXTERNAL) then
  444. begin
  445. get_cpp_or_java_class_external_status(current_objectdef);
  446. gotexternal:=true;
  447. end
  448. else
  449. break;
  450. end;
  451. { don't use <=, because there's a bug in the 2.6.0 SPARC code
  452. generator regarding handling this expression }
  453. if ([oo_is_abstract, oo_is_sealed] * current_structdef.objectoptions) = [oo_is_abstract, oo_is_sealed] then
  454. Message(parser_e_abstract_and_sealed_conflict);
  455. { set default external name in case of no external directive }
  456. if (current_objectdef.objecttype=odt_javaclass) and
  457. not gotexternal then
  458. get_cpp_or_java_class_external_status(current_objectdef)
  459. end;
  460. odt_cppclass,
  461. odt_interfacejava:
  462. get_cpp_or_java_class_external_status(current_objectdef);
  463. odt_objcclass,odt_objcprotocol,odt_objccategory:
  464. get_objc_class_or_protocol_external_status(current_objectdef);
  465. odt_helper: ; // nothing
  466. end;
  467. end;
  468. procedure parse_parent_classes;
  469. var
  470. intfchildof,
  471. childof : tobjectdef;
  472. hdef : tdef;
  473. hasparentdefined : boolean;
  474. begin
  475. childof:=nil;
  476. intfchildof:=nil;
  477. hasparentdefined:=false;
  478. { reads the parent class }
  479. if (token=_LKLAMMER) or
  480. is_objccategory(current_structdef) then
  481. begin
  482. consume(_LKLAMMER);
  483. { use single_type instead of id_type for specialize support }
  484. single_type(hdef,[stoAllowSpecialization, stoParseClassParent]);
  485. if (not assigned(hdef)) or
  486. (hdef.typ<>objectdef) then
  487. begin
  488. if assigned(hdef) then
  489. Message1(type_e_class_type_expected,hdef.typename)
  490. else if is_objccategory(current_structdef) then
  491. { a category must specify the class to extend }
  492. Message(type_e_objcclass_type_expected);
  493. end
  494. else
  495. begin
  496. childof:=tobjectdef(hdef);
  497. { a mix of class, interfaces, objects and cppclasses
  498. isn't allowed }
  499. case current_objectdef.objecttype of
  500. odt_class,
  501. odt_javaclass:
  502. if (childof.objecttype<>current_objectdef.objecttype) then
  503. begin
  504. if (is_interface(childof) and
  505. is_class(current_objectdef)) or
  506. (is_javainterface(childof) and
  507. is_javaclass(current_objectdef)) then
  508. begin
  509. { we insert the interface after the child
  510. is set, see below
  511. }
  512. intfchildof:=childof;
  513. childof:=class_tobject;
  514. end
  515. else
  516. Message(parser_e_mix_of_classes_and_objects);
  517. end
  518. else
  519. if oo_is_sealed in childof.objectoptions then
  520. Message1(parser_e_sealed_descendant,childof.typename)
  521. else
  522. childof:=find_real_class_definition(childof,true);
  523. odt_interfacecorba,
  524. odt_interfacecom:
  525. begin
  526. if not(is_interface(childof)) then
  527. Message(parser_e_mix_of_classes_and_objects);
  528. current_objectdef.objecttype:=childof.objecttype;
  529. end;
  530. odt_cppclass:
  531. if not(is_cppclass(childof)) then
  532. Message(parser_e_mix_of_classes_and_objects);
  533. odt_objcclass:
  534. if not(is_objcclass(childof) or
  535. is_objccategory(childof)) then
  536. begin
  537. if is_objcprotocol(childof) then
  538. begin
  539. if not(oo_is_classhelper in current_structdef.objectoptions) then
  540. begin
  541. intfchildof:=childof;
  542. childof:=nil;
  543. CGMessage(parser_h_no_objc_parent);
  544. end
  545. else
  546. { a category must specify the class to extend }
  547. CGMessage(type_e_objcclass_type_expected);
  548. end
  549. else
  550. Message(parser_e_mix_of_classes_and_objects);
  551. end
  552. else
  553. childof:=find_real_class_definition(childof,true);
  554. odt_objcprotocol:
  555. begin
  556. if not(is_objcprotocol(childof)) then
  557. Message(parser_e_mix_of_classes_and_objects);
  558. intfchildof:=childof;
  559. childof:=nil;
  560. end;
  561. odt_interfacejava:
  562. begin
  563. if not(is_javainterface(childof)) then
  564. Message(parser_e_mix_of_classes_and_objects);
  565. intfchildof:=find_real_class_definition(childof,true);
  566. childof:=nil;
  567. end;
  568. odt_object:
  569. if not(is_object(childof)) then
  570. Message(parser_e_mix_of_classes_and_objects)
  571. else
  572. if oo_is_sealed in childof.objectoptions then
  573. Message1(parser_e_sealed_descendant,childof.typename);
  574. odt_dispinterface:
  575. Message(parser_e_dispinterface_cant_have_parent);
  576. odt_helper:
  577. if not is_objectpascal_helper(childof) then
  578. begin
  579. Message(type_e_helper_type_expected);
  580. childof:=nil;
  581. end;
  582. end;
  583. end;
  584. hasparentdefined:=true;
  585. end;
  586. { if no parent class, then a class get tobject as parent }
  587. if not assigned(childof) then
  588. begin
  589. case current_objectdef.objecttype of
  590. odt_class:
  591. if current_objectdef<>class_tobject then
  592. childof:=class_tobject;
  593. odt_interfacecom:
  594. if current_objectdef<>interface_iunknown then
  595. childof:=interface_iunknown;
  596. odt_dispinterface:
  597. childof:=interface_idispatch;
  598. odt_objcclass:
  599. CGMessage(parser_h_no_objc_parent);
  600. odt_javaclass:
  601. { inherit from TObject by default for compatibility }
  602. if current_objectdef<>java_jlobject then
  603. childof:=class_tobject;
  604. end;
  605. end;
  606. if assigned(childof) then
  607. begin
  608. { Forbid not completly defined objects to be used as parents. This will
  609. also prevent circular loops of classes, because we set the forward flag
  610. at the start of the new definition and will reset it below after the
  611. parent has been set }
  612. if (oo_is_forward in childof.objectoptions) then
  613. Message1(parser_e_forward_declaration_must_be_resolved,childof.objrealname^)
  614. else if not(oo_is_formal in childof.objectoptions) then
  615. current_objectdef.set_parent(childof)
  616. else
  617. Message1(sym_e_formal_class_not_resolved,childof.objrealname^);
  618. end;
  619. { remove forward flag, is resolved }
  620. exclude(current_structdef.objectoptions,oo_is_forward);
  621. if hasparentdefined then
  622. begin
  623. if current_objectdef.objecttype in [odt_class,odt_objcclass,odt_objcprotocol,odt_javaclass,odt_interfacejava] then
  624. begin
  625. if assigned(intfchildof) then
  626. if current_objectdef.objecttype=odt_class then
  627. handleImplementedInterface(intfchildof)
  628. else
  629. handleImplementedProtocolOrJavaIntf(intfchildof);
  630. readImplementedInterfacesAndProtocols(current_objectdef.objecttype=odt_class);
  631. end;
  632. consume(_RKLAMMER);
  633. end;
  634. end;
  635. procedure parse_extended_type(helpertype:thelpertype);
  636. var
  637. hdef: tdef;
  638. begin
  639. if not is_objectpascal_helper(current_structdef) then
  640. Internalerror(2011021103);
  641. if helpertype=ht_none then
  642. Internalerror(2011021001);
  643. consume(_FOR);
  644. single_type(hdef,[stoParseClassParent]);
  645. if (not assigned(hdef)) or
  646. not (hdef.typ in [objectdef,recorddef]) then
  647. begin
  648. if helpertype=ht_class then
  649. Message1(type_e_class_type_expected,hdef.typename)
  650. else
  651. if helpertype=ht_record then
  652. Message1(type_e_record_type_expected,hdef.typename);
  653. end
  654. else
  655. begin
  656. case helpertype of
  657. ht_class:
  658. begin
  659. if not is_class(hdef) then
  660. Message1(type_e_class_type_expected,hdef.typename);
  661. { a class helper must extend the same class or a subclass
  662. of the class extended by the parent class helper }
  663. if assigned(current_objectdef.childof) then
  664. begin
  665. if not is_class(current_objectdef.childof.extendeddef) then
  666. Internalerror(2011021101);
  667. if not hdef.is_related(current_objectdef.childof.extendeddef) then
  668. Message1(type_e_class_helper_must_extend_subclass,current_objectdef.childof.extendeddef.typename);
  669. end;
  670. end;
  671. ht_record:
  672. begin
  673. if not is_record(hdef) then
  674. Message1(type_e_record_type_expected,hdef.typename);
  675. { a record helper must extend the same record as the
  676. parent helper }
  677. if assigned(current_objectdef.childof) then
  678. begin
  679. if not is_record(current_objectdef.childof.extendeddef) then
  680. Internalerror(2011021102);
  681. if hdef<>current_objectdef.childof.extendeddef then
  682. Message1(type_e_record_helper_must_extend_same_record,current_objectdef.childof.extendeddef.typename);
  683. end;
  684. end;
  685. else
  686. hdef:=nil;
  687. end;
  688. end;
  689. if assigned(hdef) then
  690. current_objectdef.extendeddef:=hdef
  691. else
  692. current_objectdef.extendeddef:=generrordef;
  693. end;
  694. procedure parse_guid;
  695. begin
  696. { read GUID }
  697. if (current_objectdef.objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) and
  698. try_to_consume(_LECKKLAMMER) then
  699. begin
  700. readinterfaceiid;
  701. consume(_RECKKLAMMER);
  702. end
  703. else if (current_objectdef.objecttype=odt_dispinterface) then
  704. message(parser_e_dispinterface_needs_a_guid);
  705. end;
  706. function method_dec(astruct: tabstractrecorddef; is_classdef: boolean): tprocdef;
  707. procedure chkobjc(pd: tprocdef);
  708. begin
  709. if is_objc_class_or_protocol(pd.struct) then
  710. begin
  711. include(pd.procoptions,po_objc);
  712. end;
  713. end;
  714. procedure chkjava(pd: tprocdef);
  715. begin
  716. {$ifdef jvm}
  717. if is_java_class_or_interface(pd.struct) then
  718. begin
  719. { mark all non-virtual instance methods as "virtual; final;",
  720. because
  721. a) that's the only way to guarantee "non-virtual" behaviour
  722. (other than making them class methods with an explicit self
  723. pointer, but that causes problems with interface mappings
  724. and procvars)
  725. b) if we don't mark them virtual, they don't get added to the
  726. vmt and we can't check whether child classes try to override
  727. them
  728. }
  729. if is_javaclass(pd.struct) then
  730. begin
  731. if not(po_virtualmethod in pd.procoptions) and
  732. not(po_classmethod in pd.procoptions) then
  733. begin
  734. include(pd.procoptions,po_virtualmethod);
  735. include(pd.procoptions,po_finalmethod);
  736. include(pd.procoptions,po_java_nonvirtual);
  737. end
  738. else if [po_virtualmethod,po_classmethod]<=pd.procoptions then
  739. begin
  740. if po_staticmethod in pd.procoptions then
  741. Message(type_e_java_class_method_not_static_virtual);
  742. end;
  743. end;
  744. end;
  745. {$endif}
  746. end;
  747. procedure chkcpp(pd:tprocdef);
  748. begin
  749. { nothing currently }
  750. end;
  751. var
  752. oldparse_only: boolean;
  753. begin
  754. case token of
  755. _PROCEDURE,
  756. _FUNCTION:
  757. begin
  758. if (astruct.symtable.currentvisibility=vis_published) and
  759. not(oo_can_have_published in astruct.objectoptions) then
  760. Message(parser_e_cant_have_published);
  761. oldparse_only:=parse_only;
  762. parse_only:=true;
  763. result:=parse_proc_dec(is_classdef,astruct);
  764. { this is for error recovery as well as forward }
  765. { interface mappings, i.e. mapping to a method }
  766. { which isn't declared yet }
  767. if assigned(result) then
  768. begin
  769. parse_object_proc_directives(result);
  770. { check if dispid is set }
  771. if is_dispinterface(result.struct) and not (po_dispid in result.procoptions) then
  772. begin
  773. result.dispid:=tobjectdef(result.struct).get_next_dispid;
  774. include(result.procoptions, po_dispid);
  775. end;
  776. { all Macintosh Object Pascal methods are virtual. }
  777. { this can't be a class method, because macpas mode }
  778. { has no m_class }
  779. if (m_mac in current_settings.modeswitches) then
  780. include(result.procoptions,po_virtualmethod);
  781. { for record helpers only static class methods are allowed }
  782. if is_objectpascal_helper(astruct) and
  783. is_record(tobjectdef(astruct).extendeddef) and
  784. is_classdef and not (po_staticmethod in result.procoptions) then
  785. MessagePos(result.fileinfo,parser_e_class_methods_only_static_in_records);
  786. handle_calling_convention(result);
  787. { add definition to procsym }
  788. proc_add_definition(result);
  789. { add procdef options to objectdef options }
  790. if (po_msgint in result.procoptions) then
  791. include(astruct.objectoptions,oo_has_msgint);
  792. if (po_msgstr in result.procoptions) then
  793. include(astruct.objectoptions,oo_has_msgstr);
  794. if (po_virtualmethod in result.procoptions) then
  795. include(astruct.objectoptions,oo_has_virtual);
  796. chkcpp(result);
  797. chkobjc(result);
  798. chkjava(result);
  799. end;
  800. maybe_parse_hint_directives(result);
  801. parse_only:=oldparse_only;
  802. end;
  803. _CONSTRUCTOR :
  804. begin
  805. if (astruct.symtable.currentvisibility=vis_published) and
  806. not(oo_can_have_published in astruct.objectoptions) then
  807. Message(parser_e_cant_have_published);
  808. if not is_classdef and not(astruct.symtable.currentvisibility in [vis_public,vis_published]) then
  809. Message(parser_w_constructor_should_be_public);
  810. if is_interface(astruct) then
  811. Message(parser_e_no_con_des_in_interfaces);
  812. { Objective-C does not know the concept of a constructor }
  813. if is_objc_class_or_protocol(astruct) then
  814. Message(parser_e_objc_no_constructor_destructor);
  815. if is_objectpascal_helper(astruct) then
  816. if is_classdef then
  817. { class constructors are not allowed in class helpers }
  818. Message(parser_e_no_class_constructor_in_helpers)
  819. else if is_record(tobjectdef(astruct).extendeddef) then
  820. { as long as constructors aren't allowed in records they
  821. aren't allowed in helpers either }
  822. Message(parser_e_no_constructor_in_records);
  823. { only 1 class constructor is allowed }
  824. if is_classdef and (oo_has_class_constructor in astruct.objectoptions) then
  825. Message1(parser_e_only_one_class_constructor_allowed, astruct.objrealname^);
  826. oldparse_only:=parse_only;
  827. parse_only:=true;
  828. if is_classdef then
  829. result:=class_constructor_head(current_structdef)
  830. else
  831. result:=constructor_head;
  832. chkcpp(result);
  833. parse_only:=oldparse_only;
  834. end;
  835. _DESTRUCTOR :
  836. begin
  837. if (astruct.symtable.currentvisibility=vis_published) and
  838. not(oo_can_have_published in astruct.objectoptions) then
  839. Message(parser_e_cant_have_published);
  840. if not is_classdef then
  841. if (oo_has_new_destructor in astruct.objectoptions) then
  842. Message(parser_n_only_one_destructor);
  843. if is_interface(astruct) then
  844. Message(parser_e_no_con_des_in_interfaces);
  845. { (class) destructors are not allowed in class helpers }
  846. if is_objectpascal_helper(astruct) then
  847. Message(parser_e_no_destructor_in_records);
  848. if not is_classdef and (astruct.symtable.currentvisibility<>vis_public) then
  849. Message(parser_w_destructor_should_be_public);
  850. { Objective-C does not know the concept of a destructor }
  851. if is_objc_class_or_protocol(astruct) then
  852. Message(parser_e_objc_no_constructor_destructor);
  853. { only 1 class destructor is allowed }
  854. if is_classdef and (oo_has_class_destructor in astruct.objectoptions) then
  855. Message1(parser_e_only_one_class_destructor_allowed, astruct.objrealname^);
  856. oldparse_only:=parse_only;
  857. parse_only:=true;
  858. if is_classdef then
  859. result:=class_destructor_head(current_structdef)
  860. else
  861. result:=destructor_head;
  862. chkcpp(result);
  863. parse_only:=oldparse_only;
  864. end;
  865. else
  866. internalerror(2011032102);
  867. end;
  868. end;
  869. procedure parse_object_members;
  870. var
  871. typedconstswritable: boolean;
  872. object_member_blocktype : tblock_type;
  873. fields_allowed, is_classdef, class_fields, is_final, final_fields: boolean;
  874. vdoptions: tvar_dec_options;
  875. fieldlist: tfpobjectlist;
  876. procedure parse_const;
  877. begin
  878. if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass,odt_interfacejava]) then
  879. Message(parser_e_type_var_const_only_in_records_and_classes);
  880. consume(_CONST);
  881. object_member_blocktype:=bt_const;
  882. final_fields:=is_final;
  883. is_final:=false;
  884. end;
  885. procedure parse_var;
  886. begin
  887. if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass]) and
  888. { Java interfaces can contain static final class vars }
  889. not((current_objectdef.objecttype=odt_interfacejava) and
  890. is_final and is_classdef) then
  891. Message(parser_e_type_var_const_only_in_records_and_classes);
  892. consume(_VAR);
  893. fields_allowed:=true;
  894. object_member_blocktype:=bt_general;
  895. class_fields:=is_classdef;
  896. final_fields:=is_final;
  897. is_classdef:=false;
  898. is_final:=false;
  899. end;
  900. procedure parse_class;
  901. begin
  902. is_classdef:=false;
  903. { read class method/field/property }
  904. consume(_CLASS);
  905. { class modifier is only allowed for procedures, functions, }
  906. { constructors, destructors, fields and properties }
  907. if not(token in [_FUNCTION,_PROCEDURE,_PROPERTY,_VAR,_CONSTRUCTOR,_DESTRUCTOR]) then
  908. Message(parser_e_procedure_or_function_expected);
  909. { Java interfaces can contain final class vars }
  910. if is_interface(current_structdef) or
  911. (is_javainterface(current_structdef) and
  912. (not(is_final) or
  913. (token<>_VAR))) then
  914. Message(parser_e_no_static_method_in_interfaces)
  915. else
  916. { class methods are also allowed for Objective-C protocols }
  917. is_classdef:=true;
  918. end;
  919. procedure parse_visibility(vis: tvisibility; oo: tobjectoption);
  920. begin
  921. { Objective-C and Java classes do not support "published",
  922. as basically everything is published. }
  923. if (vis=vis_published) and
  924. (is_objc_class_or_protocol(current_structdef) or
  925. is_java_class_or_interface(current_structdef)) then
  926. Message(parser_e_no_objc_published)
  927. else if is_interface(current_structdef) or
  928. is_objc_protocol_or_category(current_structdef) or
  929. is_javainterface(current_structdef) then
  930. Message(parser_e_no_access_specifier_in_interfaces);
  931. current_structdef.symtable.currentvisibility:=vis;
  932. consume(token);
  933. if (oo<>oo_none) then
  934. include(current_structdef.objectoptions,oo);
  935. fields_allowed:=true;
  936. is_classdef:=false;
  937. class_fields:=false;
  938. is_final:=false;
  939. object_member_blocktype:=bt_general;
  940. end;
  941. begin
  942. { empty class declaration ? }
  943. if (current_objectdef.objecttype in [odt_class,odt_objcclass,odt_javaclass]) and
  944. (token=_SEMICOLON) then
  945. exit;
  946. { in "publishable" classes the default access type is published }
  947. if (oo_can_have_published in current_structdef.objectoptions) then
  948. current_structdef.symtable.currentvisibility:=vis_published
  949. else
  950. current_structdef.symtable.currentvisibility:=vis_public;
  951. fields_allowed:=true;
  952. is_classdef:=false;
  953. class_fields:=false;
  954. is_final:=false;
  955. final_fields:=false;
  956. object_member_blocktype:=bt_general;
  957. fieldlist:=tfpobjectlist.create(false);
  958. repeat
  959. case token of
  960. _TYPE :
  961. begin
  962. if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass,odt_interfacejava]) then
  963. Message(parser_e_type_var_const_only_in_records_and_classes);
  964. consume(_TYPE);
  965. object_member_blocktype:=bt_type;
  966. end;
  967. _VAR :
  968. begin
  969. parse_var;
  970. end;
  971. _CONST:
  972. begin
  973. parse_const
  974. end;
  975. _ID :
  976. begin
  977. if is_objcprotocol(current_structdef) and
  978. ((idtoken=_REQUIRED) or
  979. (idtoken=_OPTIONAL)) then
  980. begin
  981. current_structdef.symtable.currentlyoptional:=(idtoken=_OPTIONAL);
  982. consume(idtoken)
  983. end
  984. else case idtoken of
  985. _PRIVATE :
  986. begin
  987. parse_visibility(vis_private,oo_has_private);
  988. end;
  989. _PROTECTED :
  990. begin
  991. parse_visibility(vis_protected,oo_has_protected);
  992. end;
  993. _PUBLIC :
  994. begin
  995. parse_visibility(vis_public,oo_none);
  996. end;
  997. _PUBLISHED :
  998. begin
  999. parse_visibility(vis_published,oo_none);
  1000. end;
  1001. _STRICT :
  1002. begin
  1003. if is_interface(current_structdef) or
  1004. is_objc_protocol_or_category(current_structdef) or
  1005. is_javainterface(current_structdef) then
  1006. Message(parser_e_no_access_specifier_in_interfaces);
  1007. consume(_STRICT);
  1008. if token=_ID then
  1009. begin
  1010. case idtoken of
  1011. _PRIVATE:
  1012. begin
  1013. consume(_PRIVATE);
  1014. current_structdef.symtable.currentvisibility:=vis_strictprivate;
  1015. include(current_structdef.objectoptions,oo_has_strictprivate);
  1016. end;
  1017. _PROTECTED:
  1018. begin
  1019. consume(_PROTECTED);
  1020. current_structdef.symtable.currentvisibility:=vis_strictprotected;
  1021. include(current_structdef.objectoptions,oo_has_strictprotected);
  1022. end;
  1023. else
  1024. message(parser_e_protected_or_private_expected);
  1025. end;
  1026. end
  1027. else
  1028. message(parser_e_protected_or_private_expected);
  1029. fields_allowed:=true;
  1030. is_classdef:=false;
  1031. class_fields:=false;
  1032. is_final:=false;
  1033. final_fields:=false;
  1034. object_member_blocktype:=bt_general;
  1035. end
  1036. else if (m_final_fields in current_settings.modeswitches) and
  1037. (token=_ID) and
  1038. (idtoken=_FINAL) then
  1039. begin
  1040. { currently only supported for external classes, because
  1041. requires fully working DFA otherwise }
  1042. if (current_structdef.typ<>objectdef) or
  1043. not(oo_is_external in tobjectdef(current_structdef).objectoptions) then
  1044. Message(parser_e_final_only_external);
  1045. consume(_final);
  1046. is_final:=true;
  1047. if token=_CLASS then
  1048. parse_class;
  1049. if not(token in [_CONST,_VAR]) then
  1050. message(parser_e_final_only_const_var);
  1051. end
  1052. else
  1053. begin
  1054. if object_member_blocktype=bt_general then
  1055. begin
  1056. if is_interface(current_structdef) or
  1057. is_objc_protocol_or_category(current_structdef) or
  1058. is_objectpascal_helper(current_structdef) or
  1059. (is_javainterface(current_structdef) and
  1060. not(class_fields and final_fields)) then
  1061. Message(parser_e_no_vars_in_interfaces);
  1062. if (current_structdef.symtable.currentvisibility=vis_published) and
  1063. not(oo_can_have_published in current_structdef.objectoptions) then
  1064. Message(parser_e_cant_have_published);
  1065. if (not fields_allowed) then
  1066. Message(parser_e_field_not_allowed_here);
  1067. vdoptions:=[vd_object];
  1068. if class_fields then
  1069. include(vdoptions,vd_class);
  1070. if is_class(current_structdef) then
  1071. include(vdoptions,vd_canreorder);
  1072. if final_fields then
  1073. include(vdoptions,vd_final);
  1074. read_record_fields(vdoptions,fieldlist);
  1075. end
  1076. else if object_member_blocktype=bt_type then
  1077. types_dec(true)
  1078. else if object_member_blocktype=bt_const then
  1079. begin
  1080. if final_fields then
  1081. begin
  1082. { the value of final fields cannot be changed
  1083. once they've been assigned a value }
  1084. typedconstswritable:=cs_typed_const_writable in current_settings.localswitches;
  1085. exclude(current_settings.localswitches,cs_typed_const_writable);
  1086. end;
  1087. consts_dec(true,not is_javainterface(current_structdef));
  1088. if final_fields and
  1089. typedconstswritable then
  1090. include(current_settings.localswitches,cs_typed_const_writable);
  1091. end
  1092. else
  1093. internalerror(201001110);
  1094. end;
  1095. end;
  1096. end;
  1097. _PROPERTY :
  1098. begin
  1099. struct_property_dec(is_classdef);
  1100. fields_allowed:=false;
  1101. is_classdef:=false;
  1102. end;
  1103. _CLASS:
  1104. begin
  1105. parse_class;
  1106. end;
  1107. _PROCEDURE,
  1108. _FUNCTION,
  1109. _CONSTRUCTOR,
  1110. _DESTRUCTOR :
  1111. begin
  1112. method_dec(current_structdef,is_classdef);
  1113. fields_allowed:=false;
  1114. is_classdef:=false;
  1115. end;
  1116. _END :
  1117. begin
  1118. consume(_END);
  1119. break;
  1120. end;
  1121. else
  1122. consume(_ID); { Give a ident expected message, like tp7 }
  1123. end;
  1124. until false;
  1125. if is_class(current_structdef) then
  1126. tabstractrecordsymtable(current_structdef.symtable).addfieldlist(fieldlist,true);
  1127. fieldlist.free;
  1128. end;
  1129. function object_dec(objecttype:tobjecttyp;const n:tidstring;objsym:tsym;genericdef:tstoreddef;genericlist:TFPObjectList;fd : tobjectdef;helpertype:thelpertype) : tobjectdef;
  1130. var
  1131. old_current_structdef: tabstractrecorddef;
  1132. old_current_genericdef,
  1133. old_current_specializedef: tstoreddef;
  1134. hrecst: trecordsymtable;
  1135. fsym: tfieldvarsym;
  1136. old_parse_generic: boolean;
  1137. list: TFPObjectList;
  1138. s: String;
  1139. st: TSymtable;
  1140. olddef: tdef;
  1141. begin
  1142. old_current_structdef:=current_structdef;
  1143. old_current_genericdef:=current_genericdef;
  1144. old_current_specializedef:=current_specializedef;
  1145. old_parse_generic:=parse_generic;
  1146. current_structdef:=nil;
  1147. current_genericdef:=nil;
  1148. current_specializedef:=nil;
  1149. { objects and class types can't be declared local }
  1150. if not(symtablestack.top.symtabletype in [globalsymtable,staticsymtable,objectsymtable,recordsymtable]) and
  1151. not assigned(genericlist) then
  1152. Message(parser_e_no_local_objects);
  1153. { reuse forward objectdef? }
  1154. if assigned(fd) then
  1155. begin
  1156. if fd.objecttype<>objecttype then
  1157. begin
  1158. Message(parser_e_forward_mismatch);
  1159. { recover }
  1160. current_structdef:=tobjectdef.create(current_objectdef.objecttype,n,nil);
  1161. include(current_structdef.objectoptions,oo_is_forward);
  1162. end
  1163. else
  1164. current_structdef:=fd
  1165. end
  1166. else
  1167. begin
  1168. { anonym objects aren't allow (o : object a : longint; end;) }
  1169. if n='' then
  1170. Message(parser_f_no_anonym_objects);
  1171. { create new class }
  1172. current_structdef:=tobjectdef.create(objecttype,n,nil);
  1173. { include always the forward flag, it'll be removed after the parent class have been
  1174. added. This is to prevent circular childof loops }
  1175. include(current_structdef.objectoptions,oo_is_forward);
  1176. if (cs_compilesystem in current_settings.moduleswitches) then
  1177. begin
  1178. case current_objectdef.objecttype of
  1179. odt_interfacecom :
  1180. if (current_structdef.objname^='IUNKNOWN') then
  1181. interface_iunknown:=current_objectdef
  1182. else
  1183. if (current_structdef.objname^='IDISPATCH') then
  1184. interface_idispatch:=current_objectdef;
  1185. odt_class :
  1186. if (current_structdef.objname^='TOBJECT') then
  1187. class_tobject:=current_objectdef;
  1188. odt_javaclass:
  1189. begin
  1190. if (current_structdef.objname^='TOBJECT') then
  1191. class_tobject:=current_objectdef
  1192. else if (current_objectdef.objname^='JLOBJECT') then
  1193. begin
  1194. java_jlobject:=current_objectdef;
  1195. { the methodpointer type is normally created in
  1196. psystem, but java_jlobject is not yet available
  1197. there... }
  1198. hrecst:=trecordsymtable.create('',1);
  1199. fsym:=tfieldvarsym.create('$proc',vs_value,java_jlobject,[]);
  1200. hrecst.insert(fsym);
  1201. hrecst.addfield(fsym,vis_hidden);
  1202. fsym:=tfieldvarsym.create('$data',vs_value,java_jlobject,[]);
  1203. hrecst.insert(fsym);
  1204. hrecst.addfield(fsym,vis_hidden);
  1205. methodpointertype:=trecorddef.create('',hrecst);
  1206. systemunit.insert(ttypesym.create('$methodpointer',methodpointertype));
  1207. end
  1208. else if (current_objectdef.objname^='JLTHROWABLE') then
  1209. java_jlthrowable:=current_objectdef
  1210. else if (current_objectdef.objname^='FPCBASERECORDTYPE') then
  1211. java_fpcbaserecordtype:=current_objectdef
  1212. else if (current_objectdef.objname^='JLSTRING') then
  1213. java_jlstring:=current_objectdef
  1214. else if (current_objectdef.objname^='ANSISTRINGCLASS') then
  1215. java_ansistring:=current_objectdef
  1216. else if (current_objectdef.objname^='SHORTSTRINGCLASS') then
  1217. java_shortstring:=current_objectdef
  1218. else if (current_objectdef.objname^='JLENUM') then
  1219. java_jlenum:=current_objectdef
  1220. else if (current_objectdef.objname^='JUENUMSET') then
  1221. java_juenumset:=current_objectdef
  1222. else if (current_objectdef.objname^='FPCBITSET') then
  1223. java_jubitset:=current_objectdef
  1224. else if (current_objectdef.objname^='FPCBASEPROCVARTYPE') then
  1225. java_procvarbase:=current_objectdef;
  1226. end;
  1227. end;
  1228. end;
  1229. if (current_module.modulename^='OBJCBASE') then
  1230. begin
  1231. case current_objectdef.objecttype of
  1232. odt_objcclass:
  1233. if (current_objectdef.objname^='Protocol') then
  1234. objc_protocoltype:=current_objectdef;
  1235. end;
  1236. end;
  1237. end;
  1238. { usage of specialized type inside its generic template }
  1239. if assigned(genericdef) then
  1240. current_specializedef:=current_structdef
  1241. { reject declaration of generic class inside generic class }
  1242. else if assigned(genericlist) then
  1243. current_genericdef:=current_structdef;
  1244. { nested types of specializations are specializations as well }
  1245. if assigned(old_current_structdef) and
  1246. (df_specialization in old_current_structdef.defoptions) then
  1247. include(current_structdef.defoptions,df_specialization);
  1248. if assigned(old_current_structdef) and
  1249. (df_generic in old_current_structdef.defoptions) then
  1250. begin
  1251. include(current_structdef.defoptions,df_generic);
  1252. current_genericdef:=current_structdef;
  1253. end;
  1254. { set published flag in $M+ mode, it can also be inherited and will
  1255. be added when the parent class set with tobjectdef.set_parent (PFV) }
  1256. if (cs_generate_rtti in current_settings.localswitches) and
  1257. (current_objectdef.objecttype in [odt_interfacecom,odt_class,odt_helper]) then
  1258. include(current_structdef.objectoptions,oo_can_have_published);
  1259. { Objective-C/Java objectdefs can be "formal definitions", in which case
  1260. the syntax is "type tc = objcclass external;" -> we have to parse
  1261. its object options (external) already here, to make sure that such
  1262. definitions are recognised as formal defs }
  1263. if objecttype in [odt_objcclass,odt_objcprotocol,odt_objccategory,odt_javaclass,odt_interfacejava] then
  1264. parse_object_options;
  1265. { forward def? }
  1266. if not assigned(fd) and
  1267. (token=_SEMICOLON) then
  1268. begin
  1269. { add to the list of definitions to check that the forward
  1270. is resolved. this is required for delphi mode }
  1271. current_module.checkforwarddefs.add(current_structdef);
  1272. end
  1273. else
  1274. begin
  1275. { change objccategories into objcclass helpers }
  1276. if (objecttype=odt_objccategory) then
  1277. begin
  1278. current_objectdef.objecttype:=odt_objcclass;
  1279. include(current_structdef.objectoptions,oo_is_classhelper);
  1280. end;
  1281. { include the class helper flag for Object Pascal helpers }
  1282. if (objecttype=odt_helper) then
  1283. include(current_objectdef.objectoptions,oo_is_classhelper);
  1284. { parse list of options (abstract / sealed) }
  1285. if not(objecttype in [odt_objcclass,odt_objcprotocol,odt_objccategory,odt_javaclass,odt_interfacejava]) then
  1286. parse_object_options;
  1287. symtablestack.push(current_structdef.symtable);
  1288. insert_generic_parameter_types(current_structdef,genericdef,genericlist);
  1289. { when we are parsing a generic already then this is a generic as
  1290. well }
  1291. if old_parse_generic then
  1292. include(current_structdef.defoptions, df_generic);
  1293. parse_generic:=(df_generic in current_structdef.defoptions);
  1294. { in non-Delphi modes we need a strict private symbol without type
  1295. count and type parameters in the name to simply resolving }
  1296. maybe_insert_generic_rename_symbol(n,genericlist);
  1297. { parse list of parent classes }
  1298. { for record helpers in mode Delphi this is not allowed }
  1299. if not (is_objectpascal_helper(current_objectdef) and
  1300. (m_delphi in current_settings.modeswitches) and
  1301. (helpertype=ht_record)) then
  1302. parse_parent_classes
  1303. else
  1304. { remove forward flag, is resolved (this is normally done inside
  1305. parse_parent_classes) }
  1306. exclude(current_structdef.objectoptions,oo_is_forward);
  1307. { parse extended type for helpers }
  1308. if is_objectpascal_helper(current_structdef) then
  1309. parse_extended_type(helpertype);
  1310. { parse optional GUID for interfaces }
  1311. parse_guid;
  1312. { classes can handle links to themself not only inside type blocks
  1313. but in const blocks too. to make this possible we need to set
  1314. their symbols to real defs instead of errordef }
  1315. if assigned(objsym) and (objecttype in [odt_class,odt_javaclass,odt_interfacejava]) then
  1316. begin
  1317. olddef:=ttypesym(objsym).typedef;
  1318. ttypesym(objsym).typedef:=current_structdef;
  1319. current_structdef.typesym:=objsym;
  1320. end
  1321. else
  1322. olddef:=nil;
  1323. { parse and insert object members }
  1324. parse_object_members;
  1325. if assigned(olddef) then
  1326. begin
  1327. ttypesym(objsym).typedef:=olddef;
  1328. current_structdef.typesym:=nil;
  1329. end;
  1330. if not(oo_is_external in current_structdef.objectoptions) then
  1331. begin
  1332. { In Java, constructors are not automatically inherited (so you can
  1333. hide them). Emulate the Pascal behaviour for classes implemented
  1334. in Pascal (we cannot do it for classes implemented in Java, since
  1335. we obviously cannot add constructors to those) }
  1336. if is_javaclass(current_structdef) then
  1337. begin
  1338. add_missing_parent_constructors_intf(tobjectdef(current_structdef),true,vis_none);
  1339. {$ifdef jvm}
  1340. maybe_add_public_default_java_constructor(tobjectdef(current_structdef));
  1341. jvm_wrap_virtual_class_methods(tobjectdef(current_structdef));
  1342. {$endif}
  1343. end;
  1344. { need method to hold the initialization code for typed constants? }
  1345. if (target_info.system in systems_typed_constants_node_init) and
  1346. not is_any_interface_kind(current_structdef) then
  1347. add_typedconst_init_routine(current_structdef);
  1348. end;
  1349. symtablestack.pop(current_structdef.symtable);
  1350. end;
  1351. { generate vmt space if needed }
  1352. if not(oo_has_vmt in current_structdef.objectoptions) and
  1353. not(oo_is_forward in current_structdef.objectoptions) and
  1354. (
  1355. ([oo_has_virtual,oo_has_constructor,oo_has_destructor]*current_structdef.objectoptions<>[]) or
  1356. (current_objectdef.objecttype in [odt_class])
  1357. ) then
  1358. current_objectdef.insertvmt;
  1359. { for implemented classes with a vmt check if there is a constructor }
  1360. if (oo_has_vmt in current_structdef.objectoptions) and
  1361. not(oo_is_forward in current_structdef.objectoptions) and
  1362. not(oo_has_constructor in current_structdef.objectoptions) and
  1363. not is_objc_class_or_protocol(current_structdef) and
  1364. not is_java_class_or_interface(current_structdef) then
  1365. Message1(parser_w_virtual_without_constructor,current_structdef.objrealname^);
  1366. if is_interface(current_structdef) or
  1367. is_objcprotocol(current_structdef) or
  1368. is_javainterface(current_structdef) then
  1369. setinterfacemethodoptions
  1370. else if is_objcclass(current_structdef) then
  1371. setobjcclassmethodoptions;
  1372. { if this helper is defined in the implementation section of the unit
  1373. or inside the main project file, the extendeddefs list of the current
  1374. module must be updated (it will be removed when poping the symtable) }
  1375. if is_objectpascal_helper(current_structdef) and
  1376. (current_objectdef.extendeddef.typ in [recorddef,objectdef]) then
  1377. begin
  1378. { the topmost symtable must be a static symtable }
  1379. st:=current_structdef.owner;
  1380. while st.symtabletype in [objectsymtable,recordsymtable] do
  1381. st:=st.defowner.owner;
  1382. if st.symtabletype=staticsymtable then
  1383. begin
  1384. s:=make_mangledname('',tabstractrecorddef(current_objectdef.extendeddef).symtable,'');
  1385. list:=TFPObjectList(current_module.extendeddefs.Find(s));
  1386. if not assigned(list) then
  1387. begin
  1388. list:=TFPObjectList.Create(false);
  1389. current_module.extendeddefs.Add(s, list);
  1390. end;
  1391. list.add(current_structdef);
  1392. end;
  1393. end;
  1394. tabstractrecordsymtable(current_objectdef.symtable).addalignmentpadding;
  1395. { return defined objectdef }
  1396. result:=current_objectdef;
  1397. { restore old state }
  1398. current_structdef:=old_current_structdef;
  1399. current_genericdef:=old_current_genericdef;
  1400. current_specializedef:=old_current_specializedef;
  1401. parse_generic:=old_parse_generic;
  1402. end;
  1403. end.