symtable.pas 121 KB

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