pdecl.pas 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  1. {
  2. $Id$
  3. Copyright (c) 1993-99 by Florian Klaempfl
  4. Does declaration (but not type) 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. globtype,tokens,globals,symtable;
  22. procedure parameter_dec(aktprocdef:pabstractprocdef);
  23. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  24. { reads the declaration blocks }
  25. procedure read_declarations(islibrary : boolean);
  26. { reads declarations in the interface part of a unit }
  27. procedure read_interface_declarations;
  28. implementation
  29. uses
  30. cobjects,scanner,
  31. symconst,aasm,tree,pass_1,strings,
  32. files,types,verbose,systems,import,
  33. cpubase
  34. {$ifndef newcg}
  35. ,tccnv
  36. {$endif newcg}
  37. {$ifdef GDB}
  38. ,gdb
  39. {$endif GDB}
  40. { parser specific stuff }
  41. ,pbase,ptconst,pexpr,ptype,psub,pexports
  42. { processor specific stuff }
  43. { codegen }
  44. {$ifdef newcg}
  45. ,cgbase
  46. {$else}
  47. ,hcodegen
  48. {$endif}
  49. ,hcgdata
  50. ;
  51. procedure parameter_dec(aktprocdef:pabstractprocdef);
  52. {
  53. handle_procvar needs the same changes
  54. }
  55. var
  56. is_procvar : boolean;
  57. sc : Pstringcontainer;
  58. s : string;
  59. storetokenpos : tfileposinfo;
  60. p : Pdef;
  61. hsym : psym;
  62. hvs,
  63. vs : Pvarsym;
  64. hs1,hs2 : string;
  65. varspez : Tvarspez;
  66. inserthigh : boolean;
  67. begin
  68. { parsing a proc or procvar ? }
  69. is_procvar:=(aktprocdef^.deftype=procvardef);
  70. consume(_LKLAMMER);
  71. inc(testcurobject);
  72. repeat
  73. if try_to_consume(_VAR) then
  74. varspez:=vs_var
  75. else
  76. if try_to_consume(_CONST) then
  77. varspez:=vs_const
  78. else
  79. varspez:=vs_value;
  80. inserthigh:=false;
  81. readtypesym:=nil;
  82. if idtoken=_SELF then
  83. begin
  84. { only allowed in procvars and class methods }
  85. if is_procvar or
  86. (assigned(procinfo^._class) and procinfo^._class^.is_class) then
  87. begin
  88. if not is_procvar then
  89. begin
  90. {$ifndef UseNiceNames}
  91. hs2:=hs2+'$'+'self';
  92. {$else UseNiceNames}
  93. hs2:=hs2+tostr(length('self'))+'self';
  94. {$endif UseNiceNames}
  95. vs:=new(Pvarsym,init('@',procinfo^._class));
  96. vs^.varspez:=vs_var;
  97. { insert the sym in the parasymtable }
  98. pprocdef(aktprocdef)^.parast^.insert(vs);
  99. {$ifdef INCLUDEOK}
  100. include(aktprocdef^.procoptions,po_containsself);
  101. {$else}
  102. aktprocdef^.procoptions:=aktprocdef^.procoptions+[po_containsself];
  103. {$endif}
  104. inc(procinfo^.selfpointer_offset,vs^.address);
  105. end;
  106. consume(idtoken);
  107. consume(_COLON);
  108. p:=single_type(hs1,false);
  109. if assigned(readtypesym) then
  110. aktprocdef^.concattypesym(readtypesym,vs_value)
  111. else
  112. aktprocdef^.concatdef(p,vs_value);
  113. { check the types for procedures only }
  114. if not is_procvar then
  115. CheckTypes(p,procinfo^._class);
  116. end
  117. else
  118. consume(_ID);
  119. end
  120. else
  121. begin
  122. { read identifiers }
  123. sc:=idlist;
  124. { read type declaration, force reading for value and const paras }
  125. if (token=_COLON) or (varspez=vs_value) then
  126. begin
  127. consume(_COLON);
  128. { check for an open array }
  129. if token=_ARRAY then
  130. begin
  131. consume(_ARRAY);
  132. consume(_OF);
  133. { define range and type of range }
  134. p:=new(Parraydef,init(0,-1,s32bitdef));
  135. { array of const ? }
  136. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  137. begin
  138. consume(_CONST);
  139. srsym:=nil;
  140. getsymonlyin(systemunit,'TVARREC');
  141. if not assigned(srsym) then
  142. InternalError(1234124);
  143. Parraydef(p)^.definition:=ptypesym(srsym)^.definition;
  144. Parraydef(p)^.IsArrayOfConst:=true;
  145. hs1:='array_of_const';
  146. end
  147. else
  148. begin
  149. { define field type }
  150. Parraydef(p)^.definition:=single_type(hs1,false);
  151. hs1:='array_of_'+hs1;
  152. { we don't need the typesym anymore }
  153. readtypesym:=nil;
  154. end;
  155. inserthigh:=true;
  156. end
  157. { open string ? }
  158. else if (varspez=vs_var) and
  159. (
  160. (
  161. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  162. (cs_openstring in aktmoduleswitches) and
  163. not(cs_ansistrings in aktlocalswitches)
  164. ) or
  165. (idtoken=_OPENSTRING)) then
  166. begin
  167. consume(token);
  168. p:=openshortstringdef;
  169. hs1:='openstring';
  170. inserthigh:=true;
  171. end
  172. { everything else }
  173. else
  174. p:=single_type(hs1,false);
  175. end
  176. else
  177. begin
  178. {$ifndef UseNiceNames}
  179. hs1:='$$$';
  180. {$else UseNiceNames}
  181. hs1:='var';
  182. {$endif UseNiceNames}
  183. p:=cformaldef;
  184. end;
  185. if not is_procvar then
  186. hs2:=pprocdef(aktprocdef)^.mangledname;
  187. storetokenpos:=tokenpos;
  188. while not sc^.empty do
  189. begin
  190. s:=sc^.get_with_tokeninfo(tokenpos);
  191. if assigned(readtypesym) then
  192. aktprocdef^.concattypesym(readtypesym,varspez)
  193. else
  194. aktprocdef^.concatdef(p,varspez);
  195. { For proc vars we only need the definitions }
  196. if not is_procvar then
  197. begin
  198. {$ifndef UseNiceNames}
  199. hs2:=hs2+'$'+hs1;
  200. {$else UseNiceNames}
  201. hs2:=hs2+tostr(length(hs1))+hs1;
  202. {$endif UseNiceNames}
  203. if assigned(readtypesym) then
  204. vs:=new(Pvarsym,initsym(s,readtypesym))
  205. else
  206. vs:=new(Pvarsym,init(s,p));
  207. vs^.varspez:=varspez;
  208. { we have to add this to avoid var param to be in registers !!!}
  209. if (varspez in [vs_var,vs_const]) and push_addr_param(p) then
  210. {$ifdef INCLUDEOK}
  211. include(vs^.varoptions,vo_regable);
  212. {$else}
  213. vs^.varoptions:=vs^.varoptions+[vo_regable];
  214. {$endif}
  215. { search for duplicate ids in object members/methods }
  216. { but only the current class, I don't know why ... }
  217. { at least TP and Delphi do it in that way (FK) }
  218. if assigned(procinfo^._class) and
  219. (lexlevel=normal_function_level) then
  220. begin
  221. hsym:=procinfo^._class^.symtable^.search(vs^.name);
  222. if assigned(hsym) then
  223. DuplicateSym(hsym);
  224. end;
  225. { do we need a local copy? }
  226. if (varspez=vs_value) and
  227. push_addr_param(p) and
  228. not(is_open_array(p) or is_array_of_const(p)) then
  229. vs^.setname('val'+vs^.name);
  230. { insert the sym in the parasymtable }
  231. pprocdef(aktprocdef)^.parast^.insert(vs);
  232. { also need to push a high value? }
  233. if inserthigh then
  234. begin
  235. hvs:=new(Pvarsym,init('high'+s,s32bitdef));
  236. hvs^.varspez:=vs_const;
  237. pprocdef(aktprocdef)^.parast^.insert(hvs);
  238. end;
  239. end;
  240. end;
  241. dispose(sc,done);
  242. tokenpos:=storetokenpos;
  243. end;
  244. { set the new mangled name }
  245. if not is_procvar then
  246. pprocdef(aktprocdef)^.setmangledname(hs2);
  247. until not try_to_consume(_SEMICOLON);
  248. dec(testcurobject);
  249. consume(_RKLAMMER);
  250. end;
  251. const
  252. variantrecordlevel : longint = 0;
  253. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  254. { reads the filed of a record into a }
  255. { symtablestack, if record=false }
  256. { variants are forbidden, so this procedure }
  257. { can be used to read object fields }
  258. { if absolute is true, ABSOLUTE and file }
  259. { types are allowed }
  260. { => the procedure is also used to read }
  261. { a sequence of variable declaration }
  262. procedure insert_syms(st : psymtable;sc : pstringcontainer;def : pdef;sym:ptypesym;is_threadvar : boolean);
  263. { inserts the symbols of sc in st with def as definition or sym as ptypesym, sc is disposed }
  264. var
  265. s : string;
  266. filepos : tfileposinfo;
  267. ss : pvarsym;
  268. begin
  269. { can't have a definition and ttypesym }
  270. if assigned(def) and assigned(sym) then
  271. internalerror(5438257);
  272. filepos:=tokenpos;
  273. while not sc^.empty do
  274. begin
  275. s:=sc^.get_with_tokeninfo(tokenpos);
  276. if assigned(sym) then
  277. ss:=new(pvarsym,initsym(s,sym))
  278. else
  279. ss:=new(pvarsym,init(s,def));
  280. if is_threadvar then
  281. {$ifdef INCLUDEOK}
  282. include(ss^.varoptions,vo_is_thread_var);
  283. {$else}
  284. ss^.varoptions:=ss^.varoptions+[vo_is_thread_var];
  285. {$endif}
  286. st^.insert(ss);
  287. { static data fields are inserted in the globalsymtable }
  288. if (st^.symtabletype=objectsymtable) and
  289. (sp_static in current_object_option) then
  290. begin
  291. s:=lower(st^.name^)+'_'+s;
  292. st^.defowner^.owner^.insert(new(pvarsym,init(s,def)));
  293. end;
  294. end;
  295. dispose(sc,done);
  296. tokenpos:=filepos;
  297. end;
  298. var
  299. sc : pstringcontainer;
  300. s : stringid;
  301. old_block_type : tblock_type;
  302. declarepos,storetokenpos : tfileposinfo;
  303. symdone : boolean;
  304. { to handle absolute }
  305. abssym : pabsolutesym;
  306. l : longint;
  307. code : integer;
  308. { c var }
  309. newtype : ptypesym;
  310. is_dll,
  311. is_gpc_name,is_cdecl,extern_aktvarsym,export_aktvarsym : boolean;
  312. dll_name,
  313. C_name : string;
  314. { case }
  315. p,casedef : pdef;
  316. { Delphi initialized vars }
  317. pconstsym : ptypedconstsym;
  318. { maxsize contains the max. size of a variant }
  319. { startvarrec contains the start of the variant part of a record }
  320. maxsize,startvarrec : longint;
  321. pt : ptree;
  322. begin
  323. old_block_type:=block_type;
  324. block_type:=bt_type;
  325. is_gpc_name:=false;
  326. { Force an expected ID error message }
  327. if not (token in [_ID,_CASE,_END]) then
  328. consume(_ID);
  329. { read vars }
  330. while (token=_ID) and
  331. not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
  332. begin
  333. C_name:=orgpattern;
  334. sc:=idlist;
  335. consume(_COLON);
  336. if (m_gpc in aktmodeswitches) and
  337. not(is_record or is_object or is_threadvar) and
  338. (token=_ID) and (orgpattern='__asmname__') then
  339. begin
  340. consume(_ID);
  341. C_name:=pattern;
  342. if token=_CCHAR then
  343. consume(_CCHAR)
  344. else
  345. consume(_CSTRING);
  346. Is_gpc_name:=true;
  347. end;
  348. { this is needed for Delphi mode at least
  349. but should be OK for all modes !! (PM) }
  350. ignore_equal:=true;
  351. p:=read_type('');
  352. if (variantrecordlevel>0) and p^.needs_inittable then
  353. Message(parser_e_cant_use_inittable_here);
  354. ignore_equal:=false;
  355. symdone:=false;
  356. if is_gpc_name then
  357. begin
  358. storetokenpos:=tokenpos;
  359. s:=sc^.get_with_tokeninfo(tokenpos);
  360. if not sc^.empty then
  361. Message(parser_e_absolute_only_one_var);
  362. dispose(sc,done);
  363. aktvarsym:=new(pvarsym,init_C(s,target_os.Cprefix+C_name,p));
  364. {$ifdef INCLUDEOK}
  365. include(aktvarsym^.varoptions,vo_is_external);
  366. {$else}
  367. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  368. {$endif}
  369. symtablestack^.insert(aktvarsym);
  370. tokenpos:=storetokenpos;
  371. symdone:=true;
  372. end;
  373. { check for absolute }
  374. if not symdone and
  375. (idtoken=_ABSOLUTE) and not(is_record or is_object or is_threadvar) then
  376. begin
  377. consume(_ABSOLUTE);
  378. { only allowed for one var }
  379. s:=sc^.get_with_tokeninfo(declarepos);
  380. if not sc^.empty then
  381. Message(parser_e_absolute_only_one_var);
  382. dispose(sc,done);
  383. { parse the rest }
  384. if token=_ID then
  385. begin
  386. getsym(pattern,true);
  387. consume(_ID);
  388. { support unit.variable }
  389. if srsym^.typ=unitsym then
  390. begin
  391. consume(_POINT);
  392. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  393. consume(_ID);
  394. end;
  395. { we should check the result type of srsym }
  396. if not (srsym^.typ in [varsym,typedconstsym]) then
  397. Message(parser_e_absolute_only_to_var_or_const);
  398. storetokenpos:=tokenpos;
  399. tokenpos:=declarepos;
  400. abssym:=new(pabsolutesym,init(s,p));
  401. abssym^.abstyp:=tovar;
  402. abssym^.ref:=srsym;
  403. symtablestack^.insert(abssym);
  404. tokenpos:=storetokenpos;
  405. end
  406. else
  407. if (token=_CSTRING) or (token=_CCHAR) then
  408. begin
  409. storetokenpos:=tokenpos;
  410. tokenpos:=declarepos;
  411. abssym:=new(pabsolutesym,init(s,p));
  412. s:=pattern;
  413. consume(token);
  414. abssym^.abstyp:=toasm;
  415. abssym^.asmname:=stringdup(s);
  416. symtablestack^.insert(abssym);
  417. tokenpos:=storetokenpos;
  418. end
  419. else
  420. { absolute address ?!? }
  421. if token=_INTCONST then
  422. begin
  423. if (target_info.target=target_i386_go32v2) then
  424. begin
  425. storetokenpos:=tokenpos;
  426. tokenpos:=declarepos;
  427. abssym:=new(pabsolutesym,init(s,p));
  428. abssym^.abstyp:=toaddr;
  429. abssym^.absseg:=false;
  430. s:=pattern;
  431. consume(_INTCONST);
  432. val(s,abssym^.address,code);
  433. if token=_COLON then
  434. begin
  435. consume(token);
  436. s:=pattern;
  437. consume(_INTCONST);
  438. val(s,l,code);
  439. abssym^.address:=abssym^.address shl 4+l;
  440. abssym^.absseg:=true;
  441. end;
  442. symtablestack^.insert(abssym);
  443. tokenpos:=storetokenpos;
  444. end
  445. else
  446. Message(parser_e_absolute_only_to_var_or_const);
  447. end
  448. else
  449. Message(parser_e_absolute_only_to_var_or_const);
  450. symdone:=true;
  451. end;
  452. { Handling of Delphi typed const = initialized vars ! }
  453. { When should this be rejected ?
  454. - in parasymtable
  455. - in record or object
  456. - ... (PM) }
  457. if (m_delphi in aktmodeswitches) and (token=_EQUAL) and
  458. not (symtablestack^.symtabletype in [parasymtable]) and
  459. not is_record and not is_object then
  460. begin
  461. storetokenpos:=tokenpos;
  462. s:=sc^.get_with_tokeninfo(tokenpos);
  463. if not sc^.empty then
  464. Message(parser_e_initialized_only_one_var);
  465. if assigned(readtypesym) then
  466. pconstsym:=new(ptypedconstsym,initsym(s,readtypesym,false))
  467. else
  468. pconstsym:=new(ptypedconstsym,init(s,p,false));
  469. symtablestack^.insert(pconstsym);
  470. tokenpos:=storetokenpos;
  471. consume(_EQUAL);
  472. readtypedconst(p,pconstsym,false);
  473. symdone:=true;
  474. end;
  475. { for a record there doesn't need to be a ; before the END or ) }
  476. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  477. consume(_SEMICOLON);
  478. { procvar handling }
  479. if (p^.deftype=procvardef) and (p^.sym=nil) then
  480. begin
  481. newtype:=new(ptypesym,init('unnamed',p));
  482. parse_var_proc_directives(psym(newtype));
  483. newtype^.definition:=nil;
  484. p^.sym:=nil;
  485. dispose(newtype,done);
  486. end;
  487. { Check for variable directives }
  488. if not symdone and (token=_ID) then
  489. begin
  490. { Check for C Variable declarations }
  491. if (m_cvar_support in aktmodeswitches) and
  492. not(is_record or is_object or is_threadvar) and
  493. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  494. begin
  495. { only allowed for one var }
  496. s:=sc^.get_with_tokeninfo(declarepos);
  497. if not sc^.empty then
  498. Message(parser_e_absolute_only_one_var);
  499. dispose(sc,done);
  500. { defaults }
  501. is_dll:=false;
  502. is_cdecl:=false;
  503. extern_aktvarsym:=false;
  504. export_aktvarsym:=false;
  505. { cdecl }
  506. if idtoken=_CVAR then
  507. begin
  508. consume(_CVAR);
  509. consume(_SEMICOLON);
  510. is_cdecl:=true;
  511. C_name:=target_os.Cprefix+C_name;
  512. end;
  513. { external }
  514. if idtoken=_EXTERNAL then
  515. begin
  516. consume(_EXTERNAL);
  517. extern_aktvarsym:=true;
  518. end;
  519. { export }
  520. if idtoken in [_EXPORT,_PUBLIC] then
  521. begin
  522. consume(_ID);
  523. if extern_aktvarsym then
  524. Message(parser_e_not_external_and_export)
  525. else
  526. export_aktvarsym:=true;
  527. end;
  528. { external and export need a name after when no cdecl is used }
  529. if not is_cdecl then
  530. begin
  531. { dll name ? }
  532. if (extern_aktvarsym) and (idtoken<>_NAME) then
  533. begin
  534. is_dll:=true;
  535. dll_name:=get_stringconst;
  536. end;
  537. consume(_NAME);
  538. C_name:=get_stringconst;
  539. end;
  540. { consume the ; when export or external is used }
  541. if extern_aktvarsym or export_aktvarsym then
  542. consume(_SEMICOLON);
  543. { insert in the symtable }
  544. storetokenpos:=tokenpos;
  545. tokenpos:=declarepos;
  546. if is_dll then
  547. begin
  548. if assigned(readtypesym) then
  549. aktvarsym:=new(pvarsym,initsym_dll(s,readtypesym))
  550. else
  551. aktvarsym:=new(pvarsym,init_dll(s,p))
  552. end
  553. else
  554. begin
  555. if assigned(readtypesym) then
  556. aktvarsym:=new(pvarsym,initsym_C(s,C_name,readtypesym))
  557. else
  558. aktvarsym:=new(pvarsym,init_C(s,C_name,p));
  559. end;
  560. { set some vars options }
  561. if export_aktvarsym then
  562. inc(aktvarsym^.refs);
  563. if extern_aktvarsym then
  564. {$ifdef INCLUDEOK}
  565. include(aktvarsym^.varoptions,vo_is_external);
  566. {$else}
  567. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  568. {$endif}
  569. { insert in the stack/datasegment }
  570. symtablestack^.insert(aktvarsym);
  571. tokenpos:=storetokenpos;
  572. { now we can insert it in the import lib if its a dll, or
  573. add it to the externals }
  574. if extern_aktvarsym then
  575. begin
  576. if is_dll then
  577. begin
  578. if not(current_module^.uses_imports) then
  579. begin
  580. current_module^.uses_imports:=true;
  581. importlib^.preparelib(current_module^.modulename^);
  582. end;
  583. importlib^.importvariable(aktvarsym^.mangledname,dll_name,C_name)
  584. end
  585. end;
  586. symdone:=true;
  587. end
  588. else
  589. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  590. begin
  591. {$ifdef INCLUDEOK}
  592. include(current_object_option,sp_static);
  593. {$else}
  594. current_object_option:=current_object_option+[sp_static];
  595. {$endif}
  596. if assigned(readtypesym) then
  597. insert_syms(symtablestack,sc,nil,readtypesym,false)
  598. else
  599. insert_syms(symtablestack,sc,p,nil,false);
  600. {$ifdef INCLUDEOK}
  601. exclude(current_object_option,sp_static);
  602. {$else}
  603. current_object_option:=current_object_option-[sp_static];
  604. {$endif}
  605. consume(_STATIC);
  606. consume(_SEMICOLON);
  607. symdone:=true;
  608. end;
  609. end;
  610. { insert it in the symtable, if not done yet }
  611. if not symdone then
  612. begin
  613. if (sp_published in current_object_option) and
  614. (not((p^.deftype=objectdef) and (pobjectdef(p)^.is_class))) then
  615. Message(parser_e_cant_publish_that)
  616. else if (sp_published in current_object_option) and
  617. not(oo_can_have_published in pobjectdef(p)^.objectoptions) then
  618. Message(parser_e_only_publishable_classes_can__be_published);
  619. if assigned(readtypesym) then
  620. insert_syms(symtablestack,sc,nil,readtypesym,is_threadvar)
  621. else
  622. insert_syms(symtablestack,sc,p,nil,is_threadvar);
  623. end;
  624. end;
  625. { Check for Case }
  626. if is_record and (token=_CASE) then
  627. begin
  628. maxsize:=0;
  629. consume(_CASE);
  630. s:=pattern;
  631. getsym(s,false);
  632. { may be only a type: }
  633. if assigned(srsym) and (srsym^.typ in [typesym,unitsym]) then
  634. casedef:=read_type('')
  635. else
  636. begin
  637. consume(_ID);
  638. consume(_COLON);
  639. casedef:=read_type('');
  640. symtablestack^.insert(new(pvarsym,init(s,casedef)));
  641. end;
  642. if not(is_ordinal(casedef)) or is_64bitint(casedef) then
  643. Message(type_e_ordinal_expr_expected);
  644. consume(_OF);
  645. startvarrec:=symtablestack^.datasize;
  646. repeat
  647. repeat
  648. pt:=comp_expr(true);
  649. do_firstpass(pt);
  650. if not(pt^.treetype=ordconstn) then
  651. Message(cg_e_illegal_expression);
  652. disposetree(pt);
  653. if token=_COMMA then
  654. consume(_COMMA)
  655. else
  656. break;
  657. until false;
  658. consume(_COLON);
  659. { read the vars }
  660. consume(_LKLAMMER);
  661. inc(variantrecordlevel);
  662. if token<>_RKLAMMER then
  663. read_var_decs(true,false,false);
  664. dec(variantrecordlevel);
  665. consume(_RKLAMMER);
  666. { calculates maximal variant size }
  667. maxsize:=max(maxsize,symtablestack^.datasize);
  668. { the items of the next variant are overlayed }
  669. symtablestack^.datasize:=startvarrec;
  670. if (token<>_END) and (token<>_RKLAMMER) then
  671. consume(_SEMICOLON)
  672. else
  673. break;
  674. until (token=_END) or (token=_RKLAMMER);
  675. { at last set the record size to that of the biggest variant }
  676. symtablestack^.datasize:=maxsize;
  677. end;
  678. block_type:=old_block_type;
  679. end;
  680. procedure const_dec;
  681. var
  682. name : stringid;
  683. p : ptree;
  684. def : pdef;
  685. sym : psym;
  686. storetokenpos,filepos : tfileposinfo;
  687. old_block_type : tblock_type;
  688. ps : pconstset;
  689. pd : pbestreal;
  690. sp : pchar;
  691. skipequal : boolean;
  692. begin
  693. consume(_CONST);
  694. old_block_type:=block_type;
  695. block_type:=bt_const;
  696. repeat
  697. name:=pattern;
  698. filepos:=tokenpos;
  699. consume(_ID);
  700. case token of
  701. _EQUAL:
  702. begin
  703. consume(_EQUAL);
  704. p:=comp_expr(true);
  705. do_firstpass(p);
  706. storetokenpos:=tokenpos;
  707. tokenpos:=filepos;
  708. case p^.treetype of
  709. ordconstn:
  710. begin
  711. if is_constintnode(p) then
  712. symtablestack^.insert(new(pconstsym,init_def(name,constint,p^.value,nil)))
  713. else if is_constcharnode(p) then
  714. symtablestack^.insert(new(pconstsym,init_def(name,constchar,p^.value,nil)))
  715. else if is_constboolnode(p) then
  716. symtablestack^.insert(new(pconstsym,init_def(name,constbool,p^.value,nil)))
  717. else if p^.resulttype^.deftype=enumdef then
  718. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  719. else if p^.resulttype^.deftype=pointerdef then
  720. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  721. else internalerror(111);
  722. end;
  723. stringconstn:
  724. begin
  725. getmem(sp,p^.length+1);
  726. move(p^.value_str^,sp^,p^.length+1);
  727. symtablestack^.insert(new(pconstsym,init_string(name,conststring,sp,p^.length)));
  728. end;
  729. realconstn :
  730. begin
  731. new(pd);
  732. pd^:=p^.value_real;
  733. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd))));
  734. end;
  735. setconstn :
  736. begin
  737. new(ps);
  738. ps^:=p^.value_set^;
  739. symtablestack^.insert(new(pconstsym,init_def(name,constset,longint(ps),p^.resulttype)));
  740. end;
  741. pointerconstn :
  742. begin
  743. symtablestack^.insert(new(pconstsym,init_def(name,constpointer,p^.value,p^.resulttype)))
  744. end;
  745. niln :
  746. begin
  747. symtablestack^.insert(new(pconstsym,init_def(name,constnil,0,p^.resulttype)));
  748. end;
  749. else
  750. Message(cg_e_illegal_expression);
  751. end;
  752. tokenpos:=storetokenpos;
  753. consume(_SEMICOLON);
  754. disposetree(p);
  755. end;
  756. _COLON:
  757. begin
  758. { set the blocktype first so a consume also supports a
  759. caret, to support const s : ^string = nil }
  760. block_type:=bt_type;
  761. consume(_COLON);
  762. ignore_equal:=true;
  763. def:=read_type('');
  764. ignore_equal:=false;
  765. block_type:=bt_const;
  766. skipequal:=false;
  767. { create symbol }
  768. storetokenpos:=tokenpos;
  769. tokenpos:=filepos;
  770. {$ifdef DELPHI_CONST_IN_RODATA}
  771. if m_delphi in aktmodeswitches then
  772. begin
  773. if assigned(readtypesym) then
  774. sym:=new(ptypedconstsym,initsym(name,readtypesym,true))
  775. else
  776. sym:=new(ptypedconstsym,init(name,def,true))
  777. end
  778. else
  779. {$endif DELPHI_CONST_IN_RODATA}
  780. begin
  781. if assigned(readtypesym) then
  782. sym:=new(ptypedconstsym,initsym(name,readtypesym,false))
  783. else
  784. sym:=new(ptypedconstsym,init(name,def,false))
  785. end;
  786. tokenpos:=storetokenpos;
  787. symtablestack^.insert(sym);
  788. { procvar can have proc directives }
  789. if (def^.deftype=procvardef) then
  790. begin
  791. { support p : procedure;stdcall=nil; }
  792. if (token=_SEMICOLON) then
  793. begin
  794. consume(_SEMICOLON);
  795. if is_proc_directive(token) then
  796. parse_var_proc_directives(sym)
  797. else
  798. begin
  799. Message(parser_e_proc_directive_expected);
  800. skipequal:=true;
  801. end;
  802. end
  803. else
  804. { support p : procedure stdcall=nil; }
  805. begin
  806. if is_proc_directive(token) then
  807. parse_var_proc_directives(sym);
  808. end;
  809. end;
  810. if not skipequal then
  811. begin
  812. { get init value }
  813. consume(_EQUAL);
  814. {$ifdef DELPHI_CONST_IN_RODATA}
  815. if m_delphi in aktmodeswitches then
  816. readtypedconst(def,ptypedconstsym(sym),true)
  817. else
  818. {$endif DELPHI_CONST_IN_RODATA}
  819. readtypedconst(def,ptypedconstsym(sym),false);
  820. consume(_SEMICOLON);
  821. end;
  822. end;
  823. else
  824. { generate an error }
  825. consume(_EQUAL);
  826. end;
  827. until token<>_ID;
  828. block_type:=old_block_type;
  829. end;
  830. procedure label_dec;
  831. var
  832. hl : pasmlabel;
  833. begin
  834. consume(_LABEL);
  835. if not(cs_support_goto in aktmoduleswitches) then
  836. Message(sym_e_goto_and_label_not_supported);
  837. repeat
  838. if not(token in [_ID,_INTCONST]) then
  839. consume(_ID)
  840. else
  841. begin
  842. getlabel(hl);
  843. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  844. consume(token);
  845. end;
  846. if token<>_SEMICOLON then consume(_COMMA);
  847. until not(token in [_ID,_INTCONST]);
  848. consume(_SEMICOLON);
  849. end;
  850. { search in symtablestack used, but not defined type }
  851. procedure resolve_type_forward(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
  852. var
  853. hpd,pd : pdef;
  854. begin
  855. { Check only typesyms or record/object fields }
  856. case psym(p)^.typ of
  857. typesym :
  858. pd:=ptypesym(p)^.definition;
  859. varsym :
  860. if (psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  861. pd:=pvarsym(p)^.definition
  862. else
  863. exit;
  864. else
  865. exit;
  866. end;
  867. case pd^.deftype of
  868. pointerdef,
  869. classrefdef :
  870. begin
  871. { classrefdef inherits from pointerdef }
  872. hpd:=ppointerdef(pd)^.definition;
  873. { still a forward def ? }
  874. if hpd^.deftype=forwarddef then
  875. begin
  876. { try to resolve the forward }
  877. getsym(pforwarddef(hpd)^.tosymname,false);
  878. { we don't need the forwarddef anymore, dispose it }
  879. dispose(hpd,done);
  880. { was a type sym found ? }
  881. if assigned(srsym) and
  882. (srsym^.typ=typesym) then
  883. begin
  884. ppointerdef(pd)^.definition:=ptypesym(srsym)^.definition;
  885. {$ifdef GDB}
  886. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  887. (psym(p)^.owner^.symtabletype in [globalsymtable,staticsymtable]) then
  888. begin
  889. ptypesym(p)^.isusedinstab := true;
  890. psym(p)^.concatstabto(debuglist);
  891. end;
  892. {$endif GDB}
  893. { we need a class type for classrefdef }
  894. if (pd^.deftype=classrefdef) and
  895. not((ptypesym(srsym)^.definition^.deftype=objectdef) and
  896. pobjectdef(ptypesym(srsym)^.definition)^.is_class) then
  897. Message1(type_e_class_type_expected,ptypesym(srsym)^.definition^.typename);
  898. end
  899. else
  900. begin
  901. MessagePos1(psym(p)^.fileinfo,sym_e_forward_type_not_resolved,p^.name);
  902. { try to recover }
  903. ppointerdef(pd)^.definition:=generrordef;
  904. end;
  905. end;
  906. end;
  907. recorddef :
  908. precorddef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  909. objectdef :
  910. { Don't check objectdefs in objects/records, because these can't
  911. exist (anonymous objects aren't allowed) }
  912. if not(psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  913. pobjectdef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  914. end;
  915. end;
  916. { reads a type declaration to the symbol table }
  917. procedure type_dec;
  918. var
  919. typename : stringid;
  920. newtype : ptypesym;
  921. sym : psym;
  922. old_block_type : tblock_type;
  923. begin
  924. old_block_type:=block_type;
  925. block_type:=bt_type;
  926. consume(_TYPE);
  927. typecanbeforward:=true;
  928. repeat
  929. typename:=pattern;
  930. consume(_ID);
  931. consume(_EQUAL);
  932. { support 'ttype=type word' syntax }
  933. if token=_TYPE then
  934. Consume(_TYPE);
  935. { is the type already defined? }
  936. getsym(typename,false);
  937. sym:=srsym;
  938. newtype:=nil;
  939. { found a symbol with this name? }
  940. if assigned(sym) then
  941. begin
  942. if (sym^.typ=typesym) then
  943. begin
  944. if (token=_CLASS) and
  945. (assigned(ptypesym(sym)^.definition)) and
  946. (ptypesym(sym)^.definition^.deftype=objectdef) and
  947. pobjectdef(ptypesym(sym)^.definition)^.is_class and
  948. (oo_is_forward in pobjectdef(ptypesym(sym)^.definition)^.objectoptions) then
  949. begin
  950. { we can ignore the result }
  951. { the definition is modified }
  952. object_dec(typename,pobjectdef(ptypesym(sym)^.definition));
  953. newtype:=ptypesym(sym);
  954. end;
  955. end;
  956. end;
  957. { no old type reused ? Then insert this new type }
  958. if not assigned(newtype) then
  959. begin
  960. newtype:=new(ptypesym,init(typename,read_type(typename)));
  961. newtype:=ptypesym(symtablestack^.insert(newtype));
  962. end;
  963. consume(_SEMICOLON);
  964. if assigned(newtype^.definition) and
  965. (newtype^.definition^.deftype=procvardef) then
  966. parse_var_proc_directives(psym(newtype));
  967. until token<>_ID;
  968. typecanbeforward:=false;
  969. symtablestack^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  970. block_type:=old_block_type;
  971. end;
  972. procedure var_dec;
  973. { parses varaible declarations and inserts them in }
  974. { the top symbol table of symtablestack }
  975. begin
  976. consume(_VAR);
  977. read_var_decs(false,false,false);
  978. end;
  979. procedure threadvar_dec;
  980. { parses thread variable declarations and inserts them in }
  981. { the top symbol table of symtablestack }
  982. begin
  983. consume(_THREADVAR);
  984. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  985. message(parser_e_threadvars_only_sg);
  986. read_var_decs(false,false,true);
  987. end;
  988. procedure resourcestring_dec;
  989. var
  990. name : stringid;
  991. p : ptree;
  992. storetokenpos,filepos : tfileposinfo;
  993. old_block_type : tblock_type;
  994. sp : pchar;
  995. begin
  996. consume(_RESOURCESTRING);
  997. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  998. message(parser_e_resourcestring_only_sg);
  999. old_block_type:=block_type;
  1000. block_type:=bt_const;
  1001. repeat
  1002. name:=pattern;
  1003. filepos:=tokenpos;
  1004. consume(_ID);
  1005. case token of
  1006. _EQUAL:
  1007. begin
  1008. consume(_EQUAL);
  1009. p:=comp_expr(true);
  1010. do_firstpass(p);
  1011. storetokenpos:=tokenpos;
  1012. tokenpos:=filepos;
  1013. case p^.treetype of
  1014. ordconstn:
  1015. begin
  1016. if is_constcharnode(p) then
  1017. begin
  1018. getmem(sp,2);
  1019. sp[0]:=chr(p^.value);
  1020. sp[1]:=#0;
  1021. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,1)));
  1022. end
  1023. else
  1024. Message(cg_e_illegal_expression);
  1025. end;
  1026. stringconstn:
  1027. begin
  1028. getmem(sp,p^.length+1);
  1029. move(p^.value_str^,sp^,p^.length+1);
  1030. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,p^.length)));
  1031. end;
  1032. else
  1033. Message(cg_e_illegal_expression);
  1034. end;
  1035. tokenpos:=storetokenpos;
  1036. consume(_SEMICOLON);
  1037. disposetree(p);
  1038. end;
  1039. else consume(_EQUAL);
  1040. end;
  1041. until token<>_ID;
  1042. block_type:=old_block_type;
  1043. end;
  1044. procedure Not_supported_for_inline(t : ttoken);
  1045. begin
  1046. if assigned(aktprocsym) and
  1047. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1048. Begin
  1049. Message1(parser_w_not_supported_for_inline,tokenstring(t));
  1050. Message(parser_w_inlining_disabled);
  1051. {$ifdef INCLUDEOK}
  1052. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  1053. {$else}
  1054. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions-[pocall_inline];
  1055. {$endif}
  1056. End;
  1057. end;
  1058. procedure read_declarations(islibrary : boolean);
  1059. begin
  1060. repeat
  1061. case token of
  1062. _LABEL:
  1063. begin
  1064. Not_supported_for_inline(token);
  1065. label_dec;
  1066. end;
  1067. _CONST:
  1068. begin
  1069. Not_supported_for_inline(token);
  1070. const_dec;
  1071. end;
  1072. _TYPE:
  1073. begin
  1074. Not_supported_for_inline(token);
  1075. type_dec;
  1076. end;
  1077. _VAR:
  1078. var_dec;
  1079. _THREADVAR:
  1080. threadvar_dec;
  1081. _CONSTRUCTOR,_DESTRUCTOR,
  1082. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1083. begin
  1084. Not_supported_for_inline(token);
  1085. read_proc;
  1086. end;
  1087. _RESOURCESTRING:
  1088. resourcestring_dec;
  1089. _EXPORTS:
  1090. begin
  1091. Not_supported_for_inline(token);
  1092. { here we should be at lexlevel 1, no ? PM }
  1093. if (lexlevel<>main_program_level) or
  1094. (not islibrary and not DLLsource) then
  1095. begin
  1096. Message(parser_e_syntax_error);
  1097. consume_all_until(_SEMICOLON);
  1098. end
  1099. else if islibrary then
  1100. read_exports;
  1101. end
  1102. else break;
  1103. end;
  1104. until false;
  1105. end;
  1106. procedure read_interface_declarations;
  1107. begin
  1108. {Since the body is now parsed at lexlevel 1, and the declarations
  1109. must be parsed at the same lexlevel we increase the lexlevel.}
  1110. inc(lexlevel);
  1111. repeat
  1112. case token of
  1113. _CONST : const_dec;
  1114. _TYPE : type_dec;
  1115. _VAR : var_dec;
  1116. _THREADVAR : threadvar_dec;
  1117. _RESOURCESTRING:
  1118. resourcestring_dec;
  1119. _FUNCTION,
  1120. _PROCEDURE,
  1121. _OPERATOR : read_proc;
  1122. else
  1123. break;
  1124. end;
  1125. until false;
  1126. dec(lexlevel);
  1127. end;
  1128. end.
  1129. {
  1130. $Log$
  1131. Revision 1.170 1999-11-09 23:06:45 peter
  1132. * esi_offset -> selfpointer_offset to be newcg compatible
  1133. * hcogegen -> cgbase fixes for newcg
  1134. Revision 1.169 1999/11/09 12:58:29 peter
  1135. * support absolute unit.variable
  1136. Revision 1.168 1999/11/06 14:34:21 peter
  1137. * truncated log to 20 revs
  1138. Revision 1.167 1999/10/26 12:30:44 peter
  1139. * const parameter is now checked
  1140. * better and generic check if a node can be used for assigning
  1141. * export fixes
  1142. * procvar equal works now (it never had worked at least from 0.99.8)
  1143. * defcoll changed to linkedlist with pparaitem so it can easily be
  1144. walked both directions
  1145. Revision 1.166 1999/10/22 10:39:34 peter
  1146. * split type reading from pdecl to ptype unit
  1147. * parameter_dec routine is now used for procedure and procvars
  1148. Revision 1.165 1999/10/21 16:41:41 florian
  1149. * problems with readln fixed: esi wasn't restored correctly when
  1150. reading ordinal fields of objects futher the register allocation
  1151. didn't take care of the extra register when reading ordinal values
  1152. * enumerations can now be used in constant indexes of properties
  1153. Revision 1.164 1999/10/14 14:57:52 florian
  1154. - removed the hcodegen use in the new cg, use cgbase instead
  1155. Revision 1.163 1999/10/06 17:39:14 peter
  1156. * fixed stabs writting for forward types
  1157. Revision 1.162 1999/10/03 19:44:42 peter
  1158. * removed objpasunit reference, tvarrec is now searched in systemunit
  1159. where it already was located
  1160. Revision 1.161 1999/10/01 11:18:02 peter
  1161. * class/record type forward checking fixed
  1162. Revision 1.159 1999/10/01 10:05:42 peter
  1163. + procedure directive support in const declarations, fixes bug 232
  1164. Revision 1.158 1999/10/01 08:02:46 peter
  1165. * forward type declaration rewritten
  1166. Revision 1.157 1999/09/27 23:44:53 peter
  1167. * procinfo is now a pointer
  1168. * support for result setting in sub procedure
  1169. Revision 1.156 1999/09/26 21:30:19 peter
  1170. + constant pointer support which can happend with typecasting like
  1171. const p=pointer(1)
  1172. * better procvar parsing in typed consts
  1173. Revision 1.155 1999/09/20 16:38:59 peter
  1174. * cs_create_smart instead of cs_smartlink
  1175. * -CX is create smartlink
  1176. * -CD is create dynamic, but does nothing atm.
  1177. Revision 1.154 1999/09/15 22:09:24 florian
  1178. + rtti is now automatically generated for published classes, i.e.
  1179. they are handled like an implicit property
  1180. Revision 1.153 1999/09/14 11:09:08 florian
  1181. * per default a property is stored, fixed
  1182. Revision 1.152 1999/09/12 14:50:50 florian
  1183. + implemented creation of methodname/address tables
  1184. Revision 1.151 1999/09/12 08:48:09 florian
  1185. * bugs 593 and 607 fixed
  1186. * some other potential bugs with array constructors fixed
  1187. * for classes compiled in $M+ and it's childs, the default access method
  1188. is now published
  1189. * fixed copyright message (it is now 1993-99)
  1190. Revision 1.150 1999/09/10 20:57:33 florian
  1191. * some more fixes for stored properties
  1192. Revision 1.149 1999/09/10 18:48:07 florian
  1193. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  1194. * most things for stored properties fixed
  1195. Revision 1.148 1999/09/08 21:06:06 michael
  1196. * Stored specifier for properties is now correctly parsed
  1197. Revision 1.147 1999/09/02 09:23:51 peter
  1198. * fixed double dispose of propsymlist
  1199. }