pdecvar.pas 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Parses variable declarations. Used for var statement and record
  4. definitions
  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 pdecvar;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. symtable,symsym,symdef,symtype;
  24. type
  25. tvar_dec_option=(vd_record,vd_object,vd_threadvar,vd_class,vd_final,vd_canreorder,vd_check_generic);
  26. tvar_dec_options=set of tvar_dec_option;
  27. function read_property_dec(is_classproperty:boolean;astruct:tabstractrecorddef):tpropertysym;
  28. procedure read_var_decls(options:Tvar_dec_options;out had_generic:boolean);
  29. procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc: ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
  30. procedure read_public_and_external(vs: tabstractvarsym);
  31. procedure try_consume_sectiondirective(var asection: ansistring);
  32. function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
  33. implementation
  34. uses
  35. SysUtils,
  36. { common }
  37. cutils,
  38. { global }
  39. globtype,globals,tokens,verbose,constexp,
  40. systems,
  41. { symtable }
  42. symconst,symbase,defutil,defcmp,symutil,symcreat,
  43. {$if defined(i386) or defined(i8086) or defined(wasm)}
  44. symcpu,
  45. {$endif}
  46. fmodule,htypechk,procdefutil,
  47. { pass 1 }
  48. node,pass_1,aasmbase,aasmdata,
  49. ncon,nset,ncnv,nld,nutils,
  50. { codegen }
  51. ngenutil,
  52. { parser }
  53. scanner,
  54. pbase,pexpr,ptype,ptconst,pdecsub,pparautl;
  55. function read_property_dec(is_classproperty:boolean;astruct:tabstractrecorddef):tpropertysym;
  56. { convert a node tree to symlist and return the last
  57. symbol }
  58. function parse_symlist(pl:tpropaccesslist;out def:tdef):boolean;
  59. var
  60. idx : longint;
  61. sym : tsym;
  62. srsymtable : TSymtable;
  63. st : TSymtable;
  64. p : tnode;
  65. begin
  66. result:=true;
  67. def:=nil;
  68. if token=_ID then
  69. begin
  70. if assigned(astruct) then
  71. sym:=search_struct_member(astruct,pattern)
  72. else
  73. searchsym(pattern,sym,srsymtable);
  74. if assigned(sym) then
  75. begin
  76. if assigned(astruct) and
  77. not is_visible_for_object(sym,astruct) then
  78. Message(parser_e_cant_access_private_member);
  79. case sym.typ of
  80. fieldvarsym :
  81. begin
  82. addsymref(sym);
  83. pl.addsym(sl_load,sym);
  84. def:=tfieldvarsym(sym).vardef;
  85. end;
  86. procsym :
  87. begin
  88. addsymref(sym);
  89. pl.addsym(sl_call,sym);
  90. end;
  91. else
  92. begin
  93. Message1(parser_e_illegal_field_or_method,orgpattern);
  94. def:=generrordef;
  95. result:=false;
  96. end;
  97. end;
  98. end
  99. else
  100. begin
  101. Message1(parser_e_illegal_field_or_method,orgpattern);
  102. def:=generrordef;
  103. result:=false;
  104. end;
  105. consume(_ID);
  106. repeat
  107. case token of
  108. _ID,
  109. _SEMICOLON :
  110. begin
  111. break;
  112. end;
  113. _POINT :
  114. begin
  115. if not is_object(def) and not is_record(def) then
  116. message(sym_e_type_must_be_rec_or_object);
  117. consume(_POINT);
  118. if assigned(def) then
  119. begin
  120. st:=def.GetSymtable(gs_record);
  121. if assigned(st) then
  122. begin
  123. sym:=tsym(st.Find(pattern));
  124. if not(assigned(sym)) and is_object(def) then
  125. sym:=search_struct_member(tobjectdef(def),pattern);
  126. if assigned(sym) then
  127. begin
  128. pl.addsym(sl_subscript,sym);
  129. case sym.typ of
  130. fieldvarsym :
  131. def:=tfieldvarsym(sym).vardef;
  132. else
  133. begin
  134. Message1(sym_e_illegal_field,orgpattern);
  135. result:=false;
  136. end;
  137. end;
  138. end
  139. else
  140. begin
  141. Message1(sym_e_illegal_field,orgpattern);
  142. result:=false;
  143. end;
  144. end
  145. else
  146. begin
  147. Message(parser_e_invalid_qualifier);
  148. result:=false;
  149. end;
  150. end
  151. else
  152. begin
  153. Message(parser_e_invalid_qualifier);
  154. result:=false;
  155. end;
  156. consume(_ID);
  157. end;
  158. _LECKKLAMMER :
  159. begin
  160. consume(_LECKKLAMMER);
  161. repeat
  162. if assigned(def) and (def.typ=arraydef) then
  163. begin
  164. idx:=0;
  165. p:=comp_expr([ef_accept_equal]);
  166. if (not codegenerror) then
  167. begin
  168. if (p.nodetype=ordconstn) then
  169. begin
  170. { type/range checking }
  171. inserttypeconv(p,tarraydef(def).rangedef);
  172. if (Tordconstnode(p).value<int64(low(longint))) or
  173. (Tordconstnode(p).value>int64(high(longint))) then
  174. message(parser_e_array_range_out_of_bounds)
  175. else
  176. idx:=Tordconstnode(p).value.svalue
  177. end
  178. else
  179. Message(type_e_ordinal_expr_expected)
  180. end;
  181. pl.addconst(sl_vec,idx,p.resultdef);
  182. p.free;
  183. p := nil;
  184. def:=tarraydef(def).elementdef;
  185. end
  186. else
  187. begin
  188. Message(parser_e_invalid_qualifier);
  189. result:=false;
  190. end;
  191. until not try_to_consume(_COMMA);
  192. consume(_RECKKLAMMER);
  193. end;
  194. else
  195. begin
  196. Message(parser_e_ill_property_access_sym);
  197. result:=false;
  198. break;
  199. end;
  200. end;
  201. until false;
  202. end
  203. else
  204. begin
  205. Message(parser_e_ill_property_access_sym);
  206. result:=false;
  207. end;
  208. end;
  209. function has_implicit_default(p : tpropertysym) : boolean;
  210. begin
  211. has_implicit_default:=
  212. (is_string(p.propdef) or
  213. is_real(p.propdef) or
  214. is_pointer(p.propdef));
  215. end;
  216. function allow_default_property(p : tpropertysym) : boolean;
  217. begin
  218. allow_default_property:=
  219. (is_ordinal(p.propdef) or
  220. {$ifndef cpu64bitaddr}
  221. is_64bitint(p.propdef) or
  222. {$endif cpu64bitaddr}
  223. is_class(p.propdef) or
  224. is_single(p.propdef) or
  225. (p.propdef.typ in [classrefdef,pointerdef]) or
  226. is_smallset(p.propdef)
  227. ) and not
  228. (
  229. (p.propdef.typ=arraydef) and
  230. (ppo_indexed in p.propoptions)
  231. ) and not
  232. (ppo_hasparameters in p.propoptions);
  233. end;
  234. procedure create_accessor_procsym(p: tpropertysym; pd: tprocdef; const prefix: string;
  235. accesstype: tpropaccesslisttypes);
  236. var
  237. sym: tprocsym;
  238. begin
  239. if not assigned(astruct) then
  240. handle_calling_convention(pd,hcc_default_actions_intf)
  241. else
  242. handle_calling_convention(pd,hcc_default_actions_intf_struct);
  243. sym:=cprocsym.create(prefix+lower(p.realname));
  244. symtablestack.top.insertsym(sym);
  245. pd.procsym:=sym;
  246. include(pd.procoptions,po_dispid);
  247. include(pd.procoptions,po_global);
  248. pd.visibility:=vis_private;
  249. proc_add_definition(pd);
  250. p.propaccesslist[accesstype].addsym(sl_call,sym);
  251. p.propaccesslist[accesstype].procdef:=pd;
  252. end;
  253. procedure parse_dispinterface(p : tpropertysym; readpd,writepd: tprocdef;
  254. var paranr: word);
  255. var
  256. hasread, haswrite: boolean;
  257. pt: tnode;
  258. hdispid: longint;
  259. hparavs: tparavarsym;
  260. begin
  261. p.propaccesslist[palt_read].clear;
  262. p.propaccesslist[palt_write].clear;
  263. hasread:=true;
  264. haswrite:=true;
  265. hdispid:=0;
  266. if try_to_consume(_READONLY) then
  267. haswrite:=false
  268. else if try_to_consume(_WRITEONLY) then
  269. hasread:=false;
  270. if try_to_consume(_DISPID) then
  271. begin
  272. pt:=comp_expr([ef_accept_equal]);
  273. if is_constintnode(pt) then
  274. if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
  275. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(longint)),tostr(high(longint)))
  276. else
  277. hdispid:=Tordconstnode(pt).value.svalue
  278. else
  279. Message(parser_e_dispid_must_be_ord_const);
  280. pt.free;
  281. pt := nil;
  282. end
  283. else
  284. hdispid:=tobjectdef(astruct).get_next_dispid;
  285. { COM property is simply a pair of methods, tagged with 'propertyget'
  286. and 'propertyset' flags (or a single method if access is restricted).
  287. Creating these implicit accessor methods also allows the rest of compiler
  288. to handle dispinterface properties the same way as regular ones. }
  289. if hasread then
  290. begin
  291. readpd.returndef:=p.propdef;
  292. readpd.dispid:=hdispid;
  293. readpd.proctypeoption:=potype_propgetter;
  294. create_accessor_procsym(p,readpd,'get$',palt_read);
  295. end;
  296. if haswrite then
  297. begin
  298. { add an extra parameter, a placeholder of the value to set }
  299. inc(paranr);
  300. hparavs:=cparavarsym.create('$value',10*paranr,vs_value,p.propdef,[]);
  301. writepd.parast.insertsym(hparavs);
  302. writepd.proctypeoption:=potype_propsetter;
  303. writepd.dispid:=hdispid;
  304. create_accessor_procsym(p,writepd,'put$',palt_write);
  305. end;
  306. end;
  307. var
  308. sym : tsym;
  309. srsymtable: tsymtable;
  310. p : tpropertysym;
  311. overridden : tsym;
  312. varspez : tvarspez;
  313. hdef : tdef;
  314. arraytype : tdef;
  315. def : tdef;
  316. pt : tnode;
  317. sc : TFPObjectList;
  318. paranr : word;
  319. i : longint;
  320. ImplIntf : TImplementedInterface;
  321. found,
  322. gotreadorwrite: boolean;
  323. hreadparavs,
  324. hparavs : tparavarsym;
  325. storedprocdef: tprocvardef;
  326. readprocdef,
  327. writeprocdef : tprocdef;
  328. begin
  329. result:=nil;
  330. { Generate temp procdefs to search for matching read/write
  331. procedures. the readprocdef will store all definitions }
  332. paranr:=0;
  333. readprocdef:=cprocdef.create(normal_function_level,false);
  334. writeprocdef:=cprocdef.create(normal_function_level,false);
  335. readprocdef.struct:=astruct;
  336. writeprocdef.struct:=astruct;
  337. if assigned(astruct) and is_classproperty then
  338. begin
  339. readprocdef.procoptions:=[po_staticmethod,po_classmethod];
  340. writeprocdef.procoptions:=[po_staticmethod,po_classmethod];
  341. end;
  342. if token<>_ID then
  343. begin
  344. consume(_ID);
  345. consume(_SEMICOLON);
  346. exit;
  347. end;
  348. { Generate propertysym and insert in symtablestack }
  349. p:=cpropertysym.create(orgpattern);
  350. p.visibility:=symtablestack.top.currentvisibility;
  351. p.default:=longint($80000000);
  352. if is_classproperty then
  353. include(p.symoptions, sp_static);
  354. symtablestack.top.insertsym(p);
  355. consume(_ID);
  356. { property parameters ? }
  357. if try_to_consume(_LECKKLAMMER) then
  358. begin
  359. if (p.visibility=vis_published) then
  360. Message(parser_e_cant_publish_that_property);
  361. { create a list of the parameters }
  362. p.parast:=tparasymtable.create(nil,0);
  363. symtablestack.push(p.parast);
  364. sc:=TFPObjectList.create(false);
  365. repeat
  366. if try_to_consume(_VAR) then
  367. varspez:=vs_var
  368. else if try_to_consume(_CONST) then
  369. varspez:=vs_const
  370. else if try_to_consume(_CONSTREF) then
  371. varspez:=vs_constref
  372. else if (m_out in current_settings.modeswitches) and try_to_consume(_OUT) then
  373. varspez:=vs_out
  374. else
  375. varspez:=vs_value;
  376. sc.clear;
  377. repeat
  378. inc(paranr);
  379. hreadparavs:=cparavarsym.create(orgpattern,10*paranr,varspez,generrordef,[]);
  380. p.parast.insertsym(hreadparavs);
  381. sc.add(hreadparavs);
  382. consume(_ID);
  383. until not try_to_consume(_COMMA);
  384. if try_to_consume(_COLON) then
  385. begin
  386. if try_to_consume(_ARRAY) then
  387. begin
  388. consume(_OF);
  389. { define range and type of range }
  390. hdef:=carraydef.create_openarray;
  391. hdef.owner:=astruct.symtable;
  392. { define field type }
  393. single_type(arraytype,[]);
  394. tarraydef(hdef).elementdef:=arraytype;
  395. end
  396. else
  397. single_type(hdef,[]);
  398. end
  399. else
  400. hdef:=cformaltype;
  401. for i:=0 to sc.count-1 do
  402. tparavarsym(sc[i]).vardef:=hdef;
  403. until not try_to_consume(_SEMICOLON);
  404. sc.free;
  405. sc := nil;
  406. symtablestack.pop(p.parast);
  407. consume(_RECKKLAMMER);
  408. { the parser need to know if a property has parameters, the
  409. index parameter doesn't count (PFV) }
  410. if paranr>0 then
  411. begin
  412. p.add_accessor_parameters(readprocdef,writeprocdef);
  413. include(p.propoptions,ppo_hasparameters);
  414. end;
  415. end;
  416. { overridden property ? }
  417. { force property interface
  418. there is a property parameter
  419. a global property }
  420. if (token=_COLON) or (paranr>0) or (astruct=nil) then
  421. begin
  422. consume(_COLON);
  423. single_type(p.propdef,[stoAllowSpecialization]);
  424. if is_dispinterface(astruct) and not is_automatable(p.propdef) then
  425. Message1(type_e_not_automatable,p.propdef.typename);
  426. if (idtoken=_INDEX) then
  427. begin
  428. consume(_INDEX);
  429. pt:=comp_expr([ef_accept_equal]);
  430. { Only allow enum and integer indexes. Convert all integer
  431. values to objpas.integer (s32int on 32- and 64-bit targets,
  432. s16int on 16- and 8-bit) to be compatible with delphi,
  433. because the procedure matching requires equal parameters }
  434. if is_constnode(pt) and
  435. is_ordinal(pt.resultdef)
  436. and (not is_64bitint(pt.resultdef))
  437. {$if defined(cpu8bitalu) or defined(cpu16bitalu)}
  438. and (not is_32bitint(pt.resultdef))
  439. {$endif}
  440. then
  441. begin
  442. if is_integer(pt.resultdef) then
  443. {$if defined(cpu8bitalu) or defined(cpu16bitalu)}
  444. inserttypeconv_internal(pt,s16inttype);
  445. {$else}
  446. inserttypeconv_internal(pt,s32inttype);
  447. {$endif}
  448. p.index:=tordconstnode(pt).value.svalue;
  449. end
  450. else
  451. begin
  452. Message(parser_e_invalid_property_index_value);
  453. p.index:=0;
  454. end;
  455. p.indexdef:=pt.resultdef;
  456. include(p.propoptions,ppo_indexed);
  457. { concat a longint to the para templates }
  458. p.add_index_parameter(paranr,readprocdef,writeprocdef);
  459. pt.free;
  460. pt := nil;
  461. end;
  462. end
  463. else
  464. begin
  465. { do an property override }
  466. if (astruct.typ=objectdef) and assigned(tobjectdef(astruct).childof) then
  467. overridden:=search_struct_member(tobjectdef(astruct).childof,p.name)
  468. else
  469. overridden:=nil;
  470. if assigned(overridden) and
  471. (overridden.typ=propertysym) and
  472. not(is_dispinterface(astruct)) then
  473. begin
  474. tpropertysym(overridden).makeduplicate(p,readprocdef,writeprocdef,paranr);
  475. p.register_override(tpropertysym(overridden));
  476. end
  477. else
  478. begin
  479. p.propdef:=generrordef;
  480. message(parser_e_no_property_found_to_override);
  481. end;
  482. end;
  483. if ((p.visibility=vis_published) or is_dispinterface(astruct))
  484. and not (astruct.is_generic and (p.propdef.typ=undefineddef)) then
  485. begin
  486. { ignore is_publishable for interfaces (related to $M+ directive).
  487. $M has effect on visibility of default section for classes.
  488. Interface has always only public section (fix for problem in tb0631.pp) }
  489. if (sp_static in p.symoptions) or ((p.propdef.is_publishable=pp_error) and not is_interface(astruct)) then
  490. begin
  491. Message(parser_e_cant_publish_that_property);
  492. p.visibility:=vis_public;
  493. end
  494. else
  495. if (p.propdef.is_publishable=pp_ignore) and not is_interface(astruct) then
  496. begin
  497. Message(parser_w_ignoring_published_property);
  498. p.visibility:=vis_public;
  499. end;
  500. end;
  501. if not(is_dispinterface(astruct)) then
  502. begin
  503. gotreadorwrite:=false;
  504. { parse accessors }
  505. if try_to_consume(_READ) then
  506. begin
  507. gotreadorwrite:=true;
  508. p.propaccesslist[palt_read].clear;
  509. if parse_symlist(p.propaccesslist[palt_read],def) then
  510. begin
  511. sym:=p.propaccesslist[palt_read].firstsym^.sym;
  512. { getter is a function returning the type of the property }
  513. if sym.typ=procsym then
  514. begin
  515. readprocdef.returndef:=p.propdef;
  516. { Insert hidden parameters }
  517. if assigned(astruct) then
  518. handle_calling_convention(readprocdef,hcc_default_actions_intf_struct)
  519. else
  520. handle_calling_convention(readprocdef,hcc_default_actions_intf);
  521. end;
  522. p.add_getter_or_setter_for_sym(palt_read,sym,def,readprocdef);
  523. end;
  524. end
  525. else
  526. p.inherit_accessor(palt_read);
  527. if try_to_consume(_WRITE) then
  528. begin
  529. gotreadorwrite:=true;
  530. p.propaccesslist[palt_write].clear;
  531. if parse_symlist(p.propaccesslist[palt_write],def) then
  532. begin
  533. sym:=p.propaccesslist[palt_write].firstsym^.sym;
  534. if sym.typ=procsym then
  535. begin
  536. { settter is a procedure with an extra value parameter
  537. of the of the property }
  538. writeprocdef.returndef:=voidtype;
  539. inc(paranr);
  540. hparavs:=cparavarsym.create('$value',10*paranr,vs_value,p.propdef,[]);
  541. writeprocdef.parast.insertsym(hparavs);
  542. { Insert hidden parameters }
  543. if not assigned(astruct) then
  544. handle_calling_convention(writeprocdef,hcc_default_actions_intf)
  545. else
  546. handle_calling_convention(writeprocdef,hcc_default_actions_intf_struct);
  547. end;
  548. p.add_getter_or_setter_for_sym(palt_write,sym,def,writeprocdef);
  549. end;
  550. end
  551. else
  552. p.inherit_accessor(palt_write);
  553. { a new property (needs to declare a getter or setter, except in
  554. an interface }
  555. if not(ppo_overrides in p.propoptions) and
  556. not is_interface(astruct) and
  557. not gotreadorwrite then
  558. Consume(_READ);
  559. end
  560. else
  561. parse_dispinterface(p,readprocdef,writeprocdef,paranr);
  562. { stored is not allowed for dispinterfaces, records or class properties }
  563. if assigned(astruct) and not(is_dispinterface(astruct) or is_record(astruct)) and not is_classproperty then
  564. begin
  565. { ppo_stored is default on for not overridden properties }
  566. if not assigned(p.overriddenpropsym) then
  567. include(p.propoptions,ppo_stored);
  568. if try_to_consume(_STORED) then
  569. begin
  570. include(p.propoptions,ppo_stored);
  571. p.propaccesslist[palt_stored].clear;
  572. if token=_ID then
  573. begin
  574. { in the case that idtoken=_DEFAULT }
  575. { we have to do nothing except }
  576. { setting ppo_stored, it's the same }
  577. { as stored true }
  578. if idtoken<>_DEFAULT then
  579. begin
  580. { parse_symlist cannot deal with constsyms, and
  581. we also don't want to put constsyms in symlists
  582. since they have to be evaluated immediately rather
  583. than each time the property is accessed
  584. The proper fix would be to always create a parse tree
  585. and then convert that one, if appropriate, to a symlist.
  586. Currently, we e.g. don't support any constant expressions
  587. yet either here, while Delphi does.
  588. }
  589. { make sure we don't let constants mask class fields/
  590. methods
  591. }
  592. sym:=nil;
  593. if (not assigned(astruct) or
  594. (search_struct_member(astruct,pattern)=nil)) and
  595. searchsym(pattern,sym,srsymtable) and
  596. (sym.typ = constsym) then
  597. begin
  598. addsymref(sym);
  599. if not is_boolean(tconstsym(sym).constdef) then
  600. Message(parser_e_stored_property_must_be_boolean)
  601. else if (tconstsym(sym).value.valueord=0) then
  602. { same as for _FALSE }
  603. exclude(p.propoptions,ppo_stored)
  604. else
  605. begin
  606. { same as for _TRUE }
  607. { do nothing - ppo_stored is already set to p.propoptions in "include(p.propoptions,ppo_stored);" above }
  608. { especially do not reset the default value - the stored specifier is independent on the default value! }
  609. end;
  610. consume(_ID);
  611. end
  612. else if parse_symlist(p.propaccesslist[palt_stored],def) then
  613. begin
  614. sym:=p.propaccesslist[palt_stored].firstsym^.sym;
  615. case sym.typ of
  616. procsym :
  617. begin
  618. { Create a temporary procvardef to handle parameters }
  619. storedprocdef:=cprocvardef.create(normal_function_level,true);
  620. include(storedprocdef.procoptions,po_methodpointer);
  621. { Return type must be boolean }
  622. storedprocdef.returndef:=pasbool1type;
  623. { Add index parameter if needed }
  624. if ppo_indexed in p.propoptions then
  625. begin
  626. hparavs:=cparavarsym.create('$index',10,vs_value,p.indexdef,[]);
  627. storedprocdef.parast.insertsym(hparavs);
  628. end;
  629. { Insert hidden parameters }
  630. if not assigned(astruct) then
  631. handle_calling_convention(storedprocdef,hcc_default_actions_intf)
  632. else
  633. handle_calling_convention(storedprocdef,hcc_default_actions_intf_struct);
  634. p.propaccesslist[palt_stored].procdef:=Tprocsym(sym).Find_procdef_bypara(storedprocdef.paras,storedprocdef.returndef,[cpo_allowdefaults,cpo_ignorehidden]);
  635. if not assigned(p.propaccesslist[palt_stored].procdef) then
  636. message(parser_e_ill_property_storage_sym);
  637. { Not needed anymore }
  638. storedprocdef.owner.deletedef(storedprocdef);
  639. end;
  640. fieldvarsym :
  641. begin
  642. if not assigned(def) then
  643. internalerror(200310073);
  644. if (ppo_hasparameters in p.propoptions) or
  645. not(is_boolean(def)) then
  646. Message(parser_e_stored_property_must_be_boolean);
  647. end;
  648. else
  649. Message(parser_e_ill_property_access_sym);
  650. end;
  651. end;
  652. end;
  653. end;
  654. end;
  655. end;
  656. if has_implicit_default(p) and not assigned(p.overriddenpropsym) then
  657. begin
  658. p.default:=0;
  659. end;
  660. if not is_record(astruct) and try_to_consume(_DEFAULT) then
  661. begin
  662. if not allow_default_property(p) then
  663. begin
  664. Message(parser_e_property_cant_have_a_default_value);
  665. { Error recovery }
  666. pt:=comp_expr([ef_accept_equal]);
  667. pt.free;
  668. pt := nil;
  669. end
  670. else
  671. begin
  672. { Get the result of the default, the firstpass is
  673. needed to support values like -1 }
  674. pt:=comp_expr([ef_accept_equal]);
  675. if (p.propdef.typ=setdef) and
  676. (pt.nodetype=arrayconstructorn) then
  677. begin
  678. arrayconstructor_to_set(pt);
  679. do_typecheckpass(pt);
  680. end;
  681. inserttypeconv(pt,p.propdef);
  682. if not(is_constnode(pt)) then
  683. Message(parser_e_property_default_value_must_const);
  684. { Set default value }
  685. case pt.nodetype of
  686. setconstn :
  687. p.default:=plongint(tsetconstnode(pt).value_set)^;
  688. ordconstn :
  689. if (Tordconstnode(pt).value<int64(low(longint))) or
  690. (Tordconstnode(pt).value>int64(high(cardinal))) then
  691. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(longint)),tostr(high(cardinal)))
  692. else
  693. p.default:=longint(tordconstnode(pt).value.svalue);
  694. niln :
  695. p.default:=0;
  696. realconstn:
  697. p.default:=longint(single(trealconstnode(pt).value_real));
  698. else if not codegenerror then
  699. internalerror(2019050525);
  700. end;
  701. pt.free;
  702. pt := nil;
  703. end;
  704. end
  705. else if not is_record(astruct) and try_to_consume(_NODEFAULT) then
  706. begin
  707. p.default:=longint($80000000);
  708. end;
  709. (*
  710. else {if allow_default_property(p) then
  711. begin
  712. p.default:=longint($80000000);
  713. end;
  714. *)
  715. { Parse possible "implements" keyword }
  716. if not is_record(astruct) and try_to_consume(_IMPLEMENTS) then
  717. repeat
  718. single_type(def,[]);
  719. if not(is_interface(def)) then
  720. message(parser_e_class_implements_must_be_interface);
  721. if is_interface(p.propdef) then
  722. begin
  723. { an interface type may delegate itself or one of its ancestors }
  724. if not def_is_related(p.propdef,def) then
  725. begin
  726. message2(parser_e_implements_must_have_correct_type,def.typename,p.propdef.typename);
  727. exit;
  728. end;
  729. end
  730. else if is_class(p.propdef) then
  731. begin
  732. ImplIntf:=find_implemented_interface(tobjectdef(p.propdef),tobjectdef(def));
  733. if assigned(ImplIntf) then
  734. begin
  735. if compare_defs(ImplIntf.IntfDef,def,nothingn)<te_equal then
  736. begin
  737. message2(parser_e_implements_must_have_correct_type,ImplIntf.IntfDef.typename,def.typename);
  738. exit;
  739. end;
  740. end
  741. else
  742. begin
  743. message2(parser_e_class_doesnt_implement_interface,p.propdef.typename,def.typename);
  744. exit;
  745. end;
  746. end
  747. else
  748. begin
  749. message(parser_e_implements_must_be_class_or_interface);
  750. exit;
  751. end;
  752. if not assigned(p.propaccesslist[palt_read].firstsym) then
  753. begin
  754. message(parser_e_implements_must_read_specifier);
  755. exit;
  756. end;
  757. if assigned(p.propaccesslist[palt_read].procdef) and
  758. (tprocdef(p.propaccesslist[palt_read].procdef).proccalloption<>pocall_default) then
  759. message(parser_e_implements_getter_not_default_cc);
  760. if assigned(p.propaccesslist[palt_write].firstsym) then
  761. begin
  762. message(parser_e_implements_must_not_have_write_specifier);
  763. exit;
  764. end;
  765. if assigned(p.propaccesslist[palt_stored].firstsym) then
  766. begin
  767. message(parser_e_implements_must_not_have_stored_specifier);
  768. exit;
  769. end;
  770. found:=false;
  771. ImplIntf:=nil;
  772. for i:=0 to tobjectdef(astruct).ImplementedInterfaces.Count-1 do
  773. begin
  774. ImplIntf:=TImplementedInterface(tobjectdef(astruct).ImplementedInterfaces[i]);
  775. if compare_defs(def,ImplIntf.IntfDef,nothingn)>=te_equal then
  776. begin
  777. found:=true;
  778. break;
  779. end;
  780. end;
  781. if found then
  782. begin
  783. { An interface may not be delegated by more than one property,
  784. it also may not have method mappings. }
  785. if Assigned(ImplIntf.ImplementsGetter) then
  786. message1(parser_e_duplicate_implements_clause,ImplIntf.IntfDef.typename);
  787. if Assigned(ImplIntf.NameMappings) then
  788. message2(parser_e_mapping_no_implements,ImplIntf.IntfDef.typename,astruct.objrealname^);
  789. ImplIntf.ImplementsGetter:=p;
  790. ImplIntf.VtblImplIntf:=ImplIntf;
  791. case p.propaccesslist[palt_read].firstsym^.sym.typ of
  792. procsym :
  793. begin
  794. if (po_virtualmethod in tprocdef(p.propaccesslist[palt_read].procdef).procoptions) and
  795. not is_objectpascal_helper(tprocdef(p.propaccesslist[palt_read].procdef).struct) then
  796. ImplIntf.IType:=etVirtualMethodResult
  797. else
  798. ImplIntf.IType:=etStaticMethodResult;
  799. end;
  800. fieldvarsym :
  801. begin
  802. ImplIntf.IType:=etFieldValue;
  803. { this must be done in a more robust way. Can't read the
  804. fieldvarsym's fieldoffset yet, because it may not yet
  805. be set }
  806. ImplIntf.ImplementsField:=p.propaccesslist[palt_read].firstsym^.sym;
  807. end
  808. else
  809. internalerror(200802161);
  810. end;
  811. if not is_interface(p.propdef) then
  812. case ImplIntf.IType of
  813. etVirtualMethodResult: ImplIntf.IType := etVirtualMethodClass;
  814. etStaticMethodResult: ImplIntf.IType := etStaticMethodClass;
  815. etFieldValue: ImplIntf.IType := etFieldValueClass;
  816. else
  817. internalerror(200912101);
  818. end;
  819. end
  820. else
  821. message1(parser_e_implements_uses_non_implemented_interface,def.typename);
  822. until not try_to_consume(_COMMA);
  823. { register propgetter and propsetter procdefs }
  824. if assigned(current_module) and current_module.in_interface then
  825. begin
  826. if readprocdef.proctypeoption=potype_propgetter then
  827. readprocdef.register_def
  828. else
  829. readprocdef.free; // no nil needed
  830. if writeprocdef.proctypeoption=potype_propsetter then
  831. writeprocdef.register_def
  832. else
  833. writeprocdef.free; // no nil needed
  834. end
  835. else
  836. begin
  837. if readprocdef.proctypeoption=potype_propgetter then
  838. readprocdef.maybe_put_in_symtable_stack
  839. else
  840. readprocdef.free; // no nil needed
  841. if writeprocdef.proctypeoption=potype_propsetter then
  842. writeprocdef.maybe_put_in_symtable_stack
  843. else
  844. writeprocdef.free; // no nil needed
  845. end;
  846. result:=p;
  847. end;
  848. function maybe_parse_proc_directives(def:tdef):boolean;
  849. begin
  850. result:=false;
  851. { Process procvar directives before = and ; }
  852. if (
  853. (def.typ=procvardef) or
  854. is_funcref(def)
  855. ) and
  856. (def.typesym=nil) and
  857. check_proc_directive(true) then
  858. begin
  859. parse_proctype_directives(def);
  860. result:=true;
  861. end;
  862. end;
  863. const
  864. variantrecordlevel : longint = 0;
  865. procedure read_public_and_external_sc(sc:TFPObjectList);
  866. var
  867. vs: tabstractvarsym;
  868. begin
  869. { only allowed for one var }
  870. vs:=tabstractvarsym(sc[0]);
  871. if sc.count>1 then
  872. Message1(parser_e_directive_only_one_var,arraytokeninfo[idtoken].str);
  873. read_public_and_external(vs);
  874. end;
  875. procedure read_public_and_external(vs: tabstractvarsym);
  876. var
  877. is_dll,
  878. is_far,
  879. is_cdecl,
  880. is_external_var,
  881. is_weak_external,
  882. is_public_var : boolean;
  883. dll_name,section_name,
  884. C_name,mangledname : string;
  885. begin
  886. { only allowed for one var }
  887. { only allow external and public on global symbols }
  888. if vs.typ<>staticvarsym then
  889. begin
  890. Message(parser_e_no_local_var_external);
  891. exit;
  892. end;
  893. { defaults }
  894. is_dll:=false;
  895. is_far:=false;
  896. is_cdecl:=false;
  897. is_external_var:=false;
  898. is_public_var:=false;
  899. section_name := '';
  900. dll_name := '';
  901. C_name:=vs.realname;
  902. { macpas specific handling due to some switches}
  903. if (m_mac in current_settings.modeswitches) then
  904. begin
  905. if (cs_external_var in current_settings.localswitches) then
  906. begin {The effect of this is the same as if cvar; external; has been given as directives.}
  907. is_cdecl:=true;
  908. is_external_var:=true;
  909. end
  910. else if (cs_externally_visible in current_settings.localswitches) then
  911. begin {The effect of this is the same as if cvar has been given as directives and it's made public.}
  912. is_cdecl:=true;
  913. is_public_var:=true;
  914. end;
  915. end;
  916. { cdecl }
  917. if try_to_consume(_CVAR) then
  918. begin
  919. consume(_SEMICOLON);
  920. is_cdecl:=true;
  921. end;
  922. { external }
  923. is_weak_external:=try_to_consume(_WEAKEXTERNAL);
  924. if is_weak_external or
  925. try_to_consume(_EXTERNAL) then
  926. begin
  927. is_external_var:=true;
  928. { near/far? }
  929. if target_info.system in systems_allow_external_far_var then
  930. begin
  931. if try_to_consume(_FAR) then
  932. is_far:=true
  933. else if try_to_consume(_NEAR) then
  934. is_far:=false;
  935. end;
  936. if (idtoken<>_NAME) and (token<>_SEMICOLON) then
  937. begin
  938. is_dll:=true;
  939. dll_name:=get_stringconst;
  940. if ExtractFileExt(dll_name)='' then
  941. dll_name:=ChangeFileExt(dll_name,target_info.sharedlibext);
  942. end;
  943. if not(is_cdecl) and try_to_consume(_NAME) then
  944. C_name:=get_stringconst;
  945. consume(_SEMICOLON);
  946. end;
  947. { export or public }
  948. if idtoken in [_EXPORT,_PUBLIC] then
  949. begin
  950. consume(_ID);
  951. if is_external_var then
  952. Message(parser_e_not_external_and_export)
  953. else
  954. is_public_var:=true;
  955. if try_to_consume(_NAME) then
  956. C_name:=get_stringconst;
  957. if (target_info.system in systems_allow_section_no_semicolon) and
  958. (vs.typ=staticvarsym) and
  959. try_to_consume (_SECTION) then
  960. section_name:=get_stringconst;
  961. consume(_SEMICOLON);
  962. end;
  963. { Windows uses an indirect reference using import tables }
  964. if is_dll and
  965. (target_info.system in systems_all_windows) then
  966. include(vs.varoptions,vo_is_dll_var);
  967. { This can only happen if vs.typ=staticvarsym }
  968. if section_name<>'' then
  969. begin
  970. tstaticvarsym(vs).section:=section_name;
  971. include(vs.varoptions,vo_has_section);
  972. end;
  973. { Add C _ prefix }
  974. if is_cdecl or
  975. (
  976. is_dll and
  977. (target_info.system in systems_darwin)
  978. ) then
  979. C_Name := target_info.Cprefix+C_Name;
  980. if is_public_var then
  981. begin
  982. include(vs.varoptions,vo_is_public);
  983. vs.varregable := vr_none;
  984. { mark as referenced }
  985. inc(vs.refs);
  986. end;
  987. mangledname:=C_name;
  988. { now we can insert it in the import lib if its a dll, or
  989. add it to the externals }
  990. if is_external_var then
  991. begin
  992. if vo_is_typed_const in vs.varoptions then
  993. Message(parser_e_initialized_not_for_external);
  994. include(vs.varoptions,vo_is_external);
  995. if is_far then
  996. include(vs.varoptions,vo_is_far);
  997. if (is_weak_external) then
  998. begin
  999. if not(target_info.system in systems_weak_linking) then
  1000. message(parser_e_weak_external_not_supported);
  1001. include(vs.varoptions,vo_is_weak_external);
  1002. end;
  1003. vs.varregable := vr_none;
  1004. if is_dll then
  1005. begin
  1006. if target_info.system in (systems_all_windows + systems_nativent +
  1007. [system_i386_emx, system_i386_os2]) then
  1008. mangledname:=make_dllmangledname(dll_name,C_name,0,pocall_none);
  1009. current_module.AddExternalImport(dll_name,C_Name,mangledname,0,true,false);
  1010. end
  1011. else
  1012. if tf_has_dllscanner in target_info.flags then
  1013. current_module.dllscannerinputlist.Add(vs.mangledname,vs);
  1014. end;
  1015. { Set the assembler name }
  1016. tstaticvarsym(vs).set_mangledbasename(mangledname);
  1017. tstaticvarsym(vs).set_mangledname(mangledname);
  1018. end;
  1019. procedure try_consume_sectiondirective(var asection: ansistring);
  1020. begin
  1021. if idtoken=_SECTION then
  1022. begin
  1023. consume(_ID);
  1024. asection:=get_stringconst;
  1025. consume(_SEMICOLON);
  1026. end;
  1027. end;
  1028. procedure try_read_field_external(vs: tabstractvarsym);
  1029. var
  1030. extname: string;
  1031. begin
  1032. if try_to_consume(_EXTERNAL) then
  1033. begin
  1034. consume(_NAME);
  1035. extname:=get_stringconst;
  1036. tfieldvarsym(vs).set_externalname(extname);
  1037. consume(_SEMICOLON);
  1038. end;
  1039. end;
  1040. procedure try_read_field_external_sc(sc:TFPObjectList);
  1041. var
  1042. vs: tabstractvarsym;
  1043. begin
  1044. { only allowed for one var }
  1045. vs:=tabstractvarsym(sc[0]);
  1046. if sc.count>1 then
  1047. Message1(parser_e_directive_only_one_var,arraytokeninfo[idtoken].str);
  1048. try_read_field_external(vs);
  1049. end;
  1050. procedure read_var_decls(options:Tvar_dec_options;out had_generic:boolean);
  1051. procedure read_default_value(sc : TFPObjectList);
  1052. var
  1053. vs : tabstractnormalvarsym;
  1054. tcsym : tstaticvarsym;
  1055. templist : tasmlist;
  1056. begin
  1057. vs:=tabstractnormalvarsym(sc[0]);
  1058. if sc.count>1 then
  1059. Message(parser_e_initialized_only_one_var);
  1060. if vo_is_thread_var in vs.varoptions then
  1061. Message(parser_e_initialized_not_for_threadvar);
  1062. consume(_EQ);
  1063. case vs.typ of
  1064. localvarsym :
  1065. begin
  1066. tcsym:=cstaticvarsym.create('$default'+vs.realname,vs_const,vs.vardef,[]);
  1067. include(tcsym.symoptions,sp_internal);
  1068. symtablestack.top.insertsym(tcsym);
  1069. templist:=tasmlist.create;
  1070. read_typed_const(templist,tcsym,false);
  1071. { in case of a generic routine, this initialisation value is not
  1072. used, and will be re-parsed during specialisations (and the
  1073. current version is not type-correct and hence breaks code
  1074. generation for LLVM) }
  1075. if not parse_generic then
  1076. begin
  1077. vs.defaultconstsym:=tcsym;
  1078. current_asmdata.asmlists[al_typedconsts].concatlist(templist);
  1079. end;
  1080. templist.free;
  1081. templist := nil;
  1082. end;
  1083. staticvarsym :
  1084. begin
  1085. maybe_guarantee_record_typesym(vs.vardef,vs.vardef.owner);
  1086. read_typed_const(current_asmdata.asmlists[al_typedconsts],tstaticvarsym(vs),false);
  1087. end;
  1088. else
  1089. internalerror(200611051);
  1090. end;
  1091. vs.varstate:=vs_initialised;
  1092. end;
  1093. {$ifdef gpc_mode}
  1094. procedure read_gpc_name(sc : TFPObjectList);
  1095. var
  1096. vs : tabstractnormalvarsym;
  1097. C_Name : string;
  1098. begin
  1099. consume(_ID);
  1100. C_Name:=get_stringconst;
  1101. vs:=tabstractnormalvarsym(sc[0]);
  1102. if sc.count>1 then
  1103. Message(parser_e_directive_only_one_var,'ABSOLUTE');
  1104. if vs.typ=staticvarsym then
  1105. begin
  1106. tstaticvarsym(vs).set_mangledname(C_Name);
  1107. include(vs.varoptions,vo_is_external);
  1108. end
  1109. else
  1110. Message(parser_e_no_local_var_external);
  1111. end;
  1112. {$endif}
  1113. procedure read_absolute(sc : TFPObjectList);
  1114. var
  1115. vs : tabstractvarsym;
  1116. abssym : tabsolutevarsym;
  1117. pt,hp : tnode;
  1118. st : tsymtable;
  1119. {$if defined(i386) or defined(i8086)}
  1120. tmpaddr : int64;
  1121. {$endif defined(i386) or defined(i8086)}
  1122. begin
  1123. abssym:=nil;
  1124. { only allowed for one var }
  1125. vs:=tabstractvarsym(sc[0]);
  1126. if sc.count>1 then
  1127. Message1(parser_e_directive_only_one_var,'ABSOLUTE');
  1128. if vo_is_typed_const in vs.varoptions then
  1129. Message(parser_e_initialized_not_for_external);
  1130. { parse the rest }
  1131. pt:=expr(true);
  1132. { check allowed absolute types }
  1133. if (pt.nodetype=stringconstn) or
  1134. (is_constcharnode(pt)) then
  1135. begin
  1136. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1137. abssym.fileinfo:=vs.fileinfo;
  1138. if pt.nodetype=stringconstn then
  1139. abssym.asmname:=stringdup(tstringconstnode(pt).asrawbytestring)
  1140. else
  1141. abssym.asmname:=stringdup(chr(tordconstnode(pt).value.svalue));
  1142. abssym.abstyp:=toasm;
  1143. end
  1144. { address }
  1145. else if is_constintnode(pt) then
  1146. begin
  1147. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1148. abssym.fileinfo:=vs.fileinfo;
  1149. abssym.abstyp:=toaddr;
  1150. {$ifndef cpu64bitaddr}
  1151. { on 64 bit systems, abssym.addroffset is a qword and hence this
  1152. test is useless (value is a 64 bit entity) and will always fail
  1153. for positive values (since int64(high(abssym.addroffset))=-1
  1154. }
  1155. if (Tordconstnode(pt).value<int64(low(abssym.addroffset))) or
  1156. (Tordconstnode(pt).value>int64(high(abssym.addroffset))) then
  1157. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1158. else
  1159. {$endif}
  1160. abssym.addroffset:=Tordconstnode(pt).value.svalue;
  1161. {$if defined(i386) or defined(i8086)}
  1162. tcpuabsolutevarsym(abssym).absseg:=false;
  1163. if (target_info.system in [system_i386_go32v2,system_i386_watcom,system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) and
  1164. try_to_consume(_COLON) then
  1165. begin
  1166. pt.free;
  1167. pt:=expr(true);
  1168. if is_constintnode(pt) then
  1169. begin
  1170. {$if defined(i8086)}
  1171. tcpuabsolutevarsym(abssym).addrsegment:=abssym.addroffset;
  1172. tmpaddr:=tordconstnode(pt).value.svalue;
  1173. if (tmpaddr<int64(low(abssym.addroffset))) or
  1174. (tmpaddr>int64(high(abssym.addroffset))) then
  1175. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1176. else
  1177. abssym.addroffset:=tmpaddr;
  1178. {$elseif defined(i386)}
  1179. tmpaddr:=abssym.addroffset shl 4+tordconstnode(pt).value.svalue;
  1180. if (tmpaddr<int64(low(abssym.addroffset))) or
  1181. (tmpaddr>int64(high(abssym.addroffset))) then
  1182. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1183. else
  1184. abssym.addroffset:=tmpaddr;
  1185. {$endif}
  1186. tcpuabsolutevarsym(abssym).absseg:=true;
  1187. end
  1188. else
  1189. Message(type_e_ordinal_expr_expected);
  1190. end;
  1191. {$endif i386 or i8086}
  1192. end
  1193. { variable }
  1194. else
  1195. begin
  1196. { we have to be able to take the address of the absolute
  1197. expression
  1198. }
  1199. valid_for_addr(pt,true);
  1200. { remove subscriptn before checking for loadn }
  1201. hp:=pt;
  1202. while (hp.nodetype in [subscriptn,typeconvn,vecn]) do
  1203. begin
  1204. { check for implicit dereferencing and reject it }
  1205. if (hp.nodetype in [subscriptn,vecn]) then
  1206. begin
  1207. if (tunarynode(hp).left.resultdef.typ in [pointerdef,classrefdef]) then
  1208. break;
  1209. { catch, e.g., 'var b: char absolute pchar_var[5];"
  1210. (pchar_var[5] is a pchar_2_string typeconv ->
  1211. the vecn only sees an array of char)
  1212. I don't know if all of these type conversions are
  1213. possible, but they're definitely all bad.
  1214. }
  1215. if (tunarynode(hp).left.nodetype=typeconvn) and
  1216. (ttypeconvnode(tunarynode(hp).left).convtype in
  1217. [tc_pchar_2_string,tc_pointer_2_array,
  1218. tc_intf_2_string,tc_intf_2_guid,
  1219. tc_dynarray_2_variant,tc_interface_2_variant,
  1220. tc_array_2_dynarray]) then
  1221. break;
  1222. if (tunarynode(hp).left.resultdef.typ=stringdef) and
  1223. not(tstringdef(tunarynode(hp).left.resultdef).stringtype in [st_shortstring,st_longstring]) then
  1224. break;
  1225. if (tunarynode(hp).left.resultdef.typ=objectdef) and
  1226. (tobjectdef(tunarynode(hp).left.resultdef).objecttype<>odt_object) then
  1227. break;
  1228. if is_dynamic_array(tunarynode(hp).left.resultdef) then
  1229. break;
  1230. end;
  1231. hp:=tunarynode(hp).left;
  1232. end;
  1233. if (hp.nodetype=loadn) then
  1234. begin
  1235. { we should check the result type of loadn }
  1236. if not (tloadnode(hp).symtableentry.typ in [fieldvarsym,staticvarsym,localvarsym,paravarsym,absolutevarsym]) then
  1237. Message(parser_e_absolute_only_to_var_or_const);
  1238. if vs=tloadnode(hp).symtableentry then
  1239. Message(parser_e_absolute_sym_cannot_reference_itself)
  1240. else
  1241. begin
  1242. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1243. abssym.fileinfo:=vs.fileinfo;
  1244. abssym.abstyp:=tovar;
  1245. abssym.ref:=node_to_propaccesslist(pt);
  1246. end;
  1247. { if the sizes are different, can't be a regvar since you }
  1248. { can't be "absolute upper 8 bits of a register" (except }
  1249. { if its a record field of the same size of a record }
  1250. { regvar, but in that case pt.resultdef.size will have }
  1251. { the same size since it refers to the field and not to }
  1252. { the whole record -- which is why we use pt and not hp) }
  1253. { we can't take the size of an open array or an array of const }
  1254. if is_open_array(pt.resultdef) or
  1255. is_array_of_const(pt.resultdef) or
  1256. (vs.vardef.size <> pt.resultdef.size) then
  1257. make_not_regable(pt,[ra_addr_regable]);
  1258. end
  1259. else
  1260. Message(parser_e_absolute_only_to_var_or_const);
  1261. end;
  1262. pt.free;
  1263. pt := nil;
  1264. { replace old varsym with the new absolutevarsym }
  1265. if assigned(abssym) then
  1266. begin
  1267. st:=vs.owner;
  1268. vs.owner.Deletesym(vs);
  1269. st.insertsym(abssym);
  1270. sc[0]:=abssym;
  1271. end;
  1272. end;
  1273. var
  1274. sc : TFPObjectList;
  1275. vs : tabstractvarsym;
  1276. hdef : tdef;
  1277. i : longint;
  1278. flags : thccflags;
  1279. first,
  1280. isgeneric,
  1281. semicoloneaten,
  1282. allowdefaultvalue,
  1283. hasdefaultvalue : boolean;
  1284. hintsymoptions : tsymoptions;
  1285. deprecatedmsg : pshortstring;
  1286. old_block_type : tblock_type;
  1287. sectionname : ansistring;
  1288. typepos,
  1289. tmp_filepos,
  1290. old_current_filepos : tfileposinfo;
  1291. begin
  1292. old_block_type:=block_type;
  1293. block_type:=bt_var;
  1294. { Force an expected ID error message }
  1295. if not (token in [_ID,_CASE,_END]) then
  1296. consume(_ID);
  1297. { read vars }
  1298. sc:=TFPObjectList.create(false);
  1299. first:=true;
  1300. had_generic:=false;
  1301. vs:=nil;
  1302. fillchar(tmp_filepos,sizeof(tmp_filepos),0);
  1303. while (token=_ID) do
  1304. begin
  1305. semicoloneaten:=false;
  1306. hasdefaultvalue:=false;
  1307. allowdefaultvalue:=true;
  1308. sc.clear;
  1309. repeat
  1310. if (token = _ID) then
  1311. begin
  1312. isgeneric:=(vd_check_generic in options) and
  1313. not (m_delphi in current_settings.modeswitches) and
  1314. (idtoken=_GENERIC);
  1315. case symtablestack.top.symtabletype of
  1316. localsymtable :
  1317. vs:=clocalvarsym.create(orgpattern,vs_value,generrordef,[]);
  1318. staticsymtable,
  1319. globalsymtable :
  1320. begin
  1321. vs:=cstaticvarsym.create(orgpattern,vs_value,generrordef,[]);
  1322. if vd_threadvar in options then
  1323. include(vs.varoptions,vo_is_thread_var);
  1324. end;
  1325. else
  1326. internalerror(200411064);
  1327. end;
  1328. sc.add(vs);
  1329. if isgeneric then
  1330. tmp_filepos:=current_filepos;
  1331. end
  1332. else
  1333. isgeneric:=false;
  1334. consume(_ID);
  1335. { when the first variable had been read the next declaration could be
  1336. a "generic procedure", "generic function" or
  1337. "generic class (function/procedure)" }
  1338. if not first
  1339. and isgeneric
  1340. and (sc.count=1)
  1341. and (token in [_PROCEDURE,_FUNCTION,_CLASS]) then
  1342. begin
  1343. vs.free;
  1344. vs := nil;
  1345. sc.clear;
  1346. had_generic:=true;
  1347. break;
  1348. end
  1349. else
  1350. begin
  1351. vs.register_sym;
  1352. if isgeneric then
  1353. begin
  1354. { ensure correct error position }
  1355. old_current_filepos:=current_filepos;
  1356. current_filepos:=tmp_filepos;
  1357. symtablestack.top.insertsym(vs);
  1358. current_filepos:=old_current_filepos;
  1359. end
  1360. else
  1361. symtablestack.top.insertsym(vs);
  1362. end;
  1363. until not try_to_consume(_COMMA);
  1364. if had_generic then
  1365. break;
  1366. { read variable type def }
  1367. block_type:=bt_var_type;
  1368. consume(_COLON);
  1369. typepos:=current_tokenpos;
  1370. {$ifdef gpc_mode}
  1371. if (m_gpc in current_settings.modeswitches) and
  1372. (token=_ID) and
  1373. (orgpattern='__asmname__') then
  1374. read_gpc_name(sc);
  1375. {$endif}
  1376. read_anon_type(hdef,false,nil);
  1377. maybe_guarantee_record_typesym(hdef,symtablestack.top);
  1378. for i:=0 to sc.count-1 do
  1379. begin
  1380. vs:=tabstractvarsym(sc[i]);
  1381. vs.vardef:=hdef;
  1382. end;
  1383. block_type:=bt_var;
  1384. { Process procvar directives }
  1385. if maybe_parse_proc_directives(hdef) then
  1386. semicoloneaten:=true;
  1387. { check for absolute }
  1388. if try_to_consume(_ABSOLUTE) then
  1389. begin
  1390. read_absolute(sc);
  1391. allowdefaultvalue:=false;
  1392. end;
  1393. { Check for EXTERNAL etc directives before a semicolon }
  1394. if (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) or (idtoken = _WEAKEXTERNAL) then
  1395. begin
  1396. read_public_and_external_sc(sc);
  1397. allowdefaultvalue:=false;
  1398. semicoloneaten:=true;
  1399. end;
  1400. { try to parse the hint directives }
  1401. hintsymoptions:=[];
  1402. deprecatedmsg:=nil;
  1403. try_consume_hintdirective(hintsymoptions,deprecatedmsg);
  1404. for i:=0 to sc.count-1 do
  1405. begin
  1406. vs:=tabstractvarsym(sc[i]);
  1407. vs.symoptions := vs.symoptions + hintsymoptions;
  1408. if deprecatedmsg<>nil then
  1409. vs.deprecatedmsg:=stringdup(deprecatedmsg^);
  1410. end;
  1411. stringdispose(deprecatedmsg);
  1412. { Handling of Delphi typed const = initialized vars }
  1413. if allowdefaultvalue and
  1414. (token=_EQ) and
  1415. not(m_tp7 in current_settings.modeswitches) and
  1416. (symtablestack.top.symtabletype<>parasymtable) then
  1417. begin
  1418. { Add calling convention for procvar }
  1419. if (
  1420. (hdef.typ=procvardef) or
  1421. is_funcref(hdef)
  1422. ) and
  1423. (hdef.typesym=nil) then
  1424. begin
  1425. if po_is_function_ref in tprocvardef(hdef).procoptions then
  1426. begin
  1427. if not (m_function_references in current_settings.modeswitches) and
  1428. not (po_is_block in tprocvardef(hdef).procoptions) then
  1429. messagepos(typepos,sym_e_error_in_type_def)
  1430. else
  1431. begin
  1432. if adjust_funcref(hdef,nil,nil) then
  1433. { the def was changed, so update it }
  1434. for i:=0 to sc.count-1 do
  1435. begin
  1436. vs:=tabstractvarsym(sc[i]);
  1437. vs.vardef:=hdef;
  1438. end;
  1439. if current_scanner.replay_stack_depth=0 then
  1440. hdef.register_def;
  1441. end;
  1442. end;
  1443. handle_calling_convention(hdef,hcc_default_actions_intf);
  1444. end;
  1445. read_default_value(sc);
  1446. hasdefaultvalue:=true;
  1447. end
  1448. else
  1449. begin
  1450. if not(semicoloneaten) then
  1451. consume(_SEMICOLON);
  1452. end;
  1453. { Support calling convention for procvars after semicolon }
  1454. if not(hasdefaultvalue) and
  1455. (
  1456. (hdef.typ=procvardef) or
  1457. is_funcref(hdef)
  1458. ) and
  1459. (hdef.typesym=nil) then
  1460. begin
  1461. { Parse procvar directives after ; }
  1462. maybe_parse_proc_directives(hdef);
  1463. if (hdef.typ=procvardef) and (po_is_function_ref in tprocvardef(hdef).procoptions) then
  1464. begin
  1465. if not (m_function_references in current_settings.modeswitches) and
  1466. not (po_is_block in tprocvardef(hdef).procoptions) then
  1467. messagepos(typepos,sym_e_error_in_type_def)
  1468. else
  1469. begin
  1470. if adjust_funcref(hdef,nil,nil) then
  1471. { the def was changed, so update it }
  1472. for i:=0 to sc.count-1 do
  1473. begin
  1474. vs:=tabstractvarsym(sc[i]);
  1475. vs.vardef:=hdef;
  1476. end;
  1477. if current_scanner.replay_stack_depth=0 then
  1478. hdef.register_def;
  1479. end;
  1480. end;
  1481. { Add calling convention for procvar }
  1482. if hdef.typ=procvardef then
  1483. flags:=hcc_default_actions_intf
  1484. else
  1485. flags:=hcc_default_actions_intf_struct;
  1486. handle_calling_convention(hdef,flags);
  1487. { Handling of Delphi typed const = initialized vars }
  1488. if (token=_EQ) and
  1489. not(m_tp7 in current_settings.modeswitches) and
  1490. (symtablestack.top.symtabletype<>parasymtable) then
  1491. begin
  1492. read_default_value(sc);
  1493. hasdefaultvalue:=true;
  1494. end;
  1495. end;
  1496. { Check for EXTERNAL etc directives or, in macpas, if cs_external_var is set}
  1497. if (
  1498. (
  1499. ((idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) or (idtoken = _WEAKEXTERNAL)) and
  1500. (m_cvar_support in current_settings.modeswitches)
  1501. ) or
  1502. (
  1503. (m_mac in current_settings.modeswitches) and
  1504. (
  1505. (cs_external_var in current_settings.localswitches) or
  1506. (cs_externally_visible in current_settings.localswitches)
  1507. )
  1508. )
  1509. ) then
  1510. read_public_and_external_sc(sc);
  1511. { try to parse a section directive }
  1512. if (target_info.system in systems_allow_section) and
  1513. (symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) and
  1514. (idtoken=_SECTION) then
  1515. begin
  1516. try_consume_sectiondirective(sectionname);
  1517. if sectionname<>'' then
  1518. begin
  1519. for i:=0 to sc.count-1 do
  1520. begin
  1521. vs:=tabstractvarsym(sc[i]);
  1522. if (vs.varoptions *[vo_is_external,vo_is_weak_external])<>[] then
  1523. Message(parser_e_externals_no_section);
  1524. if vs.typ<>staticvarsym then
  1525. Message(parser_e_section_no_locals);
  1526. tstaticvarsym(vs).section:=sectionname;
  1527. include(vs.varoptions, vo_has_section);
  1528. end;
  1529. end;
  1530. end;
  1531. { allocate normal variable (non-external and non-typed-const) staticvarsyms }
  1532. for i:=0 to sc.count-1 do
  1533. begin
  1534. vs:=tabstractvarsym(sc[i]);
  1535. if (vs.typ=staticvarsym) and
  1536. not(vo_is_typed_const in vs.varoptions) and
  1537. not(vo_is_external in vs.varoptions) then
  1538. cnodeutils.insertbssdata(tstaticvarsym(vs));
  1539. if vo_is_public in vs.varoptions then
  1540. current_module.add_public_asmsym(vs.mangledname,AB_GLOBAL,AT_DATA);
  1541. end;
  1542. first:=false;
  1543. end;
  1544. block_type:=old_block_type;
  1545. { free the list }
  1546. sc.free;
  1547. sc := nil;
  1548. end;
  1549. function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
  1550. var
  1551. stowner,tmpdef : tdef;
  1552. st : tsymtable;
  1553. begin
  1554. result:=true;
  1555. st:=symtablestack.top;
  1556. if not (st.symtabletype in [recordsymtable,objectsymtable]) then
  1557. exit;
  1558. stowner:=tdef(st.defowner);
  1559. while assigned(stowner) and (stowner.typ in [objectdef,recorddef]) do
  1560. begin
  1561. if def.typ=arraydef then
  1562. begin
  1563. tmpdef:=def;
  1564. while (tmpdef.typ=arraydef) do
  1565. begin
  1566. { dynamic arrays are allowed in certain cases }
  1567. if allowdynarray and (ado_IsDynamicArray in tarraydef(tmpdef).arrayoptions) then
  1568. begin
  1569. tmpdef:=nil;
  1570. break;
  1571. end;
  1572. tmpdef:=tarraydef(tmpdef).elementdef;
  1573. end;
  1574. end
  1575. else
  1576. tmpdef:=def;
  1577. if assigned(tmpdef) and
  1578. (is_object(tmpdef) or is_record(tmpdef)) and
  1579. is_owned_by(tabstractrecorddef(stowner),tabstractrecorddef(tmpdef)) then
  1580. begin
  1581. Message1(type_e_type_is_not_completly_defined,tabstractrecorddef(tmpdef).RttiName);
  1582. result:=false;
  1583. break;
  1584. end;
  1585. stowner:=tdef(stowner.owner.defowner);
  1586. end;
  1587. end;
  1588. procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
  1589. var
  1590. sc : TFPObjectList;
  1591. i : longint;
  1592. hs,sorg : string;
  1593. gendef,hdef,casetype : tdef;
  1594. { maxsize contains the max. size of a variant }
  1595. { startvarrec contains the start of the variant part of a record }
  1596. maxsize, startvarrecsize : asizeint;
  1597. usedalign,
  1598. maxalignment,startvarrecalign,
  1599. maxpadalign, startpadalign: shortint;
  1600. pt : tnode;
  1601. fieldvs : tfieldvarsym;
  1602. hstaticvs : tstaticvarsym;
  1603. vs : tabstractvarsym;
  1604. srsym : tsym;
  1605. srsymtable : TSymtable;
  1606. visibility : tvisibility;
  1607. recst : tabstractrecordsymtable;
  1608. unionsymtable : trecordsymtable;
  1609. offset : longint;
  1610. uniondef : trecorddef;
  1611. hintsymoptions : tsymoptions;
  1612. deprecatedmsg : pshortstring;
  1613. hadgendummy,
  1614. semicoloneaten,
  1615. removeclassoption: boolean;
  1616. dummyattrelementcount : integer;
  1617. {$if defined(powerpc) or defined(powerpc64)}
  1618. tempdef: tdef;
  1619. is_first_type: boolean;
  1620. {$endif powerpc or powerpc64}
  1621. old_block_type: tblock_type;
  1622. typepos : tfileposinfo;
  1623. begin
  1624. old_block_type:=block_type;
  1625. block_type:=bt_var;
  1626. recst:=tabstractrecordsymtable(symtablestack.top);
  1627. {$if defined(powerpc) or defined(powerpc64)}
  1628. is_first_type:=true;
  1629. {$endif powerpc or powerpc64}
  1630. { Force an expected ID error message }
  1631. if not (token in [_ID,_CASE,_END]) then
  1632. consume(_ID);
  1633. { read vars }
  1634. sc:=TFPObjectList.create(false);
  1635. removeclassoption:=false;
  1636. had_generic:=false;
  1637. attr_element_count:=0;
  1638. while (token=_ID) and
  1639. not(((vd_object in options) or
  1640. ((vd_record in options) and (m_advanced_records in current_settings.modeswitches))) and
  1641. ((idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED,_STRICT]) or
  1642. ((m_final_fields in current_settings.modeswitches) and
  1643. (idtoken=_FINAL)))) do
  1644. begin
  1645. visibility:=symtablestack.top.currentvisibility;
  1646. semicoloneaten:=false;
  1647. sc.clear;
  1648. repeat
  1649. sorg:=orgpattern;
  1650. if token=_ID then
  1651. begin
  1652. vs:=cfieldvarsym.create(sorg,vs_value,generrordef,[]);
  1653. { normally the visibility is set via addfield, but sometimes
  1654. we collect symbols so we can add them in a batch of
  1655. potentially mixed visibility, and then the individual
  1656. symbols need to have their visibility already set }
  1657. vs.visibility:=visibility;
  1658. if (vd_check_generic in options) and (idtoken=_GENERIC) then
  1659. had_generic:=true;
  1660. end
  1661. else
  1662. vs:=nil;
  1663. consume(_ID);
  1664. if assigned(vs) and
  1665. (
  1666. not had_generic or
  1667. not (token in [_PROCEDURE,_FUNCTION,_CLASS])
  1668. ) then
  1669. begin
  1670. vs.register_sym;
  1671. sc.add(vs);
  1672. recst.insertsym(vs);
  1673. had_generic:=false;
  1674. end
  1675. else
  1676. vs.free; // no nil needed
  1677. until not try_to_consume(_COMMA);
  1678. if m_delphi in current_settings.modeswitches then
  1679. block_type:=bt_var_type
  1680. else
  1681. block_type:=old_block_type;
  1682. if had_generic and (sc.count=0) then
  1683. break;
  1684. consume(_COLON);
  1685. if attr_element_count=0 then
  1686. attr_element_count:=sc.Count;
  1687. typepos:=current_filepos;
  1688. { make sure that the correct genericdef is set up, especially if
  1689. we're dealing with anonymous type declarations }
  1690. gendef:=nil;
  1691. if df_specialization in current_structdef.defoptions then
  1692. begin
  1693. srsymtable:=current_structdef.genericdef.getsymtable(gs_record);
  1694. if not assigned(srsymtable) then
  1695. internalerror(2024041204);
  1696. srsym:=tsym(srsymtable.find(tabstractvarsym(sc[0]).name));
  1697. if not assigned(srsym) then
  1698. internalerror(2024041205);
  1699. if srsym.typ<>fieldvarsym then
  1700. internalerror(2024041206);
  1701. gendef:=tfieldvarsym(srsym).vardef;
  1702. end;
  1703. read_anon_type(hdef,false,tstoreddef(gendef));
  1704. maybe_guarantee_record_typesym(hdef,symtablestack.top);
  1705. {$ifdef wasm}
  1706. if is_wasm_reference_type(hdef) then
  1707. messagepos(typepos,sym_e_wasm_ref_types_cannot_be_used_in_records);
  1708. {$endif wasm}
  1709. block_type:=bt_var;
  1710. { allow only static fields reference to struct where they are declared }
  1711. if not (vd_class in options) then
  1712. begin
  1713. if not check_allowed_for_var_or_const(hdef,true) then
  1714. { for error recovery or compiler will crash later }
  1715. hdef:=generrordef;
  1716. end;
  1717. { field type is a generic param so set a flag in the struct }
  1718. if assigned(hdef.typesym) and (sp_generic_para in hdef.typesym.symoptions) then
  1719. include(current_structdef.defoptions,df_has_generic_fields);
  1720. { Process procvar directives }
  1721. if maybe_parse_proc_directives(hdef) then
  1722. semicoloneaten:=true;
  1723. {$if defined(powerpc) or defined(powerpc64)}
  1724. { from gcc/gcc/config/rs6000/rs6000.h:
  1725. /* APPLE LOCAL begin Macintosh alignment 2002-1-22 ff */
  1726. /* Return the alignment of a struct based on the Macintosh PowerPC
  1727. alignment rules. In general the alignment of a struct is
  1728. determined by the greatest alignment of its elements. However, the
  1729. PowerPC rules cause the alignment of a struct to peg at word
  1730. alignment except when the first field has greater than word
  1731. (32-bit) alignment, in which case the alignment is determined by
  1732. the alignment of the first field. */
  1733. }
  1734. { TODO: check whether this is also for AIX }
  1735. if (target_info.abi in [abi_powerpc_aix,abi_powerpc_darwin]) and
  1736. is_first_type and
  1737. (symtablestack.top.symtabletype=recordsymtable) and
  1738. (trecordsymtable(symtablestack.top).usefieldalignment=C_alignment) then
  1739. begin
  1740. tempdef:=hdef;
  1741. while tempdef.typ=arraydef do
  1742. tempdef:=tarraydef(tempdef).elementdef;
  1743. if tempdef.typ<>recorddef then
  1744. maxpadalign:=tempdef.alignment
  1745. else
  1746. maxpadalign:=trecorddef(tempdef).padalignment;
  1747. if (maxpadalign>4) and
  1748. (maxpadalign>trecordsymtable(symtablestack.top).padalignment) then
  1749. trecordsymtable(symtablestack.top).padalignment:=maxpadalign;
  1750. is_first_type:=false;
  1751. end;
  1752. {$endif powerpc or powerpc64}
  1753. { types that use init/final are not allowed in variant parts, but
  1754. classes are allowed }
  1755. if (variantrecordlevel>0) then
  1756. if is_managed_type(hdef) then
  1757. Message(parser_e_cant_use_inittable_here);
  1758. { try to parse the hint directives }
  1759. hintsymoptions:=[];
  1760. deprecatedmsg:=nil;
  1761. try_consume_hintdirective(hintsymoptions,deprecatedmsg);
  1762. { update variable type and hints }
  1763. for i:=0 to sc.count-1 do
  1764. begin
  1765. fieldvs:=tfieldvarsym(sc[i]);
  1766. fieldvs.vardef:=hdef;
  1767. { insert any additional hint directives }
  1768. fieldvs.symoptions := fieldvs.symoptions + hintsymoptions;
  1769. if deprecatedmsg<>nil then
  1770. fieldvs.deprecatedmsg:=stringdup(deprecatedmsg^);
  1771. end;
  1772. stringdispose(deprecatedmsg);
  1773. { Records and objects can't have default values }
  1774. { for a record there doesn't need to be a ; before the END or ) }
  1775. if not(token in [_END,_RKLAMMER]) and
  1776. not(semicoloneaten) then
  1777. consume(_SEMICOLON);
  1778. { Parse procvar directives after ; }
  1779. maybe_parse_proc_directives(hdef);
  1780. { Add calling convention for procvar }
  1781. if (
  1782. (hdef.typ=procvardef) or
  1783. is_funcref(hdef)
  1784. ) and (hdef.typesym=nil) then
  1785. begin
  1786. if (hdef.typ=procvardef) and (po_is_function_ref in tprocvardef(hdef).procoptions) then
  1787. begin
  1788. if not (m_function_references in current_settings.modeswitches) and
  1789. not (po_is_block in tprocvardef(hdef).procoptions) then
  1790. messagepos(typepos,sym_e_error_in_type_def)
  1791. else
  1792. begin
  1793. if adjust_funcref(hdef,nil,nil) then
  1794. { the def was changed, so update it }
  1795. for i:=0 to sc.count-1 do
  1796. begin
  1797. fieldvs:=tfieldvarsym(sc[i]);
  1798. fieldvs.vardef:=hdef;
  1799. end;
  1800. if current_scanner.replay_stack_depth=0 then
  1801. hdef.register_def;
  1802. end;
  1803. end;
  1804. handle_calling_convention(hdef,hcc_default_actions_intf);
  1805. end;
  1806. if (vd_object in options) then
  1807. begin
  1808. { if it is not a class var section and token=STATIC then it is a class field too }
  1809. if not (vd_class in options) and try_to_consume(_STATIC) then
  1810. begin
  1811. consume(_SEMICOLON);
  1812. include(options,vd_class);
  1813. removeclassoption:=true;
  1814. end;
  1815. { Fields in Java classes/interfaces can have a separately
  1816. specified external name }
  1817. if is_java_class_or_interface(tdef(recst.defowner)) and
  1818. (oo_is_external in tobjectdef(recst.defowner).objectoptions) then
  1819. try_read_field_external_sc(sc);
  1820. end;
  1821. if (visibility=vis_published) and
  1822. not(is_class(hdef)) then
  1823. begin
  1824. MessagePos(tfieldvarsym(sc[0]).fileinfo,parser_e_cant_publish_that);
  1825. visibility:=vis_public;
  1826. end;
  1827. if (visibility=vis_published) and
  1828. not(oo_can_have_published in tobjectdef(hdef).objectoptions) and
  1829. not(m_delphi in current_settings.modeswitches) then
  1830. begin
  1831. MessagePos(tfieldvarsym(sc[0]).fileinfo,parser_e_only_publishable_classes_can_be_published);
  1832. visibility:=vis_public;
  1833. end;
  1834. if vd_class in options then
  1835. begin
  1836. { add static flag and staticvarsyms }
  1837. for i:=0 to sc.count-1 do
  1838. begin
  1839. fieldvs:=tfieldvarsym(sc[i]);
  1840. fieldvs.visibility:=visibility;
  1841. hstaticvs:=make_field_static(recst,fieldvs);
  1842. if vd_threadvar in options then
  1843. include(hstaticvs.varoptions,vo_is_thread_var);
  1844. if not parse_generic then
  1845. cnodeutils.insertbssdata(hstaticvs);
  1846. if vd_final in options then
  1847. hstaticvs.varspez:=vs_final;
  1848. end;
  1849. if removeclassoption then
  1850. begin
  1851. exclude(options,vd_class);
  1852. removeclassoption:=false;
  1853. end;
  1854. end;
  1855. if vd_final in options then
  1856. begin
  1857. { add final flag }
  1858. for i:=0 to sc.count-1 do
  1859. begin
  1860. fieldvs:=tfieldvarsym(sc[i]);
  1861. fieldvs.varspez:=vs_final;
  1862. end;
  1863. end;
  1864. if not(vd_canreorder in options) then
  1865. { add field(s) to the recordsymtable }
  1866. recst.addfieldlist(sc,false)
  1867. else
  1868. { we may reorder the fields before adding them to the symbol
  1869. table }
  1870. reorderlist.concatlistcopy(sc)
  1871. end;
  1872. if m_delphi in current_settings.modeswitches then
  1873. block_type:=bt_var_type
  1874. else
  1875. block_type:=old_block_type;
  1876. { Check for Case }
  1877. if (vd_record in options) and
  1878. try_to_consume(_CASE) then
  1879. begin
  1880. maxsize:=0;
  1881. maxalignment:=0;
  1882. maxpadalign:=0;
  1883. { already inside a variant record? if not, setup a new variantdesc chain }
  1884. if not(assigned(variantdesc)) then
  1885. variantdesc:=@trecorddef(trecordsymtable(recst).defowner).variantrecdesc;
  1886. { else just concat the info to the given one }
  1887. new(variantdesc^);
  1888. fillchar(variantdesc^^,sizeof(tvariantrecdesc),0);
  1889. { including a field declaration? }
  1890. fieldvs:=nil;
  1891. if token=_ID then
  1892. begin
  1893. sorg:=orgpattern;
  1894. hs:=pattern;
  1895. searchsym(hs,srsym,srsymtable);
  1896. if not(assigned(srsym) and (srsym.typ in [typesym,unitsym])) then
  1897. begin
  1898. consume(_ID);
  1899. consume(_COLON);
  1900. fieldvs:=cfieldvarsym.create(sorg,vs_value,generrordef,[]);
  1901. variantdesc^^.variantselector:=fieldvs;
  1902. symtablestack.top.insertsym(fieldvs);
  1903. end;
  1904. end;
  1905. read_anon_type(casetype,true,nil);
  1906. block_type:=bt_var;
  1907. if assigned(fieldvs) then
  1908. begin
  1909. fieldvs.vardef:=casetype;
  1910. recst.addfield(fieldvs,recst.currentvisibility);
  1911. end;
  1912. if not(is_ordinal(casetype))
  1913. {$ifndef cpu64bitaddr}
  1914. or is_64bitint(casetype)
  1915. {$endif cpu64bitaddr}
  1916. then
  1917. Message(type_e_ordinal_expr_expected);
  1918. consume(_OF);
  1919. UnionSymtable:=trecordsymtable.create('',current_settings.packrecords,current_settings.alignment.recordalignmin);
  1920. UnionDef:=crecorddef.create('',unionsymtable);
  1921. uniondef.isunion:=true;
  1922. startvarrecsize:=UnionSymtable.datasize;
  1923. { align the bitpacking to the next byte }
  1924. UnionSymtable.datasize:=startvarrecsize;
  1925. startvarrecalign:=UnionSymtable.fieldalignment;
  1926. startpadalign:=Unionsymtable.padalignment;
  1927. symtablestack.push(UnionSymtable);
  1928. repeat
  1929. SetLength(variantdesc^^.branches,length(variantdesc^^.branches)+1);
  1930. fillchar(variantdesc^^.branches[high(variantdesc^^.branches)],
  1931. sizeof(variantdesc^^.branches[high(variantdesc^^.branches)]),0);
  1932. repeat
  1933. pt:=comp_expr([ef_accept_equal]);
  1934. if not(pt.nodetype=ordconstn) then
  1935. Message(parser_e_illegal_expression);
  1936. inserttypeconv(pt,casetype);
  1937. { iso pascal does not support ranges in variant record definitions }
  1938. if (([m_iso,m_extpas]*current_settings.modeswitches)=[]) and try_to_consume(_POINTPOINT) then
  1939. pt:=crangenode.create(pt,comp_expr([ef_accept_equal]))
  1940. else
  1941. begin
  1942. with variantdesc^^.branches[high(variantdesc^^.branches)] do
  1943. begin
  1944. SetLength(values,length(values)+1);
  1945. values[high(values)]:=tordconstnode(pt).value;
  1946. end;
  1947. end;
  1948. pt.free;
  1949. pt := nil;
  1950. if token=_COMMA then
  1951. consume(_COMMA)
  1952. else
  1953. break;
  1954. until false;
  1955. if m_delphi in current_settings.modeswitches then
  1956. block_type:=bt_var_type
  1957. else
  1958. block_type:=old_block_type;
  1959. consume(_COLON);
  1960. { read the vars }
  1961. consume(_LKLAMMER);
  1962. inc(variantrecordlevel);
  1963. if token<>_RKLAMMER then
  1964. read_record_fields([vd_record],nil,@variantdesc^^.branches[high(variantdesc^^.branches)].nestedvariant,hadgendummy,dummyattrelementcount);
  1965. dec(variantrecordlevel);
  1966. consume(_RKLAMMER);
  1967. { calculates maximal variant size }
  1968. maxsize:=max(maxsize,unionsymtable.datasize);
  1969. maxalignment:=max(maxalignment,unionsymtable.fieldalignment);
  1970. maxpadalign:=max(maxpadalign,unionsymtable.padalignment);
  1971. { the items of the next variant are overlayed }
  1972. unionsymtable.datasize:=startvarrecsize;
  1973. unionsymtable.fieldalignment:=startvarrecalign;
  1974. unionsymtable.padalignment:=startpadalign;
  1975. if (token<>_END) and (token<>_RKLAMMER) then
  1976. consume(_SEMICOLON)
  1977. else
  1978. break;
  1979. until (token=_END) or (token=_RKLAMMER);
  1980. symtablestack.pop(UnionSymtable);
  1981. { at last set the record size to that of the biggest variant }
  1982. unionsymtable.datasize:=maxsize;
  1983. unionsymtable.fieldalignment:=maxalignment;
  1984. unionsymtable.addalignmentpadding;
  1985. {$if defined(powerpc) or defined(powerpc64)}
  1986. { parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
  1987. if (target_info.system in [system_powerpc_darwin, system_powerpc_macosclassic, system_powerpc64_darwin]) and
  1988. is_first_type and
  1989. (recst.usefieldalignment=C_alignment) and
  1990. (maxpadalign>recst.padalignment) then
  1991. recst.padalignment:=maxpadalign;
  1992. {$endif powerpc or powerpc64}
  1993. { Align the offset where the union symtable is added }
  1994. case recst.usefieldalignment of
  1995. { allow the unionsymtable to be aligned however it wants }
  1996. { (within the global min/max limits) }
  1997. 0, { default }
  1998. C_alignment:
  1999. usedalign:=used_align(unionsymtable.recordalignment,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
  2000. { 1 byte alignment if we are bitpacked }
  2001. bit_alignment:
  2002. usedalign:=1;
  2003. mac68k_alignment:
  2004. usedalign:=2;
  2005. { otherwise alignment at the packrecords alignment of the }
  2006. { current record }
  2007. else
  2008. usedalign:=used_align(recst.fieldalignment,current_settings.alignment.recordalignmin,current_settings.alignment.recordalignmax);
  2009. end;
  2010. offset:=align(recst.datasize,usedalign);
  2011. recst.datasize:=offset+unionsymtable.datasize;
  2012. if unionsymtable.recordalignment>recst.fieldalignment then
  2013. recst.fieldalignment:=unionsymtable.recordalignment;
  2014. if unionsymtable.explicitrecordalignment>recst.explicitrecordalignment then
  2015. recst.explicitrecordalignment:=unionsymtable.explicitrecordalignment;
  2016. trecordsymtable(recst).insertunionst(Unionsymtable,offset);
  2017. uniondef.owner.deletedef(uniondef);
  2018. end;
  2019. { free the list }
  2020. sc.free;
  2021. sc := nil;
  2022. {$ifdef powerpc}
  2023. is_first_type := false;
  2024. {$endif powerpc}
  2025. block_type:=old_block_type;
  2026. end;
  2027. end.