pdecobj.pas 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. {
  2. $Id$
  3. Copyright (c) 1998-2001 by Florian Klaempfl
  4. Does object types for Free Pascal
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit pdecobj;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. globtype,symtype,symdef;
  23. { parses a object declaration }
  24. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  25. implementation
  26. uses
  27. cutils,cclasses,
  28. globals,verbose,systems,tokens,
  29. aasm,symconst,symbase,symsym,symtable,types,
  30. cgbase,
  31. node,nld,nmem,ncon,ncnv,ncal,pass_1,
  32. scanner,
  33. pbase,pexpr,pdecsub,pdecvar,ptype;
  34. function object_dec(const n : stringid;fd : tobjectdef) : tdef;
  35. { this function parses an object or class declaration }
  36. var
  37. actmembertype : tsymoptions;
  38. there_is_a_destructor : boolean;
  39. classtype : tobjectdeftype;
  40. childof : tobjectdef;
  41. aktclass : tobjectdef;
  42. procedure constructor_head;
  43. begin
  44. consume(_CONSTRUCTOR);
  45. { must be at same level as in implementation }
  46. inc(lexlevel);
  47. parse_proc_head(potype_constructor);
  48. dec(lexlevel);
  49. if (cs_constructor_name in aktglobalswitches) and (aktprocsym.name<>'INIT') then
  50. Message(parser_e_constructorname_must_be_init);
  51. include(aktclass.objectoptions,oo_has_constructor);
  52. consume(_SEMICOLON);
  53. begin
  54. if is_class(aktclass) then
  55. begin
  56. { CLASS constructors return the created instance }
  57. aktprocdef.rettype.def:=aktclass;
  58. end
  59. else
  60. begin
  61. { OBJECT constructors return a boolean }
  62. aktprocdef.rettype:=booltype;
  63. end;
  64. end;
  65. end;
  66. procedure property_dec;
  67. { convert a node tree to symlist and return the last
  68. symbol }
  69. function parse_symlist(pl:tsymlist):boolean;
  70. var
  71. idx : longint;
  72. sym : tsym;
  73. def : tdef;
  74. st : tsymtable;
  75. begin
  76. parse_symlist:=true;
  77. def:=nil;
  78. if token=_ID then
  79. begin
  80. sym:=search_class_member(aktclass,pattern);
  81. if assigned(sym) then
  82. begin
  83. case sym.typ of
  84. varsym :
  85. begin
  86. pl.addsym(sl_load,sym);
  87. def:=tvarsym(sym).vartype.def;
  88. end;
  89. procsym :
  90. begin
  91. pl.addsym(sl_call,sym);
  92. end;
  93. end;
  94. end
  95. else
  96. begin
  97. Message1(parser_e_illegal_field_or_method,pattern);
  98. parse_symlist:=false;
  99. end;
  100. consume(_ID);
  101. repeat
  102. case token of
  103. _ID,
  104. _SEMICOLON :
  105. begin
  106. break;
  107. end;
  108. _POINT :
  109. begin
  110. consume(_POINT);
  111. if assigned(def) then
  112. begin
  113. st:=def.getsymtable(gs_record);
  114. if assigned(st) then
  115. begin
  116. sym:=searchsymonlyin(st,pattern);
  117. if assigned(sym) then
  118. begin
  119. pl.addsym(sl_subscript,sym);
  120. case sym.typ of
  121. varsym :
  122. def:=tvarsym(sym).vartype.def;
  123. else
  124. begin
  125. Message1(sym_e_illegal_field,pattern);
  126. parse_symlist:=false;
  127. end;
  128. end;
  129. end
  130. else
  131. begin
  132. Message1(sym_e_illegal_field,pattern);
  133. parse_symlist:=false;
  134. end;
  135. end
  136. else
  137. begin
  138. Message(cg_e_invalid_qualifier);
  139. parse_symlist:=false;
  140. end;
  141. end;
  142. consume(_ID);
  143. end;
  144. _LECKKLAMMER :
  145. begin
  146. consume(_LECKKLAMMER);
  147. repeat
  148. if def.deftype=arraydef then
  149. begin
  150. idx:=get_intconst;
  151. pl.addconst(sl_vec,idx);
  152. def:=tarraydef(def).elementtype.def;
  153. end
  154. else
  155. begin
  156. Message(cg_e_invalid_qualifier);
  157. parse_symlist:=false;
  158. end;
  159. until not try_to_consume(_COMMA);
  160. consume(_RECKKLAMMER);
  161. end;
  162. else
  163. begin
  164. Message(parser_e_ill_property_access_sym);
  165. parse_symlist:=false;
  166. break;
  167. end;
  168. end;
  169. until false;
  170. end
  171. else
  172. begin
  173. Message(parser_e_ill_property_access_sym);
  174. parse_symlist:=false;
  175. end;
  176. pl.def:=def;
  177. end;
  178. var
  179. sym : tsym;
  180. propertyparas : tlinkedlist;
  181. { returns the matching procedure to access a property }
  182. function get_procdef : tprocdef;
  183. var
  184. p : pprocdeflist;
  185. begin
  186. get_procdef:=nil;
  187. p:=tprocsym(sym).defs;
  188. while assigned(p) do
  189. begin
  190. if equal_paras(p^.def.para,propertyparas,cp_value_equal_const) or
  191. convertable_paras(p^.def.para,propertyparas,cp_value_equal_const) then
  192. begin
  193. get_procdef:=p^.def;
  194. exit;
  195. end;
  196. p:=p^.next;
  197. end;
  198. end;
  199. var
  200. hp2,datacoll : tparaitem;
  201. p : tpropertysym;
  202. overriden : tsym;
  203. hs : string;
  204. varspez : tvarspez;
  205. sc : tidstringlist;
  206. s : string;
  207. tt : ttype;
  208. declarepos : tfileposinfo;
  209. pp : pprocdeflist;
  210. pd : tprocdef;
  211. pt : tnode;
  212. propname : stringid;
  213. begin
  214. { check for a class }
  215. aktprocsym:=nil;
  216. aktprocdef:=nil;
  217. if not((is_class_or_interface(aktclass)) or
  218. ((m_delphi in aktmodeswitches) and (is_object(aktclass)))) then
  219. Message(parser_e_syntax_error);
  220. consume(_PROPERTY);
  221. propertyparas:=TParaLinkedList.Create;
  222. datacoll:=nil;
  223. if token=_ID then
  224. begin
  225. p:=tpropertysym.create(orgpattern);
  226. propname:=pattern;
  227. consume(_ID);
  228. { property parameters ? }
  229. if token=_LECKKLAMMER then
  230. begin
  231. if (sp_published in current_object_option) then
  232. Message(parser_e_cant_publish_that_property);
  233. { create a list of the parameters in propertyparas }
  234. consume(_LECKKLAMMER);
  235. inc(testcurobject);
  236. repeat
  237. if token=_VAR then
  238. begin
  239. consume(_VAR);
  240. varspez:=vs_var;
  241. end
  242. else if token=_CONST then
  243. begin
  244. consume(_CONST);
  245. varspez:=vs_const;
  246. end
  247. else if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  248. begin
  249. consume(_OUT);
  250. varspez:=vs_out;
  251. end
  252. else varspez:=vs_value;
  253. sc:=consume_idlist;
  254. {$ifdef fixLeaksOnError}
  255. strContStack.push(sc);
  256. {$endif fixLeaksOnError}
  257. if token=_COLON then
  258. begin
  259. consume(_COLON);
  260. if token=_ARRAY then
  261. begin
  262. {
  263. if (varspez<>vs_const) and
  264. (varspez<>vs_var) then
  265. begin
  266. varspez:=vs_const;
  267. Message(parser_e_illegal_open_parameter);
  268. end;
  269. }
  270. consume(_ARRAY);
  271. consume(_OF);
  272. { define range and type of range }
  273. tt.setdef(tarraydef.create(0,-1,s32bittype));
  274. { define field type }
  275. single_type(tarraydef(tt.def).elementtype,s,false);
  276. end
  277. else
  278. single_type(tt,s,false);
  279. end
  280. else
  281. tt:=cformaltype;
  282. repeat
  283. s:=sc.get(declarepos);
  284. if s='' then
  285. break;
  286. hp2:=TParaItem.create;
  287. hp2.paratyp:=varspez;
  288. hp2.paratype:=tt;
  289. propertyparas.insert(hp2);
  290. until false;
  291. {$ifdef fixLeaksOnError}
  292. if strContStack.pop <> sc then
  293. writeln('problem with strContStack in ptype');
  294. {$endif fixLeaksOnError}
  295. sc.free;
  296. until not try_to_consume(_SEMICOLON);
  297. dec(testcurobject);
  298. consume(_RECKKLAMMER);
  299. { the parser need to know if a property has parameters, the
  300. index parameter doesn't count (PFV) }
  301. if not(propertyparas.empty) then
  302. include(p.propoptions,ppo_hasparameters);
  303. end;
  304. { overriden property ? }
  305. { force property interface, if there is a property parameter }
  306. if (token=_COLON) or not(propertyparas.empty) then
  307. begin
  308. consume(_COLON);
  309. single_type(p.proptype,hs,false);
  310. if (idtoken=_INDEX) then
  311. begin
  312. consume(_INDEX);
  313. pt:=comp_expr(true);
  314. if is_constnode(pt) and
  315. is_ordinal(pt.resulttype.def) and
  316. (not is_64bitint(pt.resulttype.def)) then
  317. p.index:=tordconstnode(pt).value
  318. else
  319. begin
  320. Message(parser_e_invalid_property_index_value);
  321. p.index:=0;
  322. end;
  323. p.indextype.setdef(pt.resulttype.def);
  324. include(p.propoptions,ppo_indexed);
  325. { concat a longint to the para template }
  326. hp2:=TParaItem.Create;
  327. hp2.paratyp:=vs_value;
  328. hp2.paratype:=p.indextype;
  329. propertyparas.insert(hp2);
  330. pt.free;
  331. end;
  332. end
  333. else
  334. begin
  335. { do an property override }
  336. overriden:=search_class_member(aktclass,propname);
  337. if assigned(overriden) and (overriden.typ=propertysym) then
  338. begin
  339. p.dooverride(tpropertysym(overriden));
  340. end
  341. else
  342. begin
  343. p.proptype:=generrortype;
  344. message(parser_e_no_property_found_to_override);
  345. end;
  346. end;
  347. if (sp_published in current_object_option) and
  348. not(p.proptype.def.is_publishable) then
  349. Message(parser_e_cant_publish_that_property);
  350. { create data defcoll to allow correct parameter checks }
  351. datacoll:=TParaItem.Create;
  352. datacoll.paratyp:=vs_value;
  353. datacoll.paratype:=p.proptype;
  354. if try_to_consume(_READ) then
  355. begin
  356. p.readaccess.clear;
  357. if parse_symlist(p.readaccess) then
  358. begin
  359. sym:=p.readaccess.firstsym^.sym;
  360. case sym.typ of
  361. procsym :
  362. begin
  363. pd:=get_procdef;
  364. if not(assigned(pd)) or
  365. not(is_equal(pd.rettype.def,p.proptype.def)) then
  366. Message(parser_e_ill_property_access_sym);
  367. p.readaccess.setdef(pd);
  368. end;
  369. varsym :
  370. begin
  371. if CheckTypes(p.readaccess.def,p.proptype.def) then
  372. begin
  373. { property parameters are allowed if this is
  374. an indexed property, because the index is then
  375. the parameter.
  376. Note: In the help of Kylix it is written
  377. that it isn't allowed, but the compiler accepts it (PFV) }
  378. if (ppo_hasparameters in p.propoptions) then
  379. Message(parser_e_ill_property_access_sym);
  380. end;
  381. end;
  382. else
  383. Message(parser_e_ill_property_access_sym);
  384. end;
  385. end;
  386. end;
  387. if try_to_consume(_WRITE) then
  388. begin
  389. p.writeaccess.clear;
  390. if parse_symlist(p.writeaccess) then
  391. begin
  392. sym:=p.writeaccess.firstsym^.sym;
  393. case sym.typ of
  394. procsym :
  395. begin
  396. { insert data entry to check access method }
  397. propertyparas.insert(datacoll);
  398. pd:=get_procdef;
  399. { ... and remove it }
  400. propertyparas.remove(datacoll);
  401. if not(assigned(pd)) then
  402. Message(parser_e_ill_property_access_sym);
  403. p.writeaccess.setdef(pd);
  404. end;
  405. varsym :
  406. begin
  407. if CheckTypes(p.writeaccess.def,p.proptype.def) then
  408. begin
  409. { property parameters are allowed if this is
  410. an indexed property, because the index is then
  411. the parameter.
  412. Note: In the help of Kylix it is written
  413. that it isn't allowed, but the compiler accepts it (PFV) }
  414. if (ppo_hasparameters in p.propoptions) then
  415. Message(parser_e_ill_property_access_sym);
  416. end;
  417. end;
  418. else
  419. Message(parser_e_ill_property_access_sym);
  420. end;
  421. end;
  422. end;
  423. include(p.propoptions,ppo_stored);
  424. if try_to_consume(_STORED) then
  425. begin
  426. p.storedaccess.clear;
  427. case token of
  428. _ID:
  429. begin
  430. { in the case that idtoken=_DEFAULT }
  431. { we have to do nothing except }
  432. { setting ppo_stored, it's the same }
  433. { as stored true }
  434. if idtoken<>_DEFAULT then
  435. begin
  436. if parse_symlist(p.storedaccess) then
  437. begin
  438. sym:=p.storedaccess.firstsym^.sym;
  439. case sym.typ of
  440. procsym :
  441. begin
  442. pp:=tprocsym(sym).defs;
  443. while assigned(pp) do
  444. begin
  445. { the stored function shouldn't have any parameters }
  446. if pp^.def.Para.empty then
  447. break;
  448. pp:=pp^.next;
  449. end;
  450. { found we a procedure and does it really return a bool? }
  451. if assigned(pp) and
  452. is_boolean(pp^.def.rettype.def) then
  453. p.storedaccess.setdef(pp^.def)
  454. else
  455. Message(parser_e_ill_property_storage_sym);
  456. end;
  457. varsym :
  458. begin
  459. if (ppo_hasparameters in p.propoptions) or
  460. not(is_boolean(p.storedaccess.def)) then
  461. Message(parser_e_stored_property_must_be_boolean);
  462. end;
  463. else
  464. Message(parser_e_ill_property_access_sym);
  465. end;
  466. end;
  467. end;
  468. end;
  469. _FALSE:
  470. begin
  471. consume(_FALSE);
  472. exclude(p.propoptions,ppo_stored);
  473. end;
  474. _TRUE:
  475. consume(_TRUE);
  476. end;
  477. end;
  478. if try_to_consume(_DEFAULT) then
  479. begin
  480. if not(is_ordinal(p.proptype.def) or
  481. is_64bitint(p.proptype.def) or
  482. ((p.proptype.def.deftype=setdef) and
  483. (tsetdef(p.proptype.def).settype=smallset))) or
  484. not(propertyparas.empty) then
  485. Message(parser_e_property_cant_have_a_default_value);
  486. { Get the result of the default, the firstpass is
  487. needed to support values like -1 }
  488. pt:=comp_expr(true);
  489. if (p.proptype.def.deftype=setdef) and
  490. (pt.nodetype=arrayconstructorn) then
  491. begin
  492. arrayconstructor_to_set(tarrayconstructornode(pt));
  493. do_resulttypepass(pt);
  494. end;
  495. inserttypeconv(pt,p.proptype);
  496. if not(is_constnode(pt)) then
  497. Message(parser_e_property_default_value_must_const);
  498. if pt.nodetype=setconstn then
  499. p.default:=plongint(tsetconstnode(pt).value_set)^
  500. else
  501. p.default:=tordconstnode(pt).value;
  502. pt.free;
  503. end
  504. else if try_to_consume(_NODEFAULT) then
  505. begin
  506. p.default:=0;
  507. end;
  508. symtablestack.insert(p);
  509. { default property ? }
  510. consume(_SEMICOLON);
  511. if (idtoken=_DEFAULT) then
  512. begin
  513. consume(_DEFAULT);
  514. { overriding a default propertyp is allowed
  515. p2:=search_default_property(aktclass);
  516. if assigned(p2) then
  517. message1(parser_e_only_one_default_property,
  518. tobjectdef(p2.owner.defowner)^.objname^)
  519. else
  520. }
  521. begin
  522. include(p.propoptions,ppo_defaultproperty);
  523. if propertyparas.empty then
  524. message(parser_e_property_need_paras);
  525. end;
  526. consume(_SEMICOLON);
  527. end;
  528. { clean up }
  529. if assigned(datacoll) then
  530. datacoll.free;
  531. end
  532. else
  533. begin
  534. consume(_ID);
  535. consume(_SEMICOLON);
  536. end;
  537. propertyparas.free;
  538. end;
  539. procedure destructor_head;
  540. begin
  541. consume(_DESTRUCTOR);
  542. inc(lexlevel);
  543. parse_proc_head(potype_destructor);
  544. dec(lexlevel);
  545. if (cs_constructor_name in aktglobalswitches) and (aktprocsym.name<>'DONE') then
  546. Message(parser_e_destructorname_must_be_done);
  547. include(aktclass.objectoptions,oo_has_destructor);
  548. consume(_SEMICOLON);
  549. if not(aktprocdef.Para.empty) then
  550. if not (m_tp in aktmodeswitches) then
  551. Message(parser_e_no_paras_for_destructor);
  552. { no return value }
  553. aktprocdef.rettype:=voidtype;
  554. end;
  555. var
  556. hs : string;
  557. pcrd : tclassrefdef;
  558. tt : ttype;
  559. oldprocinfo : pprocinfo;
  560. oldprocsym : tprocsym;
  561. oldprocdef : tprocdef;
  562. oldparse_only : boolean;
  563. storetypecanbeforward : boolean;
  564. procedure setclassattributes;
  565. begin
  566. { publishable }
  567. if classtype in [odt_interfacecom,odt_class] then
  568. begin
  569. aktclass.objecttype:=classtype;
  570. if (cs_generate_rtti in aktlocalswitches) or
  571. (assigned(aktclass.childof) and
  572. (oo_can_have_published in aktclass.childof.objectoptions)) then
  573. begin
  574. include(aktclass.objectoptions,oo_can_have_published);
  575. { in "publishable" classes the default access type is published }
  576. actmembertype:=[sp_published];
  577. { don't know if this is necessary (FK) }
  578. current_object_option:=[sp_published];
  579. end;
  580. end;
  581. end;
  582. procedure setclassparent;
  583. begin
  584. if assigned(fd) then
  585. aktclass:=fd
  586. else
  587. aktclass:=tobjectdef.create(classtype,n,nil);
  588. { is the current class tobject? }
  589. { so you could define your own tobject }
  590. if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_class) and (upper(n)='TOBJECT') then
  591. class_tobject:=aktclass
  592. else if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  593. interface_iunknown:=aktclass
  594. else
  595. begin
  596. case classtype of
  597. odt_class:
  598. childof:=class_tobject;
  599. odt_interfacecom:
  600. childof:=interface_iunknown;
  601. end;
  602. if (oo_is_forward in childof.objectoptions) then
  603. Message1(parser_e_forward_declaration_must_be_resolved,childof.objname^);
  604. aktclass.set_parent(childof);
  605. end;
  606. end;
  607. procedure setinterfacemethodoptions;
  608. var
  609. i: longint;
  610. defs: TIndexArray;
  611. pd: tprocdef;
  612. begin
  613. include(aktclass.objectoptions,oo_has_virtual);
  614. defs:=aktclass.symtable.defindex;
  615. for i:=1 to defs.count do
  616. begin
  617. pd:=tprocdef(defs.search(i));
  618. if pd.deftype=procdef then
  619. begin
  620. pd.extnumber:=aktclass.lastvtableindex;
  621. inc(aktclass.lastvtableindex);
  622. include(pd.procoptions,po_virtualmethod);
  623. pd.forwarddef:=false;
  624. end;
  625. end;
  626. end;
  627. function readobjecttype : boolean;
  628. begin
  629. readobjecttype:=true;
  630. { distinguish classes and objects }
  631. case token of
  632. _OBJECT:
  633. begin
  634. classtype:=odt_object;
  635. consume(_OBJECT)
  636. end;
  637. _CPPCLASS:
  638. begin
  639. classtype:=odt_cppclass;
  640. consume(_CPPCLASS);
  641. end;
  642. _INTERFACE:
  643. begin
  644. if aktinterfacetype=it_interfacecom then
  645. classtype:=odt_interfacecom
  646. else {it_interfacecorba}
  647. classtype:=odt_interfacecorba;
  648. consume(_INTERFACE);
  649. { forward declaration }
  650. if not(assigned(fd)) and (token=_SEMICOLON) then
  651. begin
  652. { also anonym objects aren't allow (o : object a : longint; end;) }
  653. if n='' then
  654. Message(parser_f_no_anonym_objects);
  655. aktclass:=tobjectdef.create(classtype,n,nil);
  656. if (cs_compilesystem in aktmoduleswitches) and
  657. (classtype=odt_interfacecom) and (upper(n)='IUNKNOWN') then
  658. interface_iunknown:=aktclass;
  659. include(aktclass.objectoptions,oo_is_forward);
  660. object_dec:=aktclass;
  661. typecanbeforward:=storetypecanbeforward;
  662. readobjecttype:=false;
  663. exit;
  664. end;
  665. end;
  666. _CLASS:
  667. begin
  668. classtype:=odt_class;
  669. consume(_CLASS);
  670. if not(assigned(fd)) and
  671. (token=_OF) and
  672. { Delphi only allows class of in type blocks.
  673. Note that when parsing the type of a variable declaration
  674. the blocktype is bt_type so the check for typecanbeforward
  675. is also necessary (PFV) }
  676. (((block_type=bt_type) and typecanbeforward) or
  677. not(m_delphi in aktmodeswitches)) then
  678. begin
  679. { a hack, but it's easy to handle }
  680. { class reference type }
  681. consume(_OF);
  682. single_type(tt,hs,typecanbeforward);
  683. { accept hp1, if is a forward def or a class }
  684. if (tt.def.deftype=forwarddef) or
  685. is_class(tt.def) then
  686. begin
  687. pcrd:=tclassrefdef.create(tt);
  688. object_dec:=pcrd;
  689. end
  690. else
  691. begin
  692. object_dec:=generrortype.def;
  693. Message1(type_e_class_type_expected,generrortype.def.typename);
  694. end;
  695. typecanbeforward:=storetypecanbeforward;
  696. readobjecttype:=false;
  697. exit;
  698. end
  699. { forward class }
  700. else if not(assigned(fd)) and (token=_SEMICOLON) then
  701. begin
  702. { also anonym objects aren't allow (o : object a : longint; end;) }
  703. if n='' then
  704. Message(parser_f_no_anonym_objects);
  705. aktclass:=tobjectdef.create(odt_class,n,nil);
  706. if (cs_compilesystem in aktmoduleswitches) and (upper(n)='TOBJECT') then
  707. class_tobject:=aktclass;
  708. aktclass.objecttype:=odt_class;
  709. include(aktclass.objectoptions,oo_is_forward);
  710. { all classes must have a vmt !! at offset zero }
  711. if not(oo_has_vmt in aktclass.objectoptions) then
  712. aktclass.insertvmt;
  713. object_dec:=aktclass;
  714. typecanbeforward:=storetypecanbeforward;
  715. readobjecttype:=false;
  716. exit;
  717. end;
  718. end;
  719. else
  720. begin
  721. classtype:=odt_class; { this is error but try to recover }
  722. consume(_OBJECT);
  723. end;
  724. end;
  725. end;
  726. procedure readimplementedinterfaces;
  727. var
  728. implintf: tobjectdef;
  729. tt : ttype;
  730. begin
  731. while try_to_consume(_COMMA) do begin
  732. id_type(tt,pattern,false);
  733. implintf:=tobjectdef(tt.def);
  734. if (tt.def.deftype<>objectdef) then begin
  735. Message1(type_e_interface_type_expected,tt.def.typename);
  736. Continue; { omit }
  737. end;
  738. if not is_interface(implintf) then begin
  739. Message1(type_e_interface_type_expected,implintf.typename);
  740. Continue; { omit }
  741. end;
  742. if aktclass.implementedinterfaces.searchintf(tt.def)<>-1 then
  743. Message1(sym_e_duplicate_id,tt.def.name)
  744. else
  745. aktclass.implementedinterfaces.addintf(tt.def);
  746. end;
  747. end;
  748. procedure readinterfaceiid;
  749. var
  750. p : tnode;
  751. begin
  752. p:=comp_expr(true);
  753. if p.nodetype=stringconstn then
  754. begin
  755. aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
  756. p.free;
  757. aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
  758. if (classtype=odt_interfacecom) and not aktclass.isiidguidvalid then
  759. Message(parser_e_improper_guid_syntax);
  760. end
  761. else
  762. begin
  763. p.free;
  764. Message(cg_e_illegal_expression);
  765. end;
  766. end;
  767. procedure readparentclasses;
  768. begin
  769. { reads the parent class }
  770. if token=_LKLAMMER then
  771. begin
  772. consume(_LKLAMMER);
  773. id_type(tt,pattern,false);
  774. childof:=tobjectdef(tt.def);
  775. if (not assigned(childof)) or
  776. (childof.deftype<>objectdef) then
  777. begin
  778. if assigned(childof) then
  779. Message1(type_e_class_type_expected,childof.typename);
  780. childof:=nil;
  781. aktclass:=tobjectdef.create(classtype,n,nil);
  782. end
  783. else
  784. begin
  785. { a mix of class, interfaces, objects and cppclasses
  786. isn't allowed }
  787. case classtype of
  788. odt_class:
  789. if not(is_class(childof)) and
  790. not(is_interface(childof)) then
  791. Message(parser_e_mix_of_classes_and_objects);
  792. odt_interfacecorba,
  793. odt_interfacecom:
  794. if not(is_interface(childof)) then
  795. Message(parser_e_mix_of_classes_and_objects);
  796. odt_cppclass:
  797. if not(is_cppclass(childof)) then
  798. Message(parser_e_mix_of_classes_and_objects);
  799. odt_object:
  800. if not(is_object(childof)) then
  801. Message(parser_e_mix_of_classes_and_objects);
  802. end;
  803. { the forward of the child must be resolved to get
  804. correct field addresses }
  805. if assigned(fd) then
  806. begin
  807. if (oo_is_forward in childof.objectoptions) then
  808. Message1(parser_e_forward_declaration_must_be_resolved,childof.objname^);
  809. aktclass:=fd;
  810. { we must inherit several options !!
  811. this was missing !!
  812. all is now done in set_parent
  813. including symtable datasize setting PM }
  814. fd.set_parent(childof);
  815. end
  816. else
  817. aktclass:=tobjectdef.create(classtype,n,childof);
  818. if aktclass.objecttype=odt_class then
  819. readimplementedinterfaces;
  820. end;
  821. consume(_RKLAMMER);
  822. end
  823. { if no parent class, then a class get tobject as parent }
  824. else if classtype in [odt_class,odt_interfacecom] then
  825. setclassparent
  826. else
  827. aktclass:=tobjectdef.create(classtype,n,nil);
  828. { read GUID }
  829. if (classtype in [odt_interfacecom,odt_interfacecorba]) and
  830. try_to_consume(_LECKKLAMMER) then
  831. begin
  832. readinterfaceiid;
  833. consume(_RECKKLAMMER);
  834. end;
  835. end;
  836. procedure chkcpp;
  837. begin
  838. if is_cppclass(aktclass) then
  839. begin
  840. aktprocdef.proccalloption:=pocall_cppdecl;
  841. aktprocdef.setmangledname(
  842. target_info.Cprefix+aktprocdef.cplusplusmangledname);
  843. end;
  844. end;
  845. begin
  846. {Nowadays aktprocsym may already have a value, so we need to save
  847. it.}
  848. oldprocdef:=aktprocdef;
  849. oldprocsym:=aktprocsym;
  850. { forward is resolved }
  851. if assigned(fd) then
  852. exclude(fd.objectoptions,oo_is_forward);
  853. there_is_a_destructor:=false;
  854. actmembertype:=[sp_public];
  855. { objects and class types can't be declared local }
  856. if not(symtablestack.symtabletype in [globalsymtable,staticsymtable]) then
  857. Message(parser_e_no_local_objects);
  858. storetypecanbeforward:=typecanbeforward;
  859. { for tp mode don't allow forward types }
  860. if (m_tp in aktmodeswitches) and
  861. not (m_delphi in aktmodeswitches) then
  862. typecanbeforward:=false;
  863. if not(readobjecttype) then
  864. exit;
  865. { also anonym objects aren't allow (o : object a : longint; end;) }
  866. if n='' then
  867. Message(parser_f_no_anonym_objects);
  868. readparentclasses;
  869. { default access is public }
  870. actmembertype:=[sp_public];
  871. { set class flags and inherits published, if necessary? }
  872. setclassattributes;
  873. aktobjectdef:=aktclass;
  874. aktclass.symtable.next:=symtablestack;
  875. symtablestack:=aktclass.symtable;
  876. testcurobject:=1;
  877. curobjectname:=Upper(n);
  878. { new procinfo }
  879. oldprocinfo:=procinfo;
  880. new(procinfo,init);
  881. procinfo^._class:=aktclass;
  882. { short class declaration ? }
  883. if (classtype<>odt_class) or (token<>_SEMICOLON) then
  884. begin
  885. { Parse componenten }
  886. repeat
  887. if (sp_private in actmembertype) then
  888. include(aktclass.objectoptions,oo_has_private);
  889. if (sp_protected in actmembertype) then
  890. include(aktclass.objectoptions,oo_has_protected);
  891. case token of
  892. _ID :
  893. begin
  894. case idtoken of
  895. _PRIVATE :
  896. begin
  897. if is_interface(aktclass) then
  898. Message(parser_e_no_access_specifier_in_interfaces);
  899. consume(_PRIVATE);
  900. actmembertype:=[sp_private];
  901. current_object_option:=[sp_private];
  902. end;
  903. _PROTECTED :
  904. begin
  905. if is_interface(aktclass) then
  906. Message(parser_e_no_access_specifier_in_interfaces);
  907. consume(_PROTECTED);
  908. current_object_option:=[sp_protected];
  909. actmembertype:=[sp_protected];
  910. end;
  911. _PUBLIC :
  912. begin
  913. if is_interface(aktclass) then
  914. Message(parser_e_no_access_specifier_in_interfaces);
  915. consume(_PUBLIC);
  916. current_object_option:=[sp_public];
  917. actmembertype:=[sp_public];
  918. end;
  919. _PUBLISHED :
  920. begin
  921. if is_interface(aktclass) then
  922. Message(parser_e_no_access_specifier_in_interfaces)
  923. else
  924. if not(oo_can_have_published in aktclass.objectoptions) then
  925. Message(parser_e_cant_have_published);
  926. consume(_PUBLISHED);
  927. current_object_option:=[sp_published];
  928. actmembertype:=[sp_published];
  929. end;
  930. else
  931. begin
  932. if is_interface(aktclass) then
  933. Message(parser_e_no_vars_in_interfaces);
  934. read_var_decs(false,true,false);
  935. end;
  936. end;
  937. end;
  938. _PROPERTY :
  939. begin
  940. property_dec;
  941. end;
  942. _PROCEDURE,
  943. _FUNCTION,
  944. _CLASS :
  945. begin
  946. oldparse_only:=parse_only;
  947. parse_only:=true;
  948. parse_proc_dec;
  949. { this is for error recovery as well as forward }
  950. { interface mappings, i.e. mapping to a method }
  951. { which isn't declared yet }
  952. if assigned(aktprocsym) then
  953. begin
  954. parse_object_proc_directives(aktprocsym);
  955. { add definition to procsym }
  956. proc_add_definition(aktprocsym,aktprocdef);
  957. { add procdef options to objectdef options }
  958. if (po_msgint in aktprocdef.procoptions) then
  959. include(aktclass.objectoptions,oo_has_msgint);
  960. if (po_msgstr in aktprocdef.procoptions) then
  961. include(aktclass.objectoptions,oo_has_msgstr);
  962. if (po_virtualmethod in aktprocdef.procoptions) then
  963. include(aktclass.objectoptions,oo_has_virtual);
  964. chkcpp;
  965. end;
  966. parse_only:=oldparse_only;
  967. end;
  968. _CONSTRUCTOR :
  969. begin
  970. if not(sp_public in actmembertype) then
  971. Message(parser_w_constructor_should_be_public);
  972. if is_interface(aktclass) then
  973. Message(parser_e_no_con_des_in_interfaces);
  974. oldparse_only:=parse_only;
  975. parse_only:=true;
  976. constructor_head;
  977. parse_object_proc_directives(aktprocsym);
  978. { add definition to procsym }
  979. proc_add_definition(aktprocsym,aktprocdef);
  980. { add procdef options to objectdef options }
  981. if (po_virtualmethod in aktprocdef.procoptions) then
  982. include(aktclass.objectoptions,oo_has_virtual);
  983. chkcpp;
  984. parse_only:=oldparse_only;
  985. end;
  986. _DESTRUCTOR :
  987. begin
  988. if there_is_a_destructor then
  989. Message(parser_n_only_one_destructor);
  990. if is_interface(aktclass) then
  991. Message(parser_e_no_con_des_in_interfaces);
  992. there_is_a_destructor:=true;
  993. if not(sp_public in actmembertype) then
  994. Message(parser_w_destructor_should_be_public);
  995. oldparse_only:=parse_only;
  996. parse_only:=true;
  997. destructor_head;
  998. parse_object_proc_directives(aktprocsym);
  999. { add definition to procsym }
  1000. proc_add_definition(aktprocsym,aktprocdef);
  1001. { add procdef options to objectdef options }
  1002. if (po_virtualmethod in aktprocdef.procoptions) then
  1003. include(aktclass.objectoptions,oo_has_virtual);
  1004. chkcpp;
  1005. parse_only:=oldparse_only;
  1006. end;
  1007. _END :
  1008. begin
  1009. consume(_END);
  1010. break;
  1011. end;
  1012. else
  1013. consume(_ID); { Give a ident expected message, like tp7 }
  1014. end;
  1015. until false;
  1016. current_object_option:=[sp_public];
  1017. end;
  1018. { generate vmt space if needed }
  1019. if not(oo_has_vmt in aktclass.objectoptions) and
  1020. (([oo_has_virtual,oo_has_constructor,oo_has_destructor]*aktclass.objectoptions<>[]) or
  1021. (classtype in [odt_class])
  1022. ) then
  1023. aktclass.insertvmt;
  1024. if is_interface(aktclass) then
  1025. setinterfacemethodoptions;
  1026. { reset }
  1027. testcurobject:=0;
  1028. curobjectname:='';
  1029. typecanbeforward:=storetypecanbeforward;
  1030. { restore old state }
  1031. symtablestack:=symtablestack.next;
  1032. aktobjectdef:=nil;
  1033. {Restore procinfo}
  1034. dispose(procinfo,done);
  1035. procinfo:=oldprocinfo;
  1036. {Restore the aktprocsym.}
  1037. aktprocsym:=oldprocsym;
  1038. aktprocdef:=oldprocdef;
  1039. object_dec:=aktclass;
  1040. end;
  1041. end.
  1042. {
  1043. $Log$
  1044. Revision 1.34 2001-12-06 17:57:35 florian
  1045. + parasym to tparaitem added
  1046. Revision 1.33 2001/11/02 22:58:02 peter
  1047. * procsym definition rewrite
  1048. Revision 1.32 2001/10/25 21:22:35 peter
  1049. * calling convention rewrite
  1050. Revision 1.31 2001/10/21 13:10:50 peter
  1051. * better support for indexed properties
  1052. Revision 1.30 2001/10/21 12:33:06 peter
  1053. * array access for properties added
  1054. Revision 1.29 2001/08/30 20:13:53 peter
  1055. * rtti/init table updates
  1056. * rttisym for reusable global rtti/init info
  1057. * support published for interfaces
  1058. Revision 1.28 2001/08/26 13:36:44 florian
  1059. * some cg reorganisation
  1060. * some PPC updates
  1061. Revision 1.27 2001/08/22 21:16:20 florian
  1062. * some interfaces related problems regarding
  1063. mapping of interface implementions fixed
  1064. Revision 1.26 2001/06/03 21:57:36 peter
  1065. + hint directive parsing support
  1066. Revision 1.25 2001/05/04 15:52:03 florian
  1067. * some Delphi incompatibilities fixed:
  1068. - out, dispose and new can be used as idenfiers now
  1069. - const p = apointerype(nil); is supported now
  1070. + support for const p = apointertype(pointer(1234)); added
  1071. Revision 1.24 2001/04/21 15:36:00 peter
  1072. * check for type block when parsing class of
  1073. Revision 1.23 2001/04/21 13:37:16 peter
  1074. * made tclassheader using class of to implement cpu dependent code
  1075. Revision 1.22 2001/04/18 22:01:54 peter
  1076. * registration of targets and assemblers
  1077. Revision 1.21 2001/04/13 01:22:11 peter
  1078. * symtable change to classes
  1079. * range check generation and errors fixed, make cycle DEBUG=1 works
  1080. * memory leaks fixed
  1081. Revision 1.20 2001/04/04 22:43:51 peter
  1082. * remove unnecessary calls to firstpass
  1083. Revision 1.19 2001/04/04 21:30:43 florian
  1084. * applied several fixes to get the DD8 Delphi Unit compiled
  1085. e.g. "forward"-interfaces are working now
  1086. Revision 1.18 2001/04/02 21:20:31 peter
  1087. * resulttype rewrite
  1088. Revision 1.17 2001/03/16 14:56:38 marco
  1089. * Pavel's fixes commited (Peter asked). Cycled to test
  1090. Revision 1.16 2001/03/11 22:58:49 peter
  1091. * getsym redesign, removed the globals srsym,srsymtable
  1092. Revision 1.15 2000/12/25 00:07:27 peter
  1093. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1094. tlinkedlist objects)
  1095. Revision 1.14 2000/11/29 00:30:35 florian
  1096. * unused units removed from uses clause
  1097. * some changes for widestrings
  1098. Revision 1.13 2000/11/17 17:32:58 florian
  1099. * properties can now be used in interfaces
  1100. Revision 1.12 2000/11/17 08:21:07 florian
  1101. *** empty log message ***
  1102. Revision 1.11 2000/11/12 23:24:11 florian
  1103. * interfaces are basically running
  1104. Revision 1.10 2000/11/12 22:17:47 peter
  1105. * some realname updates for messages
  1106. Revision 1.9 2000/11/06 23:05:52 florian
  1107. * more fixes
  1108. Revision 1.8 2000/11/06 20:30:55 peter
  1109. * more fixes to get make cycle working
  1110. Revision 1.7 2000/11/04 18:03:57 florian
  1111. * fixed upper/lower case problem
  1112. Revision 1.6 2000/11/04 17:31:00 florian
  1113. * fixed some problems of previous commit
  1114. Revision 1.5 2000/11/04 14:25:20 florian
  1115. + merged Attila's changes for interfaces, not tested yet
  1116. Revision 1.4 2000/10/31 22:02:49 peter
  1117. * symtable splitted, no real code changes
  1118. Revision 1.3 2000/10/26 21:54:03 peter
  1119. * fixed crash with error in child definition (merged)
  1120. Revision 1.2 2000/10/21 18:16:11 florian
  1121. * a lot of changes:
  1122. - basic dyn. array support
  1123. - basic C++ support
  1124. - some work for interfaces done
  1125. ....
  1126. Revision 1.1 2000/10/14 10:14:51 peter
  1127. * moehrendorf oct 2000 rewrite
  1128. }