symtable.pas 107 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  3. This unit handles the symbol tables
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit symtable;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,cclasses,
  23. { global }
  24. cpuinfo,globtype,tokens,
  25. { symtable }
  26. symconst,symbase,symtype,symdef,symsym,
  27. { ppu }
  28. ppu,
  29. { assembler }
  30. aasmtai,aasmdata
  31. ;
  32. {****************************************************************************
  33. Symtable types
  34. ****************************************************************************}
  35. type
  36. tstoredsymtable = class(TSymtable)
  37. private
  38. b_needs_init_final : boolean;
  39. procedure _needs_init_final(sym:TObject;arg:pointer);
  40. procedure check_forward(sym:TObject;arg:pointer);
  41. procedure labeldefined(sym:TObject;arg:pointer);
  42. procedure varsymbolused(sym:TObject;arg:pointer);
  43. procedure TestPrivate(sym:TObject;arg:pointer);
  44. procedure objectprivatesymbolused(sym:TObject;arg:pointer);
  45. procedure loaddefs(ppufile:tcompilerppufile);
  46. procedure loadsyms(ppufile:tcompilerppufile);
  47. procedure writedefs(ppufile:tcompilerppufile);
  48. procedure writesyms(ppufile:tcompilerppufile);
  49. public
  50. procedure insert(sym:TSymEntry;checkdup:boolean=true);override;
  51. procedure delete(sym:TSymEntry);override;
  52. { load/write }
  53. procedure ppuload(ppufile:tcompilerppufile);virtual;
  54. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  55. procedure buildderef;virtual;
  56. procedure buildderefimpl;virtual;
  57. procedure deref;virtual;
  58. procedure derefimpl;virtual;
  59. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  60. procedure allsymbolsused;
  61. procedure allprivatesused;
  62. procedure check_forwards;
  63. procedure checklabels;
  64. function needs_init_final : boolean;
  65. procedure testfordefaultproperty(sym:TObject;arg:pointer);
  66. end;
  67. tabstractrecordsymtable = class(tstoredsymtable)
  68. public
  69. usefieldalignment, { alignment to use for fields (PACKRECORDS value), C_alignment is C style }
  70. recordalignment, { alignment desired when inserting this record }
  71. fieldalignment, { alignment current alignment used when fields are inserted }
  72. padalignment : shortint; { size to a multiple of which the symtable has to be rounded up }
  73. constructor create(const n:string;usealign:shortint);
  74. procedure ppuload(ppufile:tcompilerppufile);override;
  75. procedure ppuwrite(ppufile:tcompilerppufile);override;
  76. procedure alignrecord(fieldoffset:aint;varalign:shortint);
  77. procedure addfield(sym:tfieldvarsym;vis:tvisibility);
  78. procedure addalignmentpadding;
  79. procedure insertdef(def:TDefEntry);override;
  80. function is_packed: boolean;
  81. function has_single_field(out sym:tfieldvarsym): boolean;
  82. function get_unit_symtable: tsymtable;
  83. protected
  84. _datasize : aint;
  85. { size in bits of the data in case of bitpacked record. Only important during construction, }
  86. { no need to save in/restore from ppu file. datasize is always (databitsize+7) div 8. }
  87. databitsize : aint;
  88. procedure setdatasize(val: aint);
  89. public
  90. function iscurrentunit: boolean; override;
  91. property datasize : aint read _datasize write setdatasize;
  92. end;
  93. trecordsymtable = class(tabstractrecordsymtable)
  94. public
  95. constructor create(const n:string;usealign:shortint);
  96. procedure insertunionst(unionst : trecordsymtable;offset : longint);
  97. end;
  98. tObjectSymtable = class(tabstractrecordsymtable)
  99. public
  100. constructor create(adefowner:tdef;const n:string;usealign:shortint);
  101. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  102. end;
  103. { tabstractlocalsymtable }
  104. tabstractlocalsymtable = class(tstoredsymtable)
  105. public
  106. procedure ppuwrite(ppufile:tcompilerppufile);override;
  107. function count_locals:longint;
  108. end;
  109. tlocalsymtable = class(tabstractlocalsymtable)
  110. public
  111. constructor create(adefowner:tdef;level:byte);
  112. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  113. end;
  114. { tparasymtable }
  115. tparasymtable = class(tabstractlocalsymtable)
  116. public
  117. readonly: boolean;
  118. constructor create(adefowner:tdef;level:byte);
  119. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  120. procedure insertdef(def:TDefEntry);override;
  121. end;
  122. tabstractuniTSymtable = class(tstoredsymtable)
  123. public
  124. constructor create(const n : string;id:word);
  125. function iscurrentunit:boolean;override;
  126. end;
  127. tglobalsymtable = class(tabstractuniTSymtable)
  128. public
  129. unittypecount : word;
  130. constructor create(const n : string;id:word);
  131. procedure ppuload(ppufile:tcompilerppufile);override;
  132. procedure ppuwrite(ppufile:tcompilerppufile);override;
  133. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  134. end;
  135. tstaticsymtable = class(tabstractuniTSymtable)
  136. public
  137. constructor create(const n : string;id:word);
  138. procedure ppuload(ppufile:tcompilerppufile);override;
  139. procedure ppuwrite(ppufile:tcompilerppufile);override;
  140. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  141. end;
  142. twithsymtable = class(TSymtable)
  143. withrefnode : tobject; { tnode }
  144. constructor create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  145. destructor destroy;override;
  146. procedure clear;override;
  147. procedure insertdef(def:TDefEntry);override;
  148. end;
  149. tstt_excepTSymtable = class(TSymtable)
  150. public
  151. constructor create;
  152. end;
  153. tmacrosymtable = class(tstoredsymtable)
  154. public
  155. constructor create(exported: boolean);
  156. end;
  157. { tenumsymtable }
  158. tenumsymtable = class(tstoredsymtable)
  159. public
  160. procedure insert(sym: TSymEntry; checkdup: boolean = true); override;
  161. constructor create(adefowner:tdef);
  162. end;
  163. { tarraysymtable }
  164. tarraysymtable = class(tstoredsymtable)
  165. public
  166. procedure insertdef(def:TDefEntry);override;
  167. constructor create(adefowner:tdef);
  168. end;
  169. var
  170. systemunit : tglobalsymtable; { pointer to the system unit }
  171. {****************************************************************************
  172. Functions
  173. ****************************************************************************}
  174. {*** Misc ***}
  175. function FullTypeName(def,otherdef:tdef):string;
  176. function generate_nested_name(symtable:tsymtable;delimiter:string):string;
  177. procedure incompatibletypes(def1,def2:tdef);
  178. procedure hidesym(sym:TSymEntry);
  179. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  180. {*** Search ***}
  181. procedure addsymref(sym:tsym);
  182. function is_owned_by(childdef,ownerdef:tabstractrecorddef):boolean;
  183. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
  184. function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
  185. function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
  186. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  187. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  188. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  189. function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
  190. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable;searchhelper:boolean):boolean;
  191. function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  192. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  193. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  194. function search_system_type(const s: TIDString): ttypesym;
  195. function search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
  196. function search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
  197. function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
  198. function search_enumerator_operator(from_def,to_def:Tdef):Tprocdef;
  199. function search_last_objectpascal_helper(pd : tabstractrecorddef;out odef : tobjectdef):boolean;
  200. function search_objectpascal_class_helper(pd,contextclassh : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  201. function search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  202. function search_objc_method(const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  203. {Looks for macro s (must be given in upper case) in the macrosymbolstack, }
  204. {and returns it if found. Returns nil otherwise.}
  205. function search_macro(const s : string):tsym;
  206. { Additionally to searching for a macro, also checks whether it's still }
  207. { actually defined (could be disable using "undef") }
  208. function defined_macro(const s : string):boolean;
  209. {*** Object Helpers ***}
  210. function search_default_property(pd : tobjectdef) : tpropertysym;
  211. function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
  212. {*** Macro Helpers ***}
  213. {If called initially, the following procedures manipulate macros in }
  214. {initialmacrotable, otherwise they manipulate system macros local to a module.}
  215. {Name can be given in any case (it will be converted to upper case).}
  216. procedure def_system_macro(const name : string);
  217. procedure set_system_macro(const name, value : string);
  218. procedure set_system_compvar(const name, value : string);
  219. procedure undef_system_macro(const name : string);
  220. {*** symtable stack ***}
  221. { $ifdef DEBUG
  222. procedure test_symtablestack;
  223. procedure list_symtablestack;
  224. $endif DEBUG}
  225. {$ifdef UNITALIASES}
  226. type
  227. punit_alias = ^tunit_alias;
  228. tunit_alias = object(TNamedIndexItem)
  229. newname : pshortstring;
  230. constructor init(const n:string);
  231. destructor done;virtual;
  232. end;
  233. var
  234. unitaliases : pdictionary;
  235. procedure addunitalias(const n:string);
  236. function getunitalias(const n:string):string;
  237. {$endif UNITALIASES}
  238. {*** Init / Done ***}
  239. procedure IniTSymtable;
  240. procedure DoneSymtable;
  241. const
  242. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] = (
  243. { NOTOKEN } 'error',
  244. { _PLUS } 'plus',
  245. { _MINUS } 'minus',
  246. { _STAR } 'star',
  247. { _SLASH } 'slash',
  248. { _EQ } 'equal',
  249. { _GT } 'greater',
  250. { _LT } 'lower',
  251. { _GTE } 'greater_or_equal',
  252. { _LTE } 'lower_or_equal',
  253. { _NE } 'not_equal',
  254. { _SYMDIF } 'sym_diff',
  255. { _STARSTAR } 'starstar',
  256. { _OP_AS } 'as',
  257. { _OP_IN } 'in',
  258. { _OP_IS } 'is',
  259. { _OP_OR } 'or',
  260. { _OP_AND } 'and',
  261. { _OP_DIV } 'div',
  262. { _OP_MOD } 'mod',
  263. { _OP_NOT } 'not',
  264. { _OP_SHL } 'shl',
  265. { _OP_SHR } 'shr',
  266. { _OP_XOR } 'xor',
  267. { _ASSIGNMENT } 'assign',
  268. { _OP_EXPLICIT } 'explicit',
  269. { _OP_ENUMERATOR } 'enumerator',
  270. { _OP_INC } 'inc',
  271. { _OP_DEC } 'dec');
  272. implementation
  273. uses
  274. { global }
  275. verbose,globals,
  276. { target }
  277. systems,
  278. { symtable }
  279. symutil,defcmp,defutil,
  280. { module }
  281. fmodule,
  282. { codegen }
  283. procinfo
  284. ;
  285. var
  286. dupnr : longint; { unique number for duplicate symbols }
  287. {*****************************************************************************
  288. TStoredSymtable
  289. *****************************************************************************}
  290. procedure tstoredsymtable.insert(sym:TSymEntry;checkdup:boolean=true);
  291. begin
  292. inherited insert(sym,checkdup);
  293. end;
  294. procedure tstoredsymtable.delete(sym:TSymEntry);
  295. begin
  296. inherited delete(sym);
  297. end;
  298. procedure tstoredsymtable.ppuload(ppufile:tcompilerppufile);
  299. begin
  300. { load the table's flags }
  301. if ppufile.readentry<>ibsymtableoptions then
  302. Message(unit_f_ppu_read_error);
  303. ppufile.getsmallset(tableoptions);
  304. { load definitions }
  305. loaddefs(ppufile);
  306. { load symbols }
  307. loadsyms(ppufile);
  308. end;
  309. procedure tstoredsymtable.ppuwrite(ppufile:tcompilerppufile);
  310. begin
  311. { write the table's flags }
  312. ppufile.putsmallset(tableoptions);
  313. ppufile.writeentry(ibsymtableoptions);
  314. { write definitions }
  315. writedefs(ppufile);
  316. { write symbols }
  317. writesyms(ppufile);
  318. end;
  319. procedure tstoredsymtable.loaddefs(ppufile:tcompilerppufile);
  320. var
  321. def : tdef;
  322. b : byte;
  323. begin
  324. { load start of definition section, which holds the amount of defs }
  325. if ppufile.readentry<>ibstartdefs then
  326. Message(unit_f_ppu_read_error);
  327. { read definitions }
  328. repeat
  329. b:=ppufile.readentry;
  330. case b of
  331. ibpointerdef : def:=tpointerdef.ppuload(ppufile);
  332. ibarraydef : def:=tarraydef.ppuload(ppufile);
  333. iborddef : def:=torddef.ppuload(ppufile);
  334. ibfloatdef : def:=tfloatdef.ppuload(ppufile);
  335. ibprocdef : def:=tprocdef.ppuload(ppufile);
  336. ibshortstringdef : def:=tstringdef.loadshort(ppufile);
  337. iblongstringdef : def:=tstringdef.loadlong(ppufile);
  338. ibansistringdef : def:=tstringdef.loadansi(ppufile);
  339. ibwidestringdef : def:=tstringdef.loadwide(ppufile);
  340. ibunicodestringdef : def:=tstringdef.loadunicode(ppufile);
  341. ibrecorddef : def:=trecorddef.ppuload(ppufile);
  342. ibobjectdef : def:=tobjectdef.ppuload(ppufile);
  343. ibenumdef : def:=tenumdef.ppuload(ppufile);
  344. ibsetdef : def:=tsetdef.ppuload(ppufile);
  345. ibprocvardef : def:=tprocvardef.ppuload(ppufile);
  346. ibfiledef : def:=tfiledef.ppuload(ppufile);
  347. ibclassrefdef : def:=tclassrefdef.ppuload(ppufile);
  348. ibformaldef : def:=tformaldef.ppuload(ppufile);
  349. ibvariantdef : def:=tvariantdef.ppuload(ppufile);
  350. ibundefineddef : def:=tundefineddef.ppuload(ppufile);
  351. ibenddefs : break;
  352. ibend : Message(unit_f_ppu_read_error);
  353. else
  354. Message1(unit_f_ppu_invalid_entry,tostr(b));
  355. end;
  356. InsertDef(def);
  357. until false;
  358. end;
  359. procedure tstoredsymtable.loadsyms(ppufile:tcompilerppufile);
  360. var
  361. b : byte;
  362. sym : tsym;
  363. begin
  364. { load start of definition section, which holds the amount of defs }
  365. if ppufile.readentry<>ibstartsyms then
  366. Message(unit_f_ppu_read_error);
  367. { now read the symbols }
  368. repeat
  369. b:=ppufile.readentry;
  370. case b of
  371. ibtypesym : sym:=ttypesym.ppuload(ppufile);
  372. ibprocsym : sym:=tprocsym.ppuload(ppufile);
  373. ibconstsym : sym:=tconstsym.ppuload(ppufile);
  374. ibstaticvarsym : sym:=tstaticvarsym.ppuload(ppufile);
  375. iblocalvarsym : sym:=tlocalvarsym.ppuload(ppufile);
  376. ibparavarsym : sym:=tparavarsym.ppuload(ppufile);
  377. ibfieldvarsym : sym:=tfieldvarsym.ppuload(ppufile);
  378. ibabsolutevarsym : sym:=tabsolutevarsym.ppuload(ppufile);
  379. ibenumsym : sym:=tenumsym.ppuload(ppufile);
  380. ibpropertysym : sym:=tpropertysym.ppuload(ppufile);
  381. ibunitsym : sym:=tunitsym.ppuload(ppufile);
  382. iblabelsym : sym:=tlabelsym.ppuload(ppufile);
  383. ibsyssym : sym:=tsyssym.ppuload(ppufile);
  384. ibmacrosym : sym:=tmacro.ppuload(ppufile);
  385. ibendsyms : break;
  386. ibend : Message(unit_f_ppu_read_error);
  387. else
  388. Message1(unit_f_ppu_invalid_entry,tostr(b));
  389. end;
  390. Insert(sym,false);
  391. until false;
  392. end;
  393. procedure tstoredsymtable.writedefs(ppufile:tcompilerppufile);
  394. var
  395. i : longint;
  396. def : tstoreddef;
  397. begin
  398. { each definition get a number, write then the amount of defs to the
  399. ibstartdef entry }
  400. ppufile.putlongint(DefList.count);
  401. ppufile.writeentry(ibstartdefs);
  402. { now write the definition }
  403. for i:=0 to DefList.Count-1 do
  404. begin
  405. def:=tstoreddef(DefList[i]);
  406. def.ppuwrite(ppufile);
  407. end;
  408. { write end of definitions }
  409. ppufile.writeentry(ibenddefs);
  410. end;
  411. procedure tstoredsymtable.writesyms(ppufile:tcompilerppufile);
  412. var
  413. i : longint;
  414. sym : Tstoredsym;
  415. begin
  416. { each definition get a number, write then the amount of syms and the
  417. datasize to the ibsymdef entry }
  418. ppufile.putlongint(SymList.count);
  419. ppufile.writeentry(ibstartsyms);
  420. { foreach is used to write all symbols }
  421. for i:=0 to SymList.Count-1 do
  422. begin
  423. sym:=tstoredsym(SymList[i]);
  424. sym.ppuwrite(ppufile);
  425. end;
  426. { end of symbols }
  427. ppufile.writeentry(ibendsyms);
  428. end;
  429. procedure tstoredsymtable.buildderef;
  430. var
  431. i : longint;
  432. def : tstoreddef;
  433. sym : tstoredsym;
  434. begin
  435. { interface definitions }
  436. for i:=0 to DefList.Count-1 do
  437. begin
  438. def:=tstoreddef(DefList[i]);
  439. def.buildderef;
  440. end;
  441. { interface symbols }
  442. for i:=0 to SymList.Count-1 do
  443. begin
  444. sym:=tstoredsym(SymList[i]);
  445. sym.buildderef;
  446. end;
  447. end;
  448. procedure tstoredsymtable.buildderefimpl;
  449. var
  450. i : longint;
  451. def : tstoreddef;
  452. begin
  453. { implementation definitions }
  454. for i:=0 to DefList.Count-1 do
  455. begin
  456. def:=tstoreddef(DefList[i]);
  457. def.buildderefimpl;
  458. end;
  459. end;
  460. procedure tstoredsymtable.deref;
  461. var
  462. i : longint;
  463. def : tstoreddef;
  464. sym : tstoredsym;
  465. begin
  466. { first deref the interface ttype symbols. This is needs
  467. to be done before the interface defs are derefed, because
  468. the interface defs can contain references to the type symbols
  469. which then already need to contain a resolved typedef field (PFV) }
  470. for i:=0 to SymList.Count-1 do
  471. begin
  472. sym:=tstoredsym(SymList[i]);
  473. if sym.typ=typesym then
  474. sym.deref;
  475. end;
  476. { interface definitions }
  477. for i:=0 to DefList.Count-1 do
  478. begin
  479. def:=tstoreddef(DefList[i]);
  480. def.deref;
  481. end;
  482. { interface symbols }
  483. for i:=0 to SymList.Count-1 do
  484. begin
  485. sym:=tstoredsym(SymList[i]);
  486. if sym.typ<>typesym then
  487. sym.deref;
  488. end;
  489. end;
  490. procedure tstoredsymtable.derefimpl;
  491. var
  492. i : longint;
  493. def : tstoreddef;
  494. begin
  495. { implementation definitions }
  496. for i:=0 to DefList.Count-1 do
  497. begin
  498. def:=tstoreddef(DefList[i]);
  499. def.derefimpl;
  500. end;
  501. end;
  502. function tstoredsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  503. var
  504. hsym : tsym;
  505. begin
  506. hsym:=tsym(FindWithHash(hashedid));
  507. if assigned(hsym) then
  508. DuplicateSym(hashedid,sym,hsym);
  509. result:=assigned(hsym);
  510. end;
  511. {**************************************
  512. Callbacks
  513. **************************************}
  514. procedure TStoredSymtable.check_forward(sym:TObject;arg:pointer);
  515. begin
  516. if tsym(sym).typ=procsym then
  517. tprocsym(sym).check_forward
  518. { check also object method table }
  519. { we needn't to test the def list }
  520. { because each object has to have a type sym,
  521. only test objects declarations, not type renamings }
  522. else
  523. if (tsym(sym).typ=typesym) and
  524. assigned(ttypesym(sym).typedef) and
  525. (ttypesym(sym).typedef.typesym=ttypesym(sym)) and
  526. (ttypesym(sym).typedef.typ in [objectdef,recorddef]) then
  527. tabstractrecorddef(ttypesym(sym).typedef).check_forwards;
  528. end;
  529. procedure TStoredSymtable.labeldefined(sym:TObject;arg:pointer);
  530. begin
  531. if (tsym(sym).typ=labelsym) and
  532. not(tlabelsym(sym).defined) then
  533. begin
  534. if tlabelsym(sym).used then
  535. Message1(sym_e_label_used_and_not_defined,tlabelsym(sym).realname)
  536. else
  537. Message1(sym_w_label_not_defined,tlabelsym(sym).realname);
  538. end;
  539. end;
  540. procedure TStoredSymtable.varsymbolused(sym:TObject;arg:pointer);
  541. begin
  542. if (tsym(sym).typ in [staticvarsym,localvarsym,paravarsym,fieldvarsym]) and
  543. ((tsym(sym).owner.symtabletype in
  544. [parasymtable,localsymtable,ObjectSymtable,recordsymtable,staticsymtable])) then
  545. begin
  546. { unused symbol should be reported only if no }
  547. { error is reported }
  548. { if the symbol is in a register it is used }
  549. { also don't count the value parameters which have local copies }
  550. { also don't claim for high param of open parameters (PM) }
  551. if (Errorcount<>0) or
  552. ([vo_is_hidden_para,vo_is_funcret] * tabstractvarsym(sym).varoptions = [vo_is_hidden_para]) or
  553. (sp_internal in tsym(sym).symoptions) then
  554. exit;
  555. if (tstoredsym(sym).refs=0) then
  556. begin
  557. if (vo_is_funcret in tabstractvarsym(sym).varoptions) then
  558. begin
  559. { don't warn about the result of constructors }
  560. if ((tsym(sym).owner.symtabletype<>localsymtable) or
  561. (tprocdef(tsym(sym).owner.defowner).proctypeoption<>potype_constructor)) and
  562. not(cs_opt_nodedfa in current_settings.optimizerswitches) then
  563. MessagePos(tsym(sym).fileinfo,sym_w_function_result_not_set)
  564. end
  565. else if (tsym(sym).owner.symtabletype=parasymtable) then
  566. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_not_used,tsym(sym).prettyname)
  567. else if (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  568. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname)
  569. else
  570. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_not_used,tsym(sym).prettyname);
  571. end
  572. else if tabstractvarsym(sym).varstate in [vs_written,vs_initialised] then
  573. begin
  574. if (tsym(sym).owner.symtabletype=parasymtable) then
  575. begin
  576. if not(tabstractvarsym(sym).varspez in [vs_var,vs_out,vs_constref]) and
  577. not(vo_is_funcret in tabstractvarsym(sym).varoptions) then
  578. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_only_set,tsym(sym).prettyname)
  579. end
  580. else if (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  581. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_only_set,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname)
  582. else if tabstractvarsym(sym).varoptions*[vo_is_funcret,vo_is_public,vo_is_external]=[] then
  583. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_only_set,tsym(sym).prettyname);
  584. end
  585. else if (tabstractvarsym(sym).varstate = vs_read_not_warned) and
  586. ([vo_is_public,vo_is_external] * tabstractvarsym(sym).varoptions = []) then
  587. MessagePos1(tsym(sym).fileinfo,sym_w_identifier_only_read,tsym(sym).prettyname)
  588. end
  589. else if ((tsym(sym).owner.symtabletype in
  590. [ObjectSymtable,parasymtable,localsymtable,staticsymtable,recordsymtable])) then
  591. begin
  592. if (Errorcount<>0) or
  593. (sp_internal in tsym(sym).symoptions) then
  594. exit;
  595. { do not claim for inherited private fields !! }
  596. if (tsym(sym).refs=0) and (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  597. case tsym(sym).typ of
  598. typesym:
  599. MessagePos2(tsym(sym).fileinfo,sym_n_private_type_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  600. constsym:
  601. MessagePos2(tsym(sym).fileinfo,sym_n_private_const_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  602. propertysym:
  603. MessagePos2(tsym(sym).fileinfo,sym_n_private_property_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  604. else
  605. MessagePos2(tsym(sym).fileinfo,sym_n_private_method_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  606. end
  607. { units references are problematic }
  608. else
  609. begin
  610. if (tsym(sym).refs=0) and
  611. not(tsym(sym).typ in [enumsym,unitsym]) and
  612. not(is_funcret_sym(tsym(sym))) and
  613. { don't complain about compiler generated syms for specializations, see also #13405 }
  614. not((tsym(sym).typ=typesym) and (df_specialization in ttypesym(sym).typedef.defoptions) and
  615. (pos('$',ttypesym(sym).Realname)<>0)) and
  616. (
  617. (tsym(sym).typ<>procsym) or
  618. ((tsym(sym).owner.symtabletype=staticsymtable) and
  619. not current_module.is_unit)
  620. ) and
  621. { don't complain about alias for hidden _cmd parameter to
  622. obj-c methods }
  623. not((tsym(sym).typ in [localvarsym,paravarsym,absolutevarsym]) and
  624. (vo_is_msgsel in tabstractvarsym(sym).varoptions)) then
  625. MessagePos2(tsym(sym).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(sym).typ],tsym(sym).prettyname);
  626. end;
  627. end;
  628. end;
  629. procedure TStoredSymtable.TestPrivate(sym:TObject;arg:pointer);
  630. begin
  631. if tsym(sym).visibility in [vis_private,vis_strictprivate] then
  632. varsymbolused(sym,arg);
  633. end;
  634. procedure TStoredSymtable.objectprivatesymbolused(sym:TObject;arg:pointer);
  635. begin
  636. {
  637. Don't test simple object aliases PM
  638. }
  639. if (tsym(sym).typ=typesym) and
  640. (ttypesym(sym).typedef.typ in [objectdef,recorddef]) and
  641. (ttypesym(sym).typedef.typesym=tsym(sym)) then
  642. tabstractrecorddef(ttypesym(sym).typedef).symtable.SymList.ForEachCall(@TestPrivate,nil);
  643. end;
  644. procedure tstoredsymtable.testfordefaultproperty(sym:TObject;arg:pointer);
  645. begin
  646. if (tsym(sym).typ=propertysym) and
  647. (ppo_defaultproperty in tpropertysym(sym).propoptions) then
  648. ppointer(arg)^:=sym;
  649. end;
  650. {***********************************************
  651. Process all entries
  652. ***********************************************}
  653. { checks, if all procsyms and methods are defined }
  654. procedure tstoredsymtable.check_forwards;
  655. begin
  656. SymList.ForEachCall(@check_forward,nil);
  657. end;
  658. procedure tstoredsymtable.checklabels;
  659. begin
  660. SymList.ForEachCall(@labeldefined,nil);
  661. end;
  662. procedure tstoredsymtable.allsymbolsused;
  663. begin
  664. SymList.ForEachCall(@varsymbolused,nil);
  665. end;
  666. procedure tstoredsymtable.allprivatesused;
  667. begin
  668. SymList.ForEachCall(@objectprivatesymbolused,nil);
  669. end;
  670. procedure TStoredSymtable._needs_init_final(sym:TObject;arg:pointer);
  671. begin
  672. if b_needs_init_final then
  673. exit;
  674. { don't check static symbols - they can be present in structures only and
  675. always have a reference to a symbol defined on unit level }
  676. if sp_static in tsym(sym).symoptions then
  677. exit;
  678. case tsym(sym).typ of
  679. fieldvarsym,
  680. staticvarsym,
  681. localvarsym,
  682. paravarsym :
  683. begin
  684. if is_managed_type(tabstractvarsym(sym).vardef) then
  685. b_needs_init_final:=true;
  686. end;
  687. end;
  688. end;
  689. { returns true, if p contains data which needs init/final code }
  690. function tstoredsymtable.needs_init_final : boolean;
  691. begin
  692. b_needs_init_final:=false;
  693. SymList.ForEachCall(@_needs_init_final,nil);
  694. needs_init_final:=b_needs_init_final;
  695. end;
  696. {****************************************************************************
  697. TAbstractRecordSymtable
  698. ****************************************************************************}
  699. constructor tabstractrecordsymtable.create(const n:string;usealign:shortint);
  700. begin
  701. inherited create(n);
  702. moduleid:=current_module.moduleid;
  703. _datasize:=0;
  704. databitsize:=0;
  705. recordalignment:=1;
  706. usefieldalignment:=usealign;
  707. padalignment:=1;
  708. { recordalign C_alignment means C record packing, that starts
  709. with an alignment of 1 }
  710. case usealign of
  711. C_alignment,
  712. bit_alignment:
  713. fieldalignment:=1;
  714. mac68k_alignment:
  715. fieldalignment:=2;
  716. else
  717. fieldalignment:=usealign;
  718. end;
  719. end;
  720. procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
  721. begin
  722. inherited ppuload(ppufile);
  723. end;
  724. procedure tabstractrecordsymtable.ppuwrite(ppufile:tcompilerppufile);
  725. var
  726. oldtyp : byte;
  727. begin
  728. oldtyp:=ppufile.entrytyp;
  729. ppufile.entrytyp:=subentryid;
  730. inherited ppuwrite(ppufile);
  731. ppufile.entrytyp:=oldtyp;
  732. end;
  733. function field2recordalignment(fieldoffs, fieldalign: aint): aint;
  734. begin
  735. { optimal alignment of the record when declaring a variable of this }
  736. { type is independent of the packrecords setting }
  737. if (fieldoffs mod fieldalign) = 0 then
  738. result:=fieldalign
  739. else if (fieldalign >= 16) and
  740. ((fieldoffs mod 16) = 0) and
  741. ((fieldalign mod 16) = 0) then
  742. result:=16
  743. else if (fieldalign >= 8) and
  744. ((fieldoffs mod 8) = 0) and
  745. ((fieldalign mod 8) = 0) then
  746. result:=8
  747. else if (fieldalign >= 4) and
  748. ((fieldoffs mod 4) = 0) and
  749. ((fieldalign mod 4) = 0) then
  750. result:=4
  751. else if (fieldalign >= 2) and
  752. ((fieldoffs mod 2) = 0) and
  753. ((fieldalign mod 2) = 0) then
  754. result:=2
  755. else
  756. result:=1;
  757. end;
  758. procedure tabstractrecordsymtable.alignrecord(fieldoffset:aint;varalign:shortint);
  759. var
  760. varalignrecord: shortint;
  761. begin
  762. case usefieldalignment of
  763. C_alignment:
  764. varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
  765. mac68k_alignment:
  766. varalignrecord:=2;
  767. else
  768. varalignrecord:=field2recordalignment(fieldoffset,varalign);
  769. end;
  770. recordalignment:=max(recordalignment,varalignrecord);
  771. end;
  772. procedure tabstractrecordsymtable.addfield(sym:tfieldvarsym;vis:tvisibility);
  773. var
  774. l : aint;
  775. varalignfield,
  776. varalign : shortint;
  777. vardef : tdef;
  778. begin
  779. if (sym.owner<>self) then
  780. internalerror(200602031);
  781. if sym.fieldoffset<>-1 then
  782. internalerror(200602032);
  783. { set visibility for the symbol }
  784. sym.visibility:=vis;
  785. { this symbol can't be loaded to a register }
  786. sym.varregable:=vr_none;
  787. { Calculate field offset }
  788. l:=sym.getsize;
  789. vardef:=sym.vardef;
  790. varalign:=vardef.alignment;
  791. case usefieldalignment of
  792. bit_alignment:
  793. begin
  794. { bitpacking only happens for ordinals, the rest is aligned at }
  795. { 1 byte (compatible with GPC/GCC) }
  796. if is_ordinal(vardef) then
  797. begin
  798. sym.fieldoffset:=databitsize;
  799. l:=sym.getpackedbitsize;
  800. end
  801. else
  802. begin
  803. databitsize:=_datasize*8;
  804. sym.fieldoffset:=databitsize;
  805. if (l>high(aint) div 8) then
  806. Message(sym_e_segment_too_large);
  807. l:=l*8;
  808. end;
  809. if varalign=0 then
  810. varalign:=size_2_align(l);
  811. recordalignment:=max(recordalignment,field2recordalignment(databitsize mod 8,varalign));
  812. { bit packed records are limited to high(aint) bits }
  813. { instead of bytes to avoid double precision }
  814. { arithmetic in offset calculations }
  815. if int64(l)>high(aint)-sym.fieldoffset then
  816. begin
  817. Message(sym_e_segment_too_large);
  818. _datasize:=high(aint);
  819. databitsize:=high(aint);
  820. end
  821. else
  822. begin
  823. databitsize:=sym.fieldoffset+l;
  824. _datasize:=(databitsize+7) div 8;
  825. end;
  826. { rest is not applicable }
  827. exit;
  828. end;
  829. { Calc the alignment size for C style records }
  830. C_alignment:
  831. begin
  832. if (varalign>4) and
  833. ((varalign mod 4)<>0) and
  834. (vardef.typ=arraydef) then
  835. Message1(sym_w_wrong_C_pack,vardef.typename);
  836. if varalign=0 then
  837. varalign:=l;
  838. if (fieldalignment<current_settings.alignment.maxCrecordalign) then
  839. begin
  840. if (varalign>16) and (fieldalignment<32) then
  841. fieldalignment:=32
  842. else if (varalign>12) and (fieldalignment<16) then
  843. fieldalignment:=16
  844. { 12 is needed for long double }
  845. else if (varalign>8) and (fieldalignment<12) then
  846. fieldalignment:=12
  847. else if (varalign>4) and (fieldalignment<8) then
  848. fieldalignment:=8
  849. else if (varalign>2) and (fieldalignment<4) then
  850. fieldalignment:=4
  851. else if (varalign>1) and (fieldalignment<2) then
  852. fieldalignment:=2;
  853. end;
  854. fieldalignment:=min(fieldalignment,current_settings.alignment.maxCrecordalign);
  855. end;
  856. mac68k_alignment:
  857. begin
  858. { mac68k alignment (C description):
  859. * char is aligned to 1 byte
  860. * everything else (except vector) is aligned to 2 bytes
  861. * vector is aligned to 16 bytes
  862. }
  863. if l>1 then
  864. fieldalignment:=2
  865. else
  866. fieldalignment:=1;
  867. varalign:=2;
  868. end;
  869. end;
  870. if varalign=0 then
  871. varalign:=size_2_align(l);
  872. varalignfield:=used_align(varalign,current_settings.alignment.recordalignmin,fieldalignment);
  873. sym.fieldoffset:=align(_datasize,varalignfield);
  874. if l>high(aint)-sym.fieldoffset then
  875. begin
  876. Message(sym_e_segment_too_large);
  877. _datasize:=high(aint);
  878. end
  879. else
  880. _datasize:=sym.fieldoffset+l;
  881. { Calc alignment needed for this record }
  882. alignrecord(sym.fieldoffset,varalign);
  883. end;
  884. procedure tabstractrecordsymtable.addalignmentpadding;
  885. begin
  886. { make the record size aligned correctly so it can be
  887. used as elements in an array. For C records we
  888. use the fieldalignment, because that is updated with the
  889. used alignment. }
  890. if (padalignment = 1) then
  891. case usefieldalignment of
  892. C_alignment:
  893. padalignment:=fieldalignment;
  894. { bitpacked }
  895. bit_alignment:
  896. padalignment:=1;
  897. { mac68k: always round to multiple of 2 }
  898. mac68k_alignment:
  899. padalignment:=2;
  900. { default/no packrecords specified }
  901. 0:
  902. padalignment:=recordalignment
  903. { specific packrecords setting -> use as upper limit }
  904. else
  905. padalignment:=min(recordalignment,usefieldalignment);
  906. end;
  907. _datasize:=align(_datasize,padalignment);
  908. end;
  909. procedure tabstractrecordsymtable.insertdef(def:TDefEntry);
  910. begin
  911. { Enums must also be available outside the record scope,
  912. insert in the owner of this symtable }
  913. if def.typ=enumdef then
  914. defowner.owner.insertdef(def)
  915. else
  916. inherited insertdef(def);
  917. end;
  918. function tabstractrecordsymtable.is_packed: boolean;
  919. begin
  920. result:=usefieldalignment=bit_alignment;
  921. end;
  922. function tabstractrecordsymtable.has_single_field(out sym: tfieldvarsym): boolean;
  923. var
  924. i: longint;
  925. begin
  926. result:=false;
  927. { If a record contains a union, it does not contain a "single
  928. non-composite field" in the context of certain ABIs requiring
  929. special treatment for such records }
  930. if (defowner.typ=recorddef) and
  931. trecorddef(defowner).isunion then
  932. exit;
  933. { a record/object can contain other things than fields }
  934. for i:=0 to SymList.Count-1 do
  935. begin
  936. if tsym(symlist[i]).typ=fieldvarsym then
  937. begin
  938. if result then
  939. begin
  940. result:=false;
  941. exit;
  942. end;
  943. result:=true;
  944. sym:=tfieldvarsym(symlist[i])
  945. end;
  946. end;
  947. end;
  948. function tabstractrecordsymtable.get_unit_symtable: tsymtable;
  949. begin
  950. result:=defowner.owner;
  951. while assigned(result) and (result.symtabletype in [ObjectSymtable,recordsymtable]) do
  952. result:=result.defowner.owner;
  953. end;
  954. procedure tabstractrecordsymtable.setdatasize(val: aint);
  955. begin
  956. _datasize:=val;
  957. if (usefieldalignment=bit_alignment) then
  958. { can overflow in non bitpacked records }
  959. databitsize:=val*8;
  960. end;
  961. function tabstractrecordsymtable.iscurrentunit: boolean;
  962. begin
  963. Result := Assigned(current_module) and (current_module.moduleid=moduleid);
  964. end;
  965. {****************************************************************************
  966. TRecordSymtable
  967. ****************************************************************************}
  968. constructor trecordsymtable.create(const n:string;usealign:shortint);
  969. begin
  970. inherited create(n,usealign);
  971. symtabletype:=recordsymtable;
  972. end;
  973. { this procedure is reserved for inserting case variant into
  974. a record symtable }
  975. { the offset is the location of the start of the variant
  976. and datasize and dataalignment corresponds to
  977. the complete size (see code in pdecl unit) PM }
  978. procedure trecordsymtable.insertunionst(unionst : trecordsymtable;offset : longint);
  979. var
  980. sym : tsym;
  981. def : tdef;
  982. i : integer;
  983. varalignrecord,varalign,
  984. storesize,storealign : aint;
  985. bitsize: aint;
  986. begin
  987. storesize:=_datasize;
  988. storealign:=fieldalignment;
  989. _datasize:=offset;
  990. if (usefieldalignment=bit_alignment) then
  991. databitsize:=offset*8;
  992. { We move the ownership of the defs and symbols to the new recordsymtable.
  993. The old unionsymtable keeps the references, but doesn't own the
  994. objects anymore }
  995. unionst.DefList.OwnsObjects:=false;
  996. unionst.SymList.OwnsObjects:=false;
  997. { copy symbols }
  998. for i:=0 to unionst.SymList.Count-1 do
  999. begin
  1000. sym:=TSym(unionst.SymList[i]);
  1001. if sym.typ<>fieldvarsym then
  1002. internalerror(200601272);
  1003. if tfieldvarsym(sym).fieldoffset=0 then
  1004. include(tfieldvarsym(sym).varoptions,vo_is_first_field);
  1005. { add to this record symtable }
  1006. // unionst.SymList.List.List^[i].Data:=nil;
  1007. sym.ChangeOwner(self);
  1008. varalign:=tfieldvarsym(sym).vardef.alignment;
  1009. if varalign=0 then
  1010. varalign:=size_2_align(tfieldvarsym(sym).getsize);
  1011. { retrieve size }
  1012. if (usefieldalignment=bit_alignment) then
  1013. begin
  1014. { bit packed records are limited to high(aint) bits }
  1015. { instead of bytes to avoid double precision }
  1016. { arithmetic in offset calculations }
  1017. if is_ordinal(tfieldvarsym(sym).vardef) then
  1018. bitsize:=tfieldvarsym(sym).getpackedbitsize
  1019. else
  1020. begin
  1021. bitsize:=tfieldvarsym(sym).getsize;
  1022. if (bitsize>high(aint) div 8) then
  1023. Message(sym_e_segment_too_large);
  1024. bitsize:=bitsize*8;
  1025. end;
  1026. if bitsize>high(aint)-databitsize then
  1027. begin
  1028. Message(sym_e_segment_too_large);
  1029. _datasize:=high(aint);
  1030. databitsize:=high(aint);
  1031. end
  1032. else
  1033. begin
  1034. databitsize:=tfieldvarsym(sym).fieldoffset+offset*8;
  1035. _datasize:=(databitsize+7) div 8;
  1036. end;
  1037. tfieldvarsym(sym).fieldoffset:=databitsize;
  1038. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset div 8,varalign);
  1039. end
  1040. else
  1041. begin
  1042. if tfieldvarsym(sym).getsize>high(aint)-_datasize then
  1043. begin
  1044. Message(sym_e_segment_too_large);
  1045. _datasize:=high(aint);
  1046. end
  1047. else
  1048. _datasize:=tfieldvarsym(sym).fieldoffset+offset;
  1049. { update address }
  1050. tfieldvarsym(sym).fieldoffset:=_datasize;
  1051. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset,varalign);
  1052. end;
  1053. { update alignment of this record }
  1054. if (usefieldalignment<>C_alignment) and
  1055. (usefieldalignment<>mac68k_alignment) then
  1056. recordalignment:=max(recordalignment,varalignrecord);
  1057. end;
  1058. { update alignment for C records }
  1059. if (usefieldalignment=C_alignment) and
  1060. (usefieldalignment<>mac68k_alignment) then
  1061. recordalignment:=max(recordalignment,unionst.recordalignment);
  1062. { Register defs in the new record symtable }
  1063. for i:=0 to unionst.DefList.Count-1 do
  1064. begin
  1065. def:=TDef(unionst.DefList[i]);
  1066. def.ChangeOwner(self);
  1067. end;
  1068. _datasize:=storesize;
  1069. fieldalignment:=storealign;
  1070. { If a record contains a union, it does not contain a "single
  1071. non-composite field" in the context of certain ABIs requiring
  1072. special treatment for such records }
  1073. if defowner.typ=recorddef then
  1074. trecorddef(defowner).isunion:=true;
  1075. end;
  1076. {****************************************************************************
  1077. TObjectSymtable
  1078. ****************************************************************************}
  1079. constructor tObjectSymtable.create(adefowner:tdef;const n:string;usealign:shortint);
  1080. begin
  1081. inherited create(n,usealign);
  1082. symtabletype:=ObjectSymtable;
  1083. defowner:=adefowner;
  1084. end;
  1085. function tObjectSymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1086. var
  1087. hsym : tsym;
  1088. begin
  1089. result:=false;
  1090. if not assigned(defowner) then
  1091. internalerror(200602061);
  1092. { procsym and propertysym have special code
  1093. to override values in inherited classes. For other
  1094. symbols check for duplicates }
  1095. if not(sym.typ in [procsym,propertysym]) then
  1096. begin
  1097. { but private ids can be reused }
  1098. hsym:=search_struct_member(tobjectdef(defowner),hashedid.id);
  1099. if assigned(hsym) and
  1100. (
  1101. (
  1102. not(m_delphi in current_settings.modeswitches) and
  1103. is_visible_for_object(hsym,tobjectdef(defowner))
  1104. ) or
  1105. (
  1106. { In Delphi, you can repeat members of a parent class. You can't }
  1107. { do this for objects however, and you (obviouly) can't }
  1108. { declare two fields with the same name in a single class }
  1109. (m_delphi in current_settings.modeswitches) and
  1110. (
  1111. is_object(tdef(defowner)) or
  1112. (hsym.owner = self)
  1113. )
  1114. )
  1115. ) then
  1116. begin
  1117. DuplicateSym(hashedid,sym,hsym);
  1118. result:=true;
  1119. end;
  1120. end
  1121. else
  1122. begin
  1123. if not(m_duplicate_names in current_settings.modeswitches) then
  1124. result:=inherited checkduplicate(hashedid,sym);
  1125. end;
  1126. end;
  1127. {****************************************************************************
  1128. TAbstractLocalSymtable
  1129. ****************************************************************************}
  1130. procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1131. var
  1132. oldtyp : byte;
  1133. begin
  1134. oldtyp:=ppufile.entrytyp;
  1135. ppufile.entrytyp:=subentryid;
  1136. inherited ppuwrite(ppufile);
  1137. ppufile.entrytyp:=oldtyp;
  1138. end;
  1139. function tabstractlocalsymtable.count_locals:longint;
  1140. var
  1141. i : longint;
  1142. sym : tsym;
  1143. begin
  1144. result:=0;
  1145. for i:=0 to SymList.Count-1 do
  1146. begin
  1147. sym:=tsym(SymList[i]);
  1148. { Count only varsyms, but ignore the funcretsym }
  1149. if (tsym(sym).typ in [localvarsym,paravarsym]) and
  1150. (tsym(sym)<>current_procinfo.procdef.funcretsym) and
  1151. (not(vo_is_parentfp in tabstractvarsym(sym).varoptions) or
  1152. (tstoredsym(sym).refs>0)) then
  1153. inc(result);
  1154. end;
  1155. end;
  1156. {****************************************************************************
  1157. TLocalSymtable
  1158. ****************************************************************************}
  1159. constructor tlocalsymtable.create(adefowner:tdef;level:byte);
  1160. begin
  1161. inherited create('');
  1162. defowner:=adefowner;
  1163. symtabletype:=localsymtable;
  1164. symtablelevel:=level;
  1165. end;
  1166. function tlocalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1167. var
  1168. hsym : tsym;
  1169. begin
  1170. if not assigned(defowner) or
  1171. (defowner.typ<>procdef) then
  1172. internalerror(200602042);
  1173. result:=false;
  1174. hsym:=tsym(FindWithHash(hashedid));
  1175. if assigned(hsym) then
  1176. begin
  1177. { a local and the function can have the same
  1178. name in TP and Delphi, but RESULT not }
  1179. if (m_duplicate_names in current_settings.modeswitches) and
  1180. (hsym.typ in [absolutevarsym,localvarsym]) and
  1181. (vo_is_funcret in tabstractvarsym(hsym).varoptions) and
  1182. not((m_result in current_settings.modeswitches) and
  1183. (vo_is_result in tabstractvarsym(hsym).varoptions)) then
  1184. HideSym(hsym)
  1185. else
  1186. DuplicateSym(hashedid,sym,hsym);
  1187. result:=true;
  1188. exit;
  1189. end;
  1190. { check also parasymtable, this needs to be done here because
  1191. of the special situation with the funcret sym that needs to be
  1192. hidden for tp and delphi modes }
  1193. hsym:=tsym(tabstractprocdef(defowner).parast.FindWithHash(hashedid));
  1194. if assigned(hsym) then
  1195. begin
  1196. { a local and the function can have the same
  1197. name in TP and Delphi, but RESULT not }
  1198. if (m_duplicate_names in current_settings.modeswitches) and
  1199. (sym.typ in [absolutevarsym,localvarsym]) and
  1200. (vo_is_funcret in tabstractvarsym(sym).varoptions) and
  1201. not((m_result in current_settings.modeswitches) and
  1202. (vo_is_result in tabstractvarsym(sym).varoptions)) then
  1203. Hidesym(sym)
  1204. else
  1205. DuplicateSym(hashedid,sym,hsym);
  1206. result:=true;
  1207. exit;
  1208. end;
  1209. { check ObjectSymtable, skip this for funcret sym because
  1210. that will always be positive because it has the same name
  1211. as the procsym }
  1212. if not is_funcret_sym(sym) and
  1213. (defowner.typ=procdef) and
  1214. assigned(tprocdef(defowner).struct) and
  1215. (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
  1216. (
  1217. not(m_delphi in current_settings.modeswitches) or
  1218. is_object(tprocdef(defowner).struct)
  1219. ) then
  1220. result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
  1221. end;
  1222. {****************************************************************************
  1223. TParaSymtable
  1224. ****************************************************************************}
  1225. constructor tparasymtable.create(adefowner:tdef;level:byte);
  1226. begin
  1227. inherited create('');
  1228. readonly:=false;
  1229. defowner:=adefowner;
  1230. symtabletype:=parasymtable;
  1231. symtablelevel:=level;
  1232. end;
  1233. function tparasymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1234. begin
  1235. result:=inherited checkduplicate(hashedid,sym);
  1236. if result then
  1237. exit;
  1238. if not(m_duplicate_names in current_settings.modeswitches) and
  1239. (defowner.typ=procdef) and
  1240. assigned(tprocdef(defowner).struct) and
  1241. (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
  1242. (
  1243. not(m_delphi in current_settings.modeswitches) or
  1244. is_object(tprocdef(defowner).struct)
  1245. ) then
  1246. result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
  1247. end;
  1248. procedure tparasymtable.insertdef(def: TDefEntry);
  1249. begin
  1250. if readonly then
  1251. defowner.owner.insertdef(def)
  1252. else
  1253. inherited insertdef(def);
  1254. end;
  1255. {****************************************************************************
  1256. TAbstractUniTSymtable
  1257. ****************************************************************************}
  1258. constructor tabstractuniTSymtable.create(const n : string;id:word);
  1259. begin
  1260. inherited create(n);
  1261. moduleid:=id;
  1262. end;
  1263. function tabstractuniTSymtable.iscurrentunit:boolean;
  1264. begin
  1265. result:=assigned(current_module) and
  1266. (
  1267. (current_module.globalsymtable=self) or
  1268. (current_module.localsymtable=self)
  1269. );
  1270. end;
  1271. {****************************************************************************
  1272. TStaticSymtable
  1273. ****************************************************************************}
  1274. constructor tstaticsymtable.create(const n : string;id:word);
  1275. begin
  1276. inherited create(n,id);
  1277. symtabletype:=staticsymtable;
  1278. symtablelevel:=main_program_level;
  1279. end;
  1280. procedure tstaticsymtable.ppuload(ppufile:tcompilerppufile);
  1281. begin
  1282. inherited ppuload(ppufile);
  1283. { now we can deref the syms and defs }
  1284. deref;
  1285. end;
  1286. procedure tstaticsymtable.ppuwrite(ppufile:tcompilerppufile);
  1287. begin
  1288. inherited ppuwrite(ppufile);
  1289. end;
  1290. function tstaticsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1291. var
  1292. hsym : tsym;
  1293. begin
  1294. result:=false;
  1295. hsym:=tsym(FindWithHash(hashedid));
  1296. if assigned(hsym) then
  1297. begin
  1298. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1299. unit, the unit can then not be accessed anymore using
  1300. <unit>.<id>, so we can hide the symbol }
  1301. if (m_delphi in current_settings.modeswitches) and
  1302. (hsym.typ=symconst.unitsym) then
  1303. HideSym(hsym)
  1304. else
  1305. DuplicateSym(hashedid,sym,hsym);
  1306. result:=true;
  1307. exit;
  1308. end;
  1309. if (current_module.localsymtable=self) and
  1310. assigned(current_module.globalsymtable) then
  1311. result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(hashedid,sym);
  1312. end;
  1313. {****************************************************************************
  1314. TGlobalSymtable
  1315. ****************************************************************************}
  1316. constructor tglobalsymtable.create(const n : string;id:word);
  1317. begin
  1318. inherited create(n,id);
  1319. symtabletype:=globalsymtable;
  1320. symtablelevel:=main_program_level;
  1321. end;
  1322. procedure tglobalsymtable.ppuload(ppufile:tcompilerppufile);
  1323. begin
  1324. inherited ppuload(ppufile);
  1325. { now we can deref the syms and defs }
  1326. deref;
  1327. end;
  1328. procedure tglobalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1329. begin
  1330. { write the symtable entries }
  1331. inherited ppuwrite(ppufile);
  1332. end;
  1333. function tglobalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1334. var
  1335. hsym : tsym;
  1336. begin
  1337. result:=false;
  1338. hsym:=tsym(FindWithHash(hashedid));
  1339. if assigned(hsym) then
  1340. begin
  1341. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1342. unit, the unit can then not be accessed anymore using
  1343. <unit>.<id>, so we can hide the symbol }
  1344. if (m_delphi in current_settings.modeswitches) and
  1345. (hsym.typ=symconst.unitsym) then
  1346. HideSym(hsym)
  1347. else
  1348. DuplicateSym(hashedid,sym,hsym);
  1349. result:=true;
  1350. exit;
  1351. end;
  1352. end;
  1353. {****************************************************************************
  1354. TWITHSYMTABLE
  1355. ****************************************************************************}
  1356. constructor twithsymtable.create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  1357. begin
  1358. inherited create('');
  1359. symtabletype:=withsymtable;
  1360. withrefnode:=refnode;
  1361. { Replace SymList with the passed symlist }
  1362. SymList.free;
  1363. SymList:=ASymList;
  1364. defowner:=aowner;
  1365. end;
  1366. destructor twithsymtable.destroy;
  1367. begin
  1368. withrefnode.free;
  1369. { Disable SymList because we don't Own it }
  1370. SymList:=nil;
  1371. inherited destroy;
  1372. end;
  1373. procedure twithsymtable.clear;
  1374. begin
  1375. { remove no entry from a withsymtable as it is only a pointer to the
  1376. recorddef or objectdef symtable }
  1377. end;
  1378. procedure twithsymtable.insertdef(def:TDefEntry);
  1379. begin
  1380. { Definitions can't be registered in the withsymtable
  1381. because the withsymtable is removed after the with block.
  1382. We can't easily solve it here because the next symtable in the
  1383. stack is not known. }
  1384. internalerror(200602046);
  1385. end;
  1386. {****************************************************************************
  1387. TSTT_ExceptionSymtable
  1388. ****************************************************************************}
  1389. constructor tstt_excepTSymtable.create;
  1390. begin
  1391. inherited create('');
  1392. symtabletype:=stt_excepTSymtable;
  1393. end;
  1394. {****************************************************************************
  1395. TMacroSymtable
  1396. ****************************************************************************}
  1397. constructor tmacrosymtable.create(exported: boolean);
  1398. begin
  1399. inherited create('');
  1400. if exported then
  1401. symtabletype:=exportedmacrosymtable
  1402. else
  1403. symtabletype:=localmacrosymtable;
  1404. symtablelevel:=main_program_level;
  1405. end;
  1406. {****************************************************************************
  1407. TEnumSymtable
  1408. ****************************************************************************}
  1409. procedure tenumsymtable.insert(sym: TSymEntry; checkdup: boolean);
  1410. var
  1411. value: longint;
  1412. def: tenumdef;
  1413. begin
  1414. // defowner = nil only when we are loading from ppu
  1415. if defowner<>nil then
  1416. begin
  1417. { First entry? Then we need to set the minval }
  1418. value:=tenumsym(sym).value;
  1419. def:=tenumdef(defowner);
  1420. if SymList.count=0 then
  1421. begin
  1422. if value>0 then
  1423. def.has_jumps:=true;
  1424. def.setmin(value);
  1425. def.setmax(value);
  1426. end
  1427. else
  1428. begin
  1429. { check for jumps }
  1430. if value>def.max+1 then
  1431. def.has_jumps:=true;
  1432. { update low and high }
  1433. if def.min>value then
  1434. def.setmin(value);
  1435. if def.max<value then
  1436. def.setmax(value);
  1437. end;
  1438. end;
  1439. inherited insert(sym, checkdup);
  1440. end;
  1441. constructor tenumsymtable.create(adefowner: tdef);
  1442. begin
  1443. inherited Create('');
  1444. symtabletype:=enumsymtable;
  1445. defowner:=adefowner;
  1446. end;
  1447. {****************************************************************************
  1448. TArraySymtable
  1449. ****************************************************************************}
  1450. procedure tarraysymtable.insertdef(def: TDefEntry);
  1451. begin
  1452. { Enums must also be available outside the record scope,
  1453. insert in the owner of this symtable }
  1454. if def.typ=enumdef then
  1455. defowner.owner.insertdef(def)
  1456. else
  1457. inherited insertdef(def);
  1458. end;
  1459. constructor tarraysymtable.create(adefowner: tdef);
  1460. begin
  1461. inherited Create('');
  1462. symtabletype:=arraysymtable;
  1463. defowner:=adefowner;
  1464. end;
  1465. {*****************************************************************************
  1466. Helper Routines
  1467. *****************************************************************************}
  1468. function FullTypeName(def,otherdef:tdef):string;
  1469. var
  1470. s1,s2 : string;
  1471. begin
  1472. if def.typ in [objectdef,recorddef] then
  1473. s1:=tabstractrecorddef(def).RttiName
  1474. else
  1475. s1:=def.typename;
  1476. { When the names are the same try to include the unit name }
  1477. if assigned(otherdef) and
  1478. (def.owner.symtabletype in [globalsymtable,staticsymtable]) then
  1479. begin
  1480. s2:=otherdef.typename;
  1481. if upper(s1)=upper(s2) then
  1482. s1:=def.owner.realname^+'.'+s1;
  1483. end;
  1484. FullTypeName:=s1;
  1485. end;
  1486. function generate_nested_name(symtable:tsymtable;delimiter:string):string;
  1487. begin
  1488. result:='';
  1489. while assigned(symtable) and (symtable.symtabletype in [ObjectSymtable,recordsymtable]) do
  1490. begin
  1491. if (result='') then
  1492. result:=symtable.name^
  1493. else
  1494. result:=symtable.name^+delimiter+result;
  1495. symtable:=symtable.defowner.owner;
  1496. end;
  1497. end;
  1498. procedure incompatibletypes(def1,def2:tdef);
  1499. begin
  1500. { When there is an errordef there is already an error message show }
  1501. if (def2.typ=errordef) or
  1502. (def1.typ=errordef) then
  1503. exit;
  1504. CGMessage2(type_e_incompatible_types,FullTypeName(def1,def2),FullTypeName(def2,def1));
  1505. end;
  1506. procedure hidesym(sym:TSymEntry);
  1507. begin
  1508. sym.realname:='$hidden'+sym.realname;
  1509. tsym(sym).visibility:=vis_hidden;
  1510. end;
  1511. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  1512. var
  1513. st : TSymtable;
  1514. begin
  1515. Message1(sym_e_duplicate_id,tsym(origsym).realname);
  1516. { Write hint where the original symbol was found }
  1517. st:=finduniTSymtable(origsym.owner);
  1518. with tsym(origsym).fileinfo do
  1519. begin
  1520. if assigned(st) and
  1521. (st.symtabletype=globalsymtable) and
  1522. st.iscurrentunit then
  1523. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line))
  1524. else if assigned(st.name) then
  1525. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line));
  1526. end;
  1527. { Rename duplicate sym to an unreachable name, but it can be
  1528. inserted in the symtable without errors }
  1529. inc(dupnr);
  1530. hashedid.id:='dup'+tostr(dupnr)+hashedid.id;
  1531. if assigned(dupsym) then
  1532. include(tsym(dupsym).symoptions,sp_implicitrename);
  1533. end;
  1534. {*****************************************************************************
  1535. Search
  1536. *****************************************************************************}
  1537. procedure addsymref(sym:tsym);
  1538. begin
  1539. { symbol uses count }
  1540. sym.IncRefCount;
  1541. { unit uses count }
  1542. if assigned(current_module) and
  1543. (sym.owner.symtabletype=globalsymtable) then
  1544. begin
  1545. if tglobalsymtable(sym.owner).moduleid>=current_module.unitmapsize then
  1546. internalerror(200501152);
  1547. inc(current_module.unitmap[tglobalsymtable(sym.owner).moduleid].refs);
  1548. end;
  1549. end;
  1550. function is_owned_by(childdef,ownerdef:tabstractrecorddef):boolean;
  1551. begin
  1552. result:=childdef=ownerdef;
  1553. if not result and (childdef.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  1554. result:=is_owned_by(tabstractrecorddef(childdef.owner.defowner),ownerdef);
  1555. end;
  1556. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
  1557. var
  1558. symownerdef : tabstractrecorddef;
  1559. begin
  1560. result:=false;
  1561. { Get objdectdef owner of the symtable for the is_related checks }
  1562. if not assigned(symst) or
  1563. not (symst.symtabletype in [objectsymtable,recordsymtable]) then
  1564. internalerror(200810285);
  1565. symownerdef:=tabstractrecorddef(symst.defowner);
  1566. case symvisibility of
  1567. vis_private :
  1568. begin
  1569. { private symbols are allowed when we are in the same
  1570. module as they are defined }
  1571. result:=(
  1572. (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1573. (symownerdef.owner.iscurrentunit)
  1574. ) or
  1575. ( // the case of specialize inside the generic declaration
  1576. (symownerdef.owner.symtabletype = objectsymtable) and
  1577. (
  1578. assigned(current_structdef) and
  1579. (
  1580. (current_structdef=symownerdef) or
  1581. (current_structdef.owner.iscurrentunit)
  1582. )
  1583. ) or
  1584. (
  1585. not assigned(current_structdef) and
  1586. (symownerdef.owner.iscurrentunit)
  1587. )
  1588. );
  1589. end;
  1590. vis_strictprivate :
  1591. begin
  1592. result:=assigned(current_structdef) and
  1593. is_owned_by(current_structdef,symownerdef);
  1594. end;
  1595. vis_strictprotected :
  1596. begin
  1597. result:=assigned(current_structdef) and
  1598. (current_structdef.is_related(symownerdef) or
  1599. is_owned_by(current_structdef,symownerdef));
  1600. end;
  1601. vis_protected :
  1602. begin
  1603. { protected symbols are visible in the module that defines them and
  1604. also visible to related objects. The related object must be defined
  1605. in the current module }
  1606. result:=(
  1607. (
  1608. (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1609. (symownerdef.owner.iscurrentunit)
  1610. ) or
  1611. (
  1612. assigned(contextobjdef) and
  1613. (contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable,ObjectSymtable]) and
  1614. (contextobjdef.owner.iscurrentunit) and
  1615. contextobjdef.is_related(symownerdef)
  1616. ) or
  1617. ( // the case of specialize inside the generic declaration
  1618. (symownerdef.owner.symtabletype = objectsymtable) and
  1619. (
  1620. assigned(current_structdef) and
  1621. (
  1622. (current_structdef=symownerdef) or
  1623. (current_structdef.owner.iscurrentunit)
  1624. )
  1625. ) or
  1626. (
  1627. not assigned(current_structdef) and
  1628. (symownerdef.owner.iscurrentunit)
  1629. )
  1630. )
  1631. );
  1632. end;
  1633. vis_public,
  1634. vis_published :
  1635. result:=true;
  1636. end;
  1637. end;
  1638. function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
  1639. begin
  1640. result:=is_visible_for_object(pd.owner,pd.visibility,contextobjdef);
  1641. end;
  1642. function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
  1643. var
  1644. i : longint;
  1645. pd : tprocdef;
  1646. begin
  1647. if sym.typ=procsym then
  1648. begin
  1649. { A procsym is visible, when there is at least one of the procdefs visible }
  1650. result:=false;
  1651. for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
  1652. begin
  1653. pd:=tprocdef(tprocsym(sym).ProcdefList[i]);
  1654. if (pd.owner=sym.owner) and
  1655. is_visible_for_object(pd,contextobjdef) then
  1656. begin
  1657. result:=true;
  1658. exit;
  1659. end;
  1660. end;
  1661. end
  1662. else
  1663. result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
  1664. end;
  1665. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1666. var
  1667. hashedid : THashedIDString;
  1668. contextstructdef : tabstractrecorddef;
  1669. stackitem : psymtablestackitem;
  1670. begin
  1671. result:=false;
  1672. hashedid.id:=s;
  1673. stackitem:=symtablestack.stack;
  1674. while assigned(stackitem) do
  1675. begin
  1676. srsymtable:=stackitem^.symtable;
  1677. if (srsymtable.symtabletype=objectsymtable) then
  1678. begin
  1679. if searchsym_in_class(tobjectdef(srsymtable.defowner),tobjectdef(srsymtable.defowner),s,srsym,srsymtable,true) then
  1680. begin
  1681. result:=true;
  1682. exit;
  1683. end;
  1684. end
  1685. else
  1686. begin
  1687. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1688. if assigned(srsym) then
  1689. begin
  1690. { use the class from withsymtable only when it is
  1691. defined in this unit }
  1692. if (srsymtable.symtabletype=withsymtable) and
  1693. assigned(srsymtable.defowner) and
  1694. (srsymtable.defowner.typ in [recorddef,objectdef]) and
  1695. (srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1696. (srsymtable.defowner.owner.iscurrentunit) then
  1697. contextstructdef:=tabstractrecorddef(srsymtable.defowner)
  1698. else
  1699. contextstructdef:=current_structdef;
  1700. if not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
  1701. is_visible_for_object(srsym,contextstructdef) then
  1702. begin
  1703. { we need to know if a procedure references symbols
  1704. in the static symtable, because then it can't be
  1705. inlined from outside this unit }
  1706. if assigned(current_procinfo) and
  1707. (srsym.owner.symtabletype=staticsymtable) then
  1708. include(current_procinfo.flags,pi_uses_static_symtable);
  1709. addsymref(srsym);
  1710. result:=true;
  1711. exit;
  1712. end;
  1713. end;
  1714. end;
  1715. stackitem:=stackitem^.next;
  1716. end;
  1717. srsym:=nil;
  1718. srsymtable:=nil;
  1719. end;
  1720. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1721. var
  1722. hashedid : THashedIDString;
  1723. stackitem : psymtablestackitem;
  1724. classh : tobjectdef;
  1725. begin
  1726. result:=false;
  1727. hashedid.id:=s;
  1728. stackitem:=symtablestack.stack;
  1729. while assigned(stackitem) do
  1730. begin
  1731. {
  1732. It is not possible to have type symbols in:
  1733. parameters
  1734. Exception are classes, objects, records, generic definitions and specializations
  1735. that have the parameterized types inserted in the symtable.
  1736. }
  1737. srsymtable:=stackitem^.symtable;
  1738. if (srsymtable.symtabletype=ObjectSymtable) then
  1739. begin
  1740. classh:=tobjectdef(srsymtable.defowner);
  1741. while assigned(classh) do
  1742. begin
  1743. srsymtable:=classh.symtable;
  1744. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1745. if assigned(srsym) and
  1746. not(srsym.typ in [fieldvarsym,paravarsym,propertysym,procsym,labelsym]) and
  1747. is_visible_for_object(srsym,current_structdef) then
  1748. begin
  1749. addsymref(srsym);
  1750. result:=true;
  1751. exit;
  1752. end;
  1753. classh:=classh.childof;
  1754. end;
  1755. end
  1756. else
  1757. begin
  1758. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1759. if assigned(srsym) and
  1760. not(srsym.typ in [fieldvarsym,paravarsym,propertysym,procsym,labelsym]) and
  1761. (not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or is_visible_for_object(srsym,current_structdef)) then
  1762. begin
  1763. { we need to know if a procedure references symbols
  1764. in the static symtable, because then it can't be
  1765. inlined from outside this unit }
  1766. if assigned(current_procinfo) and
  1767. (srsym.owner.symtabletype=staticsymtable) then
  1768. include(current_procinfo.flags,pi_uses_static_symtable);
  1769. addsymref(srsym);
  1770. result:=true;
  1771. exit;
  1772. end;
  1773. end;
  1774. stackitem:=stackitem^.next;
  1775. end;
  1776. result:=false;
  1777. srsym:=nil;
  1778. srsymtable:=nil;
  1779. end;
  1780. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1781. var
  1782. pmod : tmodule;
  1783. begin
  1784. pmod:=tmodule(pm);
  1785. result:=false;
  1786. if assigned(pmod.globalsymtable) then
  1787. begin
  1788. srsym:=tsym(pmod.globalsymtable.Find(s));
  1789. if assigned(srsym) then
  1790. begin
  1791. srsymtable:=pmod.globalsymtable;
  1792. addsymref(srsym);
  1793. result:=true;
  1794. exit;
  1795. end;
  1796. end;
  1797. { If the module is the current unit we also need
  1798. to search the local symtable }
  1799. if (pmod=current_module) and
  1800. assigned(pmod.localsymtable) then
  1801. begin
  1802. srsym:=tsym(pmod.localsymtable.Find(s));
  1803. if assigned(srsym) then
  1804. begin
  1805. srsymtable:=pmod.localsymtable;
  1806. addsymref(srsym);
  1807. result:=true;
  1808. exit;
  1809. end;
  1810. end;
  1811. srsym:=nil;
  1812. srsymtable:=nil;
  1813. end;
  1814. function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
  1815. var
  1816. stackitem : psymtablestackitem;
  1817. begin
  1818. result:=false;
  1819. stackitem:=symtablestack.stack;
  1820. while assigned(stackitem) do
  1821. begin
  1822. srsymtable:=stackitem^.symtable;
  1823. if (srsymtable.symtabletype=globalsymtable) and
  1824. (srsymtable.name^=unitname) then
  1825. begin
  1826. srsym:=tsym(srsymtable.find(symname));
  1827. if not assigned(srsym) then
  1828. break;
  1829. result:=true;
  1830. exit;
  1831. end;
  1832. stackitem:=stackitem^.next;
  1833. end;
  1834. { If the module is the current unit we also need
  1835. to search the local symtable }
  1836. if (current_module.globalsymtable=srsymtable) and
  1837. assigned(current_module.localsymtable) then
  1838. begin
  1839. srsymtable:=current_module.localsymtable;
  1840. srsym:=tsym(srsymtable.find(symname));
  1841. if assigned(srsym) then
  1842. begin
  1843. result:=true;
  1844. exit;
  1845. end;
  1846. end;
  1847. end;
  1848. function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
  1849. var
  1850. hashedid : THashedIDString;
  1851. stackitem : psymtablestackitem;
  1852. srsymtable : tsymtable;
  1853. srsym : tsym;
  1854. begin
  1855. { not a formal definition -> return it }
  1856. if not(oo_is_formal in pd.objectoptions) then
  1857. begin
  1858. result:=pd;
  1859. exit;
  1860. end;
  1861. hashedid.id:=pd.typesym.name;
  1862. stackitem:=symtablestack.stack;
  1863. while assigned(stackitem) do
  1864. begin
  1865. srsymtable:=stackitem^.symtable;
  1866. { ObjC classes can't appear in generics or as nested class
  1867. definitions }
  1868. if not(srsymtable.symtabletype in [recordsymtable,ObjectSymtable,parasymtable]) then
  1869. begin
  1870. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1871. if assigned(srsym) and
  1872. (srsym.typ=typesym) and
  1873. is_objcclass(ttypesym(srsym).typedef) and
  1874. not(oo_is_formal in tobjectdef(ttypesym(srsym).typedef).objectoptions) then
  1875. begin
  1876. { the external name for the formal and the real definition must match }
  1877. if tobjectdef(ttypesym(srsym).typedef).objextname^<>pd.objextname^ then
  1878. begin
  1879. Message2(sym_e_external_class_name_mismatch1,pd.objextname^,pd.typename);
  1880. MessagePos1(srsym.fileinfo,sym_e_external_class_name_mismatch2,tobjectdef(ttypesym(srsym).typedef).objextname^);
  1881. end;
  1882. result:=tobjectdef(ttypesym(srsym).typedef);
  1883. if assigned(current_procinfo) and
  1884. (srsym.owner.symtabletype=staticsymtable) then
  1885. include(current_procinfo.flags,pi_uses_static_symtable);
  1886. addsymref(srsym);
  1887. exit;
  1888. end;
  1889. end;
  1890. stackitem:=stackitem^.next;
  1891. end;
  1892. { nothing found: optionally give an error and return the original
  1893. (empty) one }
  1894. if erroronfailure then
  1895. Message1(sym_e_objc_formal_class_not_resolved,pd.objrealname^);
  1896. result:=pd;
  1897. end;
  1898. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable;searchhelper:boolean):boolean;
  1899. var
  1900. hashedid : THashedIDString;
  1901. exdef : tabstractrecorddef;
  1902. orgclass : tobjectdef;
  1903. i : longint;
  1904. begin
  1905. { search for a class helper method first if this is an Object Pascal
  1906. class }
  1907. if is_class(classh) and searchhelper then
  1908. begin
  1909. result:=search_objectpascal_class_helper(classh,contextclassh,s,srsym,srsymtable);
  1910. if result then
  1911. begin
  1912. { if the procsym is overloaded we need to use the "original"
  1913. symbol; the helper symbol will be find when searching for
  1914. overloads }
  1915. if (srsym.typ<>procsym) or
  1916. not (sp_has_overloaded in tprocsym(srsym).symoptions) then
  1917. Exit;
  1918. end;
  1919. end;
  1920. orgclass:=classh;
  1921. { in case this is a formal objcclass, first find the real definition }
  1922. if assigned(classh) then
  1923. begin
  1924. if (oo_is_formal in classh.objectoptions) then
  1925. classh:=find_real_objcclass_definition(classh,true);
  1926. { The contextclassh is used for visibility. The classh must be equal to
  1927. or be a parent of contextclassh. E.g. for inherited searches the classh is the
  1928. parent or a class helper. }
  1929. if not (contextclassh.is_related(classh) or
  1930. (contextclassh.extendeddef=classh)) then
  1931. internalerror(200811161);
  1932. end;
  1933. result:=false;
  1934. hashedid.id:=s;
  1935. { an Objective-C protocol can inherit from multiple other protocols
  1936. -> uses ImplementedInterfaces instead }
  1937. if is_objcprotocol(classh) then
  1938. begin
  1939. srsymtable:=classh.symtable;
  1940. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1941. if assigned(srsym) and
  1942. is_visible_for_object(srsym,contextclassh) then
  1943. begin
  1944. addsymref(srsym);
  1945. result:=true;
  1946. exit;
  1947. end;
  1948. for i:=0 to classh.ImplementedInterfaces.count-1 do
  1949. begin
  1950. if searchsym_in_class(TImplementedInterface(classh.ImplementedInterfaces[i]).intfdef,contextclassh,s,srsym,srsymtable,true) then
  1951. begin
  1952. result:=true;
  1953. exit;
  1954. end;
  1955. end;
  1956. end
  1957. else
  1958. begin
  1959. { if we're searching for a symbol inside a helper, we must search in
  1960. the extended class/record/whatever first }
  1961. if is_objectpascal_helper(classh) then
  1962. begin
  1963. { important: disable the search for helpers here! }
  1964. if is_class(classh.extendeddef) and
  1965. searchsym_in_class(tobjectdef(classh.extendeddef), tobjectdef(classh.extendeddef), s, srsym, srsymtable, false) then
  1966. begin
  1967. result:=true;
  1968. exit;
  1969. end
  1970. else if is_record(classh.extendeddef) and
  1971. searchsym_in_record(classh.extendeddef, s, srsym, srsymtable) then
  1972. begin
  1973. result:=true;
  1974. exit;
  1975. end;
  1976. end;
  1977. while assigned(classh) do
  1978. begin
  1979. srsymtable:=classh.symtable;
  1980. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1981. if assigned(srsym) and
  1982. is_visible_for_object(srsym,contextclassh) then
  1983. begin
  1984. addsymref(srsym);
  1985. result:=true;
  1986. exit;
  1987. end;
  1988. classh:=classh.childof;
  1989. end;
  1990. end;
  1991. if is_objcclass(orgclass) then
  1992. result:=search_class_helper(orgclass,s,srsym,srsymtable)
  1993. else
  1994. begin
  1995. srsym:=nil;
  1996. srsymtable:=nil;
  1997. end;
  1998. end;
  1999. function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  2000. var
  2001. hashedid : THashedIDString;
  2002. begin
  2003. hashedid.id:=s;
  2004. srsymtable:=recordh.symtable;
  2005. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2006. if assigned(srsym) and is_visible_for_object(srsym,recordh) then
  2007. begin
  2008. addsymref(srsym);
  2009. result:=true;
  2010. exit;
  2011. end;
  2012. srsym:=nil;
  2013. srsymtable:=nil;
  2014. end;
  2015. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  2016. var
  2017. def : tdef;
  2018. i : longint;
  2019. begin
  2020. { in case this is a formal objcclass, first find the real definition }
  2021. if assigned(classh) and
  2022. (oo_is_formal in classh.objectoptions) then
  2023. classh:=find_real_objcclass_definition(classh,true);
  2024. result:=false;
  2025. def:=nil;
  2026. while assigned(classh) do
  2027. begin
  2028. for i:=0 to classh.symtable.DefList.Count-1 do
  2029. begin
  2030. def:=tstoreddef(classh.symtable.DefList[i]);
  2031. { Find also all hidden private methods to
  2032. be compatible with delphi, see tw6203 (PFV) }
  2033. if (def.typ=procdef) and
  2034. (po_msgint in tprocdef(def).procoptions) and
  2035. (tprocdef(def).messageinf.i=msgid) then
  2036. begin
  2037. srdef:=def;
  2038. srsym:=tprocdef(def).procsym;
  2039. srsymtable:=classh.symtable;
  2040. addsymref(srsym);
  2041. result:=true;
  2042. exit;
  2043. end;
  2044. end;
  2045. classh:=classh.childof;
  2046. end;
  2047. srdef:=nil;
  2048. srsym:=nil;
  2049. srsymtable:=nil;
  2050. end;
  2051. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  2052. var
  2053. def : tdef;
  2054. i : longint;
  2055. begin
  2056. { in case this is a formal objcclass, first find the real definition }
  2057. if assigned(classh) and
  2058. (oo_is_formal in classh.objectoptions) then
  2059. classh:=find_real_objcclass_definition(classh,true);
  2060. result:=false;
  2061. def:=nil;
  2062. while assigned(classh) do
  2063. begin
  2064. for i:=0 to classh.symtable.DefList.Count-1 do
  2065. begin
  2066. def:=tstoreddef(classh.symtable.DefList[i]);
  2067. { Find also all hidden private methods to
  2068. be compatible with delphi, see tw6203 (PFV) }
  2069. if (def.typ=procdef) and
  2070. (po_msgstr in tprocdef(def).procoptions) and
  2071. (tprocdef(def).messageinf.str^=s) then
  2072. begin
  2073. srsym:=tprocdef(def).procsym;
  2074. srsymtable:=classh.symtable;
  2075. addsymref(srsym);
  2076. result:=true;
  2077. exit;
  2078. end;
  2079. end;
  2080. classh:=classh.childof;
  2081. end;
  2082. srsym:=nil;
  2083. srsymtable:=nil;
  2084. end;
  2085. function search_specific_assignment_operator(assignment_type:ttoken;from_def,to_def:Tdef):Tprocdef;
  2086. var
  2087. sym : Tprocsym;
  2088. hashedid : THashedIDString;
  2089. curreq,
  2090. besteq : tequaltype;
  2091. currpd,
  2092. bestpd : tprocdef;
  2093. stackitem : psymtablestackitem;
  2094. begin
  2095. hashedid.id:=overloaded_names[assignment_type];
  2096. besteq:=te_incompatible;
  2097. bestpd:=nil;
  2098. stackitem:=symtablestack.stack;
  2099. while assigned(stackitem) do
  2100. begin
  2101. sym:=Tprocsym(stackitem^.symtable.FindWithHash(hashedid));
  2102. if sym<>nil then
  2103. begin
  2104. if sym.typ<>procsym then
  2105. internalerror(200402031);
  2106. { if the source type is an alias then this is only the second choice,
  2107. if you mess with this code, check tw4093 }
  2108. currpd:=sym.find_procdef_assignment_operator(from_def,to_def,curreq);
  2109. if curreq>besteq then
  2110. begin
  2111. besteq:=curreq;
  2112. bestpd:=currpd;
  2113. if (besteq=te_exact) then
  2114. break;
  2115. end;
  2116. end;
  2117. stackitem:=stackitem^.next;
  2118. end;
  2119. result:=bestpd;
  2120. end;
  2121. function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
  2122. begin
  2123. { search record/object symtable first for a suitable operator }
  2124. if from_def.typ in [recorddef,objectdef] then
  2125. symtablestack.push(tabstractrecorddef(from_def).symtable);
  2126. if to_def.typ in [recorddef,objectdef] then
  2127. symtablestack.push(tabstractrecorddef(to_def).symtable);
  2128. { if type conversion is explicit then search first for explicit
  2129. operator overload and if not found then use implicit operator }
  2130. if explicit then
  2131. result:=search_specific_assignment_operator(_OP_EXPLICIT,from_def,to_def)
  2132. else
  2133. result:=nil;
  2134. if result=nil then
  2135. result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,to_def);
  2136. { restore symtable stack }
  2137. if to_def.typ in [recorddef,objectdef] then
  2138. symtablestack.pop(tabstractrecorddef(to_def).symtable);
  2139. if from_def.typ in [recorddef,objectdef] then
  2140. symtablestack.pop(tabstractrecorddef(from_def).symtable);
  2141. end;
  2142. function search_enumerator_operator(from_def,to_def:Tdef): Tprocdef;
  2143. var
  2144. sym : Tprocsym;
  2145. hashedid : THashedIDString;
  2146. curreq,
  2147. besteq : tequaltype;
  2148. currpd,
  2149. bestpd : tprocdef;
  2150. stackitem : psymtablestackitem;
  2151. begin
  2152. hashedid.id:='enumerator';
  2153. besteq:=te_incompatible;
  2154. bestpd:=nil;
  2155. stackitem:=symtablestack.stack;
  2156. while assigned(stackitem) do
  2157. begin
  2158. sym:=Tprocsym(stackitem^.symtable.FindWithHash(hashedid));
  2159. if sym<>nil then
  2160. begin
  2161. if sym.typ<>procsym then
  2162. internalerror(200910241);
  2163. { if the source type is an alias then this is only the second choice,
  2164. if you mess with this code, check tw4093 }
  2165. currpd:=sym.find_procdef_enumerator_operator(from_def,to_def,curreq);
  2166. if curreq>besteq then
  2167. begin
  2168. besteq:=curreq;
  2169. bestpd:=currpd;
  2170. if (besteq=te_exact) then
  2171. break;
  2172. end;
  2173. end;
  2174. stackitem:=stackitem^.next;
  2175. end;
  2176. result:=bestpd;
  2177. end;
  2178. function search_system_type(const s: TIDString): ttypesym;
  2179. var
  2180. sym : tsym;
  2181. begin
  2182. sym:=tsym(systemunit.Find(s));
  2183. if not assigned(sym) or
  2184. (sym.typ<>typesym) then
  2185. cgmessage1(cg_f_unknown_system_type,s);
  2186. result:=ttypesym(sym);
  2187. end;
  2188. function search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
  2189. var
  2190. srsymtable: tsymtable;
  2191. sym: tsym;
  2192. begin
  2193. if searchsym_in_named_module(unitname,typename,sym,srsymtable) and
  2194. (sym.typ=typesym) then
  2195. begin
  2196. result:=ttypesym(sym);
  2197. exit;
  2198. end
  2199. else
  2200. begin
  2201. if throwerror then
  2202. cgmessage2(cg_f_unknown_type_in_unit,typename,unitname);
  2203. result:=nil;
  2204. end;
  2205. end;
  2206. function search_last_objectpascal_helper(pd : tabstractrecorddef;out odef : tobjectdef):boolean;
  2207. var
  2208. stackitem : psymtablestackitem;
  2209. i : integer;
  2210. srsymtable : tsymtable;
  2211. begin
  2212. result:=false;
  2213. stackitem:=symtablestack.stack;
  2214. while assigned(stackitem) do
  2215. begin
  2216. srsymtable:=stackitem^.symtable;
  2217. { only check symtables that contain a class helper }
  2218. if (srsymtable.symtabletype in [staticsymtable,globalsymtable]) and
  2219. (sto_has_classhelper in srsymtable.tableoptions) then
  2220. begin
  2221. { we need to search from last to first }
  2222. for i:=srsymtable.symlist.count-1 downto 0 do
  2223. begin
  2224. if not (srsymtable.symlist[i] is ttypesym) then
  2225. continue;
  2226. if not is_objectpascal_helper(ttypesym(srsymtable.symlist[i]).typedef) then
  2227. continue;
  2228. odef:=tobjectdef(ttypesym(srsymtable.symlist[i]).typedef);
  2229. { does the class helper extend the correct class? }
  2230. result:=odef.extendeddef=pd;
  2231. if result then
  2232. exit
  2233. else
  2234. odef:=nil;
  2235. end;
  2236. end;
  2237. stackitem:=stackitem^.next;
  2238. end;
  2239. end;
  2240. function search_objectpascal_class_helper(pd,contextclassh : tobjectdef;const s: string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2241. var
  2242. hashedid : THashedIDString;
  2243. classh : tobjectdef;
  2244. i : integer;
  2245. pdef : tprocdef;
  2246. begin
  2247. result:=false;
  2248. { if there is no class helper for the class then there is no need to
  2249. search further }
  2250. if not search_last_objectpascal_helper(pd,classh) then
  2251. exit;
  2252. hashedid.id:=s;
  2253. repeat
  2254. srsymtable:=classh.symtable;
  2255. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2256. if srsym<>nil then
  2257. begin
  2258. if srsym.typ=propertysym then
  2259. begin
  2260. result:=true;
  2261. exit;
  2262. end;
  2263. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2264. begin
  2265. pdef:=tprocdef(tprocsym(srsym).procdeflist[i]);
  2266. if not is_visible_for_object(pdef.owner,pdef.visibility,contextclassh) then
  2267. continue;
  2268. { we need to know if a procedure references symbols
  2269. in the static symtable, because then it can't be
  2270. inlined from outside this unit }
  2271. if assigned(current_procinfo) and
  2272. (srsym.owner.symtabletype=staticsymtable) then
  2273. include(current_procinfo.flags,pi_uses_static_symtable);
  2274. { no need to keep looking. There might be other
  2275. categories that extend this, a parent or child
  2276. class with a method with the same name (either
  2277. overriding this one, or overridden by this one),
  2278. but that doesn't matter as far as the basic
  2279. procsym is concerned.
  2280. }
  2281. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2282. srsymtable:=srsym.owner;
  2283. addsymref(srsym);
  2284. result:=true;
  2285. exit;
  2286. end;
  2287. end;
  2288. { try the class helper parent if available }
  2289. classh:=classh.childof;
  2290. until classh=nil;
  2291. srsym:=nil;
  2292. srsymtable:=nil;
  2293. end;
  2294. function search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2295. var
  2296. hashedid : THashedIDString;
  2297. stackitem : psymtablestackitem;
  2298. i : longint;
  2299. defowner : tobjectdef;
  2300. begin
  2301. hashedid.id:=class_helper_prefix+s;
  2302. stackitem:=symtablestack.stack;
  2303. while assigned(stackitem) do
  2304. begin
  2305. srsymtable:=stackitem^.symtable;
  2306. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2307. if assigned(srsym) then
  2308. begin
  2309. if not(srsymtable.symtabletype in [globalsymtable,staticsymtable]) or
  2310. not(srsym.owner.symtabletype in [globalsymtable,staticsymtable]) or
  2311. (srsym.typ<>procsym) then
  2312. internalerror(2009111505);
  2313. { check whether this procsym includes a helper for this particular class }
  2314. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2315. begin
  2316. { does pd inherit from (or is the same as) the class
  2317. that this method's category extended?
  2318. Warning: this list contains both category and objcclass methods
  2319. (for id.randommethod), so only check category methods here
  2320. }
  2321. defowner:=tobjectdef(tprocdef(tprocsym(srsym).procdeflist[i]).owner.defowner);
  2322. if (oo_is_classhelper in defowner.objectoptions) and
  2323. pd.is_related(defowner.childof) then
  2324. begin
  2325. { we need to know if a procedure references symbols
  2326. in the static symtable, because then it can't be
  2327. inlined from outside this unit }
  2328. if assigned(current_procinfo) and
  2329. (srsym.owner.symtabletype=staticsymtable) then
  2330. include(current_procinfo.flags,pi_uses_static_symtable);
  2331. { no need to keep looking. There might be other
  2332. categories that extend this, a parent or child
  2333. class with a method with the same name (either
  2334. overriding this one, or overridden by this one),
  2335. but that doesn't matter as far as the basic
  2336. procsym is concerned.
  2337. }
  2338. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2339. srsymtable:=srsym.owner;
  2340. addsymref(srsym);
  2341. result:=true;
  2342. exit;
  2343. end;
  2344. end;
  2345. end;
  2346. stackitem:=stackitem^.next;
  2347. end;
  2348. srsym:=nil;
  2349. srsymtable:=nil;
  2350. result:=false;
  2351. end;
  2352. function search_objc_method(const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2353. var
  2354. hashedid : THashedIDString;
  2355. stackitem : psymtablestackitem;
  2356. i : longint;
  2357. begin
  2358. hashedid.id:=class_helper_prefix+s;
  2359. stackitem:=symtablestack.stack;
  2360. while assigned(stackitem) do
  2361. begin
  2362. srsymtable:=stackitem^.symtable;
  2363. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2364. if assigned(srsym) then
  2365. begin
  2366. if not(srsymtable.symtabletype in [globalsymtable,staticsymtable]) or
  2367. not(srsym.owner.symtabletype in [globalsymtable,staticsymtable]) or
  2368. (srsym.typ<>procsym) then
  2369. internalerror(2009112005);
  2370. { check whether this procsym includes a helper for this particular class }
  2371. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2372. begin
  2373. { we need to know if a procedure references symbols
  2374. in the static symtable, because then it can't be
  2375. inlined from outside this unit }
  2376. if assigned(current_procinfo) and
  2377. (srsym.owner.symtabletype=staticsymtable) then
  2378. include(current_procinfo.flags,pi_uses_static_symtable);
  2379. { no need to keep looking. There might be other
  2380. methods with the same name, but that doesn't matter
  2381. as far as the basic procsym is concerned.
  2382. }
  2383. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2384. { We need the symtable in which the classhelper-like sym
  2385. is located, not the objectdef. The reason is that the
  2386. callnode will climb the symtablestack until it encounters
  2387. this symtable to start looking for overloads (and it won't
  2388. find the objectsymtable in which this method sym is
  2389. located
  2390. srsymtable:=srsym.owner;
  2391. }
  2392. addsymref(srsym);
  2393. result:=true;
  2394. exit;
  2395. end;
  2396. end;
  2397. stackitem:=stackitem^.next;
  2398. end;
  2399. srsym:=nil;
  2400. srsymtable:=nil;
  2401. result:=false;
  2402. end;
  2403. function search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
  2404. { searches n in symtable of pd and all anchestors }
  2405. var
  2406. hashedid : THashedIDString;
  2407. srsym : tsym;
  2408. orgpd : tabstractrecorddef;
  2409. srsymtable : tsymtable;
  2410. begin
  2411. { in case this is a formal objcclass, first find the real definition }
  2412. if (oo_is_formal in pd.objectoptions) then
  2413. pd:=find_real_objcclass_definition(tobjectdef(pd),true);
  2414. hashedid.id:=s;
  2415. orgpd:=pd;
  2416. while assigned(pd) do
  2417. begin
  2418. srsym:=tsym(pd.symtable.FindWithHash(hashedid));
  2419. if assigned(srsym) then
  2420. begin
  2421. search_struct_member:=srsym;
  2422. exit;
  2423. end;
  2424. if pd.typ=objectdef then
  2425. pd:=tobjectdef(pd).childof
  2426. else
  2427. pd:=nil;
  2428. end;
  2429. { not found, now look for class helpers }
  2430. if is_objcclass(pd) then
  2431. search_class_helper(tobjectdef(orgpd),s,result,srsymtable)
  2432. else
  2433. result:=nil;
  2434. end;
  2435. function search_macro(const s : string):tsym;
  2436. var
  2437. stackitem : psymtablestackitem;
  2438. hashedid : THashedIDString;
  2439. srsym : tsym;
  2440. begin
  2441. hashedid.id:=s;
  2442. { First search the localmacrosymtable before searching the
  2443. global macrosymtables from the units }
  2444. if assigned(current_module) then
  2445. begin
  2446. srsym:=tsym(current_module.localmacrosymtable.FindWithHash(hashedid));
  2447. if assigned(srsym) then
  2448. begin
  2449. result:= srsym;
  2450. exit;
  2451. end;
  2452. end;
  2453. stackitem:=macrosymtablestack.stack;
  2454. while assigned(stackitem) do
  2455. begin
  2456. srsym:=tsym(stackitem^.symtable.FindWithHash(hashedid));
  2457. if assigned(srsym) then
  2458. begin
  2459. result:= srsym;
  2460. exit;
  2461. end;
  2462. stackitem:=stackitem^.next;
  2463. end;
  2464. result:= nil;
  2465. end;
  2466. function defined_macro(const s : string):boolean;
  2467. var
  2468. mac: tmacro;
  2469. begin
  2470. mac:=tmacro(search_macro(s));
  2471. if assigned(mac) then
  2472. begin
  2473. mac.is_used:=true;
  2474. defined_macro:=mac.defined;
  2475. end
  2476. else
  2477. defined_macro:=false;
  2478. end;
  2479. {****************************************************************************
  2480. Object Helpers
  2481. ****************************************************************************}
  2482. function search_default_property(pd : tobjectdef) : tpropertysym;
  2483. { returns the default property of a class, searches also anchestors }
  2484. var
  2485. _defaultprop : tpropertysym;
  2486. begin
  2487. _defaultprop:=nil;
  2488. while assigned(pd) do
  2489. begin
  2490. pd.symtable.SymList.ForEachCall(@tstoredsymtable(pd.symtable).testfordefaultproperty,@_defaultprop);
  2491. if assigned(_defaultprop) then
  2492. break;
  2493. pd:=pd.childof;
  2494. end;
  2495. search_default_property:=_defaultprop;
  2496. end;
  2497. {****************************************************************************
  2498. Macro Helpers
  2499. ****************************************************************************}
  2500. procedure def_system_macro(const name : string);
  2501. var
  2502. mac : tmacro;
  2503. s: string;
  2504. begin
  2505. if name = '' then
  2506. internalerror(2004121202);
  2507. s:= upper(name);
  2508. mac:=tmacro(search_macro(s));
  2509. if not assigned(mac) then
  2510. begin
  2511. mac:=tmacro.create(s);
  2512. if assigned(current_module) then
  2513. current_module.localmacrosymtable.insert(mac)
  2514. else
  2515. initialmacrosymtable.insert(mac);
  2516. end;
  2517. if not mac.defined then
  2518. Message1(parser_c_macro_defined,mac.name);
  2519. mac.defined:=true;
  2520. end;
  2521. procedure set_system_macro(const name, value : string);
  2522. var
  2523. mac : tmacro;
  2524. s: string;
  2525. begin
  2526. if name = '' then
  2527. internalerror(2004121203);
  2528. s:= upper(name);
  2529. mac:=tmacro(search_macro(s));
  2530. if not assigned(mac) then
  2531. begin
  2532. mac:=tmacro.create(s);
  2533. if assigned(current_module) then
  2534. current_module.localmacrosymtable.insert(mac)
  2535. else
  2536. initialmacrosymtable.insert(mac);
  2537. end
  2538. else
  2539. begin
  2540. mac.is_compiler_var:=false;
  2541. if assigned(mac.buftext) then
  2542. freemem(mac.buftext,mac.buflen);
  2543. end;
  2544. Message2(parser_c_macro_set_to,mac.name,value);
  2545. mac.buflen:=length(value);
  2546. getmem(mac.buftext,mac.buflen);
  2547. move(value[1],mac.buftext^,mac.buflen);
  2548. mac.defined:=true;
  2549. end;
  2550. procedure set_system_compvar(const name, value : string);
  2551. var
  2552. mac : tmacro;
  2553. s: string;
  2554. begin
  2555. if name = '' then
  2556. internalerror(2004121204);
  2557. s:= upper(name);
  2558. mac:=tmacro(search_macro(s));
  2559. if not assigned(mac) then
  2560. begin
  2561. mac:=tmacro.create(s);
  2562. mac.is_compiler_var:=true;
  2563. if assigned(current_module) then
  2564. current_module.localmacrosymtable.insert(mac)
  2565. else
  2566. initialmacrosymtable.insert(mac);
  2567. end
  2568. else
  2569. begin
  2570. mac.is_compiler_var:=true;
  2571. if assigned(mac.buftext) then
  2572. freemem(mac.buftext,mac.buflen);
  2573. end;
  2574. Message2(parser_c_macro_set_to,mac.name,value);
  2575. mac.buflen:=length(value);
  2576. getmem(mac.buftext,mac.buflen);
  2577. move(value[1],mac.buftext^,mac.buflen);
  2578. mac.defined:=true;
  2579. end;
  2580. procedure undef_system_macro(const name : string);
  2581. var
  2582. mac : tmacro;
  2583. s: string;
  2584. begin
  2585. if name = '' then
  2586. internalerror(2004121205);
  2587. s:= upper(name);
  2588. mac:=tmacro(search_macro(s));
  2589. if not assigned(mac) then
  2590. {If not found, then it's already undefined.}
  2591. else
  2592. begin
  2593. if mac.defined then
  2594. Message1(parser_c_macro_undefined,mac.name);
  2595. mac.defined:=false;
  2596. mac.is_compiler_var:=false;
  2597. { delete old definition }
  2598. if assigned(mac.buftext) then
  2599. begin
  2600. freemem(mac.buftext,mac.buflen);
  2601. mac.buftext:=nil;
  2602. end;
  2603. end;
  2604. end;
  2605. {$ifdef UNITALIASES}
  2606. {****************************************************************************
  2607. TUNIT_ALIAS
  2608. ****************************************************************************}
  2609. constructor tunit_alias.create(const n:string);
  2610. var
  2611. i : longint;
  2612. begin
  2613. i:=pos('=',n);
  2614. if i=0 then
  2615. fail;
  2616. inherited createname(Copy(n,1,i-1));
  2617. newname:=stringdup(Copy(n,i+1,255));
  2618. end;
  2619. destructor tunit_alias.destroy;
  2620. begin
  2621. stringdispose(newname);
  2622. inherited destroy;
  2623. end;
  2624. procedure addunitalias(const n:string);
  2625. begin
  2626. unitaliases^.insert(tunit_alias,init(Upper(n))));
  2627. end;
  2628. function getunitalias(const n:string):string;
  2629. var
  2630. p : punit_alias;
  2631. begin
  2632. p:=punit_alias(unitaliases^.Find(Upper(n)));
  2633. if assigned(p) then
  2634. getunitalias:=punit_alias(p).newname^
  2635. else
  2636. getunitalias:=n;
  2637. end;
  2638. {$endif UNITALIASES}
  2639. {****************************************************************************
  2640. Init/Done Symtable
  2641. ****************************************************************************}
  2642. procedure InitSymtable;
  2643. begin
  2644. { Reset symbolstack }
  2645. symtablestack:=nil;
  2646. systemunit:=nil;
  2647. { create error syms and def }
  2648. generrorsym:=terrorsym.create;
  2649. generrordef:=terrordef.create;
  2650. { macros }
  2651. initialmacrosymtable:=tmacrosymtable.create(false);
  2652. macrosymtablestack:=TSymtablestack.create;
  2653. macrosymtablestack.push(initialmacrosymtable);
  2654. {$ifdef UNITALIASES}
  2655. { unit aliases }
  2656. unitaliases:=TFPHashObjectList.create;
  2657. {$endif}
  2658. { set some global vars to nil, might be important for the ide }
  2659. class_tobject:=nil;
  2660. interface_iunknown:=nil;
  2661. interface_idispatch:=nil;
  2662. rec_tguid:=nil;
  2663. dupnr:=0;
  2664. end;
  2665. procedure DoneSymtable;
  2666. begin
  2667. generrorsym.owner:=nil;
  2668. generrorsym.free;
  2669. generrordef.owner:=nil;
  2670. generrordef.free;
  2671. initialmacrosymtable.free;
  2672. macrosymtablestack.free;
  2673. {$ifdef UNITALIASES}
  2674. unitaliases.free;
  2675. {$endif}
  2676. end;
  2677. end.