symsym.pas 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  4. Implementation for the symbols types of the symtable
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symsym;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,
  24. { target }
  25. globtype,globals,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,defcmp,
  28. { ppu }
  29. ppu,symppu,
  30. cclasses,symnot,
  31. { aasm }
  32. aasmbase,aasmtai,
  33. cpuinfo,cpubase,cgbase
  34. ;
  35. type
  36. {************************************************
  37. TSym
  38. ************************************************}
  39. { this object is the base for all symbol objects }
  40. tstoredsym = class(tsym)
  41. protected
  42. _mangledname : pstring;
  43. public
  44. refs : longint;
  45. lastref,
  46. defref,
  47. lastwritten : tref;
  48. refcount : longint;
  49. {$ifdef GDB}
  50. isstabwritten : boolean;
  51. {$endif GDB}
  52. constructor create(const n : string);
  53. constructor loadsym(ppufile:tcompilerppufile);
  54. destructor destroy;override;
  55. procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
  56. procedure writesym(ppufile:tcompilerppufile);
  57. procedure buildderef;override;
  58. procedure deref;override;
  59. {$ifdef GDB}
  60. function get_var_value(const s:string):string;
  61. function stabstr_evaluate(s:string;vars:array of string):Pchar;
  62. function stabstring : pchar;virtual;
  63. procedure concatstabto(asmlist : taasmoutput);virtual;
  64. {$endif GDB}
  65. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  66. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  67. function is_visible_for_object(currobjdef:tobjectdef):boolean;
  68. function mangledname : string;
  69. procedure generate_mangledname;virtual;abstract;
  70. end;
  71. tlabelsym = class(tstoredsym)
  72. lab : tasmlabel;
  73. used,
  74. defined : boolean;
  75. code : pointer; { should be tnode }
  76. constructor create(const n : string; l : tasmlabel);
  77. destructor destroy;override;
  78. constructor ppuload(ppufile:tcompilerppufile);
  79. procedure generate_mangledname;override;
  80. procedure ppuwrite(ppufile:tcompilerppufile);override;
  81. end;
  82. tunitsym = class(tstoredsym)
  83. unitsymtable : tsymtable;
  84. constructor create(const n : string;ref : tsymtable);
  85. constructor ppuload(ppufile:tcompilerppufile);
  86. destructor destroy;override;
  87. procedure ppuwrite(ppufile:tcompilerppufile);override;
  88. {$ifdef GDB}
  89. procedure concatstabto(asmlist : taasmoutput);override;
  90. {$endif GDB}
  91. end;
  92. terrorsym = class(tstoredsym)
  93. constructor create;
  94. end;
  95. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  96. tprocsym = class(tstoredsym)
  97. protected
  98. pdlistfirst,
  99. pdlistlast : pprocdeflist; { linked list of overloaded procdefs }
  100. function getprocdef(nr:cardinal):Tprocdef;
  101. public
  102. procdef_count : byte;
  103. {$ifdef GDB}
  104. is_global : boolean;
  105. {$endif GDB}
  106. overloadchecked : boolean;
  107. overloadcount : word; { amount of overloaded functions in this module }
  108. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  109. constructor create(const n : string);
  110. constructor ppuload(ppufile:tcompilerppufile);
  111. destructor destroy;override;
  112. { writes all declarations except the specified one }
  113. procedure write_parameter_lists(skipdef:tprocdef);
  114. { tests, if all procedures definitions are defined and not }
  115. { only forward }
  116. procedure check_forward;
  117. procedure unchain_overload;
  118. procedure ppuwrite(ppufile:tcompilerppufile);override;
  119. procedure buildderef;override;
  120. procedure deref;override;
  121. procedure addprocdef(p:tprocdef);
  122. procedure addprocdef_deref(const d:tderef);
  123. procedure add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  124. procedure concat_procdefs_to(s:Tprocsym);
  125. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  126. function first_procdef:Tprocdef;
  127. function last_procdef:Tprocdef;
  128. function search_procdef_nopara_boolret:Tprocdef;
  129. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  130. function search_procdef_bypara(params:Tlinkedlist;
  131. retdef:tdef;
  132. cpoptions:tcompare_paras_options):Tprocdef;
  133. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  134. function search_procdef_unary_operator(firstpara:Tdef):Tprocdef;
  135. function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  136. function search_procdef_binary_operator(def1,def2:tdef):Tprocdef;
  137. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  138. {$ifdef GDB}
  139. function stabstring : pchar;override;
  140. procedure concatstabto(asmlist : taasmoutput);override;
  141. {$endif GDB}
  142. end;
  143. ttypesym = class(tstoredsym)
  144. restype : ttype;
  145. {$ifdef GDB}
  146. isusedinstab : boolean;
  147. {$endif GDB}
  148. constructor create(const n : string;const tt : ttype);
  149. constructor ppuload(ppufile:tcompilerppufile);
  150. procedure ppuwrite(ppufile:tcompilerppufile);override;
  151. procedure buildderef;override;
  152. procedure deref;override;
  153. function gettypedef:tdef;override;
  154. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  155. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  156. {$ifdef GDB}
  157. function stabstring : pchar;override;
  158. procedure concatstabto(asmlist : taasmoutput);override;
  159. {$endif GDB}
  160. end;
  161. tvarsym = class(tstoredsym)
  162. highvarsym : tvarsym;
  163. defaultconstsym : tsym;
  164. varoptions : tvaroptions;
  165. varspez : tvarspez; { sets the type of access }
  166. varstate : tvarstate;
  167. localloc : tparalocation; { register/reference for local var }
  168. fieldoffset : longint; { offset in record/object }
  169. paraitem : tparaitem;
  170. notifications : Tlinkedlist;
  171. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  172. constructor create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  173. constructor create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  174. constructor ppuload(ppufile:tcompilerppufile);
  175. destructor destroy;override;
  176. procedure ppuwrite(ppufile:tcompilerppufile);override;
  177. procedure buildderef;override;
  178. procedure deref;override;
  179. procedure generate_mangledname;override;
  180. procedure set_mangledname(const s:string);
  181. function getsize : longint;
  182. function getvaluesize : longint;
  183. procedure trigger_notifications(what:Tnotification_flag);
  184. function register_notification(flags:Tnotification_flags;
  185. callback:Tnotification_callback):cardinal;
  186. procedure unregister_notification(id:cardinal);
  187. {$ifdef GDB}
  188. function stabstring : pchar;override;
  189. procedure concatstabto(asmlist : taasmoutput);override;
  190. {$endif GDB}
  191. private
  192. procedure setvartype(const newtype: ttype);
  193. _vartype : ttype;
  194. public
  195. property vartype: ttype read _vartype write setvartype;
  196. end;
  197. tpropertysym = class(tstoredsym)
  198. propoptions : tpropertyoptions;
  199. propoverriden : tpropertysym;
  200. propoverridenderef : tderef;
  201. proptype,
  202. indextype : ttype;
  203. index,
  204. default : longint;
  205. readaccess,
  206. writeaccess,
  207. storedaccess : tsymlist;
  208. constructor create(const n : string);
  209. destructor destroy;override;
  210. constructor ppuload(ppufile:tcompilerppufile);
  211. function getsize : longint;
  212. procedure ppuwrite(ppufile:tcompilerppufile);override;
  213. function gettypedef:tdef;override;
  214. procedure buildderef;override;
  215. procedure deref;override;
  216. procedure dooverride(overriden:tpropertysym);
  217. {$ifdef GDB}
  218. function stabstring : pchar;override;
  219. procedure concatstabto(asmlist : taasmoutput);override;
  220. {$endif GDB}
  221. end;
  222. tabsolutesym = class(tvarsym)
  223. abstyp : absolutetyp;
  224. absseg : boolean;
  225. asmname : pstring;
  226. ref : tsymlist;
  227. constructor create(const n : string;const tt : ttype);
  228. constructor create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  229. destructor destroy;override;
  230. constructor ppuload(ppufile:tcompilerppufile);
  231. procedure buildderef;override;
  232. procedure deref;override;
  233. function mangledname : string;
  234. procedure ppuwrite(ppufile:tcompilerppufile);override;
  235. {$ifdef GDB}
  236. procedure concatstabto(asmlist : taasmoutput);override;
  237. {$endif GDB}
  238. end;
  239. ttypedconstsym = class(tstoredsym)
  240. typedconsttype : ttype;
  241. is_writable : boolean;
  242. constructor create(const n : string;p : tdef;writable : boolean);
  243. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  244. constructor ppuload(ppufile:tcompilerppufile);
  245. destructor destroy;override;
  246. procedure generate_mangledname;override;
  247. procedure ppuwrite(ppufile:tcompilerppufile);override;
  248. procedure buildderef;override;
  249. procedure deref;override;
  250. function getsize:longint;
  251. {$ifdef GDB}
  252. function stabstring : pchar;override;
  253. {$endif GDB}
  254. end;
  255. tconstvalue = record
  256. case integer of
  257. 0: (valueord : tconstexprint);
  258. 1: (valueordptr : tconstptruint);
  259. 2: (valueptr : pointer; len : longint);
  260. end;
  261. tconstsym = class(tstoredsym)
  262. consttype : ttype;
  263. consttyp : tconsttyp;
  264. value : tconstvalue;
  265. resstrindex : longint; { needed for resource strings }
  266. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint);
  267. constructor create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  268. constructor create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  269. constructor create_ptr(const n : string;t : tconsttyp;v : pointer);
  270. constructor create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  271. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  272. constructor ppuload(ppufile:tcompilerppufile);
  273. destructor destroy;override;
  274. function mangledname : string;
  275. procedure buildderef;override;
  276. procedure deref;override;
  277. procedure ppuwrite(ppufile:tcompilerppufile);override;
  278. {$ifdef GDB}
  279. function stabstring : pchar;override;
  280. procedure concatstabto(asmlist : taasmoutput);override;
  281. {$endif GDB}
  282. end;
  283. tenumsym = class(tstoredsym)
  284. value : longint;
  285. definition : tenumdef;
  286. definitionderef : tderef;
  287. nextenum : tenumsym;
  288. constructor create(const n : string;def : tenumdef;v : longint);
  289. constructor ppuload(ppufile:tcompilerppufile);
  290. procedure ppuwrite(ppufile:tcompilerppufile);override;
  291. procedure buildderef;override;
  292. procedure deref;override;
  293. procedure order;
  294. {$ifdef GDB}
  295. procedure concatstabto(asmlist : taasmoutput);override;
  296. {$endif GDB}
  297. end;
  298. tsyssym = class(tstoredsym)
  299. number : longint;
  300. constructor create(const n : string;l : longint);
  301. constructor ppuload(ppufile:tcompilerppufile);
  302. destructor destroy;override;
  303. procedure ppuwrite(ppufile:tcompilerppufile);override;
  304. {$ifdef GDB}
  305. procedure concatstabto(asmlist : taasmoutput);override;
  306. {$endif GDB}
  307. end;
  308. { compiler generated symbol to point to rtti and init/finalize tables }
  309. trttisym = class(tstoredsym)
  310. lab : tasmsymbol;
  311. rttityp : trttitype;
  312. constructor create(const n:string;rt:trttitype);
  313. constructor ppuload(ppufile:tcompilerppufile);
  314. procedure ppuwrite(ppufile:tcompilerppufile);override;
  315. function mangledname:string;
  316. function get_label:tasmsymbol;
  317. end;
  318. (*
  319. { register variables }
  320. pregvarinfo = ^tregvarinfo;
  321. tregvarinfo = record
  322. regvars : array[1..maxvarregs] of tvarsym;
  323. regvars_para : array[1..maxvarregs] of boolean;
  324. regvars_refs : array[1..maxvarregs] of longint;
  325. fpuregvars : array[1..maxfpuvarregs] of tvarsym;
  326. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  327. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  328. end;
  329. *)
  330. var
  331. generrorsym : tsym;
  332. const
  333. current_object_option : tsymoptions = [sp_public];
  334. { rtti and init/final }
  335. procedure generate_rtti(p:tsym);
  336. procedure generate_inittable(p:tsym);
  337. implementation
  338. uses
  339. {$ifdef Delphi}
  340. sysutils,
  341. {$else Delphi}
  342. strings,
  343. {$endif Delphi}
  344. { global }
  345. verbose,
  346. { target }
  347. systems,
  348. { symtable }
  349. defutil,symtable,
  350. {$ifdef GDB}
  351. gdb,
  352. {$endif GDB}
  353. { tree }
  354. node,
  355. { aasm }
  356. aasmcpu,
  357. { module }
  358. fmodule,
  359. { codegen }
  360. paramgr,cresstr,
  361. procinfo
  362. ;
  363. {****************************************************************************
  364. Helpers
  365. ****************************************************************************}
  366. {****************************************************************************
  367. TSYM (base for all symtypes)
  368. ****************************************************************************}
  369. constructor tstoredsym.create(const n : string);
  370. begin
  371. inherited create(n);
  372. symoptions:=current_object_option;
  373. {$ifdef GDB}
  374. isstabwritten := false;
  375. {$endif GDB}
  376. fileinfo:=akttokenpos;
  377. defref:=nil;
  378. refs:=0;
  379. lastwritten:=nil;
  380. refcount:=0;
  381. if (cs_browser in aktmoduleswitches) and make_ref then
  382. begin
  383. defref:=tref.create(defref,@akttokenpos);
  384. inc(refcount);
  385. end;
  386. lastref:=defref;
  387. _mangledname:=nil;
  388. end;
  389. constructor tstoredsym.loadsym(ppufile:tcompilerppufile);
  390. var
  391. s : string;
  392. nr : word;
  393. begin
  394. nr:=ppufile.getword;
  395. s:=ppufile.getstring;
  396. inherited create(s);
  397. { force the correct indexnr. must be after create! }
  398. indexnr:=nr;
  399. ppufile.getposinfo(fileinfo);
  400. ppufile.getsmallset(symoptions);
  401. lastref:=nil;
  402. defref:=nil;
  403. refs:=0;
  404. lastwritten:=nil;
  405. refcount:=0;
  406. _mangledname:=nil;
  407. {$ifdef GDB}
  408. isstabwritten := false;
  409. {$endif GDB}
  410. end;
  411. procedure tstoredsym.buildderef;
  412. begin
  413. end;
  414. procedure tstoredsym.deref;
  415. begin
  416. end;
  417. procedure tstoredsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  418. var
  419. pos : tfileposinfo;
  420. move_last : boolean;
  421. begin
  422. move_last:=lastwritten=lastref;
  423. while (not ppufile.endofentry) do
  424. begin
  425. ppufile.getposinfo(pos);
  426. inc(refcount);
  427. lastref:=tref.create(lastref,@pos);
  428. lastref.is_written:=true;
  429. if refcount=1 then
  430. defref:=lastref;
  431. end;
  432. if move_last then
  433. lastwritten:=lastref;
  434. end;
  435. { big problem here :
  436. wrong refs were written because of
  437. interface parsing of other units PM
  438. moduleindex must be checked !! }
  439. function tstoredsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  440. var
  441. d : tderef;
  442. ref : tref;
  443. symref_written,move_last : boolean;
  444. begin
  445. write_references:=false;
  446. if lastwritten=lastref then
  447. exit;
  448. { should we update lastref }
  449. move_last:=true;
  450. symref_written:=false;
  451. { write symbol refs }
  452. d.reset;
  453. if assigned(lastwritten) then
  454. ref:=lastwritten
  455. else
  456. ref:=defref;
  457. while assigned(ref) do
  458. begin
  459. if ref.moduleindex=current_module.unit_index then
  460. begin
  461. { write address to this symbol }
  462. if not symref_written then
  463. begin
  464. d.build(self);
  465. ppufile.putderef(d);
  466. symref_written:=true;
  467. end;
  468. ppufile.putposinfo(ref.posinfo);
  469. ref.is_written:=true;
  470. if move_last then
  471. lastwritten:=ref;
  472. end
  473. else if not ref.is_written then
  474. move_last:=false
  475. else if move_last then
  476. lastwritten:=ref;
  477. ref:=ref.nextref;
  478. end;
  479. if symref_written then
  480. ppufile.writeentry(ibsymref);
  481. write_references:=symref_written;
  482. end;
  483. destructor tstoredsym.destroy;
  484. begin
  485. if assigned(_mangledname) then
  486. begin
  487. {$ifdef MEMDEBUG}
  488. memmanglednames.start;
  489. {$endif MEMDEBUG}
  490. stringdispose(_mangledname);
  491. {$ifdef MEMDEBUG}
  492. memmanglednames.stop;
  493. {$endif MEMDEBUG}
  494. end;
  495. if assigned(defref) then
  496. begin
  497. {$ifdef MEMDEBUG}
  498. membrowser.start;
  499. {$endif MEMDEBUG}
  500. defref.freechain;
  501. defref.free;
  502. {$ifdef MEMDEBUG}
  503. membrowser.stop;
  504. {$endif MEMDEBUG}
  505. end;
  506. inherited destroy;
  507. end;
  508. procedure tstoredsym.writesym(ppufile:tcompilerppufile);
  509. begin
  510. ppufile.putword(indexnr);
  511. ppufile.putstring(_realname^);
  512. ppufile.putposinfo(fileinfo);
  513. ppufile.putsmallset(symoptions);
  514. end;
  515. {$ifdef GDB}
  516. function Tstoredsym.get_var_value(const s:string):string;
  517. begin
  518. if s='name' then
  519. get_var_value:=name
  520. else if s='ownername' then
  521. get_var_value:=owner.name^
  522. else if s='mangledname' then
  523. get_var_value:=mangledname
  524. else if s='line' then
  525. get_var_value:=tostr(fileinfo.line)
  526. else if s='N_LSYM' then
  527. get_var_value:=tostr(N_LSYM)
  528. else if s='N_LCSYM' then
  529. get_var_value:=tostr(N_LCSYM)
  530. else if s='N_RSYM' then
  531. get_var_value:=tostr(N_RSYM)
  532. else if s='N_TSYM' then
  533. get_var_value:=tostr(N_TSYM)
  534. else if s='N_STSYM' then
  535. get_var_value:=tostr(N_STSYM)
  536. else if s='N_FUNCTION' then
  537. get_var_value:=tostr(N_FUNCTION)
  538. else
  539. internalerror(200401152);
  540. end;
  541. function Tstoredsym.stabstr_evaluate(s:string;vars:array of string):Pchar;
  542. {S contains a prototype of a stabstring. Stabstr_evaluate will expand
  543. variables and parameters.
  544. Output is s in ASCIIZ format, with the following expanded:
  545. ${varname} - The variable name is expanded.
  546. $n - The parameter n is expanded.
  547. $$ - Is expanded to $
  548. }
  549. const maxvalue=9;
  550. maxdata=1023;
  551. var i,j:byte;
  552. varname:string[63];
  553. varno,varcounter:byte;
  554. varvalues:array[0..9] of Pstring;
  555. {1 kb of parameters is the limit. 256 extra bytes are allocated to
  556. ensure buffer integrity.}
  557. varvaluedata:array[0..maxdata+256] of char;
  558. varptr:Pchar;
  559. len:cardinal;
  560. r:Pchar;
  561. begin
  562. {Two pass approach, first, calculate the length and receive variables.}
  563. i:=1;
  564. len:=0;
  565. varcounter:=0;
  566. varptr:=@varvaluedata;
  567. while i<=length(s) do
  568. begin
  569. if (s[i]='$') and (i<length(s)) then
  570. begin
  571. if s[i+1]='$' then
  572. begin
  573. inc(len);
  574. inc(i);
  575. end
  576. else if (s[i+1]='{') and (length(s)>2) and (i<length(s)-2) then
  577. begin
  578. varname:='';
  579. inc(i,2);
  580. repeat
  581. inc(varname[0]);
  582. varname[length(varname)]:=s[i];
  583. s[i]:=char(varcounter);
  584. inc(i);
  585. until s[i]='}';
  586. varvalues[varcounter]:=Pstring(varptr);
  587. if varptr>(@varvaluedata+maxdata) then
  588. internalerror(200401151);
  589. Pstring(varptr)^:=get_var_value(varname);
  590. inc(len,length(Pstring(varptr)^));
  591. inc(varptr,length(Pstring(varptr)^)+1);
  592. inc(varcounter);
  593. end
  594. else if s[i+1] in ['0'..'9'] then
  595. begin
  596. inc(len,length(vars[byte(s[i+1])-byte('1')]));
  597. inc(i);
  598. end;
  599. end
  600. else
  601. inc(len);
  602. inc(i);
  603. end;
  604. {Second pass, writeout stabstring.}
  605. getmem(r,len+1);
  606. stabstr_evaluate:=r;
  607. i:=1;
  608. while i<=length(s) do
  609. begin
  610. if (s[i]='$') and (i<length(s)) then
  611. begin
  612. if s[i+1]='$' then
  613. begin
  614. r^:='$';
  615. inc(r);
  616. inc(i);
  617. end
  618. else if (s[i+1]='{') and (length(s)>2) and (i<length(s)-2) then
  619. begin
  620. varname:='';
  621. inc(i,2);
  622. varno:=byte(s[i]);
  623. repeat
  624. inc(i);
  625. until s[i]='}';
  626. for j:=1 to length(varvalues[varno]^) do
  627. begin
  628. r^:=varvalues[varno]^[j];
  629. inc(r);
  630. end;
  631. end
  632. else if s[i+1] in ['0'..'9'] then
  633. begin
  634. for j:=1 to length(vars[byte(s[i+1])-byte('1')]) do
  635. begin
  636. r^:=vars[byte(s[i+1])-byte('1')][j];
  637. inc(r);
  638. end;
  639. inc(i);
  640. end
  641. end
  642. else
  643. begin
  644. r^:=s[i];
  645. inc(r);
  646. end;
  647. inc(i);
  648. end;
  649. if (r-stabstr_evaluate<>len) then
  650. internalerror(5);
  651. r^:=#0;
  652. end;
  653. function tstoredsym.stabstring : pchar;
  654. begin
  655. stabstring:=stabstr_evaluate('"${name}",${N_LSYM},0,${line},0',[]);
  656. end;
  657. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  658. var
  659. stab_str : pchar;
  660. begin
  661. if not isstabwritten then
  662. begin
  663. stab_str := stabstring;
  664. if assigned(stab_str) then
  665. asmList.concat(Tai_stabs.Create(stab_str));
  666. isstabwritten:=true;
  667. end;
  668. end;
  669. {$endif GDB}
  670. function tstoredsym.is_visible_for_object(currobjdef:tobjectdef):boolean;
  671. begin
  672. is_visible_for_object:=false;
  673. { private symbols are allowed when we are in the same
  674. module as they are defined }
  675. if (sp_private in symoptions) and
  676. assigned(owner.defowner) and
  677. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  678. (owner.defowner.owner.unitid<>0) then
  679. exit;
  680. { protected symbols are vissible in the module that defines them and
  681. also visible to related objects }
  682. if (sp_protected in symoptions) and
  683. (
  684. (
  685. assigned(owner.defowner) and
  686. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  687. (owner.defowner.owner.unitid<>0)
  688. ) and
  689. not(
  690. assigned(currobjdef) and
  691. currobjdef.is_related(tobjectdef(owner.defowner))
  692. )
  693. ) then
  694. exit;
  695. is_visible_for_object:=true;
  696. end;
  697. function tstoredsym.mangledname : string;
  698. begin
  699. if not assigned(_mangledname) then
  700. begin
  701. generate_mangledname;
  702. if not assigned(_mangledname) then
  703. internalerror(200204171);
  704. end;
  705. {$ifdef compress}
  706. mangledname:=minilzw_decode(_mangledname^)
  707. {$else}
  708. mangledname:=_mangledname^
  709. {$endif}
  710. end;
  711. {****************************************************************************
  712. TLABELSYM
  713. ****************************************************************************}
  714. constructor tlabelsym.create(const n : string; l : tasmlabel);
  715. begin
  716. inherited create(n);
  717. typ:=labelsym;
  718. lab:=l;
  719. used:=false;
  720. defined:=false;
  721. code:=nil;
  722. end;
  723. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  724. begin
  725. inherited loadsym(ppufile);
  726. typ:=labelsym;
  727. { this is all dummy
  728. it is only used for local browsing }
  729. lab:=nil;
  730. code:=nil;
  731. used:=false;
  732. defined:=true;
  733. end;
  734. destructor tlabelsym.destroy;
  735. begin
  736. inherited destroy;
  737. end;
  738. procedure tlabelsym.generate_mangledname;
  739. begin
  740. {$ifdef compress}
  741. _mangledname:=stringdup(minilzw_encode(lab.name));
  742. {$else}
  743. _mangledname:=stringdup(lab.name);
  744. {$endif}
  745. end;
  746. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  747. begin
  748. if owner.symtabletype=globalsymtable then
  749. Message(sym_e_ill_label_decl)
  750. else
  751. begin
  752. inherited writesym(ppufile);
  753. ppufile.writeentry(iblabelsym);
  754. end;
  755. end;
  756. {****************************************************************************
  757. TUNITSYM
  758. ****************************************************************************}
  759. constructor tunitsym.create(const n : string;ref : tsymtable);
  760. var
  761. old_make_ref : boolean;
  762. begin
  763. old_make_ref:=make_ref;
  764. make_ref:=false;
  765. inherited create(n);
  766. make_ref:=old_make_ref;
  767. typ:=unitsym;
  768. unitsymtable:=ref;
  769. end;
  770. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  771. begin
  772. inherited loadsym(ppufile);
  773. typ:=unitsym;
  774. unitsymtable:=nil;
  775. refs:=0;
  776. end;
  777. destructor tunitsym.destroy;
  778. begin
  779. inherited destroy;
  780. end;
  781. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  782. begin
  783. inherited writesym(ppufile);
  784. ppufile.writeentry(ibunitsym);
  785. end;
  786. {$ifdef GDB}
  787. procedure tunitsym.concatstabto(asmlist : taasmoutput);
  788. begin
  789. {Nothing to write to stabs !}
  790. end;
  791. {$endif GDB}
  792. {****************************************************************************
  793. TPROCSYM
  794. ****************************************************************************}
  795. constructor tprocsym.create(const n : string);
  796. begin
  797. inherited create(n);
  798. typ:=procsym;
  799. pdlistfirst:=nil;
  800. pdlistlast:=nil;
  801. owner:=nil;
  802. {$ifdef GDB}
  803. is_global:=false;
  804. {$endif GDB}
  805. overloadchecked:=false;
  806. overloadcount:=0;
  807. procdef_count:=0;
  808. end;
  809. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  810. var
  811. pdderef : tderef;
  812. i,n : longint;
  813. begin
  814. inherited loadsym(ppufile);
  815. typ:=procsym;
  816. pdlistfirst:=nil;
  817. pdlistlast:=nil;
  818. procdef_count:=0;
  819. n:=ppufile.getword;
  820. for i:=1to n do
  821. begin
  822. ppufile.getderef(pdderef);
  823. addprocdef_deref(pdderef);
  824. end;
  825. {$ifdef GDB}
  826. is_global:=false;
  827. {$endif GDB}
  828. overloadchecked:=false;
  829. overloadcount:=$ffff; { invalid, not used anymore }
  830. end;
  831. destructor tprocsym.destroy;
  832. var
  833. hp,p : pprocdeflist;
  834. begin
  835. p:=pdlistfirst;
  836. while assigned(p) do
  837. begin
  838. hp:=p^.next;
  839. dispose(p);
  840. p:=hp;
  841. end;
  842. inherited destroy;
  843. end;
  844. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  845. var
  846. p : pprocdeflist;
  847. n : word;
  848. begin
  849. inherited writesym(ppufile);
  850. { count procdefs }
  851. n:=0;
  852. p:=pdlistfirst;
  853. while assigned(p) do
  854. begin
  855. { only write the proc definitions that belong
  856. to this procsym and are in the global symtable }
  857. if p^.own and
  858. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  859. inc(n);
  860. p:=p^.next;
  861. end;
  862. ppufile.putword(n);
  863. { write procdefs }
  864. p:=pdlistfirst;
  865. while assigned(p) do
  866. begin
  867. { only write the proc definitions that belong
  868. to this procsym and are in the global symtable }
  869. if p^.own and
  870. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  871. ppufile.putderef(p^.defderef);
  872. p:=p^.next;
  873. end;
  874. ppufile.writeentry(ibprocsym);
  875. end;
  876. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  877. var
  878. p : pprocdeflist;
  879. begin
  880. p:=pdlistfirst;
  881. while assigned(p) do
  882. begin
  883. if p^.def<>skipdef then
  884. MessagePos1(p^.def.fileinfo,sym_h_param_list,p^.def.fullprocname(false));
  885. p:=p^.next;
  886. end;
  887. end;
  888. procedure tprocsym.check_forward;
  889. var
  890. p : pprocdeflist;
  891. begin
  892. p:=pdlistfirst;
  893. while assigned(p) do
  894. begin
  895. if p^.own and
  896. (p^.def.forwarddef) then
  897. begin
  898. MessagePos1(p^.def.fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname(false));
  899. { Turn futher error messages off }
  900. p^.def.forwarddef:=false;
  901. end;
  902. p:=p^.next;
  903. end;
  904. end;
  905. procedure tprocsym.buildderef;
  906. var
  907. p : pprocdeflist;
  908. begin
  909. p:=pdlistfirst;
  910. while assigned(p) do
  911. begin
  912. if p^.own then
  913. p^.defderef.build(p^.def);
  914. p:=p^.next;
  915. end;
  916. end;
  917. procedure tprocsym.deref;
  918. var
  919. p : pprocdeflist;
  920. begin
  921. { We have removed the overloaded entries, because they
  922. are not valid anymore and we can't deref them because
  923. the unit were they come from is not necessary in
  924. our uses clause (PFV) }
  925. unchain_overload;
  926. { Deref our own procdefs }
  927. p:=pdlistfirst;
  928. while assigned(p) do
  929. begin
  930. if not p^.own then
  931. internalerror(200310291);
  932. p^.def:=tprocdef(p^.defderef.resolve);
  933. p:=p^.next;
  934. end;
  935. end;
  936. procedure tprocsym.addprocdef(p:tprocdef);
  937. var
  938. pd : pprocdeflist;
  939. begin
  940. new(pd);
  941. pd^.def:=p;
  942. pd^.defderef.reset;
  943. pd^.next:=nil;
  944. pd^.own:=(pd^.def.procsym=self);
  945. { Add at end of list to keep always
  946. a correct order, also after loading from ppu }
  947. if assigned(pdlistlast) then
  948. begin
  949. pdlistlast^.next:=pd;
  950. pdlistlast:=pd;
  951. end
  952. else
  953. begin
  954. pdlistfirst:=pd;
  955. pdlistlast:=pd;
  956. end;
  957. inc(procdef_count);
  958. end;
  959. procedure tprocsym.addprocdef_deref(const d:tderef);
  960. var
  961. pd : pprocdeflist;
  962. begin
  963. new(pd);
  964. pd^.def:=nil;
  965. pd^.defderef:=d;
  966. pd^.next:=nil;
  967. pd^.own:=true;
  968. { Add at end of list to keep always
  969. a correct order, also after loading from ppu }
  970. if assigned(pdlistlast) then
  971. begin
  972. pdlistlast^.next:=pd;
  973. pdlistlast:=pd;
  974. end
  975. else
  976. begin
  977. pdlistfirst:=pd;
  978. pdlistlast:=pd;
  979. end;
  980. inc(procdef_count);
  981. end;
  982. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  983. var
  984. i : cardinal;
  985. pd : pprocdeflist;
  986. begin
  987. pd:=pdlistfirst;
  988. for i:=2 to nr do
  989. begin
  990. if not assigned(pd) then
  991. internalerror(200209051);
  992. pd:=pd^.next;
  993. end;
  994. getprocdef:=pd^.def;
  995. end;
  996. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  997. var
  998. pd:pprocdeflist;
  999. begin
  1000. pd:=pdlistfirst;
  1001. while assigned(pd) do
  1002. begin
  1003. if Aprocsym.search_procdef_bypara(pd^.def.para,nil,cpoptions)=nil then
  1004. Aprocsym.addprocdef(pd^.def);
  1005. pd:=pd^.next;
  1006. end;
  1007. end;
  1008. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  1009. var
  1010. pd : pprocdeflist;
  1011. begin
  1012. pd:=pdlistfirst;
  1013. while assigned(pd) do
  1014. begin
  1015. s.addprocdef(pd^.def);
  1016. pd:=pd^.next;
  1017. end;
  1018. end;
  1019. function Tprocsym.first_procdef:Tprocdef;
  1020. begin
  1021. if assigned(pdlistfirst) then
  1022. first_procdef:=pdlistfirst^.def
  1023. else
  1024. first_procdef:=nil;
  1025. end;
  1026. function Tprocsym.last_procdef:Tprocdef;
  1027. begin
  1028. if assigned(pdlistlast) then
  1029. last_procdef:=pdlistlast^.def
  1030. else
  1031. last_procdef:=nil;
  1032. end;
  1033. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  1034. var
  1035. p : pprocdeflist;
  1036. begin
  1037. p:=pdlistfirst;
  1038. while assigned(p) do
  1039. begin
  1040. proc2call(p^.def,arg);
  1041. p:=p^.next;
  1042. end;
  1043. end;
  1044. function Tprocsym.search_procdef_nopara_boolret:Tprocdef;
  1045. var
  1046. p : pprocdeflist;
  1047. begin
  1048. search_procdef_nopara_boolret:=nil;
  1049. p:=pdlistfirst;
  1050. while p<>nil do
  1051. begin
  1052. if (p^.def.maxparacount=0) and
  1053. is_boolean(p^.def.rettype.def) then
  1054. begin
  1055. search_procdef_nopara_boolret:=p^.def;
  1056. break;
  1057. end;
  1058. p:=p^.next;
  1059. end;
  1060. end;
  1061. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  1062. var
  1063. p : pprocdeflist;
  1064. begin
  1065. search_procdef_bytype:=nil;
  1066. p:=pdlistfirst;
  1067. while p<>nil do
  1068. begin
  1069. if p^.def.proctypeoption=pt then
  1070. begin
  1071. search_procdef_bytype:=p^.def;
  1072. break;
  1073. end;
  1074. p:=p^.next;
  1075. end;
  1076. end;
  1077. function Tprocsym.search_procdef_bypara(params:Tlinkedlist;
  1078. retdef:tdef;
  1079. cpoptions:tcompare_paras_options):Tprocdef;
  1080. var
  1081. pd : pprocdeflist;
  1082. eq : tequaltype;
  1083. begin
  1084. search_procdef_bypara:=nil;
  1085. pd:=pdlistfirst;
  1086. while assigned(pd) do
  1087. begin
  1088. if assigned(retdef) then
  1089. eq:=compare_defs(retdef,pd^.def.rettype.def,nothingn)
  1090. else
  1091. eq:=te_equal;
  1092. if (eq>=te_equal) or
  1093. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  1094. begin
  1095. eq:=compare_paras(pd^.def.para,params,cp_value_equal_const,cpoptions);
  1096. if (eq>=te_equal) or
  1097. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  1098. begin
  1099. search_procdef_bypara:=pd^.def;
  1100. break;
  1101. end;
  1102. end;
  1103. pd:=pd^.next;
  1104. end;
  1105. end;
  1106. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  1107. var
  1108. pd : pprocdeflist;
  1109. eq,besteq : tequaltype;
  1110. bestpd : tprocdef;
  1111. begin
  1112. { This function will return the pprocdef of pprocsym that
  1113. is the best match for procvardef. When there are multiple
  1114. matches it returns nil.}
  1115. search_procdef_byprocvardef:=nil;
  1116. bestpd:=nil;
  1117. besteq:=te_incompatible;
  1118. pd:=pdlistfirst;
  1119. while assigned(pd) do
  1120. begin
  1121. eq:=proc_to_procvar_equal(pd^.def,d,false);
  1122. if eq>=te_equal then
  1123. begin
  1124. { multiple procvars with the same equal level }
  1125. if assigned(bestpd) and
  1126. (besteq=eq) then
  1127. exit;
  1128. if eq>besteq then
  1129. begin
  1130. besteq:=eq;
  1131. bestpd:=pd^.def;
  1132. end;
  1133. end;
  1134. pd:=pd^.next;
  1135. end;
  1136. search_procdef_byprocvardef:=bestpd;
  1137. end;
  1138. function Tprocsym.search_procdef_unary_operator(firstpara:Tdef):Tprocdef;
  1139. var
  1140. pd : pprocdeflist;
  1141. currpara : tparaitem;
  1142. begin
  1143. search_procdef_unary_operator:=nil;
  1144. pd:=pdlistfirst;
  1145. while assigned(pd) do
  1146. begin
  1147. currpara:=tparaitem(pd^.def.para.first);
  1148. { ignore vs_hidden parameters }
  1149. while assigned(currpara) and (currpara.is_hidden) do
  1150. currpara:=tparaitem(currpara.next);
  1151. if assigned(currpara) then
  1152. begin
  1153. if equal_defs(currpara.paratype.def,firstpara) then
  1154. begin
  1155. { This must be the last not hidden parameter }
  1156. currpara:=tparaitem(currpara.next);
  1157. while assigned(currpara) and (currpara.is_hidden) do
  1158. currpara:=tparaitem(currpara.next);
  1159. if currpara=nil then
  1160. begin
  1161. search_procdef_unary_operator:=pd^.def;
  1162. break;
  1163. end;
  1164. end;
  1165. end;
  1166. pd:=pd^.next;
  1167. end;
  1168. end;
  1169. function Tprocsym.search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  1170. var
  1171. convtyp : tconverttype;
  1172. pd : pprocdeflist;
  1173. bestpd : tprocdef;
  1174. eq,
  1175. besteq : tequaltype;
  1176. hpd : tprocdef;
  1177. currpara : tparaitem;
  1178. begin
  1179. search_procdef_assignment_operator:=nil;
  1180. bestpd:=nil;
  1181. besteq:=te_incompatible;
  1182. pd:=pdlistfirst;
  1183. while assigned(pd) do
  1184. begin
  1185. if equal_defs(todef,pd^.def.rettype.def) then
  1186. begin
  1187. currpara:=Tparaitem(pd^.def.para.first);
  1188. { ignore vs_hidden parameters }
  1189. while assigned(currpara) and (currpara.is_hidden) do
  1190. currpara:=tparaitem(currpara.next);
  1191. if assigned(currpara) then
  1192. begin
  1193. eq:=compare_defs_ext(fromdef,currpara.paratype.def,
  1194. nothingn,false,false,convtyp,hpd);
  1195. if eq=te_exact then
  1196. begin
  1197. search_procdef_assignment_operator:=pd^.def;
  1198. exit;
  1199. end;
  1200. if eq>besteq then
  1201. begin
  1202. bestpd:=pd^.def;
  1203. besteq:=eq;
  1204. end;
  1205. end;
  1206. end;
  1207. pd:=pd^.next;
  1208. end;
  1209. search_procdef_assignment_operator:=bestpd;
  1210. end;
  1211. function Tprocsym.search_procdef_binary_operator(def1,def2:tdef):Tprocdef;
  1212. var
  1213. convtyp : tconverttype;
  1214. pd : pprocdeflist;
  1215. bestpd : tprocdef;
  1216. eq1,eq2 : tequaltype;
  1217. eqlev,
  1218. bestlev : byte;
  1219. hpd : tprocdef;
  1220. nextpara,
  1221. currpara : tparaitem;
  1222. begin
  1223. search_procdef_binary_operator:=nil;
  1224. bestpd:=nil;
  1225. bestlev:=0;
  1226. pd:=pdlistfirst;
  1227. while assigned(pd) do
  1228. begin
  1229. currpara:=Tparaitem(pd^.def.para.first);
  1230. { ignore vs_hidden parameters }
  1231. while assigned(currpara) and (currpara.is_hidden) do
  1232. currpara:=tparaitem(currpara.next);
  1233. if assigned(currpara) then
  1234. begin
  1235. { Compare def1 with the first para }
  1236. eq1:=compare_defs_ext(def1,currpara.paratype.def,
  1237. nothingn,false,false,convtyp,hpd);
  1238. if eq1<>te_incompatible then
  1239. begin
  1240. { Ignore vs_hidden parameters }
  1241. repeat
  1242. currpara:=tparaitem(currpara.next);
  1243. until (not assigned(currpara)) or (not currpara.is_hidden);
  1244. if assigned(currpara) then
  1245. begin
  1246. { Ignore vs_hidden parameters }
  1247. nextpara:=currpara;
  1248. repeat
  1249. nextpara:=tparaitem(nextpara.next);
  1250. until (not assigned(nextpara)) or (not nextpara.is_hidden);
  1251. { There should be no other parameters left }
  1252. if not assigned(nextpara) then
  1253. begin
  1254. { Compare def2 with the last para }
  1255. eq2:=compare_defs_ext(def2,currpara.paratype.def,
  1256. nothingn,false,false,convtyp,hpd);
  1257. if (eq2<>te_incompatible) then
  1258. begin
  1259. { check level }
  1260. eqlev:=byte(eq1)+byte(eq2);
  1261. if eqlev=(byte(te_exact)+byte(te_exact)) then
  1262. begin
  1263. search_procdef_binary_operator:=pd^.def;
  1264. exit;
  1265. end;
  1266. if eqlev>bestlev then
  1267. begin
  1268. bestpd:=pd^.def;
  1269. bestlev:=eqlev;
  1270. end;
  1271. end;
  1272. end;
  1273. end;
  1274. end;
  1275. end;
  1276. pd:=pd^.next;
  1277. end;
  1278. search_procdef_binary_operator:=bestpd;
  1279. end;
  1280. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  1281. var
  1282. p : pprocdeflist;
  1283. begin
  1284. write_references:=false;
  1285. if not inherited write_references(ppufile,locals) then
  1286. exit;
  1287. write_references:=true;
  1288. p:=pdlistfirst;
  1289. while assigned(p) do
  1290. begin
  1291. if p^.own then
  1292. p^.def.write_references(ppufile,locals);
  1293. p:=p^.next;
  1294. end;
  1295. end;
  1296. procedure tprocsym.unchain_overload;
  1297. var
  1298. p,hp : pprocdeflist;
  1299. begin
  1300. { remove all overloaded procdefs from the
  1301. procdeflist that are not in the current symtable }
  1302. overloadchecked:=false;
  1303. p:=pdlistfirst;
  1304. { reset new lists }
  1305. pdlistfirst:=nil;
  1306. pdlistlast:=nil;
  1307. while assigned(p) do
  1308. begin
  1309. hp:=p^.next;
  1310. if p^.own then
  1311. begin
  1312. { keep, add to list }
  1313. if assigned(pdlistlast) then
  1314. begin
  1315. pdlistlast^.next:=p;
  1316. pdlistlast:=p;
  1317. end
  1318. else
  1319. begin
  1320. pdlistfirst:=p;
  1321. pdlistlast:=p;
  1322. end;
  1323. p^.next:=nil;
  1324. end
  1325. else
  1326. begin
  1327. { remove }
  1328. dispose(p);
  1329. dec(procdef_count);
  1330. end;
  1331. p:=hp;
  1332. end;
  1333. end;
  1334. {$ifdef GDB}
  1335. function tprocsym.stabstring : pchar;
  1336. begin
  1337. internalerror(200111171);
  1338. stabstring:=nil;
  1339. end;
  1340. procedure tprocsym.concatstabto(asmlist : taasmoutput);
  1341. begin
  1342. internalerror(200111172);
  1343. end;
  1344. {$endif GDB}
  1345. {****************************************************************************
  1346. TERRORSYM
  1347. ****************************************************************************}
  1348. constructor terrorsym.create;
  1349. begin
  1350. inherited create('');
  1351. typ:=errorsym;
  1352. end;
  1353. {****************************************************************************
  1354. TPROPERTYSYM
  1355. ****************************************************************************}
  1356. constructor tpropertysym.create(const n : string);
  1357. begin
  1358. inherited create(n);
  1359. typ:=propertysym;
  1360. propoptions:=[];
  1361. index:=0;
  1362. default:=0;
  1363. proptype.reset;
  1364. indextype.reset;
  1365. readaccess:=tsymlist.create;
  1366. writeaccess:=tsymlist.create;
  1367. storedaccess:=tsymlist.create;
  1368. end;
  1369. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  1370. begin
  1371. inherited loadsym(ppufile);
  1372. typ:=propertysym;
  1373. ppufile.getsmallset(propoptions);
  1374. if (ppo_is_override in propoptions) then
  1375. begin
  1376. ppufile.getderef(propoverridenderef);
  1377. { we need to have these objects initialized }
  1378. readaccess:=tsymlist.create;
  1379. writeaccess:=tsymlist.create;
  1380. storedaccess:=tsymlist.create;
  1381. end
  1382. else
  1383. begin
  1384. ppufile.gettype(proptype);
  1385. index:=ppufile.getlongint;
  1386. default:=ppufile.getlongint;
  1387. ppufile.gettype(indextype);
  1388. readaccess:=ppufile.getsymlist;
  1389. writeaccess:=ppufile.getsymlist;
  1390. storedaccess:=ppufile.getsymlist;
  1391. end;
  1392. end;
  1393. destructor tpropertysym.destroy;
  1394. begin
  1395. readaccess.free;
  1396. writeaccess.free;
  1397. storedaccess.free;
  1398. inherited destroy;
  1399. end;
  1400. function tpropertysym.gettypedef:tdef;
  1401. begin
  1402. gettypedef:=proptype.def;
  1403. end;
  1404. procedure tpropertysym.buildderef;
  1405. begin
  1406. if (ppo_is_override in propoptions) then
  1407. begin
  1408. propoverridenderef.build(propoverriden);
  1409. end
  1410. else
  1411. begin
  1412. proptype.buildderef;
  1413. indextype.buildderef;
  1414. readaccess.buildderef;
  1415. writeaccess.buildderef;
  1416. storedaccess.buildderef;
  1417. end;
  1418. end;
  1419. procedure tpropertysym.deref;
  1420. begin
  1421. if (ppo_is_override in propoptions) then
  1422. begin
  1423. propoverriden:=tpropertysym(propoverridenderef.resolve);
  1424. dooverride(propoverriden);
  1425. end
  1426. else
  1427. begin
  1428. proptype.resolve;
  1429. indextype.resolve;
  1430. readaccess.resolve;
  1431. writeaccess.resolve;
  1432. storedaccess.resolve;
  1433. end;
  1434. end;
  1435. function tpropertysym.getsize : longint;
  1436. begin
  1437. getsize:=0;
  1438. end;
  1439. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1440. begin
  1441. inherited writesym(ppufile);
  1442. ppufile.putsmallset(propoptions);
  1443. if (ppo_is_override in propoptions) then
  1444. ppufile.putderef(propoverridenderef)
  1445. else
  1446. begin
  1447. ppufile.puttype(proptype);
  1448. ppufile.putlongint(index);
  1449. ppufile.putlongint(default);
  1450. ppufile.puttype(indextype);
  1451. ppufile.putsymlist(readaccess);
  1452. ppufile.putsymlist(writeaccess);
  1453. ppufile.putsymlist(storedaccess);
  1454. end;
  1455. ppufile.writeentry(ibpropertysym);
  1456. end;
  1457. procedure tpropertysym.dooverride(overriden:tpropertysym);
  1458. begin
  1459. propoverriden:=overriden;
  1460. proptype:=overriden.proptype;
  1461. propoptions:=overriden.propoptions+[ppo_is_override];
  1462. index:=overriden.index;
  1463. default:=overriden.default;
  1464. indextype:=overriden.indextype;
  1465. readaccess.free;
  1466. readaccess:=overriden.readaccess.getcopy;
  1467. writeaccess.free;
  1468. writeaccess:=overriden.writeaccess.getcopy;
  1469. storedaccess.free;
  1470. storedaccess:=overriden.storedaccess.getcopy;
  1471. end;
  1472. {$ifdef GDB}
  1473. function tpropertysym.stabstring : pchar;
  1474. begin
  1475. { !!!! don't know how to handle }
  1476. stabstring:=nil;
  1477. end;
  1478. procedure tpropertysym.concatstabto(asmlist : taasmoutput);
  1479. begin
  1480. { !!!! don't know how to handle }
  1481. end;
  1482. {$endif GDB}
  1483. {****************************************************************************
  1484. TABSOLUTESYM
  1485. ****************************************************************************}
  1486. constructor tabsolutesym.create(const n : string;const tt : ttype);
  1487. begin
  1488. inherited create(n,vs_value,tt);
  1489. typ:=absolutesym;
  1490. ref:=nil;
  1491. end;
  1492. constructor tabsolutesym.create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  1493. begin
  1494. inherited create(n,vs_value,tt);
  1495. typ:=absolutesym;
  1496. ref:=_ref;
  1497. end;
  1498. destructor tabsolutesym.destroy;
  1499. begin
  1500. if assigned(ref) then
  1501. ref.free;
  1502. inherited destroy;
  1503. end;
  1504. constructor tabsolutesym.ppuload(ppufile:tcompilerppufile);
  1505. begin
  1506. { Note: This needs to load everything of tvarsym.write }
  1507. inherited ppuload(ppufile);
  1508. { load absolute }
  1509. typ:=absolutesym;
  1510. ref:=nil;
  1511. fieldoffset:=0;
  1512. asmname:=nil;
  1513. abstyp:=absolutetyp(ppufile.getbyte);
  1514. absseg:=false;
  1515. case abstyp of
  1516. tovar :
  1517. ref:=ppufile.getsymlist;
  1518. toasm :
  1519. asmname:=stringdup(ppufile.getstring);
  1520. toaddr :
  1521. begin
  1522. fieldoffset:=ppufile.getlongint;
  1523. absseg:=boolean(ppufile.getbyte);
  1524. end;
  1525. end;
  1526. end;
  1527. procedure tabsolutesym.ppuwrite(ppufile:tcompilerppufile);
  1528. var
  1529. hvo : tvaroptions;
  1530. begin
  1531. { Note: This needs to write everything of tvarsym.write }
  1532. inherited writesym(ppufile);
  1533. ppufile.putbyte(byte(varspez));
  1534. ppufile.putlongint(fieldoffset);
  1535. { write only definition or definitionsym }
  1536. ppufile.puttype(vartype);
  1537. hvo:=varoptions-[vo_regable,vo_fpuregable];
  1538. ppufile.putsmallset(hvo);
  1539. ppufile.putbyte(byte(abstyp));
  1540. case abstyp of
  1541. tovar :
  1542. ppufile.putsymlist(ref);
  1543. toasm :
  1544. ppufile.putstring(asmname^);
  1545. toaddr :
  1546. begin
  1547. ppufile.putlongint(fieldoffset);
  1548. ppufile.putbyte(byte(absseg));
  1549. end;
  1550. end;
  1551. ppufile.writeentry(ibabsolutesym);
  1552. end;
  1553. procedure tabsolutesym.buildderef;
  1554. begin
  1555. { inheritance of varsym.deref ! }
  1556. vartype.buildderef;
  1557. if (abstyp=tovar) then
  1558. ref.buildderef;
  1559. end;
  1560. procedure tabsolutesym.deref;
  1561. begin
  1562. { inheritance of varsym.deref ! }
  1563. vartype.resolve;
  1564. { own absolute deref }
  1565. if (abstyp=tovar) then
  1566. ref.resolve;
  1567. end;
  1568. function tabsolutesym.mangledname : string;
  1569. begin
  1570. case abstyp of
  1571. toasm :
  1572. mangledname:=asmname^;
  1573. toaddr :
  1574. mangledname:='$'+tostr(fieldoffset);
  1575. else
  1576. internalerror(10002);
  1577. end;
  1578. end;
  1579. {$ifdef GDB}
  1580. procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
  1581. begin
  1582. { I don't know how to handle this !! }
  1583. end;
  1584. {$endif GDB}
  1585. {****************************************************************************
  1586. TVARSYM
  1587. ****************************************************************************}
  1588. constructor tvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1589. begin
  1590. inherited create(n);
  1591. typ:=varsym;
  1592. vartype:=tt;
  1593. _mangledname:=nil;
  1594. varspez:=vsp;
  1595. fieldoffset:=0;
  1596. fillchar(localloc,sizeof(localloc),0);
  1597. highvarsym:=nil;
  1598. defaultconstsym:=nil;
  1599. refs:=0;
  1600. varstate:=vs_declared;
  1601. varoptions:=[];
  1602. end;
  1603. constructor tvarsym.create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  1604. begin
  1605. tvarsym(self).create(n,vsp,tt);
  1606. include(varoptions,vo_is_dll_var);
  1607. end;
  1608. constructor tvarsym.create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  1609. begin
  1610. tvarsym(self).create(n,vsp,tt);
  1611. stringdispose(_mangledname);
  1612. {$ifdef compress}
  1613. _mangledname:=stringdup(minilzw_encode(mangled));
  1614. {$else}
  1615. _mangledname:=stringdup(mangled);
  1616. {$endif}
  1617. end;
  1618. constructor tvarsym.ppuload(ppufile:tcompilerppufile);
  1619. begin
  1620. inherited loadsym(ppufile);
  1621. typ:=varsym;
  1622. fillchar(localloc,sizeof(localloc),0);
  1623. refs := 0;
  1624. varstate:=vs_used;
  1625. varspez:=tvarspez(ppufile.getbyte);
  1626. fieldoffset:=ppufile.getlongint;
  1627. highvarsym:=nil;
  1628. defaultconstsym:=nil;
  1629. ppufile.gettype(_vartype);
  1630. ppufile.getsmallset(varoptions);
  1631. if (vo_is_C_var in varoptions) then
  1632. _mangledname:=stringdup(ppufile.getstring);
  1633. end;
  1634. destructor tvarsym.destroy;
  1635. begin
  1636. if assigned(notifications) then
  1637. notifications.destroy;
  1638. inherited destroy;
  1639. end;
  1640. procedure tvarsym.buildderef;
  1641. begin
  1642. vartype.buildderef;
  1643. end;
  1644. procedure tvarsym.deref;
  1645. begin
  1646. vartype.resolve;
  1647. end;
  1648. procedure tvarsym.ppuwrite(ppufile:tcompilerppufile);
  1649. var
  1650. hvo : tvaroptions;
  1651. begin
  1652. inherited writesym(ppufile);
  1653. ppufile.putbyte(byte(varspez));
  1654. ppufile.putlongint(fieldoffset);
  1655. ppufile.puttype(vartype);
  1656. { symbols which are load are never candidates for a register,
  1657. turn off the regable }
  1658. hvo:=varoptions-[vo_regable,vo_fpuregable];
  1659. ppufile.putsmallset(hvo);
  1660. if (vo_is_C_var in varoptions) then
  1661. ppufile.putstring(_mangledname^);
  1662. ppufile.writeentry(ibvarsym);
  1663. end;
  1664. procedure tvarsym.generate_mangledname;
  1665. begin
  1666. {$ifdef compress}
  1667. _mangledname:=stringdup(minilzw_encode(make_mangledname('U',owner,name)));
  1668. {$else}
  1669. _mangledname:=stringdup(make_mangledname('U',owner,name));
  1670. {$endif}
  1671. end;
  1672. procedure tvarsym.set_mangledname(const s:string);
  1673. begin
  1674. stringdispose(_mangledname);
  1675. {$ifdef compress}
  1676. _mangledname:=stringdup(minilzw_encode(s));
  1677. {$else}
  1678. _mangledname:=stringdup(s);
  1679. {$endif}
  1680. end;
  1681. function tvarsym.getsize : longint;
  1682. begin
  1683. if assigned(vartype.def) then
  1684. getsize:=vartype.def.size
  1685. else
  1686. getsize:=0;
  1687. end;
  1688. function tvarsym.getvaluesize : longint;
  1689. begin
  1690. if assigned(vartype.def) and
  1691. (varspez=vs_value) and
  1692. ((vartype.def.deftype<>arraydef) or
  1693. tarraydef(vartype.def).isDynamicArray or
  1694. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1695. getvaluesize:=vartype.def.size
  1696. else
  1697. getvaluesize:=0;
  1698. end;
  1699. procedure Tvarsym.trigger_notifications(what:Tnotification_flag);
  1700. var n:Tnotification;
  1701. begin
  1702. if assigned(notifications) then
  1703. begin
  1704. n:=Tnotification(notifications.first);
  1705. while assigned(n) do
  1706. begin
  1707. if what in n.flags then
  1708. n.callback(what,self);
  1709. n:=Tnotification(n.next);
  1710. end;
  1711. end;
  1712. end;
  1713. function Tvarsym.register_notification(flags:Tnotification_flags;callback:
  1714. Tnotification_callback):cardinal;
  1715. var n:Tnotification;
  1716. begin
  1717. if not assigned(notifications) then
  1718. notifications:=Tlinkedlist.create;
  1719. n:=Tnotification.create(flags,callback);
  1720. register_notification:=n.id;
  1721. notifications.concat(n);
  1722. end;
  1723. procedure Tvarsym.unregister_notification(id:cardinal);
  1724. var n:Tnotification;
  1725. begin
  1726. if not assigned(notifications) then
  1727. internalerror(200212311)
  1728. else
  1729. begin
  1730. n:=Tnotification(notifications.first);
  1731. while assigned(n) do
  1732. begin
  1733. if n.id=id then
  1734. begin
  1735. notifications.remove(n);
  1736. n.destroy;
  1737. exit;
  1738. end;
  1739. n:=Tnotification(n.next);
  1740. end;
  1741. internalerror(200212311)
  1742. end;
  1743. end;
  1744. {$ifdef GDB}
  1745. function tvarsym.stabstring : pchar;
  1746. var
  1747. st : string;
  1748. threadvaroffset : string;
  1749. regidx : tregisterindex;
  1750. begin
  1751. stabstring:=nil;
  1752. st:=tstoreddef(vartype.def).numberstring;
  1753. if (vo_is_thread_var in varoptions) then
  1754. threadvaroffset:='+'+tostr(pointer_size)
  1755. else
  1756. threadvaroffset:='';
  1757. case owner.symtabletype of
  1758. objectsymtable :
  1759. if (sp_static in symoptions) then
  1760. begin
  1761. if (cs_gdb_gsym in aktglobalswitches) then
  1762. st:='G'+st
  1763. else
  1764. st:='S'+st;
  1765. stabstring:=stabstr_evaluate('"${ownername}__${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  1766. end;
  1767. globalsymtable :
  1768. begin
  1769. { Here we used S instead of
  1770. because with G GDB doesn't look at the address field
  1771. but searches the same name or with a leading underscore
  1772. but these names don't exist in pascal !}
  1773. if (cs_gdb_gsym in aktglobalswitches) then
  1774. st:='G'+st
  1775. else
  1776. st:='S'+st;
  1777. stabstring:=stabstr_evaluate('"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  1778. end;
  1779. staticsymtable :
  1780. stabstring:=stabstr_evaluate('"${name}:S$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  1781. parasymtable,
  1782. localsymtable :
  1783. begin
  1784. { There is no space allocated for not referenced locals }
  1785. if (owner.symtabletype=localsymtable) and (refs=0) then
  1786. exit;
  1787. if (vo_is_C_var in varoptions) then
  1788. begin
  1789. stabstring:=stabstr_evaluate('"${name}:S$1",${N_LCSYM},0,${line},${mangledname}',[st]);
  1790. exit;
  1791. end;
  1792. if (owner.symtabletype=parasymtable) then
  1793. begin
  1794. if paramanager.push_addr_param(varspez,vartype.def,tprocdef(owner.defowner).proccalloption) and
  1795. not(vo_has_local_copy in varoptions) then
  1796. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1797. else
  1798. st := 'p'+st;
  1799. end;
  1800. case localloc.loc of
  1801. LOC_REGISTER, LOC_FPUREGISTER :
  1802. begin
  1803. regidx:=findreg_by_number(localloc.register);
  1804. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1805. { this is the register order for GDB}
  1806. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1807. end;
  1808. LOC_REFERENCE :
  1809. { offset to ebp => will not work if the framepointer is esp
  1810. so some optimizing will make things harder to debug }
  1811. stabstring:=stabstr_evaluate('"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(localloc.reference.offset)])
  1812. else
  1813. internalerror(2003091814);
  1814. end;
  1815. end;
  1816. else
  1817. stabstring := inherited stabstring;
  1818. end;
  1819. end;
  1820. procedure tvarsym.concatstabto(asmlist : taasmoutput);
  1821. var
  1822. regidx : tregisterindex;
  1823. stab_str : pchar;
  1824. c : char;
  1825. begin
  1826. if (owner.symtabletype=parasymtable) and
  1827. (copy(name,1,6)='hidden') then
  1828. exit;
  1829. if (vo_is_self in varoptions) then
  1830. begin
  1831. if localloc.loc<>LOC_REFERENCE then
  1832. internalerror(2003091815);
  1833. if (po_classmethod in current_procinfo.procdef.procoptions) or
  1834. (po_staticmethod in current_procinfo.procdef.procoptions) then
  1835. asmlist.concat(Tai_stabs.create(stabstr_evaluate('"pvmt:p$1",${N_TSYM},0,0,$2',
  1836. [Tstoreddef(pvmttype.def).numberstring,tostr(localloc.reference.offset)])))
  1837. else
  1838. begin
  1839. if not(is_class(current_procinfo.procdef._class)) then
  1840. c:='v'
  1841. else
  1842. c:='p';
  1843. asmlist.concat(Tai_stabs.create(stabstr_evaluate('"$$t:$1",${N_TSYM},0,0,$2',
  1844. [c+current_procinfo.procdef._class.numberstring,tostr(localloc.reference.offset)])));
  1845. end;
  1846. end
  1847. else
  1848. if (localloc.loc=LOC_REGISTER) then
  1849. begin
  1850. regidx:=findreg_by_number(localloc.register);
  1851. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1852. { this is the register order for GDB}
  1853. asmlist.concat(Tai_stabs.create(stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',
  1854. [Tstoreddef(vartype.def).numberstring,tostr(regstabs_table[regidx])])));
  1855. end
  1856. else
  1857. inherited concatstabto(asmlist);
  1858. end;
  1859. {$endif GDB}
  1860. procedure tvarsym.setvartype(const newtype: ttype);
  1861. begin
  1862. _vartype := newtype;
  1863. { can we load the value into a register ? }
  1864. if not assigned(owner) or
  1865. (owner.symtabletype in [localsymtable,parasymtable]) then
  1866. begin
  1867. if tstoreddef(vartype.def).is_intregable then
  1868. include(varoptions,vo_regable)
  1869. else
  1870. exclude(varoptions,vo_regable);
  1871. if tstoreddef(vartype.def).is_fpuregable then
  1872. include(varoptions,vo_fpuregable)
  1873. else
  1874. exclude(varoptions,vo_fpuregable);
  1875. end;
  1876. end;
  1877. {****************************************************************************
  1878. TTYPEDCONSTSYM
  1879. *****************************************************************************}
  1880. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1881. begin
  1882. inherited create(n);
  1883. typ:=typedconstsym;
  1884. typedconsttype.setdef(p);
  1885. is_writable:=writable;
  1886. end;
  1887. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1888. begin
  1889. inherited create(n);
  1890. typ:=typedconstsym;
  1891. typedconsttype:=tt;
  1892. is_writable:=writable;
  1893. end;
  1894. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1895. begin
  1896. inherited loadsym(ppufile);
  1897. typ:=typedconstsym;
  1898. ppufile.gettype(typedconsttype);
  1899. is_writable:=boolean(ppufile.getbyte);
  1900. end;
  1901. destructor ttypedconstsym.destroy;
  1902. begin
  1903. inherited destroy;
  1904. end;
  1905. procedure ttypedconstsym.generate_mangledname;
  1906. begin
  1907. {$ifdef compress}
  1908. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1909. {$else}
  1910. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1911. {$endif}
  1912. end;
  1913. function ttypedconstsym.getsize : longint;
  1914. begin
  1915. if assigned(typedconsttype.def) then
  1916. getsize:=typedconsttype.def.size
  1917. else
  1918. getsize:=0;
  1919. end;
  1920. procedure ttypedconstsym.buildderef;
  1921. begin
  1922. typedconsttype.buildderef;
  1923. end;
  1924. procedure ttypedconstsym.deref;
  1925. begin
  1926. typedconsttype.resolve;
  1927. end;
  1928. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1929. begin
  1930. inherited writesym(ppufile);
  1931. ppufile.puttype(typedconsttype);
  1932. ppufile.putbyte(byte(is_writable));
  1933. ppufile.writeentry(ibtypedconstsym);
  1934. end;
  1935. {$ifdef GDB}
  1936. function ttypedconstsym.stabstring : pchar;
  1937. var st:char;
  1938. begin
  1939. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1940. st:='G'
  1941. else
  1942. st:='S';
  1943. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_STSYM},0,${line},${mangledname}',
  1944. [st,Tstoreddef(typedconsttype.def).numberstring]);
  1945. end;
  1946. {$endif GDB}
  1947. {****************************************************************************
  1948. TCONSTSYM
  1949. ****************************************************************************}
  1950. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : TConstExprInt);
  1951. begin
  1952. inherited create(n);
  1953. fillchar(value, sizeof(value), #0);
  1954. typ:=constsym;
  1955. consttyp:=t;
  1956. value.valueord:=v;
  1957. ResStrIndex:=0;
  1958. consttype.reset;
  1959. end;
  1960. constructor tconstsym.create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1961. begin
  1962. inherited create(n);
  1963. fillchar(value, sizeof(value), #0);
  1964. typ:=constsym;
  1965. consttyp:=t;
  1966. value.valueord:=v;
  1967. ResStrIndex:=0;
  1968. consttype:=tt;
  1969. end;
  1970. constructor tconstsym.create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1971. begin
  1972. inherited create(n);
  1973. fillchar(value, sizeof(value), #0);
  1974. typ:=constsym;
  1975. consttyp:=t;
  1976. value.valueordptr:=v;
  1977. ResStrIndex:=0;
  1978. consttype:=tt;
  1979. end;
  1980. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer);
  1981. begin
  1982. inherited create(n);
  1983. fillchar(value, sizeof(value), #0);
  1984. typ:=constsym;
  1985. consttyp:=t;
  1986. value.valueptr:=v;
  1987. ResStrIndex:=0;
  1988. consttype.reset;
  1989. end;
  1990. constructor tconstsym.create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1991. begin
  1992. inherited create(n);
  1993. fillchar(value, sizeof(value), #0);
  1994. typ:=constsym;
  1995. consttyp:=t;
  1996. value.valueptr:=v;
  1997. ResStrIndex:=0;
  1998. consttype:=tt;
  1999. end;
  2000. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  2001. begin
  2002. inherited create(n);
  2003. fillchar(value, sizeof(value), #0);
  2004. typ:=constsym;
  2005. consttyp:=t;
  2006. value.valueptr:=str;
  2007. consttype.reset;
  2008. value.len:=l;
  2009. if t=constresourcestring then
  2010. ResStrIndex:=ResourceStrings.Register(name,pchar(value.valueptr),value.len);
  2011. end;
  2012. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  2013. var
  2014. pd : pbestreal;
  2015. ps : pnormalset;
  2016. pc : pchar;
  2017. begin
  2018. inherited loadsym(ppufile);
  2019. typ:=constsym;
  2020. consttype.reset;
  2021. consttyp:=tconsttyp(ppufile.getbyte);
  2022. fillchar(value, sizeof(value), #0);
  2023. case consttyp of
  2024. constint:
  2025. value.valueord:=ppufile.getexprint;
  2026. constwchar,
  2027. constbool,
  2028. constchar :
  2029. value.valueord:=ppufile.getlongint;
  2030. constord :
  2031. begin
  2032. ppufile.gettype(consttype);
  2033. value.valueord:=ppufile.getexprint;
  2034. end;
  2035. constpointer :
  2036. begin
  2037. ppufile.gettype(consttype);
  2038. value.valueordptr:=ppufile.getptruint;
  2039. end;
  2040. conststring,
  2041. constresourcestring :
  2042. begin
  2043. value.len:=ppufile.getlongint;
  2044. getmem(pc,value.len+1);
  2045. ppufile.getdata(pc^,value.len);
  2046. if consttyp=constresourcestring then
  2047. ResStrIndex:=ppufile.getlongint;
  2048. value.valueptr:=pc;
  2049. end;
  2050. constreal :
  2051. begin
  2052. new(pd);
  2053. pd^:=ppufile.getreal;
  2054. value.valueptr:=pd;
  2055. end;
  2056. constset :
  2057. begin
  2058. ppufile.gettype(consttype);
  2059. new(ps);
  2060. ppufile.getnormalset(ps^);
  2061. value.valueptr:=ps;
  2062. end;
  2063. constguid :
  2064. begin
  2065. new(pguid(value.valueptr));
  2066. ppufile.getdata(value.valueptr^,sizeof(tguid));
  2067. end;
  2068. constnil : ;
  2069. else
  2070. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  2071. end;
  2072. end;
  2073. destructor tconstsym.destroy;
  2074. begin
  2075. case consttyp of
  2076. conststring,
  2077. constresourcestring :
  2078. freemem(pchar(value.valueptr),value.len+1);
  2079. constreal :
  2080. dispose(pbestreal(value.valueptr));
  2081. constset :
  2082. dispose(pnormalset(value.valueptr));
  2083. constguid :
  2084. dispose(pguid(value.valueptr));
  2085. end;
  2086. inherited destroy;
  2087. end;
  2088. function tconstsym.mangledname : string;
  2089. begin
  2090. mangledname:=name;
  2091. end;
  2092. procedure tconstsym.buildderef;
  2093. begin
  2094. if consttyp in [constord,constpointer,constset] then
  2095. consttype.buildderef;
  2096. end;
  2097. procedure tconstsym.deref;
  2098. begin
  2099. if consttyp in [constord,constpointer,constset] then
  2100. consttype.resolve;
  2101. end;
  2102. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  2103. begin
  2104. inherited writesym(ppufile);
  2105. ppufile.putbyte(byte(consttyp));
  2106. case consttyp of
  2107. constnil : ;
  2108. constint:
  2109. ppufile.putexprint(value.valueord);
  2110. constbool,
  2111. constchar,
  2112. constwchar :
  2113. ppufile.putlongint(value.valueord);
  2114. constord :
  2115. begin
  2116. ppufile.puttype(consttype);
  2117. ppufile.putexprint(value.valueord);
  2118. end;
  2119. constpointer :
  2120. begin
  2121. ppufile.puttype(consttype);
  2122. ppufile.putptruint(value.valueordptr);
  2123. end;
  2124. conststring,
  2125. constresourcestring :
  2126. begin
  2127. ppufile.putlongint(value.len);
  2128. ppufile.putdata(pchar(value.valueptr)^,value.len);
  2129. if consttyp=constresourcestring then
  2130. ppufile.putlongint(ResStrIndex);
  2131. end;
  2132. constreal :
  2133. ppufile.putreal(pbestreal(value.valueptr)^);
  2134. constset :
  2135. begin
  2136. ppufile.puttype(consttype);
  2137. ppufile.putnormalset(value.valueptr^);
  2138. end;
  2139. constguid :
  2140. ppufile.putdata(value.valueptr^,sizeof(tguid));
  2141. else
  2142. internalerror(13);
  2143. end;
  2144. ppufile.writeentry(ibconstsym);
  2145. end;
  2146. {$ifdef GDB}
  2147. function Tconstsym.stabstring:Pchar;
  2148. var st : string;
  2149. begin
  2150. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  2151. case consttyp of
  2152. conststring:
  2153. st:='s'''+strpas(pchar(value.valueptr))+'''';
  2154. constbool,
  2155. constint,
  2156. constord,
  2157. constwchar,
  2158. constchar:
  2159. st:='i'+int64tostr(value.valueord);
  2160. constpointer:
  2161. st:='i'+int64tostr(value.valueordptr);
  2162. constreal:
  2163. begin
  2164. system.str(pbestreal(value.valueptr)^,st);
  2165. st := 'r'+st;
  2166. end;
  2167. { if we don't know just put zero !! }
  2168. else st:='i0';
  2169. {***SETCONST}
  2170. {constset:;} {*** I don't know what to do with a set.}
  2171. { sets are not recognized by GDB}
  2172. {***}
  2173. end;
  2174. stabstring:=stabstr_evaluate('"${name}:c=$1",${N_FUNCTION},0,${line},0',[st]);
  2175. end;
  2176. procedure tconstsym.concatstabto(asmlist : taasmoutput);
  2177. begin
  2178. if consttyp <> conststring then
  2179. inherited concatstabto(asmlist);
  2180. end;
  2181. {$endif GDB}
  2182. {****************************************************************************
  2183. TENUMSYM
  2184. ****************************************************************************}
  2185. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  2186. begin
  2187. inherited create(n);
  2188. typ:=enumsym;
  2189. definition:=def;
  2190. value:=v;
  2191. { check for jumps }
  2192. if v>def.max+1 then
  2193. def.has_jumps:=true;
  2194. { update low and high }
  2195. if def.min>v then
  2196. def.setmin(v);
  2197. if def.max<v then
  2198. def.setmax(v);
  2199. order;
  2200. end;
  2201. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  2202. begin
  2203. inherited loadsym(ppufile);
  2204. typ:=enumsym;
  2205. ppufile.getderef(definitionderef);
  2206. value:=ppufile.getlongint;
  2207. nextenum := Nil;
  2208. end;
  2209. procedure tenumsym.buildderef;
  2210. begin
  2211. definitionderef.build(definition);
  2212. end;
  2213. procedure tenumsym.deref;
  2214. begin
  2215. definition:=tenumdef(definitionderef.resolve);
  2216. order;
  2217. end;
  2218. procedure tenumsym.order;
  2219. var
  2220. sym : tenumsym;
  2221. begin
  2222. sym := tenumsym(definition.firstenum);
  2223. if sym = nil then
  2224. begin
  2225. definition.firstenum := self;
  2226. nextenum := nil;
  2227. exit;
  2228. end;
  2229. { reorder the symbols in increasing value }
  2230. if value < sym.value then
  2231. begin
  2232. nextenum := sym;
  2233. definition.firstenum := self;
  2234. end
  2235. else
  2236. begin
  2237. while (sym.value <= value) and assigned(sym.nextenum) do
  2238. sym := sym.nextenum;
  2239. nextenum := sym.nextenum;
  2240. sym.nextenum := self;
  2241. end;
  2242. end;
  2243. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  2244. begin
  2245. inherited writesym(ppufile);
  2246. ppufile.putderef(definitionderef);
  2247. ppufile.putlongint(value);
  2248. ppufile.writeentry(ibenumsym);
  2249. end;
  2250. {$ifdef GDB}
  2251. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  2252. begin
  2253. {enum elements have no stab !}
  2254. end;
  2255. {$EndIf GDB}
  2256. {****************************************************************************
  2257. TTYPESYM
  2258. ****************************************************************************}
  2259. constructor ttypesym.create(const n : string;const tt : ttype);
  2260. begin
  2261. inherited create(n);
  2262. typ:=typesym;
  2263. restype:=tt;
  2264. {$ifdef GDB}
  2265. isusedinstab := false;
  2266. {$endif GDB}
  2267. { register the typesym for the definition }
  2268. if assigned(restype.def) and
  2269. (restype.def.deftype<>errordef) and
  2270. not(assigned(restype.def.typesym)) then
  2271. restype.def.typesym:=self;
  2272. end;
  2273. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  2274. begin
  2275. inherited loadsym(ppufile);
  2276. typ:=typesym;
  2277. {$ifdef GDB}
  2278. isusedinstab := false;
  2279. {$endif GDB}
  2280. ppufile.gettype(restype);
  2281. end;
  2282. function ttypesym.gettypedef:tdef;
  2283. begin
  2284. gettypedef:=restype.def;
  2285. end;
  2286. procedure ttypesym.buildderef;
  2287. begin
  2288. restype.buildderef;
  2289. end;
  2290. procedure ttypesym.deref;
  2291. begin
  2292. restype.resolve;
  2293. end;
  2294. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  2295. begin
  2296. inherited writesym(ppufile);
  2297. ppufile.puttype(restype);
  2298. ppufile.writeentry(ibtypesym);
  2299. end;
  2300. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2301. begin
  2302. inherited load_references(ppufile,locals);
  2303. if (restype.def.deftype=recorddef) then
  2304. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2305. if (restype.def.deftype=objectdef) then
  2306. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2307. end;
  2308. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2309. var
  2310. d : tderef;
  2311. begin
  2312. d.reset;
  2313. if not inherited write_references(ppufile,locals) then
  2314. begin
  2315. { write address of this symbol if record or object
  2316. even if no real refs are there
  2317. because we need it for the symtable }
  2318. if (restype.def.deftype in [recorddef,objectdef]) then
  2319. begin
  2320. d.build(self);
  2321. ppufile.putderef(d);
  2322. ppufile.writeentry(ibsymref);
  2323. end;
  2324. end;
  2325. write_references:=true;
  2326. if (restype.def.deftype=recorddef) then
  2327. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2328. if (restype.def.deftype=objectdef) then
  2329. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2330. end;
  2331. {$ifdef GDB}
  2332. function ttypesym.stabstring : pchar;
  2333. var stabchar:string[2];
  2334. begin
  2335. if restype.def.deftype in tagtypes then
  2336. stabchar:='Tt'
  2337. else
  2338. stabchar:='t';
  2339. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_LSYM},0,${line},0',[stabchar,tstoreddef(restype.def).numberstring]);
  2340. end;
  2341. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  2342. begin
  2343. {not stabs for forward defs }
  2344. if assigned(restype.def) then
  2345. if (restype.def.typesym = self) then
  2346. tstoreddef(restype.def).concatstabto(asmlist)
  2347. else
  2348. inherited concatstabto(asmlist);
  2349. end;
  2350. {$endif GDB}
  2351. {****************************************************************************
  2352. TSYSSYM
  2353. ****************************************************************************}
  2354. constructor tsyssym.create(const n : string;l : longint);
  2355. begin
  2356. inherited create(n);
  2357. typ:=syssym;
  2358. number:=l;
  2359. end;
  2360. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  2361. begin
  2362. inherited loadsym(ppufile);
  2363. typ:=syssym;
  2364. number:=ppufile.getlongint;
  2365. end;
  2366. destructor tsyssym.destroy;
  2367. begin
  2368. inherited destroy;
  2369. end;
  2370. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  2371. begin
  2372. inherited writesym(ppufile);
  2373. ppufile.putlongint(number);
  2374. ppufile.writeentry(ibsyssym);
  2375. end;
  2376. {$ifdef GDB}
  2377. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2378. begin
  2379. end;
  2380. {$endif GDB}
  2381. {****************************************************************************
  2382. TRTTISYM
  2383. ****************************************************************************}
  2384. constructor trttisym.create(const n:string;rt:trttitype);
  2385. const
  2386. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2387. begin
  2388. inherited create(prefix[rt]+n);
  2389. typ:=rttisym;
  2390. lab:=nil;
  2391. rttityp:=rt;
  2392. end;
  2393. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  2394. begin
  2395. inherited loadsym(ppufile);
  2396. typ:=rttisym;
  2397. lab:=nil;
  2398. rttityp:=trttitype(ppufile.getbyte);
  2399. end;
  2400. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2401. begin
  2402. inherited writesym(ppufile);
  2403. ppufile.putbyte(byte(rttityp));
  2404. ppufile.writeentry(ibrttisym);
  2405. end;
  2406. function trttisym.mangledname : string;
  2407. const
  2408. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2409. begin
  2410. result:=make_mangledname(prefix[rttityp],owner,Copy(name,5,255));
  2411. end;
  2412. function trttisym.get_label:tasmsymbol;
  2413. begin
  2414. { the label is always a global label }
  2415. if not assigned(lab) then
  2416. lab:=objectlibrary.newasmsymboldata(mangledname);
  2417. get_label:=lab;
  2418. end;
  2419. { persistent rtti generation }
  2420. procedure generate_rtti(p:tsym);
  2421. var
  2422. rsym : trttisym;
  2423. def : tstoreddef;
  2424. begin
  2425. { rtti can only be generated for classes that are always typesyms }
  2426. if not(p.typ=typesym) then
  2427. internalerror(200108261);
  2428. def:=tstoreddef(ttypesym(p).restype.def);
  2429. { there is an error, skip rtti info }
  2430. if def.deftype=errordef then
  2431. exit;
  2432. { only create rtti once for each definition }
  2433. if not(df_has_rttitable in def.defoptions) then
  2434. begin
  2435. { definition should be in the same symtable as the symbol }
  2436. if p.owner<>def.owner then
  2437. internalerror(200108262);
  2438. { create rttisym }
  2439. rsym:=trttisym.create(p.name,fullrtti);
  2440. p.owner.insert(rsym);
  2441. { register rttisym in definition }
  2442. include(def.defoptions,df_has_rttitable);
  2443. def.rttitablesym:=rsym;
  2444. { write rtti data }
  2445. def.write_child_rtti_data(fullrtti);
  2446. if (cs_create_smart in aktmoduleswitches) then
  2447. rttiList.concat(Tai_cut.Create);
  2448. rttilist.concat(tai_align.create(const_align(pointer_size)));
  2449. rttiList.concat(Tai_symbol.Create_global(rsym.get_label,0));
  2450. def.write_rtti_data(fullrtti);
  2451. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2452. end;
  2453. end;
  2454. { persistent init table generation }
  2455. procedure generate_inittable(p:tsym);
  2456. var
  2457. rsym : trttisym;
  2458. def : tstoreddef;
  2459. begin
  2460. { anonymous types are also allowed for records that can be varsym }
  2461. case p.typ of
  2462. typesym :
  2463. def:=tstoreddef(ttypesym(p).restype.def);
  2464. varsym :
  2465. def:=tstoreddef(tvarsym(p).vartype.def);
  2466. else
  2467. internalerror(200108263);
  2468. end;
  2469. { only create inittable once for each definition }
  2470. if not(df_has_inittable in def.defoptions) then
  2471. begin
  2472. { definition should be in the same symtable as the symbol }
  2473. if p.owner<>def.owner then
  2474. internalerror(200108264);
  2475. { create rttisym }
  2476. rsym:=trttisym.create(p.name,initrtti);
  2477. p.owner.insert(rsym);
  2478. { register rttisym in definition }
  2479. include(def.defoptions,df_has_inittable);
  2480. def.inittablesym:=rsym;
  2481. { write inittable data }
  2482. def.write_child_rtti_data(initrtti);
  2483. if (cs_create_smart in aktmoduleswitches) then
  2484. rttiList.concat(Tai_cut.Create);
  2485. rttilist.concat(tai_align.create(const_align(pointer_size)));
  2486. rttiList.concat(Tai_symbol.Create_global(rsym.get_label,0));
  2487. def.write_rtti_data(initrtti);
  2488. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2489. end;
  2490. end;
  2491. end.
  2492. {
  2493. $Log$
  2494. Revision 1.143 2004-01-16 18:08:39 daniel
  2495. * Applied Peters patch
  2496. Revision 1.142 2004/01/15 23:16:32 daniel
  2497. + Cleanup of stabstring generation code. Cleaner, faster, and compiler
  2498. executable reduced by 50 kb,
  2499. Revision 1.141 2004/01/11 23:56:20 daniel
  2500. * Experiment: Compress strings to save memory
  2501. Did not save a single byte of mem; clearly the core size is boosted by
  2502. temporary memory usage...
  2503. Revision 1.140 2004/01/06 15:46:12 peter
  2504. * fix stabs for locals
  2505. Revision 1.139 2003/12/23 22:13:26 peter
  2506. * don't generate rtti for errordef
  2507. Revision 1.138 2003/12/12 12:09:40 marco
  2508. * always generate RTTI patch from peter
  2509. Revision 1.137 2003/12/01 18:44:15 peter
  2510. * fixed some crashes
  2511. * fixed varargs and register calling probs
  2512. Revision 1.136 2003/11/29 18:16:39 jonas
  2513. * don't internalerror when emitting debuginfo for LOC_FPUREGISTER
  2514. Revision 1.135 2003/11/23 17:05:16 peter
  2515. * register calling is left-right
  2516. * parameter ordering
  2517. * left-right calling inserts result parameter last
  2518. Revision 1.134 2003/10/30 16:23:13 peter
  2519. * don't search for overloads in parents for constructors
  2520. Revision 1.133 2003/10/29 21:56:28 peter
  2521. * procsym.deref derefs only own procdefs
  2522. * reset paracount in procdef.deref so a second deref doesn't increase
  2523. the paracounts to invalid values
  2524. Revision 1.132 2003/10/29 19:48:51 peter
  2525. * renamed mangeldname_prefix to make_mangledname and made it more
  2526. generic
  2527. * make_mangledname is now also used for internal threadvar/resstring
  2528. lists
  2529. * Add P$ in front of program modulename to prevent duplicated symbols
  2530. at assembler level, because the main program can have the same name
  2531. as a unit, see webtbs/tw1251b
  2532. Revision 1.131 2003/10/28 15:36:01 peter
  2533. * absolute to object field supported, fixes tb0458
  2534. Revision 1.130 2003/10/22 20:40:00 peter
  2535. * write derefdata in a separate ppu entry
  2536. Revision 1.129 2003/10/22 15:22:33 peter
  2537. * fixed unitsym-globalsymtable relation so the uses of a unit
  2538. is counted correctly
  2539. Revision 1.128 2003/10/21 18:14:30 peter
  2540. * fix writing of widechar to ppu
  2541. Revision 1.127 2003/10/17 14:38:32 peter
  2542. * 64k registers supported
  2543. * fixed some memory leaks
  2544. Revision 1.126 2003/10/13 14:05:12 peter
  2545. * removed is_visible_for_proc
  2546. * search also for class overloads when finding interface
  2547. implementations
  2548. Revision 1.125 2003/10/08 19:19:45 peter
  2549. * set_varstate cleanup
  2550. Revision 1.124 2003/10/07 21:14:33 peter
  2551. * compare_paras() has a parameter to ignore hidden parameters
  2552. * cross unit overload searching ignores hidden parameters when
  2553. comparing parameter lists. Now function(string):string is
  2554. not overriden with procedure(string) which has the same visible
  2555. parameter list
  2556. Revision 1.123 2003/10/07 15:17:07 peter
  2557. * inline supported again, LOC_REFERENCEs are used to pass the
  2558. parameters
  2559. * inlineparasymtable,inlinelocalsymtable removed
  2560. * exitlabel inserting fixed
  2561. Revision 1.122 2003/10/01 20:34:49 peter
  2562. * procinfo unit contains tprocinfo
  2563. * cginfo renamed to cgbase
  2564. * moved cgmessage to verbose
  2565. * fixed ppc and sparc compiles
  2566. Revision 1.121 2003/09/25 21:25:37 peter
  2567. * has_local_copy gdb fix
  2568. Revision 1.120 2003/09/25 16:18:54 peter
  2569. * fixed stabs for globals,static
  2570. Revision 1.119 2003/09/23 17:56:06 peter
  2571. * locals and paras are allocated in the code generation
  2572. * tvarsym.localloc contains the location of para/local when
  2573. generating code for the current procedure
  2574. Revision 1.118 2003/09/16 16:17:01 peter
  2575. * varspez in calls to push_addr_param
  2576. Revision 1.117 2003/09/14 13:20:12 peter
  2577. * fix previous commit, also include objectsymtable
  2578. Revision 1.116 2003/09/14 12:58:00 peter
  2579. * support mulitple overloads in implementation, this is delphi
  2580. compatible
  2581. * procsym only stores the overloads available in the interface
  2582. Revision 1.115 2003/09/03 15:55:01 peter
  2583. * NEWRA branch merged
  2584. Revision 1.114 2003/09/03 11:18:37 florian
  2585. * fixed arm concatcopy
  2586. + arm support in the common compiler sources added
  2587. * moved some generic cg code around
  2588. + tfputype added
  2589. * ...
  2590. Revision 1.113.2.2 2003/08/29 17:28:59 peter
  2591. * next batch of updates
  2592. Revision 1.113.2.1 2003/08/27 19:55:54 peter
  2593. * first tregister patch
  2594. Revision 1.113 2003/08/20 20:29:06 daniel
  2595. * Some more R_NO changes
  2596. * Preventive code to loadref added
  2597. Revision 1.112 2003/07/05 22:41:59 peter
  2598. * check if owner.defowner is valid when checking private/protected
  2599. Revision 1.111 2003/07/04 22:41:41 pierre
  2600. * single threadvar debugging support
  2601. Revision 1.110 2003/06/13 21:19:31 peter
  2602. * current_procdef removed, use current_procinfo.procdef instead
  2603. Revision 1.109 2003/06/07 20:26:32 peter
  2604. * re-resolving added instead of reloading from ppu
  2605. * tderef object added to store deref info for resolving
  2606. Revision 1.108 2003/06/05 17:53:30 peter
  2607. * fix to compile without gdb
  2608. Revision 1.107 2003/06/02 22:59:17 florian
  2609. * absolutesyms aren't fpuregable either
  2610. Revision 1.106 2003/05/30 18:48:17 jonas
  2611. * fixed intregister bug
  2612. * fixed error in my previous commit: vo_(fpu)regable should only be set
  2613. for (inline)localsymtable and (inline)parasymtable entries
  2614. Revision 1.105 2003/05/30 13:35:10 jonas
  2615. * the vartype field of tvarsym is now a property, because is_XXXregable
  2616. must be updated when the vartype is changed
  2617. Revision 1.104 2003/05/15 18:58:53 peter
  2618. * removed selfpointer_offset, vmtpointer_offset
  2619. * tvarsym.adjusted_address
  2620. * address in localsymtable is now in the real direction
  2621. * removed some obsolete globals
  2622. Revision 1.103 2003/05/12 18:13:57 peter
  2623. * create rtti label using newasmsymboldata and update binding
  2624. only when calling tai_symbol.create
  2625. * tai_symbol.create_global added
  2626. Revision 1.102 2003/05/09 17:47:03 peter
  2627. * self moved to hidden parameter
  2628. * removed hdisposen,hnewn,selfn
  2629. Revision 1.101 2003/05/05 14:53:16 peter
  2630. * vs_hidden replaced by is_hidden boolean
  2631. Revision 1.100 2003/04/27 11:21:34 peter
  2632. * aktprocdef renamed to current_procinfo.procdef
  2633. * procinfo renamed to current_procinfo
  2634. * procinfo will now be stored in current_module so it can be
  2635. cleaned up properly
  2636. * gen_main_procsym changed to create_main_proc and release_main_proc
  2637. to also generate a tprocinfo structure
  2638. * fixed unit implicit initfinal
  2639. Revision 1.99 2003/04/27 10:03:18 jonas
  2640. * fixed stabs generation for local variables on systems where they have
  2641. a positive offset relative to the stack/framepointer
  2642. Revision 1.98 2003/04/27 07:29:51 peter
  2643. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  2644. a new procdef declaration
  2645. * aktprocsym removed
  2646. * lexlevel removed, use symtable.symtablelevel instead
  2647. * implicit init/final code uses the normal genentry/genexit
  2648. * funcret state checking updated for new funcret handling
  2649. Revision 1.97 2003/04/25 20:59:35 peter
  2650. * removed funcretn,funcretsym, function result is now in varsym
  2651. and aliases for result and function name are added using absolutesym
  2652. * vs_hidden parameter for funcret passed in parameter
  2653. * vs_hidden fixes
  2654. * writenode changed to printnode and released from extdebug
  2655. * -vp option added to generate a tree.log with the nodetree
  2656. * nicer printnode for statements, callnode
  2657. Revision 1.96 2003/04/23 13:13:58 peter
  2658. * fix operator overload search parameter order
  2659. Revision 1.95 2003/04/10 17:57:53 peter
  2660. * vs_hidden released
  2661. Revision 1.94 2003/03/17 15:54:22 peter
  2662. * store symoptions also for procdef
  2663. * check symoptions (private,public) when calculating possible
  2664. overload candidates
  2665. Revision 1.93 2003/01/15 01:44:33 peter
  2666. * merged methodpointer fixes from 1.0.x
  2667. Revision 1.92 2003/01/09 21:52:38 peter
  2668. * merged some verbosity options.
  2669. * V_LineInfo is a verbosity flag to include line info
  2670. Revision 1.91 2003/01/08 18:43:57 daniel
  2671. * Tregister changed into a record
  2672. Revision 1.90 2003/01/03 12:15:56 daniel
  2673. * Removed ifdefs around notifications
  2674. ifdefs around for loop optimizations remain
  2675. Revision 1.89 2003/01/02 11:14:02 michael
  2676. + Patch from peter to support initial values for local variables
  2677. Revision 1.88 2003/01/01 22:51:03 peter
  2678. * high value insertion changed so it works also when 2 parameters
  2679. are passed
  2680. Revision 1.87 2002/12/31 09:55:58 daniel
  2681. + Notification implementation complete
  2682. + Add for loop code optimization using notifications
  2683. results in 1.5-1.9% speed improvement in nestloop benchmark
  2684. Optimization incomplete, compiler does not cycle yet with
  2685. notifications enabled.
  2686. Revision 1.86 2002/12/30 22:44:53 daniel
  2687. * Some work on notifications
  2688. Revision 1.85 2002/12/27 18:07:44 peter
  2689. * fix crashes when searching symbols
  2690. Revision 1.84 2002/12/20 16:02:22 peter
  2691. * fix stupid copy&paste bug in binary operator search
  2692. Revision 1.83 2002/12/16 22:08:31 peter
  2693. * fix order of procdefs in procsym, procdefs are now always appended
  2694. so that loading from a ppu will keep the same order. This is
  2695. important for the generation of VMTs
  2696. Revision 1.82 2002/12/11 22:39:23 peter
  2697. * better error message when no operator is found for equal
  2698. Revision 1.81 2002/12/07 14:27:10 carl
  2699. * 3% memory optimization
  2700. * changed some types
  2701. + added type checking with different size for call node and for
  2702. parameters
  2703. Revision 1.80 2002/12/06 17:51:11 peter
  2704. * merged cdecl and array fixes
  2705. Revision 1.79 2002/11/27 20:04:10 peter
  2706. * tvarsym.get_push_size replaced by paramanager.push_size
  2707. Revision 1.78 2002/11/27 02:34:20 peter
  2708. * only find real equal procvars
  2709. Revision 1.77 2002/11/25 18:43:34 carl
  2710. - removed the invalid if <> checking (Delphi is strange on this)
  2711. + implemented abstract warning on instance creation of class with
  2712. abstract methods.
  2713. * some error message cleanups
  2714. Revision 1.76 2002/11/25 17:43:26 peter
  2715. * splitted defbase in defutil,symutil,defcmp
  2716. * merged isconvertable and is_equal into compare_defs(_ext)
  2717. * made operator search faster by walking the list only once
  2718. Revision 1.75 2002/11/23 22:50:09 carl
  2719. * some small speed optimizations
  2720. + added several new warnings/hints
  2721. Revision 1.74 2002/11/22 22:48:11 carl
  2722. * memory optimization with tconstsym (1.5%)
  2723. Revision 1.73 2002/11/18 17:31:59 peter
  2724. * pass proccalloption to ret_in_xxx and push_xxx functions
  2725. Revision 1.72 2002/11/17 16:31:57 carl
  2726. * memory optimization (3-4%) : cleanup of tai fields,
  2727. cleanup of tdef and tsym fields.
  2728. * make it work for m68k
  2729. Revision 1.71 2002/11/09 15:30:07 carl
  2730. + align RTTI tables
  2731. Revision 1.70 2002/10/13 21:33:37 peter
  2732. * give correct fileposition for undefined forward procs
  2733. Revision 1.69 2002/10/05 12:43:29 carl
  2734. * fixes for Delphi 6 compilation
  2735. (warning : Some features do not work under Delphi)
  2736. Revision 1.68 2002/10/05 00:52:20 peter
  2737. * split boolean check in two lines for easier debugging
  2738. Revision 1.67 2002/09/26 12:04:53 florian
  2739. + constsym with type=constguid can be written to ppu now,
  2740. fixes web bug 1820
  2741. Revision 1.66 2002/09/16 14:11:13 peter
  2742. * add argument to equal_paras() to support default values or not
  2743. Revision 1.65 2002/09/09 17:34:16 peter
  2744. * tdicationary.replace added to replace and item in a dictionary. This
  2745. is only allowed for the same name
  2746. * varsyms are inserted in symtable before the types are parsed. This
  2747. fixes the long standing "var longint : longint" bug
  2748. - consume_idlist and idstringlist removed. The loops are inserted
  2749. at the callers place and uses the symtable for duplicate id checking
  2750. Revision 1.64 2002/09/08 11:10:17 carl
  2751. * bugfix 2109 (bad imho, but only way)
  2752. Revision 1.63 2002/09/07 18:17:41 florian
  2753. + tvarsym.paraitem added
  2754. Revision 1.62 2002/09/07 15:25:10 peter
  2755. * old logs removed and tabs fixed
  2756. Revision 1.61 2002/09/05 19:29:45 peter
  2757. * memdebug enhancements
  2758. Revision 1.60 2002/09/05 14:51:42 peter
  2759. * internalerror instead of crash in getprocdef
  2760. Revision 1.59 2002/09/03 16:26:27 daniel
  2761. * Make Tprocdef.defs protected
  2762. Revision 1.58 2002/09/01 08:01:16 daniel
  2763. * Removed sets from Tcallnode.det_resulttype
  2764. + Added read/write notifications of variables. These will be usefull
  2765. for providing information for several optimizations. For example
  2766. the value of the loop variable of a for loop does matter is the
  2767. variable is read after the for loop, but if it's no longer used
  2768. or written, it doesn't matter and this can be used to optimize
  2769. the loop code generation.
  2770. Revision 1.57 2002/08/25 19:25:21 peter
  2771. * sym.insert_in_data removed
  2772. * symtable.insertvardata/insertconstdata added
  2773. * removed insert_in_data call from symtable.insert, it needs to be
  2774. called separatly. This allows to deref the address calculation
  2775. * procedures now calculate the parast addresses after the procedure
  2776. directives are parsed. This fixes the cdecl parast problem
  2777. * push_addr_param has an extra argument that specifies if cdecl is used
  2778. or not
  2779. Revision 1.56 2002/08/25 09:06:21 peter
  2780. * fixed loop in concat_procdefs
  2781. Revision 1.55 2002/08/20 16:54:40 peter
  2782. * write address of varsym always
  2783. Revision 1.54 2002/08/20 10:31:26 daniel
  2784. * Tcallnode.det_resulttype rewritten
  2785. Revision 1.53 2002/08/18 20:06:27 peter
  2786. * inlining is now also allowed in interface
  2787. * renamed write/load to ppuwrite/ppuload
  2788. * tnode storing in ppu
  2789. * nld,ncon,nbas are already updated for storing in ppu
  2790. Revision 1.52 2002/08/17 09:23:42 florian
  2791. * first part of procinfo rewrite
  2792. Revision 1.51 2002/08/16 14:24:59 carl
  2793. * issameref() to test if two references are the same (then emit no opcodes)
  2794. + ret_in_reg to replace ret_in_acc
  2795. (fix some register allocation bugs at the same time)
  2796. + save_std_register now has an extra parameter which is the
  2797. usedinproc registers
  2798. Revision 1.50 2002/08/13 21:40:57 florian
  2799. * more fixes for ppc calling conventions
  2800. Revision 1.49 2002/08/12 15:08:40 carl
  2801. + stab register indexes for powerpc (moved from gdb to cpubase)
  2802. + tprocessor enumeration moved to cpuinfo
  2803. + linker in target_info is now a class
  2804. * many many updates for m68k (will soon start to compile)
  2805. - removed some ifdef or correct them for correct cpu
  2806. Revision 1.48 2002/08/11 14:32:28 peter
  2807. * renamed current_library to objectlibrary
  2808. Revision 1.47 2002/08/11 13:24:14 peter
  2809. * saving of asmsymbols in ppu supported
  2810. * asmsymbollist global is removed and moved into a new class
  2811. tasmlibrarydata that will hold the info of a .a file which
  2812. corresponds with a single module. Added librarydata to tmodule
  2813. to keep the library info stored for the module. In the future the
  2814. objectfiles will also be stored to the tasmlibrarydata class
  2815. * all getlabel/newasmsymbol and friends are moved to the new class
  2816. Revision 1.46 2002/07/23 10:13:23 daniel
  2817. * Added important comment
  2818. Revision 1.45 2002/07/23 09:51:26 daniel
  2819. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2820. are worth comitting.
  2821. Revision 1.44 2002/07/20 17:45:29 daniel
  2822. * Register variables are now possible for global variables too. This is
  2823. important for small programs without procedures.
  2824. Revision 1.43 2002/07/20 11:57:58 florian
  2825. * types.pas renamed to defbase.pas because D6 contains a types
  2826. unit so this would conflicts if D6 programms are compiled
  2827. + Willamette/SSE2 instructions to assembler added
  2828. Revision 1.42 2002/07/11 14:41:31 florian
  2829. * start of the new generic parameter handling
  2830. }