pdecl.pas 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Does declaration parsing 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 pdecl;
  19. interface
  20. uses
  21. globals,symtable;
  22. var
  23. { pointer to the last read type symbol, (for "forward" }
  24. { types) }
  25. lasttypesym : ptypesym;
  26. { hack, which allows to use the current parsed }
  27. { object type as function argument type }
  28. testcurobject : byte;
  29. curobjectname : stringid;
  30. { reads a string type with optional length }
  31. { and returns a pointer to the string }
  32. { definition }
  33. function stringtype : pdef;
  34. { reads a string, file type or a type id and returns a name and }
  35. { pdef }
  36. function single_type(var s : string) : pdef;
  37. { reads the declaration blocks }
  38. procedure read_declarations(islibrary : boolean);
  39. { reads declarations in the interface part of a unit }
  40. procedure read_interface_declarations;
  41. implementation
  42. uses
  43. cobjects,scanner,aasm,tree,pass_1,
  44. types,hcodegen,verbose,systems
  45. {$ifdef GDB}
  46. ,gdb
  47. {$endif GDB}
  48. { parser specific stuff }
  49. ,pbase,ptconst,pexpr,psub,pexports
  50. { processor specific stuff }
  51. {$ifdef i386}
  52. ,i386
  53. {$endif}
  54. {$ifdef m68k}
  55. ,m68k
  56. {$endif}
  57. ;
  58. function read_type(const name : stringid) : pdef;forward;
  59. procedure read_var_decs(is_record : boolean;do_absolute : boolean);forward;
  60. procedure const_dec;
  61. var
  62. name : stringid;
  63. p : ptree;
  64. def : pdef;
  65. ps : pconstset;
  66. pd : pdouble;
  67. begin
  68. consume(_CONST);
  69. repeat
  70. name:=pattern;
  71. consume(ID);
  72. case token of
  73. EQUAL:
  74. begin
  75. consume(EQUAL);
  76. p:=expr;
  77. do_firstpass(p);
  78. case p^.treetype of
  79. ordconstn:
  80. begin
  81. if is_constintnode(p) then
  82. symtablestack^.insert(new(pconstsym,init(name,constint,p^.value,nil)))
  83. else if is_constcharnode(p) then
  84. symtablestack^.insert(new(pconstsym,init(name,constchar,p^.value,nil)))
  85. else if is_constboolnode(p) then
  86. symtablestack^.insert(new(pconstsym,init(name,constbool,p^.value,nil)))
  87. else if p^.resulttype^.deftype=enumdef then
  88. symtablestack^.insert(new(pconstsym,init(name,constord,p^.value,p^.resulttype)))
  89. else internalerror(111);
  90. end;
  91. stringconstn:
  92. {values is disposed with p so I need a copy !}
  93. symtablestack^.insert(new(pconstsym,init(name,conststring,longint(stringdup(p^.values^)),nil)));
  94. realconstn : begin
  95. new(pd);
  96. pd^:=p^.valued;
  97. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd),nil)));
  98. end;
  99. setconstrn : begin
  100. new(ps);
  101. ps^:=p^.constset^;
  102. symtablestack^.insert(new(pconstsym,init(name,
  103. constseta,longint(ps),p^.resulttype)));
  104. end;
  105. else Message(cg_e_illegal_expression);
  106. end;
  107. consume(SEMICOLON);
  108. end;
  109. COLON:
  110. begin
  111. { this was missed, so const s : ^string = nil gives an
  112. error (FK)
  113. }
  114. block_type:=bt_type;
  115. consume(COLON);
  116. ignore_equal:=true;
  117. def:=read_type('');
  118. block_type:=bt_type;
  119. ignore_equal:=false;
  120. symtablestack^.insert(new(ptypedconstsym,init(name,def)));
  121. consume(EQUAL);
  122. readtypedconst(def);
  123. consume(SEMICOLON);
  124. end;
  125. else consume(EQUAL);
  126. end;
  127. until token<>ID;
  128. end;
  129. procedure label_dec;
  130. var
  131. hl : plabel;
  132. begin
  133. consume(_LABEL);
  134. if not(cs_support_goto in aktswitches) then
  135. Message(sym_e_goto_and_label_not_supported);
  136. repeat
  137. if not(token in [ID,INTCONST]) then
  138. consume(ID)
  139. else
  140. begin
  141. getlabel(hl);
  142. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  143. consume(token);
  144. end;
  145. if token<>SEMICOLON then consume(COMMA);
  146. until not(token in [ID,INTCONST]);
  147. consume(SEMICOLON);
  148. end;
  149. { reads a string type with optional length }
  150. { and returns a pointer to the string }
  151. { definition }
  152. function stringtype : pdef;
  153. var
  154. p : ptree;
  155. d : pdef;
  156. begin
  157. consume(_STRING);
  158. if token=LECKKLAMMER then
  159. begin
  160. consume(LECKKLAMMER);
  161. p:=expr;
  162. do_firstpass(p);
  163. if not is_constintnode(p) then
  164. Message(cg_e_illegal_expression);
  165. {$ifndef UseLongString}
  166. if (p^.value<1) or (p^.value>255) then
  167. begin
  168. Message(parser_e_string_too_long);
  169. p^.value:=255;
  170. end;
  171. consume(RECKKLAMMER);
  172. if p^.value<>255 then
  173. d:=new(pstringdef,init(p^.value))
  174. {$ifndef GDB}
  175. else d:=new(pstringdef,init(255));
  176. {$else * GDB *}
  177. else d:=globaldef('SYSTEM.STRING');
  178. {$endif * GDB *}
  179. {$else UseLongString}
  180. if p^.value>255 then
  181. d:=new(pstringdef,longinit(p^.value)
  182. else if p^.value<>255 then
  183. d:=new(pstringdef,init(p^.value))
  184. {$ifndef GDB}
  185. else d:=new(pstringdef,init(255));
  186. {$else * GDB *}
  187. else d:=globaldef('SYSTEM.STRING');
  188. {$endif * GDB *}
  189. {$endif UseLongString}
  190. disposetree(p);
  191. end
  192. {$ifndef GDB}
  193. else d:=new(pstringdef,init(255));
  194. {$else * GDB *}
  195. else d:=globaldef('SYSTEM.STRING');
  196. {$endif * GDB *}
  197. stringtype:=d;
  198. end;
  199. { reads a type definition and returns a pointer }
  200. { to a appropriating pdef, s gets the name of }
  201. { the type to allow name mangling }
  202. function id_type(var s : string) : pdef;
  203. begin
  204. s:=pattern;
  205. consume(ID);
  206. if (testcurobject=2) and (curobjectname=pattern) then
  207. begin
  208. id_type:=aktobjectdef;
  209. exit;
  210. end;
  211. getsym(s,true);
  212. if assigned(srsym) then
  213. begin
  214. if srsym^.typ=unitsym then
  215. begin
  216. consume(POINT);
  217. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  218. s:=pattern;
  219. consume(ID);
  220. end;
  221. if srsym^.typ<>typesym then
  222. begin
  223. Message(sym_e_type_id_expected);
  224. lasttypesym:=ptypesym(srsym);
  225. id_type:=generrordef;
  226. exit;
  227. end;
  228. end;
  229. lasttypesym:=ptypesym(srsym);
  230. id_type:=ptypesym(srsym)^.definition;
  231. end;
  232. { reads a string, file type or a type id and returns a name and }
  233. { pdef }
  234. function single_type(var s : string) : pdef;
  235. var
  236. hs : string;
  237. begin
  238. case token of
  239. _STRING:
  240. begin
  241. single_type:=stringtype;
  242. s:='STRING';
  243. lasttypesym:=nil;
  244. end;
  245. _FILE:
  246. begin
  247. consume(_FILE);
  248. if token=_OF then
  249. begin
  250. consume(_OF);
  251. single_type:=new(pfiledef,init(ft_typed,single_type(hs)));
  252. s:='FILE$OF$'+hs;
  253. end
  254. else
  255. begin
  256. { single_type:=new(pfiledef,init(ft_untyped,nil));}
  257. single_type:=cfiledef;
  258. s:='FILE';
  259. end;
  260. lasttypesym:=nil;
  261. end;
  262. else single_type:=id_type(s);
  263. end;
  264. end;
  265. { this function parses an object or class declaration }
  266. function object_dec(const n : stringid;fd : pobjectdef) : pdef;
  267. var
  268. actmembertype : symprop;
  269. there_is_a_destructor : boolean;
  270. is_a_class : boolean;
  271. childof : pobjectdef;
  272. aktclass : pobjectdef;
  273. procedure constructor_head;
  274. begin
  275. consume(_CONSTRUCTOR);
  276. { must be at same level as in implementation }
  277. _proc_head(poconstructor);
  278. if (cs_checkconsname in aktswitches) and (aktprocsym^.name<>'INIT') then
  279. Message(parser_e_constructorname_must_be_init);
  280. consume(SEMICOLON);
  281. begin
  282. if (aktclass^.options and oois_class)<>0 then
  283. begin
  284. { CLASS constructors return the created instance }
  285. aktprocsym^.definition^.retdef:=aktclass;
  286. end
  287. else
  288. begin
  289. { OBJECT constructors return a boolean }
  290. {$IfDef GDB}
  291. {GDB doesn't like unnamed types !}
  292. aktprocsym^.definition^.retdef:=
  293. globaldef('boolean');
  294. {$Else * GDB *}
  295. aktprocsym^.definition^.retdef:=
  296. new(porddef,init(bool8bit,0,1));
  297. {$Endif * GDB *}
  298. end;
  299. end;
  300. end;
  301. procedure property_dec;
  302. var
  303. sym : psym;
  304. propertyparas : pdefcoll;
  305. { returns the matching procedure to access a property }
  306. function get_procdef : pprocdef;
  307. var
  308. p : pprocdef;
  309. begin
  310. p:=pprocsym(sym)^.definition;
  311. get_procdef:=nil;
  312. while assigned(p) do
  313. begin
  314. if equal_paras(p^.para1,propertyparas) then
  315. break;
  316. p:=p^.nextoverloaded;
  317. end;
  318. get_procdef:=p;
  319. end;
  320. var
  321. hp2,datacoll : pdefcoll;
  322. p,p2 : ppropertysym;
  323. overriden : psym;
  324. hs : string;
  325. code : word;
  326. varspez : tvarspez;
  327. sc : pstringcontainer;
  328. hp : pdef;
  329. s : string;
  330. begin
  331. { check for a class }
  332. if (aktclass^.options and oois_class=0) then
  333. Message(parser_e_syntax_error);
  334. consume(_PROPERTY);
  335. if token=ID then
  336. begin
  337. p:=new(ppropertysym,init(pattern));
  338. consume(ID);
  339. propertyparas:=nil;
  340. datacoll:=nil;
  341. { property parameters ? }
  342. if token=LECKKLAMMER then
  343. begin
  344. { create a list of the parameters in propertyparas }
  345. consume(LECKKLAMMER);
  346. inc(testcurobject);
  347. repeat
  348. if token=_VAR then
  349. begin
  350. consume(_VAR);
  351. varspez:=vs_var;
  352. end
  353. else if token=_CONST then
  354. begin
  355. consume(_CONST);
  356. varspez:=vs_const;
  357. end
  358. else varspez:=vs_value;
  359. sc:=idlist;
  360. if token=COLON then
  361. begin
  362. consume(COLON);
  363. if token=_ARRAY then
  364. begin
  365. if (varspez<>vs_const) and
  366. (varspez<>vs_var) then
  367. begin
  368. varspez:=vs_const;
  369. Message(parser_e_illegal_open_parameter);
  370. end;
  371. consume(_ARRAY);
  372. consume(_OF);
  373. { define range and type of range }
  374. hp:=new(parraydef,init(0,-1,s32bitdef));
  375. { define field type }
  376. parraydef(hp)^.definition:=single_type(s);
  377. end
  378. else
  379. hp:=single_type(s);
  380. end
  381. else
  382. hp:=new(pformaldef,init);
  383. s:=sc^.get;
  384. while s<>'' do
  385. begin
  386. new(hp2);
  387. hp2^.paratyp:=varspez;
  388. hp2^.data:=hp;
  389. hp2^.next:=propertyparas;
  390. propertyparas:=hp2;
  391. s:=sc^.get;
  392. end;
  393. dispose(sc,done);
  394. if token=SEMICOLON then consume(SEMICOLON)
  395. else break;
  396. until false;
  397. dec(testcurobject);
  398. consume(RECKKLAMMER);
  399. end;
  400. { overriden property ? }
  401. { force property interface, if there is a property parameter }
  402. if (token=COLON) or assigned(propertyparas) then
  403. begin
  404. consume(COLON);
  405. p^.proptype:=single_type(hs);
  406. if (token=ID) and (pattern='INDEX') then
  407. begin
  408. consume(ID);
  409. p^.options:=p^.options or ppo_indexed;
  410. if token=INTCONST then
  411. val(pattern,p^.index,code);
  412. consume(INTCONST);
  413. { concat a longint to the para template }
  414. new(hp2);
  415. hp2^.paratyp:=vs_value;
  416. hp2^.data:=s32bitdef;
  417. hp2^.next:=propertyparas;
  418. propertyparas:=hp2;
  419. end;
  420. end
  421. else
  422. begin
  423. { do an property override }
  424. overriden:=search_class_member(aktclass,pattern);
  425. if assigned(overriden) and (overriden^.typ=propertysym) then
  426. begin
  427. { take the whole info: }
  428. p^.options:=ppropertysym(overriden)^.options;
  429. p^.index:=ppropertysym(overriden)^.index;
  430. p^.writeaccesssym:=ppropertysym(overriden)^.writeaccesssym;
  431. p^.readaccesssym:=ppropertysym(overriden)^.readaccesssym;
  432. end
  433. else
  434. begin
  435. p^.proptype:=generrordef;
  436. message(parser_e_no_property_found_to_override);
  437. end;
  438. end;
  439. if (token=ID) and (pattern='READ') then
  440. begin
  441. consume(ID);
  442. sym:=search_class_member(aktclass,pattern);
  443. if not(assigned(sym)) then
  444. Message1(sym_e_unknown_id,pattern)
  445. else
  446. begin
  447. { !!!! check sym }
  448. { varsym aren't allowed for an indexed property
  449. or an property with parameters }
  450. if ((sym^.typ=varsym) and
  451. (((p^.options and ppo_indexed)<>0) or
  452. assigned(propertyparas))) or
  453. not(sym^.typ in [varsym,procsym]) then
  454. Message(parser_e_ill_property_access_sym);
  455. { search the matching definition }
  456. if sym^.typ=procsym then
  457. begin
  458. { !!!!!! }
  459. end;
  460. p^.readaccesssym:=sym;
  461. end;
  462. consume(ID);
  463. end;
  464. if (token=ID) and (pattern='WRITE') then
  465. begin
  466. consume(ID);
  467. sym:=search_class_member(aktclass,pattern);
  468. if not(assigned(sym)) then
  469. Message1(sym_e_unknown_id,pattern)
  470. else
  471. begin
  472. { !!!! check sym }
  473. if ((sym^.typ=varsym) and
  474. (((p^.options and ppo_indexed)<>0)
  475. { or property paras })) or
  476. not(sym^.typ in [varsym,procsym]) then
  477. Message(parser_e_ill_property_access_sym);
  478. { search the matching definition }
  479. if sym^.typ=procsym then
  480. begin
  481. { !!!!!! }
  482. end;
  483. p^.writeaccesssym:=sym;
  484. end;
  485. consume(ID);
  486. end;
  487. if (token=ID) and (pattern='STORED') then
  488. begin
  489. consume(ID);
  490. { !!!!!!!! }
  491. end;
  492. if (token=ID) and (pattern='DEFAULT') then
  493. begin
  494. consume(ID);
  495. if token=SEMICOLON then
  496. begin
  497. p2:=search_default_property(aktclass);
  498. if assigned(p2) then
  499. message1(parser_e_only_one_default_property,
  500. pobjectdef(p2^.owner^.defowner)^.name^)
  501. else
  502. begin
  503. p^.options:=p^.options and ppo_defaultproperty;
  504. if not(assigned(propertyparas)) then
  505. message(parser_e_property_need_paras);
  506. end;
  507. end
  508. else
  509. begin
  510. { !!!!!!! storage }
  511. end;
  512. consume(SEMICOLON);
  513. end
  514. else if (token=ID) and (pattern='NODEFAULT') then
  515. begin
  516. consume(ID);
  517. { !!!!!!!! }
  518. end;
  519. symtablestack^.insert(p);
  520. { clean up }
  521. if assigned(datacoll) then
  522. dispose(datacoll);
  523. end
  524. else
  525. consume(ID);
  526. consume(SEMICOLON);
  527. end;
  528. procedure destructor_head;
  529. begin
  530. consume(_DESTRUCTOR);
  531. _proc_head(podestructor);
  532. if (cs_checkconsname in aktswitches) and (aktprocsym^.name<>'DONE') then
  533. Message(parser_e_destructorname_must_be_done);
  534. consume(SEMICOLON);
  535. if assigned(aktprocsym^.definition^.para1) then
  536. Message(parser_e_no_paras_for_destructor);
  537. { no return value }
  538. aktprocsym^.definition^.retdef:=voiddef;
  539. end;
  540. procedure object_komponenten;
  541. var
  542. oldparse_only : boolean;
  543. begin
  544. repeat
  545. case token of
  546. ID:
  547. begin
  548. if (pattern='PUBLIC') or
  549. (pattern='PUBLISHED') or
  550. (pattern='PROTECTED') or
  551. (pattern='PRIVATE') then
  552. exit;
  553. read_var_decs(false,false);
  554. end;
  555. _PROPERTY:
  556. property_dec;
  557. _PROCEDURE,_FUNCTION,_CLASS:
  558. begin
  559. oldparse_only:=parse_only;
  560. parse_only:=true;
  561. proc_head;
  562. parse_only:=oldparse_only;
  563. if (token=ID) and
  564. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  565. begin
  566. if actmembertype=sp_private then
  567. Message(parser_w_priv_meth_not_virtual);
  568. consume(ID);
  569. consume(SEMICOLON);
  570. aktprocsym^.definition^.options:=
  571. aktprocsym^.definition^.options or povirtualmethod;
  572. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  573. end
  574. else if (token=ID) and (pattern='OVERRIDE') then
  575. begin
  576. consume(ID);
  577. consume(SEMICOLON);
  578. aktprocsym^.definition^.options:=
  579. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  580. end;
  581. { Delphi II extension }
  582. if (token=ID) and (pattern='ABSTRACT') then
  583. begin
  584. consume(ID);
  585. consume(SEMICOLON);
  586. if (aktprocsym^.definition^.options and povirtualmethod)<>0 then
  587. begin
  588. aktprocsym^.definition^.options:=
  589. aktprocsym^.definition^.options or
  590. poabstractmethod;
  591. end
  592. else
  593. Message(parser_e_only_virtual_methods_abstract);
  594. { the method is defined }
  595. aktprocsym^.definition^.forwarddef:=false;
  596. end;
  597. if (token=ID) and (pattern='STATIC') and
  598. (cs_static_keyword in aktswitches) then
  599. begin
  600. consume(ID);
  601. consume(SEMICOLON);
  602. aktprocsym^.properties:=
  603. aktprocsym^.properties or
  604. sp_static;
  605. aktprocsym^.definition^.options:=
  606. aktprocsym^.definition^.options or
  607. postaticmethod;
  608. end;
  609. end;
  610. _CONSTRUCTOR:
  611. begin
  612. if actmembertype<>sp_public then
  613. Message(parser_e_constructor_cannot_be_private);
  614. oldparse_only:=parse_only;
  615. parse_only:=true;
  616. constructor_head;
  617. parse_only:=oldparse_only;
  618. if (token=ID) and
  619. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  620. begin
  621. consume(ID);
  622. consume(SEMICOLON);
  623. if (aktclass^.options and oois_class=0) then
  624. Message(parser_e_constructor_cannot_be_not_virtual)
  625. else
  626. begin
  627. aktprocsym^.definition^.options:=
  628. aktprocsym^.definition^.options or povirtualmethod;
  629. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  630. end
  631. end
  632. else if (token=ID) and (pattern='OVERRIDE') then
  633. begin
  634. consume(ID);
  635. consume(SEMICOLON);
  636. if (aktclass^.options and oois_class=0) then
  637. Message(parser_e_constructor_cannot_be_not_virtual)
  638. else
  639. begin
  640. aktprocsym^.definition^.options:=
  641. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  642. end;
  643. end;
  644. end;
  645. _DESTRUCTOR:
  646. begin
  647. if there_is_a_destructor then
  648. Message(parser_n_only_one_destructor);
  649. there_is_a_destructor:=true;
  650. if actmembertype<>sp_public then
  651. Message(parser_e_destructor_cannot_be_private);
  652. oldparse_only:=parse_only;
  653. parse_only:=true;
  654. destructor_head;
  655. parse_only:=oldparse_only;
  656. if (token=ID) and
  657. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  658. begin
  659. consume(ID);
  660. consume(SEMICOLON);
  661. aktprocsym^.definition^.options:=
  662. aktprocsym^.definition^.options or povirtualmethod;
  663. end
  664. else if (token=ID) and (pattern='OVERRIDE') then
  665. begin
  666. consume(ID);
  667. consume(SEMICOLON);
  668. aktprocsym^.definition^.options:=
  669. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  670. end;
  671. end;
  672. _END : exit;
  673. else Message(parser_e_syntax_error);
  674. end;
  675. until false;
  676. end;
  677. var
  678. hs : string;
  679. pcrd : pclassrefdef;
  680. hp1 : pdef;
  681. oldprocsym:Pprocsym;
  682. begin
  683. {Nowadays aktprocsym may already have a value, so we need to save
  684. it.}
  685. oldprocsym:=aktprocsym;
  686. { forward is resolved }
  687. if assigned(fd) then
  688. fd^.options:=fd^.options and not(oo_isforward);
  689. there_is_a_destructor:=false;
  690. actmembertype:=sp_public;
  691. { objects and class types can't be declared local }
  692. if (symtablestack^.symtabletype<>globalsymtable) and
  693. (symtablestack^.symtabletype<>staticsymtable) then
  694. Message(parser_e_no_local_objects);
  695. { distinguish classes and objects }
  696. if token=_OBJECT then
  697. begin
  698. is_a_class:=false;
  699. consume(_OBJECT)
  700. end
  701. else
  702. begin
  703. is_a_class:=true;
  704. consume(_CLASS);
  705. if not(assigned(fd)) and (token=_OF) then
  706. begin
  707. { a hack, but it's easy to handle }
  708. { class reference type }
  709. consume(_OF);
  710. if typecanbeforward then
  711. forwardsallowed:=true;
  712. hp1:=single_type(hs);
  713. { accept hp1, if is a forward def ...}
  714. if ((lasttypesym<>nil)
  715. and ((lasttypesym^.properties and sp_forwarddef)<>0)) or
  716. { or a class
  717. (if the foward defined type is a class is checked, when
  718. the forward is resolved)
  719. }
  720. ((hp1^.deftype=objectdef) and (
  721. (pobjectdef(hp1)^.options and oois_class)<>0)) then
  722. begin
  723. pcrd:=new(pclassrefdef,init(hp1));
  724. object_dec:=pcrd;
  725. {I add big troubles here
  726. with var p : ^byte in graph.putimage
  727. because a save_forward was called and
  728. no resolve forward
  729. => so the definition was rewritten after
  730. having been disposed !!
  731. Strange problems appeared !!!!}
  732. {Anyhow forwards should only be allowed
  733. inside a type statement ??
  734. don't you think so }
  735. if (lasttypesym<>nil)
  736. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  737. lasttypesym^.forwardpointer:=ppointerdef(pcrd);
  738. forwardsallowed:=false;
  739. end
  740. else
  741. begin
  742. Message(parser_e_class_type_expected);
  743. object_dec:=new(perrordef,init);
  744. end;
  745. exit;
  746. end
  747. { forward class }
  748. else if not(assigned(fd)) and (token=SEMICOLON) then
  749. begin
  750. { also anonym objects aren't allow (o : object a : longint; end;) }
  751. if n='' then
  752. Message(parser_e_no_anonym_objects);
  753. if n='TOBJECT' then
  754. begin
  755. aktclass:=new(pobjectdef,init(n,nil));
  756. class_tobject:=aktclass;
  757. end
  758. else
  759. aktclass:=new(pobjectdef,init(n,class_tobject));
  760. aktclass^.options:=aktclass^.options or oois_class or oo_isforward;
  761. object_dec:=aktclass;
  762. exit;
  763. end;
  764. end;
  765. { also anonym objects aren't allow (o : object a : longint; end;) }
  766. if n='' then
  767. Message(parser_e_no_anonym_objects);
  768. { read the parent class }
  769. if token=LKLAMMER then
  770. begin
  771. consume(LKLAMMER);
  772. { does not allow objects.tobject !! }
  773. {if token<>ID then
  774. consume(ID);
  775. getsym(pattern,true);}
  776. childof:=pobjectdef(id_type(pattern));
  777. if (childof^.deftype<>objectdef) then
  778. begin
  779. Message(parser_e_class_type_expected);
  780. childof:=nil;
  781. end;
  782. { a mix of class and object isn't allowed }
  783. if (((childof^.options and oois_class)<>0) and not is_a_class) or
  784. (((childof^.options and oois_class)=0) and is_a_class) then
  785. Message(parser_e_mix_of_classes_and_objects);
  786. consume(RKLAMMER);
  787. if assigned(fd) then
  788. begin
  789. fd^.childof:=childof;
  790. aktclass:=fd;
  791. end
  792. else
  793. aktclass:=new(pobjectdef,init(n,childof));
  794. end
  795. { if no parent class, then a class get tobject as parent }
  796. else if is_a_class then
  797. begin
  798. { is the current class tobject? }
  799. { so you could define your own tobject }
  800. if n='TOBJECT' then
  801. begin
  802. if assigned(fd) then
  803. aktclass:=fd
  804. else
  805. aktclass:=new(pobjectdef,init(n,nil));
  806. class_tobject:=aktclass;
  807. end
  808. else
  809. begin
  810. childof:=class_tobject;
  811. if assigned(fd) then
  812. begin
  813. aktclass:=fd;
  814. aktclass^.childof:=childof;
  815. end
  816. else
  817. aktclass:=new(pobjectdef,init(n,childof));
  818. end;
  819. end
  820. else aktclass:=new(pobjectdef,init(n,nil));
  821. { set the class attribute }
  822. if is_a_class then
  823. aktclass^.options:=aktclass^.options or oois_class;
  824. aktobjectdef:=aktclass;
  825. { default access is public }
  826. actmembertype:=sp_public;
  827. aktclass^.publicsyms^.next:=symtablestack;
  828. symtablestack:=aktclass^.publicsyms;
  829. procinfo._class:=aktclass;
  830. testcurobject:=1;
  831. curobjectname:=n;
  832. while token<>_END do
  833. begin
  834. if (token=ID) and (pattern='PRIVATE') then
  835. begin
  836. consume(ID);
  837. actmembertype:=sp_private;
  838. current_object_option:=sp_private;
  839. end;
  840. if (token=ID) and (pattern='PROTECTED') then
  841. begin
  842. consume(ID);
  843. current_object_option:=sp_protected;
  844. actmembertype:=sp_protected;
  845. end;
  846. if (token=ID) and (pattern='PUBLIC') then
  847. begin
  848. consume(ID);
  849. current_object_option:=sp_public;
  850. actmembertype:=sp_public;
  851. end;
  852. if (token=ID) and (pattern='PUBLISHED') then
  853. begin
  854. consume(ID);
  855. current_object_option:=sp_public;
  856. actmembertype:=sp_public;
  857. end;
  858. object_komponenten;
  859. end;
  860. current_object_option:=sp_public;
  861. consume(_END);
  862. testcurobject:=0;
  863. curobjectname:='';
  864. {$ifdef MAKELIB}
  865. datasegment^.concat(new(pai_cut,init));
  866. {$endif MAKELIB}
  867. {$ifdef GDB}
  868. { generate the VMT }
  869. if cs_debuginfo in aktswitches then
  870. begin
  871. do_count_dbx:=true;
  872. if assigned(aktclass^.owner) and assigned(aktclass^.owner^.name) then
  873. debuglist^.concat(new(pai_stabs,init(strpnew('"vmt_'+aktclass^.owner^.name^+n+':S'+
  874. typeglobalnumber('__vtbl_ptr_type')+'",'+tostr(N_STSYM)+',0,0,'+aktclass^.vmt_mangledname))));
  875. end;
  876. {$endif * GDB *}
  877. datasegment^.concat(new(pai_symbol,init_global(aktclass^.vmt_mangledname)));
  878. { determine the size with publicsyms^.datasize, because }
  879. { size gives back 4 for CLASSes }
  880. datasegment^.concat(new(pai_const,init_32bit(aktclass^.publicsyms^.datasize)));
  881. datasegment^.concat(new(pai_const,init_32bit(-aktclass^.publicsyms^.datasize)));
  882. { write pointer to parent VMT, this isn't implemented in TP }
  883. { but this is not used in FPC ? (PM) }
  884. { it's not used yet, but the delphi-operators as and is need it (FK) }
  885. if assigned(aktclass^.childof) then
  886. begin
  887. datasegment^.concat(new(pai_const,init_symbol(strpnew(aktclass^.childof^.vmt_mangledname))));
  888. if aktclass^.childof^.owner^.symtabletype=unitsymtable then
  889. concat_external(aktclass^.childof^.vmt_mangledname,EXT_NEAR);
  890. end
  891. else
  892. datasegment^.concat(new(pai_const,init_32bit(0)));
  893. { this generates the entries }
  894. genvmt(aktclass);
  895. { restore old state }
  896. symtablestack:=symtablestack^.next;
  897. procinfo._class:=nil;
  898. {Restore the aktprocsym.}
  899. aktprocsym:=oldprocsym;
  900. object_dec:=aktclass;
  901. end;
  902. { reads a record declaration }
  903. function record_dec : pdef;
  904. var
  905. symtable : psymtable;
  906. begin
  907. symtable:=new(psymtable,init(recordsymtable));
  908. symtable^.next:=symtablestack;
  909. symtablestack:=symtable;
  910. consume(_RECORD);
  911. read_var_decs(true,false);
  912. { may be scale record size to a size of n*4 ? }
  913. if ((symtablestack^.datasize mod aktpackrecords)<>0) then
  914. inc(symtablestack^.datasize,aktpackrecords-(symtablestack^.datasize mod aktpackrecords));
  915. consume(_END);
  916. symtablestack:=symtable^.next;
  917. record_dec:=new(precdef,init(symtable));
  918. end;
  919. { reads a type definition and returns a pointer to it }
  920. function read_type(const name : stringid) : pdef;
  921. function handle_procvar:Pprocvardef;
  922. var
  923. sc : pstringcontainer;
  924. s : string;
  925. p : pdef;
  926. varspez : tvarspez;
  927. procvardef : pprocvardef;
  928. begin
  929. procvardef:=new(pprocvardef,init);
  930. if token=LKLAMMER then
  931. begin
  932. consume(LKLAMMER);
  933. inc(testcurobject);
  934. repeat
  935. if token=_VAR then
  936. begin
  937. consume(_VAR);
  938. varspez:=vs_var;
  939. end
  940. else if token=_CONST then
  941. begin
  942. consume(_CONST);
  943. varspez:=vs_const;
  944. end
  945. else varspez:=vs_value;
  946. sc:=idlist;
  947. if token=COLON then
  948. begin
  949. consume(COLON);
  950. if token=_ARRAY then
  951. begin
  952. if (varspez<>vs_const) and
  953. (varspez<>vs_var) then
  954. begin
  955. varspez:=vs_const;
  956. Message(parser_e_illegal_open_parameter);
  957. end;
  958. consume(_ARRAY);
  959. consume(_OF);
  960. { define range and type of range }
  961. p:=new(parraydef,init(0,-1,s32bitdef));
  962. { define field type }
  963. parraydef(p)^.definition:=single_type(s);
  964. end
  965. else
  966. p:=single_type(s);
  967. end
  968. else
  969. p:=new(pformaldef,init);
  970. s:=sc^.get;
  971. while s<>'' do
  972. begin
  973. procvardef^.concatdef(p,varspez);
  974. s:=sc^.get;
  975. end;
  976. dispose(sc,done);
  977. if token=SEMICOLON then consume(SEMICOLON)
  978. else break;
  979. until false;
  980. dec(testcurobject);
  981. consume(RKLAMMER);
  982. end;
  983. handle_procvar:=procvardef;
  984. end;
  985. var
  986. hp1,p : pdef;
  987. aufdef : penumdef;
  988. aufsym : penumsym;
  989. ap : parraydef;
  990. s : stringid;
  991. l,v,oldaktpackrecords : longint;
  992. hs : string;
  993. procedure expr_type;
  994. var
  995. pt1,pt2 : ptree;
  996. begin
  997. { use of current parsed object ? }
  998. if (token=ID) and (testcurobject=2) and (curobjectname=pattern) then
  999. begin
  1000. consume(ID);
  1001. p:=aktobjectdef;
  1002. exit;
  1003. end;
  1004. { we can't accept a equal in type }
  1005. pt1:=comp_expr(not(ignore_equal));
  1006. if (pt1^.treetype=typen) and (token<>POINTPOINT) then
  1007. begin
  1008. { a simple type renaming }
  1009. p:=pt1^.resulttype;
  1010. end
  1011. else
  1012. begin
  1013. { range type }
  1014. consume(POINTPOINT);
  1015. { range type declaration }
  1016. do_firstpass(pt1);
  1017. pt2:=comp_expr(not(ignore_equal));
  1018. do_firstpass(pt2);
  1019. { valid expression ? }
  1020. if (pt1^.treetype<>ordconstn) or
  1021. (pt2^.treetype<>ordconstn) then
  1022. Begin
  1023. Message(sym_e_error_in_type_def);
  1024. { Here we create a node type with a range of 0 }
  1025. { To make sure that no crashes will occur later }
  1026. { on in the compiler. }
  1027. p:=new(porddef,init(uauto,0,0));
  1028. end
  1029. else
  1030. p:=new(porddef,init(uauto,pt1^.value,pt2^.value));
  1031. disposetree(pt2);
  1032. end;
  1033. disposetree(pt1);
  1034. end;
  1035. var
  1036. pt : ptree;
  1037. procedure array_dec;
  1038. begin
  1039. consume(_ARRAY);
  1040. consume(LECKKLAMMER);
  1041. p:=nil;
  1042. repeat
  1043. { read the expression and check it }
  1044. pt:=expr;
  1045. if pt^.treetype=typen then
  1046. begin
  1047. if pt^.resulttype^.deftype=enumdef then
  1048. begin
  1049. if p=nil then
  1050. begin
  1051. ap:=new(parraydef,
  1052. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1053. p:=ap;
  1054. end
  1055. else
  1056. begin
  1057. ap^.definition:=new(parraydef,
  1058. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1059. ap:=parraydef(ap^.definition);
  1060. end;
  1061. end
  1062. else if pt^.resulttype^.deftype=orddef then
  1063. begin
  1064. case porddef(pt^.resulttype)^.typ of
  1065. s8bit,u8bit,s16bit,u16bit,s32bit :
  1066. begin
  1067. if p=nil then
  1068. begin
  1069. ap:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1070. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1071. p:=ap;
  1072. end
  1073. else
  1074. begin
  1075. ap^.definition:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1076. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1077. ap:=parraydef(ap^.definition);
  1078. end;
  1079. end;
  1080. bool8bit:
  1081. begin
  1082. if p=nil then
  1083. begin
  1084. ap:=new(parraydef,init(0,1,pt^.resulttype));
  1085. p:=ap;
  1086. end
  1087. else
  1088. begin
  1089. ap^.definition:=new(parraydef,init(0,1,pt^.resulttype));
  1090. ap:=parraydef(ap^.definition);
  1091. end;
  1092. end;
  1093. uchar:
  1094. begin
  1095. if p=nil then
  1096. begin
  1097. ap:=new(parraydef,init(0,255,pt^.resulttype));
  1098. p:=ap;
  1099. end
  1100. else
  1101. begin
  1102. ap^.definition:=new(parraydef,init(0,255,pt^.resulttype));
  1103. ap:=parraydef(ap^.definition);
  1104. end;
  1105. end;
  1106. else Message(sym_e_error_in_type_def);
  1107. end;
  1108. end
  1109. else Message(sym_e_error_in_type_def);
  1110. end
  1111. else
  1112. begin
  1113. do_firstpass(pt);
  1114. if (pt^.treetype<>rangen) or
  1115. (pt^.left^.treetype<>ordconstn) then
  1116. Message(sym_e_error_in_type_def);
  1117. { force the registration of the ranges }
  1118. {$ifndef GDB}
  1119. if pt^.right^.resulttype=pdef(s32bitdef) then
  1120. pt^.right^.resulttype:=new(porddef,init(
  1121. s32bit,$80000000,$7fffffff));
  1122. {$endif GDB}
  1123. if p=nil then
  1124. begin
  1125. ap:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1126. p:=ap;
  1127. end
  1128. else
  1129. begin
  1130. ap^.definition:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1131. ap:=parraydef(ap^.definition);
  1132. end;
  1133. end;
  1134. disposetree(pt);
  1135. if token=COMMA then consume(COMMA)
  1136. else break;
  1137. until false;
  1138. consume(RECKKLAMMER);
  1139. consume(_OF);
  1140. hp1:=read_type('');
  1141. { if no error, set element type }
  1142. if assigned(ap) then
  1143. ap^.definition:=hp1;
  1144. end;
  1145. begin
  1146. case token of
  1147. _STRING,_FILE:
  1148. p:=single_type(hs);
  1149. LKLAMMER:
  1150. begin
  1151. consume(LKLAMMER);
  1152. l:=-1;
  1153. aufsym := Nil;
  1154. aufdef:=new(penumdef,init);
  1155. repeat
  1156. s:=pattern;
  1157. consume(ID);
  1158. if token=ASSIGNMENT then
  1159. begin
  1160. consume(ASSIGNMENT);
  1161. v:=get_intconst;
  1162. { please leave that a note, allows type save }
  1163. { declarations in the win32 units ! }
  1164. if v<=l then
  1165. Message(parser_n_duplicate_enum);
  1166. l:=v;
  1167. end
  1168. else
  1169. inc(l);
  1170. constsymtable^.insert(new(penumsym,init(s,aufdef,l)));
  1171. if token=COMMA then
  1172. consume(COMMA)
  1173. else
  1174. break;
  1175. until false;
  1176. aufdef^.max:=l;
  1177. p:=aufdef;
  1178. consume(RKLAMMER);
  1179. end;
  1180. _ARRAY:
  1181. array_dec;
  1182. _SET:
  1183. begin
  1184. consume(_SET);
  1185. consume(_OF);
  1186. hp1:=read_type('');
  1187. case hp1^.deftype of
  1188. enumdef : p:=new(psetdef,init(hp1,penumdef(hp1)^.max));
  1189. orddef : begin
  1190. case porddef(hp1)^.typ of
  1191. uchar : p:=new(psetdef,init(hp1,255));
  1192. u8bit,s8bit,u16bit,s16bit,s32bit :
  1193. begin
  1194. if (porddef(hp1)^.von>=0) then
  1195. p:=new(psetdef,init(hp1,porddef(hp1)^.bis))
  1196. else Message(sym_e_ill_type_decl_set);
  1197. end;
  1198. else Message(sym_e_ill_type_decl_set);
  1199. end;
  1200. end;
  1201. else Message(sym_e_ill_type_decl_set);
  1202. end;
  1203. end;
  1204. CARET:
  1205. begin
  1206. consume(CARET);
  1207. { forwards allowed only inside TYPE statements }
  1208. if typecanbeforward then
  1209. forwardsallowed:=true;
  1210. hp1:=single_type(hs);
  1211. p:=new(ppointerdef,init(hp1));
  1212. {$ifndef GDB}
  1213. if lasttypesym<>nil then
  1214. save_forward(ppointerdef(p),lasttypesym);
  1215. {$else * GDB *}
  1216. {I add big troubles here
  1217. with var p : ^byte in graph.putimage
  1218. because a save_forward was called and
  1219. no resolve forward
  1220. => so the definition was rewritten after
  1221. having been disposed !!
  1222. Strange problems appeared !!!!}
  1223. {Anyhow forwards should only be allowed
  1224. inside a type statement ??
  1225. don't you think so }
  1226. if (lasttypesym<>nil)
  1227. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  1228. lasttypesym^.forwardpointer:=ppointerdef(p);
  1229. {$endif * GDB *}
  1230. forwardsallowed:=false;
  1231. end;
  1232. _RECORD:
  1233. p:=record_dec;
  1234. _PACKED:
  1235. begin
  1236. consume(_PACKED);
  1237. if token=_ARRAY then
  1238. array_dec
  1239. else
  1240. begin
  1241. oldaktpackrecords:=aktpackrecords;
  1242. aktpackrecords:=1;
  1243. if token in [_CLASS,_OBJECT] then
  1244. p:=object_dec(name,nil)
  1245. else
  1246. p:=record_dec;
  1247. aktpackrecords:=oldaktpackrecords;
  1248. end;
  1249. end;
  1250. _CLASS,
  1251. _OBJECT:
  1252. p:=object_dec(name,nil);
  1253. _PROCEDURE:
  1254. begin
  1255. consume(_PROCEDURE);
  1256. p:=handle_procvar;
  1257. end;
  1258. _FUNCTION:
  1259. begin
  1260. consume(_FUNCTION);
  1261. p:=handle_procvar;
  1262. consume(COLON);
  1263. pprocvardef(p)^.retdef:=single_type(hs);
  1264. end;
  1265. else
  1266. expr_type;
  1267. end;
  1268. read_type:=p;
  1269. end;
  1270. { search in symtablestack used, but not defined type }
  1271. procedure testforward_types(p : psym);{$ifndef FPC}far;{$endif}
  1272. begin
  1273. if (p^.typ=typesym) and ((p^.properties and sp_forwarddef)<>0) then
  1274. Message(sym_e_type_id_not_defined);
  1275. end;
  1276. { reads a type declaration to the symbol table }
  1277. procedure type_dec;
  1278. var
  1279. typename : stringid;
  1280. {$ifdef dummy}
  1281. olddef,newdef : pdef;
  1282. s : string;
  1283. {$endif dummy}
  1284. begin
  1285. block_type:=bt_type;
  1286. consume(_TYPE);
  1287. typecanbeforward:=true;
  1288. repeat
  1289. typename:=pattern;
  1290. consume(ID);
  1291. consume(EQUAL);
  1292. { here you loose the strictness of pascal
  1293. for which a redefinition like
  1294. childtype = parenttype;
  1295. child2type = parenttype;
  1296. does not make the two child types equal !!
  1297. here all vars from childtype and child2type
  1298. get the definition of parenttype !! }
  1299. {$ifdef testequaltype}
  1300. if (token = ID) or (token=_FILE) or (token=_STRING) then
  1301. begin
  1302. olddef := single_type(s);
  1303. { make a clone of olddef }
  1304. { is that ok ??? }
  1305. getmem(newdef,SizeOf(olddef));
  1306. move(olddef^,newdef^,SizeOf(olddef));
  1307. symtablestack^.insert(new(ptypesym,init(typename,newdef)));
  1308. end
  1309. else
  1310. {$endif testequaltype}
  1311. begin
  1312. getsym(typename,false);
  1313. { check if it is the definition of a forward defined class }
  1314. if assigned(srsym) and (token=_CLASS) and
  1315. (srsym^.typ=typesym) and
  1316. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  1317. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oo_isforward)<>0) and
  1318. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oois_class)<>0) then
  1319. begin
  1320. { we can ignore the result }
  1321. { the definition is modified }
  1322. object_dec(typename,pobjectdef(ptypesym(srsym)^.definition));
  1323. end
  1324. else
  1325. symtablestack^.insert(new(ptypesym,init(typename,read_type(typename))));
  1326. end;
  1327. consume(SEMICOLON);
  1328. until token<>ID;
  1329. typecanbeforward:=false;
  1330. {$ifdef tp}
  1331. symtablestack^.foreach(testforward_types);
  1332. {$else}
  1333. symtablestack^.foreach(@testforward_types);
  1334. {$endif}
  1335. resolve_forwards;
  1336. block_type:=bt_general;
  1337. end;
  1338. { parses varaible declarations and inserts them in }
  1339. { the top symbol table of symtablestack }
  1340. procedure var_dec;
  1341. {var
  1342. p : pdef;
  1343. sc : pstringcontainer; }
  1344. begin
  1345. consume(_VAR);
  1346. read_var_decs(false,true);
  1347. end;
  1348. { reads the filed of a record into a }
  1349. { symtablestack, if record=false }
  1350. { variants are forbidden, so this procedure }
  1351. { can be used to read object fields }
  1352. { if absolute is true, ABSOLUTE and file }
  1353. { types are allowed }
  1354. { => the procedure is also used to read }
  1355. { a sequence of variable declaration }
  1356. procedure read_var_decs(is_record : boolean;do_absolute : boolean);
  1357. var
  1358. sc : pstringcontainer;
  1359. s : stringid;
  1360. l : longint;
  1361. code : word;
  1362. hs : string;
  1363. p,casedef : pdef;
  1364. { maxsize contains the max. size of a variant }
  1365. { startvarrec contains the start of the variant part of a record }
  1366. maxsize,startvarrec : longint;
  1367. pt : ptree;
  1368. old_block_type : tblock_type;
  1369. { to handle absolute }
  1370. abssym : pabsolutesym;
  1371. begin
  1372. hs:='';
  1373. old_block_type:=block_type;
  1374. block_type:=bt_type;
  1375. while (token=ID) and
  1376. (pattern<>'PUBLIC') and
  1377. (pattern<>'PRIVATE') and
  1378. (pattern<>'PUBLISHED') and
  1379. (pattern<>'PROTECTED') do
  1380. begin
  1381. sc:=idlist;
  1382. consume(COLON);
  1383. p:=read_type('');
  1384. if do_absolute and (token=ID) and (pattern='ABSOLUTE') then
  1385. begin
  1386. s:=sc^.get;
  1387. if sc^.get<>'' then
  1388. Message(parser_e_absolute_only_one_var);
  1389. dispose(sc,done);
  1390. consume(ID);
  1391. if token=ID then
  1392. begin
  1393. getsym(pattern,true);
  1394. consume(ID);
  1395. { we should check the result type of srsym }
  1396. if not (srsym^.typ in [varsym,typedconstsym]) then
  1397. Message(parser_e_absolute_only_to_var_or_const);
  1398. abssym:=new(pabsolutesym,init(s,p));
  1399. abssym^.typ:=absolutesym;
  1400. abssym^.abstyp:=tovar;
  1401. abssym^.ref:=srsym;
  1402. symtablestack^.insert(abssym);
  1403. end
  1404. else
  1405. if token=CSTRING then
  1406. begin
  1407. abssym:=new(pabsolutesym,init(s,p));
  1408. s:=pattern;
  1409. consume(CSTRING);
  1410. abssym^.typ:=absolutesym;
  1411. abssym^.abstyp:=toasm;
  1412. abssym^.asmname:=stringdup(s);
  1413. symtablestack^.insert(abssym);
  1414. end
  1415. else
  1416. { absolute address ?!? }
  1417. if token=INTCONST then
  1418. begin
  1419. if (target_info.target=target_GO32V2) then
  1420. begin
  1421. abssym:=new(pabsolutesym,init(s,p));
  1422. abssym^.typ:=absolutesym;
  1423. abssym^.abstyp:=toaddr;
  1424. abssym^.absseg:=false;
  1425. s:=pattern;
  1426. consume(INTCONST);
  1427. val(s,abssym^.address,code);
  1428. if token=COLON then
  1429. begin
  1430. consume(token);
  1431. s:=pattern;
  1432. consume(INTCONST);
  1433. val(s,l,code);
  1434. abssym^.address:=abssym^.address shl 4+l;
  1435. abssym^.absseg:=true;
  1436. end;
  1437. symtablestack^.insert(abssym);
  1438. end
  1439. else
  1440. Message(parser_e_absolute_only_to_var_or_const);
  1441. end
  1442. else
  1443. Message(parser_e_absolute_only_to_var_or_const);
  1444. end
  1445. else
  1446. begin
  1447. if token=SEMICOLON then
  1448. begin
  1449. if (symtablestack^.symtabletype=objectsymtable) then
  1450. begin
  1451. consume(SEMICOLON);
  1452. if (token=ID) and (pattern='STATIC') and
  1453. (cs_static_keyword in aktswitches) then
  1454. begin
  1455. current_object_option:=current_object_option or sp_static;
  1456. insert_syms(symtablestack,sc,p);
  1457. current_object_option:=current_object_option - sp_static;
  1458. consume(ID);
  1459. consume(SEMICOLON);
  1460. end
  1461. else
  1462. { this will still be a the wrong line !! }
  1463. insert_syms(symtablestack,sc,p);
  1464. end
  1465. else
  1466. begin
  1467. { at the right line }
  1468. insert_syms(symtablestack,sc,p);
  1469. consume(SEMICOLON);
  1470. end
  1471. end
  1472. else
  1473. begin
  1474. insert_syms(symtablestack,sc,p);
  1475. if not(is_record) then
  1476. consume(SEMICOLON);
  1477. end;
  1478. end;
  1479. while token=SEMICOLON do
  1480. consume(SEMICOLON);
  1481. end;
  1482. if (token=_CASE) and is_record then
  1483. begin
  1484. maxsize:=0;
  1485. consume(_CASE);
  1486. s:=pattern;
  1487. getsym(s,false);
  1488. { may be only a type: }
  1489. if assigned(srsym) and ((srsym^.typ=typesym) or
  1490. { and with unit qualifier: }
  1491. (srsym^.typ=unitsym)) then
  1492. begin
  1493. casedef:=read_type('');
  1494. end
  1495. else
  1496. begin
  1497. consume(ID);
  1498. consume(COLON);
  1499. casedef:=read_type('');
  1500. symtablestack^.insert(new(pvarsym,init(s,casedef)));
  1501. end;
  1502. if not is_ordinal(casedef) then
  1503. Message(parser_e_ordinal_expected);
  1504. consume(_OF);
  1505. startvarrec:=symtablestack^.datasize;
  1506. repeat
  1507. repeat
  1508. pt:=expr;
  1509. do_firstpass(pt);
  1510. if not(pt^.treetype=ordconstn) then
  1511. Message(cg_e_illegal_expression);
  1512. disposetree(pt);
  1513. if token=COMMA then consume(COMMA)
  1514. else break;
  1515. until false;
  1516. consume(COLON);
  1517. consume(LKLAMMER);
  1518. if token<>RKLAMMER then
  1519. read_var_decs(true,false);
  1520. { calculates maximal variant size }
  1521. maxsize:=max(maxsize,symtablestack^.datasize);
  1522. { the items of the next variant are overlayed }
  1523. symtablestack^.datasize:=startvarrec;
  1524. consume(RKLAMMER);
  1525. if token<>SEMICOLON then
  1526. break
  1527. else
  1528. consume(SEMICOLON);
  1529. while token=SEMICOLON do
  1530. consume(SEMICOLON);
  1531. until (token=_END) or (token=RKLAMMER);
  1532. { at last set the record size to that of the biggest variant }
  1533. symtablestack^.datasize:=maxsize;
  1534. end;
  1535. block_type:=old_block_type;
  1536. end;
  1537. procedure read_declarations(islibrary : boolean);
  1538. begin
  1539. repeat
  1540. case token of
  1541. _LABEL:
  1542. label_dec;
  1543. _CONST:
  1544. const_dec;
  1545. _TYPE:
  1546. type_dec;
  1547. _VAR:
  1548. var_dec;
  1549. _CONSTRUCTOR,_DESTRUCTOR,
  1550. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1551. unter_dec;
  1552. _EXPORTS:
  1553. if islibrary then
  1554. read_exports
  1555. else
  1556. break;
  1557. else break;
  1558. end;
  1559. until false;
  1560. end;
  1561. procedure read_interface_declarations;
  1562. begin
  1563. {Since the body is now parsed at lexlevel 1, and the declarations
  1564. must be parsed at the same lexlevel we increase the lexlevel.}
  1565. inc(lexlevel);
  1566. repeat
  1567. case token of
  1568. _CONST : const_dec;
  1569. _TYPE : type_dec;
  1570. _VAR : var_dec;
  1571. { should we allow operator in interface ? }
  1572. { of course otherwise you cannot }
  1573. { declare an operator usable by other }
  1574. { units or progs PM }
  1575. _FUNCTION,_PROCEDURE,_OPERATOR : unter_dec;
  1576. else
  1577. break;
  1578. end;
  1579. until false;
  1580. dec(lexlevel);
  1581. end;
  1582. end.
  1583. {
  1584. $Log$
  1585. Revision 1.4 1998-04-08 10:26:09 florian
  1586. * correct error handling of virtual constructors
  1587. * problem with new type declaration handling fixed
  1588. Revision 1.3 1998/04/07 22:45:05 florian
  1589. * bug0092, bug0115 and bug0121 fixed
  1590. + packed object/class/array
  1591. Revision 1.2 1998/04/05 13:58:35 peter
  1592. * fixed the -Ss bug
  1593. + warning for Virtual constructors
  1594. * helppages updated with -TGO32V1
  1595. Revision 1.1.1.1 1998/03/25 11:18:14 root
  1596. * Restored version
  1597. Revision 1.31 1998/03/24 21:48:33 florian
  1598. * just a couple of fixes applied:
  1599. - problem with fixed16 solved
  1600. - internalerror 10005 problem fixed
  1601. - patch for assembler reading
  1602. - small optimizer fix
  1603. - mem is now supported
  1604. Revision 1.30 1998/03/21 23:59:39 florian
  1605. * indexed properties fixed
  1606. * ppu i/o of properties fixed
  1607. * field can be also used for write access
  1608. * overriding of properties
  1609. Revision 1.29 1998/03/18 22:50:11 florian
  1610. + fstp/fld optimization
  1611. * routines which contains asm aren't longer optimzed
  1612. * wrong ifdef TEST_FUNCRET corrected
  1613. * wrong data generation for array[0..n] of char = '01234'; fixed
  1614. * bug0097 is fixed partial
  1615. * bug0116 fixed (-Og doesn't use enter of the stack frame is greater than
  1616. 65535)
  1617. Revision 1.28 1998/03/10 16:27:41 pierre
  1618. * better line info in stabs debug
  1619. * symtabletype and lexlevel separated into two fields of tsymtable
  1620. + ifdef MAKELIB for direct library output, not complete
  1621. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1622. working
  1623. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1624. working
  1625. Revision 1.27 1998/03/10 01:17:23 peter
  1626. * all files have the same header
  1627. * messages are fully implemented, EXTDEBUG uses Comment()
  1628. + AG... files for the Assembler generation
  1629. Revision 1.26 1998/03/06 00:52:41 peter
  1630. * replaced all old messages from errore.msg, only ExtDebug and some
  1631. Comment() calls are left
  1632. * fixed options.pas
  1633. Revision 1.25 1998/03/05 22:43:49 florian
  1634. * some win32 support stuff added
  1635. Revision 1.24 1998/03/04 17:33:49 michael
  1636. + Changed ifdef FPK to ifdef FPC
  1637. Revision 1.23 1998/03/04 01:35:06 peter
  1638. * messages for unit-handling and assembler/linker
  1639. * the compiler compiles without -dGDB, but doesn't work yet
  1640. + -vh for Hint
  1641. Revision 1.22 1998/03/02 01:49:00 peter
  1642. * renamed target_DOS to target_GO32V1
  1643. + new verbose system, merged old errors and verbose units into one new
  1644. verbose.pas, so errors.pas is obsolete
  1645. Revision 1.21 1998/02/28 14:43:47 florian
  1646. * final implemenation of win32 imports
  1647. * extended tai_align to allow 8 and 16 byte aligns
  1648. Revision 1.20 1998/02/19 00:11:07 peter
  1649. * fixed -g to work again
  1650. * fixed some typos with the scriptobject
  1651. Revision 1.19 1998/02/13 10:35:23 daniel
  1652. * Made Motorola version compilable.
  1653. * Fixed optimizer
  1654. Revision 1.18 1998/02/12 17:19:19 florian
  1655. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1656. also that aktswitches isn't a pointer)
  1657. Revision 1.17 1998/02/12 11:50:25 daniel
  1658. Yes! Finally! After three retries, my patch!
  1659. Changes:
  1660. Complete rewrite of psub.pas.
  1661. Added support for DLL's.
  1662. Compiler requires less memory.
  1663. Platform units for each platform.
  1664. Revision 1.16 1998/02/11 21:56:36 florian
  1665. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  1666. Revision 1.15 1998/02/06 10:34:25 florian
  1667. * bug0082 and bug0084 fixed
  1668. Revision 1.14 1998/02/02 11:56:49 pierre
  1669. * better line info for var statement
  1670. Revision 1.13 1998/01/30 21:25:31 carl
  1671. * bugfix #86 + checking of all other macros for crashes, fixed typeof
  1672. partly among others.
  1673. Revision 1.12 1998/01/23 17:12:19 pierre
  1674. * added some improvements for as and ld :
  1675. - doserror and dosexitcode treated separately
  1676. - PATH searched if doserror=2
  1677. + start of long and ansi string (far from complete)
  1678. in conditionnal UseLongString and UseAnsiString
  1679. * options.pas cleaned (some variables shifted to globals)gl
  1680. Revision 1.11 1998/01/21 21:25:46 florian
  1681. * small problem with variante records fixed:
  1682. case a : (x,y,z) of
  1683. ...
  1684. is now allowed
  1685. Revision 1.10 1998/01/13 23:11:13 florian
  1686. + class methods
  1687. Revision 1.9 1998/01/12 13:03:31 florian
  1688. + parsing of class methods implemented
  1689. Revision 1.8 1998/01/11 10:54:23 florian
  1690. + generic library support
  1691. Revision 1.7 1998/01/09 23:08:32 florian
  1692. + C++/Delphi styled //-comments
  1693. * some bugs in Delphi object model fixed
  1694. + override directive
  1695. Revision 1.6 1998/01/09 18:01:16 florian
  1696. * VIRTUAL isn't anymore a common keyword
  1697. + DYNAMIC is equal to VIRTUAL
  1698. Revision 1.5 1998/01/09 16:08:23 florian
  1699. * abstract methods call now abstracterrorproc if they are called
  1700. a class with an abstract method can be create with a class reference else
  1701. the compiler forbides this
  1702. Revision 1.4 1998/01/09 13:39:55 florian
  1703. * public, protected and private aren't anymore key words
  1704. + published is equal to public
  1705. Revision 1.3 1998/01/09 13:18:12 florian
  1706. + "forward" class declarations (type tclass = class; )
  1707. Revision 1.2 1998/01/09 09:09:58 michael
  1708. + Initial implementation, second try
  1709. }