pdecl.pas 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013
  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. newtype : ptypesym;
  1377. {$ifdef dummy}
  1378. olddef,newdef : pdef;
  1379. s : string;
  1380. {$endif dummy}
  1381. begin
  1382. block_type:=bt_type;
  1383. consume(_TYPE);
  1384. typecanbeforward:=true;
  1385. repeat
  1386. typename:=pattern;
  1387. consume(ID);
  1388. consume(EQUAL);
  1389. { here you loose the strictness of pascal
  1390. for which a redefinition like
  1391. childtype = parenttype;
  1392. child2type = parenttype;
  1393. does not make the two child types equal !!
  1394. here all vars from childtype and child2type
  1395. get the definition of parenttype !! }
  1396. {$ifdef testequaltype}
  1397. if (token = ID) or (token=_FILE) or (token=_STRING) then
  1398. begin
  1399. olddef := single_type(s);
  1400. { make a clone of olddef }
  1401. { is that ok ??? }
  1402. getmem(newdef,SizeOf(olddef));
  1403. move(olddef^,newdef^,SizeOf(olddef));
  1404. newtype:=new(ptypesym,init(typename,newdef));
  1405. symtablestack^.insert(newtype);
  1406. end
  1407. else
  1408. {$endif testequaltype}
  1409. begin
  1410. getsym(typename,false);
  1411. { check if it is the definition of a forward defined class }
  1412. if assigned(srsym) and (token=_CLASS) and
  1413. (srsym^.typ=typesym) and
  1414. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  1415. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oo_isforward)<>0) and
  1416. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oois_class)<>0) then
  1417. begin
  1418. { we can ignore the result }
  1419. { the definition is modified }
  1420. object_dec(typename,pobjectdef(ptypesym(srsym)^.definition));
  1421. newtype:=ptypesym(srsym);
  1422. end
  1423. else
  1424. begin
  1425. newtype:=new(ptypesym,init(typename,read_type(typename)));
  1426. symtablestack^.insert(newtype);
  1427. end;
  1428. end;
  1429. consume(SEMICOLON);
  1430. if assigned(newtype^.definition) and (newtype^.definition^.deftype=procvardef) then
  1431. parse_var_proc_directives(newtype);
  1432. until token<>ID;
  1433. typecanbeforward:=false;
  1434. {$ifdef tp}
  1435. symtablestack^.foreach(testforward_types);
  1436. {$else}
  1437. symtablestack^.foreach(@testforward_types);
  1438. {$endif}
  1439. resolve_forwards;
  1440. block_type:=bt_general;
  1441. end;
  1442. { parses varaible declarations and inserts them in }
  1443. { the top symbol table of symtablestack }
  1444. procedure var_dec;
  1445. {var
  1446. p : pdef;
  1447. sc : pstringcontainer; }
  1448. begin
  1449. consume(_VAR);
  1450. read_var_decs(false,true);
  1451. end;
  1452. { reads the filed of a record into a }
  1453. { symtablestack, if record=false }
  1454. { variants are forbidden, so this procedure }
  1455. { can be used to read object fields }
  1456. { if absolute is true, ABSOLUTE and file }
  1457. { types are allowed }
  1458. { => the procedure is also used to read }
  1459. { a sequence of variable declaration }
  1460. procedure read_var_decs(is_record : boolean;do_absolute : boolean);
  1461. var
  1462. sc : pstringcontainer;
  1463. s : stringid;
  1464. l : longint;
  1465. code : word;
  1466. hs : string;
  1467. p,casedef : pdef;
  1468. { maxsize contains the max. size of a variant }
  1469. { startvarrec contains the start of the variant part of a record }
  1470. maxsize,startvarrec : longint;
  1471. pt : ptree;
  1472. old_block_type : tblock_type;
  1473. { to handle absolute }
  1474. abssym : pabsolutesym;
  1475. filepos : tfileposinfo;
  1476. Csym : pvarsym;
  1477. is_cdecl,extern_Csym,export_Csym : boolean;
  1478. C_name : string;
  1479. begin
  1480. hs:='';
  1481. old_block_type:=block_type;
  1482. block_type:=bt_type;
  1483. { Force an expected ID error message }
  1484. if not (token in [ID,_CASE,_END]) then
  1485. consume(ID);
  1486. { read vars }
  1487. while (token=ID) and
  1488. (pattern<>'PUBLIC') and
  1489. (pattern<>'PRIVATE') and
  1490. (pattern<>'PUBLISHED') and
  1491. (pattern<>'PROTECTED') do
  1492. begin
  1493. C_name:=orgpattern;
  1494. sc:=idlist;
  1495. consume(COLON);
  1496. p:=read_type('');
  1497. if do_absolute and (token=ID) and (pattern='ABSOLUTE') then
  1498. begin
  1499. s:=sc^.get_with_tokeninfo(filepos);
  1500. if sc^.get<>'' then
  1501. Message(parser_e_absolute_only_one_var);
  1502. dispose(sc,done);
  1503. consume(ID);
  1504. if token=ID then
  1505. begin
  1506. getsym(pattern,true);
  1507. consume(ID);
  1508. { we should check the result type of srsym }
  1509. if not (srsym^.typ in [varsym,typedconstsym]) then
  1510. Message(parser_e_absolute_only_to_var_or_const);
  1511. abssym:=new(pabsolutesym,init(s,p));
  1512. abssym^.typ:=absolutesym;
  1513. abssym^.abstyp:=tovar;
  1514. abssym^.ref:=srsym;
  1515. abssym^.line_no:=filepos.line;
  1516. symtablestack^.insert(abssym);
  1517. end
  1518. else
  1519. if token=CSTRING then
  1520. begin
  1521. abssym:=new(pabsolutesym,init(s,p));
  1522. s:=pattern;
  1523. consume(CSTRING);
  1524. abssym^.typ:=absolutesym;
  1525. abssym^.abstyp:=toasm;
  1526. abssym^.asmname:=stringdup(s);
  1527. abssym^.line_no:=filepos.line;
  1528. symtablestack^.insert(abssym);
  1529. end
  1530. else
  1531. { absolute address ?!? }
  1532. if token=INTCONST then
  1533. begin
  1534. {$ifdef i386}
  1535. if (target_info.target=target_GO32V2) then
  1536. begin
  1537. abssym:=new(pabsolutesym,init(s,p));
  1538. abssym^.typ:=absolutesym;
  1539. abssym^.abstyp:=toaddr;
  1540. abssym^.absseg:=false;
  1541. abssym^.line_no:=filepos.line;
  1542. s:=pattern;
  1543. consume(INTCONST);
  1544. val(s,abssym^.address,code);
  1545. if token=COLON then
  1546. begin
  1547. consume(token);
  1548. s:=pattern;
  1549. consume(INTCONST);
  1550. val(s,l,code);
  1551. abssym^.address:=abssym^.address shl 4+l;
  1552. abssym^.absseg:=true;
  1553. end;
  1554. symtablestack^.insert(abssym);
  1555. end
  1556. else
  1557. {$endif i386}
  1558. Message(parser_e_absolute_only_to_var_or_const);
  1559. end
  1560. else
  1561. Message(parser_e_absolute_only_to_var_or_const);
  1562. end
  1563. else
  1564. begin
  1565. if not(is_record) then
  1566. consume(token);
  1567. if support_c_var and do_absolute and (token=ID) and
  1568. ((pattern='EXPORT') or (pattern='EXTERNAL')
  1569. or (pattern='CDECL')) then
  1570. begin
  1571. if pattern='CDECL' then
  1572. begin
  1573. consume(ID);
  1574. consume(SEMICOLON);
  1575. is_cdecl:=true;
  1576. end
  1577. else
  1578. is_cdecl:=false;
  1579. extern_Csym:=(pattern='EXTERNAL');
  1580. if not is_cdecl then
  1581. export_Csym:=(pattern='EXPORT')
  1582. else
  1583. export_Csym:=false;
  1584. s:=sc^.get_with_tokeninfo(filepos);
  1585. if sc^.get<>'' then
  1586. Message(parser_e_absolute_only_one_var);
  1587. dispose(sc,done);
  1588. if extern_Csym or export_Csym then
  1589. consume(ID);
  1590. { external and export need a name after }
  1591. if not is_cdecl then
  1592. begin
  1593. if (token=ID) and (pattern='NAME') then
  1594. consume(ID)
  1595. else
  1596. Comment(V_error,' name keyword expected here ');
  1597. if (token<>CCHAR) and (token<>CSTRING) then
  1598. consume(CSTRING);
  1599. C_name:=pattern;
  1600. consume(token);
  1601. consume(SEMICOLON);
  1602. end;
  1603. if is_cdecl and extern_Csym then
  1604. consume(SEMICOLON);
  1605. Csym:=new(pvarsym,init_C(s,C_name,p));
  1606. if extern_Csym then
  1607. begin
  1608. Csym^.var_options:=Csym^.var_options or vo_is_external;
  1609. { correct type ?? }
  1610. externals^.concat(new(pai_external,init(Csym^.mangledname,EXT_NEAR)));
  1611. end;
  1612. symtablestack^.insert(Csym);
  1613. end
  1614. else
  1615. if (symtablestack^.symtabletype=objectsymtable) then
  1616. begin
  1617. if (token=ID) and (pattern='STATIC') and
  1618. (cs_static_keyword in aktswitches) then
  1619. begin
  1620. current_object_option:=current_object_option or sp_static;
  1621. insert_syms(symtablestack,sc,p);
  1622. current_object_option:=current_object_option - sp_static;
  1623. consume(ID);
  1624. consume(SEMICOLON);
  1625. end
  1626. else
  1627. { this will still be a the wrong line !! }
  1628. insert_syms(symtablestack,sc,p);
  1629. end
  1630. else
  1631. begin
  1632. { at the right line }
  1633. insert_syms(symtablestack,sc,p);
  1634. end;
  1635. end;
  1636. while token=SEMICOLON do
  1637. consume(SEMICOLON);
  1638. end;
  1639. if (token=_CASE) and is_record then
  1640. begin
  1641. maxsize:=0;
  1642. consume(_CASE);
  1643. s:=pattern;
  1644. getsym(s,false);
  1645. { may be only a type: }
  1646. if assigned(srsym) and ((srsym^.typ=typesym) or
  1647. { and with unit qualifier: }
  1648. (srsym^.typ=unitsym)) then
  1649. begin
  1650. casedef:=read_type('');
  1651. end
  1652. else
  1653. begin
  1654. consume(ID);
  1655. consume(COLON);
  1656. casedef:=read_type('');
  1657. symtablestack^.insert(new(pvarsym,init(s,casedef)));
  1658. end;
  1659. if not is_ordinal(casedef) then
  1660. Message(parser_e_ordinal_expected);
  1661. consume(_OF);
  1662. startvarrec:=symtablestack^.datasize;
  1663. repeat
  1664. repeat
  1665. pt:=comp_expr(true);
  1666. do_firstpass(pt);
  1667. if not(pt^.treetype=ordconstn) then
  1668. Message(cg_e_illegal_expression);
  1669. disposetree(pt);
  1670. if token=COMMA then consume(COMMA)
  1671. else break;
  1672. until false;
  1673. consume(COLON);
  1674. consume(LKLAMMER);
  1675. if token<>RKLAMMER then
  1676. read_var_decs(true,false);
  1677. { calculates maximal variant size }
  1678. maxsize:=max(maxsize,symtablestack^.datasize);
  1679. { the items of the next variant are overlayed }
  1680. symtablestack^.datasize:=startvarrec;
  1681. consume(RKLAMMER);
  1682. if token<>SEMICOLON then
  1683. break
  1684. else
  1685. consume(SEMICOLON);
  1686. while token=SEMICOLON do
  1687. consume(SEMICOLON);
  1688. until (token=_END) or (token=RKLAMMER);
  1689. { at last set the record size to that of the biggest variant }
  1690. symtablestack^.datasize:=maxsize;
  1691. end;
  1692. block_type:=old_block_type;
  1693. end;
  1694. procedure Not_supported_for_inline(t : ttoken);
  1695. begin
  1696. if assigned(aktprocsym) and
  1697. ((aktprocsym^.definition^.options and poinline)<>0) then
  1698. Begin
  1699. Comment(V_Warning,tokenstring(t)+' not yet supported inside inline procedure/function ');
  1700. Comment(V_Warning,'inlining disabled');
  1701. aktprocsym^.definition^.options:= aktprocsym^.definition^.options and not poinline;
  1702. End;
  1703. end;
  1704. procedure read_declarations(islibrary : boolean);
  1705. begin
  1706. repeat
  1707. case token of
  1708. _LABEL:
  1709. begin
  1710. Not_supported_for_inline(token);
  1711. label_dec;
  1712. end;
  1713. _CONST:
  1714. begin
  1715. Not_supported_for_inline(token);
  1716. const_dec;
  1717. end;
  1718. _TYPE:
  1719. begin
  1720. Not_supported_for_inline(token);
  1721. type_dec;
  1722. end;
  1723. _VAR:
  1724. var_dec;
  1725. _CONSTRUCTOR,_DESTRUCTOR,
  1726. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1727. begin
  1728. Not_supported_for_inline(token);
  1729. unter_dec;
  1730. end;
  1731. _EXPORTS:
  1732. begin
  1733. { here we should be at lexlevel 1, no ? PM }
  1734. Not_supported_for_inline(token);
  1735. if islibrary then
  1736. read_exports
  1737. else
  1738. break;
  1739. end
  1740. else break;
  1741. end;
  1742. until false;
  1743. end;
  1744. procedure read_interface_declarations;
  1745. begin
  1746. {Since the body is now parsed at lexlevel 1, and the declarations
  1747. must be parsed at the same lexlevel we increase the lexlevel.}
  1748. inc(lexlevel);
  1749. repeat
  1750. case token of
  1751. _CONST : const_dec;
  1752. _TYPE : type_dec;
  1753. _VAR : var_dec;
  1754. { should we allow operator in interface ? }
  1755. { of course otherwise you cannot }
  1756. { declare an operator usable by other }
  1757. { units or progs PM }
  1758. _FUNCTION,_PROCEDURE,_OPERATOR : unter_dec;
  1759. else
  1760. break;
  1761. end;
  1762. until false;
  1763. dec(lexlevel);
  1764. end;
  1765. end.
  1766. {
  1767. $Log$
  1768. Revision 1.27 1998-06-12 16:15:34 pierre
  1769. * external name 'C_var';
  1770. export name 'intern_C_var';
  1771. cdecl;
  1772. cdecl;external;
  1773. are now supported only with -Sv switch
  1774. Revision 1.25 1998/06/09 16:01:45 pierre
  1775. + added procedure directive parsing for procvars
  1776. (accepted are popstack cdecl and pascal)
  1777. + added C vars with the following syntax
  1778. var C calias 'true_c_name';(can be followed by external)
  1779. reason is that you must add the Cprefix
  1780. which is target dependent
  1781. Revision 1.24 1998/06/05 14:37:32 pierre
  1782. * fixes for inline for operators
  1783. * inline procedure more correctly restricted
  1784. Revision 1.23 1998/06/04 23:51:50 peter
  1785. * m68k compiles
  1786. + .def file creation moved to gendef.pas so it could also be used
  1787. for win32
  1788. Revision 1.22 1998/06/03 22:48:59 peter
  1789. + wordbool,longbool
  1790. * rename bis,von -> high,low
  1791. * moved some systemunit loading/creating to psystem.pas
  1792. Revision 1.21 1998/06/03 22:14:19 florian
  1793. * problem with sizes of classes fixed (if the anchestor was declared
  1794. forward, the compiler doesn't update the child classes size)
  1795. Revision 1.20 1998/05/28 14:35:54 peter
  1796. * nicer error message when no id is used after var
  1797. Revision 1.19 1998/05/23 01:21:19 peter
  1798. + aktasmmode, aktoptprocessor, aktoutputformat
  1799. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  1800. + $LIBNAME to set the library name where the unit will be put in
  1801. * splitted cgi386 a bit (codeseg to large for bp7)
  1802. * nasm, tasm works again. nasm moved to ag386nsm.pas
  1803. Revision 1.18 1998/05/20 09:42:35 pierre
  1804. + UseTokenInfo now default
  1805. * unit in interface uses and implementation uses gives error now
  1806. * only one error for unknown symbol (uses lastsymknown boolean)
  1807. the problem came from the label code !
  1808. + first inlined procedures and function work
  1809. (warning there might be allowed cases were the result is still wrong !!)
  1810. * UseBrower updated gives a global list of all position of all used symbols
  1811. with switch -gb
  1812. Revision 1.17 1998/05/11 13:07:55 peter
  1813. + $ifdef NEWPPU for the new ppuformat
  1814. + $define GDB not longer required
  1815. * removed all warnings and stripped some log comments
  1816. * no findfirst/findnext anymore to remove smartlink *.o files
  1817. Revision 1.16 1998/05/05 12:05:42 florian
  1818. * problems with properties fixed
  1819. * crash fixed: i:=l when i and l are undefined, was a problem with
  1820. implementation of private/protected
  1821. Revision 1.15 1998/05/01 09:01:23 florian
  1822. + correct semantics of private and protected
  1823. * small fix in variable scope:
  1824. a id can be used in a parameter list of a method, even it is used in
  1825. an anchestor class as field id
  1826. Revision 1.14 1998/05/01 07:43:56 florian
  1827. + basics for rtti implemented
  1828. + switch $m (generate rtti for published sections)
  1829. Revision 1.13 1998/04/30 15:59:41 pierre
  1830. * GDB works again better :
  1831. correct type info in one pass
  1832. + UseTokenInfo for better source position
  1833. * fixed one remaining bug in scanner for line counts
  1834. * several little fixes
  1835. Revision 1.12 1998/04/29 10:33:57 pierre
  1836. + added some code for ansistring (not complete nor working yet)
  1837. * corrected operator overloading
  1838. * corrected nasm output
  1839. + started inline procedures
  1840. + added starstarn : use ** for exponentiation (^ gave problems)
  1841. + started UseTokenInfo cond to get accurate positions
  1842. Revision 1.11 1998/04/28 11:45:52 florian
  1843. * make it compilable with TP
  1844. + small COM problems solved to compile classes.pp
  1845. Revision 1.10 1998/04/27 23:10:28 peter
  1846. + new scanner
  1847. * $makelib -> if smartlink
  1848. * small filename fixes pmodule.setfilename
  1849. * moved import from files.pas -> import.pas
  1850. Revision 1.9 1998/04/10 21:36:56 florian
  1851. + some stuff to support method pointers (procedure of object) added
  1852. (declaration, parameter handling)
  1853. Revision 1.8 1998/04/10 15:39:48 florian
  1854. * more fixes to get classes.pas compiled
  1855. Revision 1.7 1998/04/09 23:02:15 florian
  1856. * small problems solved to get remake3 work
  1857. Revision 1.6 1998/04/09 22:16:35 florian
  1858. * problem with previous REGALLOC solved
  1859. * improved property support
  1860. Revision 1.5 1998/04/08 14:59:20 florian
  1861. * problem with new expr_type solved
  1862. Revision 1.4 1998/04/08 10:26:09 florian
  1863. * correct error handling of virtual constructors
  1864. * problem with new type declaration handling fixed
  1865. Revision 1.3 1998/04/07 22:45:05 florian
  1866. * bug0092, bug0115 and bug0121 fixed
  1867. + packed object/class/array
  1868. Revision 1.2 1998/04/05 13:58:35 peter
  1869. * fixed the -Ss bug
  1870. + warning for Virtual constructors
  1871. * helppages updated with -TGO32V1
  1872. }