pdecl.pas 71 KB

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