FreeBASIC  0.91.0
edbg_stab.bas
Go to the documentation of this file.
1 '' debug emitter (stabs format) for GNU assembler (GAS)
2 ''
3 '' chng: nov/2004 written [v1ctor]
4 
5 
6 #include once "fb.bi"
7 #include once "fbint.bi"
8 #include once "lex.bi"
9 #include once "ir.bi"
10 #include once "emit.bi"
11 #include once "emitdbg.bi"
12 #include once "stabs.bi"
13 
14 type EDBGCTX
15  typecnt as uinteger
16 
17  label as FBSYMBOL ptr
18  lnum as integer
19  pos as integer
20  isnewline as integer
21 
22  firstline as integer '' first non-decl line
23  lastline as integer '' last /
24 
25  filename as zstring * FB_MAXPATHLEN+1
26  incfile as zstring ptr
27 end type
28 
29 declare sub hDeclUDT ( _
30  byval sym as FBSYMBOL ptr _
31  )
32 
33 declare sub hDeclENUM ( _
34  byval sym as FBSYMBOL ptr _
35  )
36 
37 declare function hDeclPointer ( _
38  byref dtype as integer _
39  ) as string
40 
41 declare function hDeclArrayDims ( _
42  byval sym as FBSYMBOL ptr _
43  ) as string
44 
45 declare function hGetDataType _
46  ( _
47  byval sym as FBSYMBOL ptr, _
48  byval do_array_typing as integer = FALSE _
49  ) as string
50 
51 
52 '' globals
53  dim shared ctx as EDBGCTX
54 
55  dim shared remapTB(0 to FB_DATATYPES-1) as integer = _
56  { _
57  7, _ '' void
58  2, _ '' byte
59  3, _ '' ubyte
60  4, _ '' char
61  5, _ '' short
62  6, _ '' ushort
63  6, _ '' wchar
64  1, _ '' int
65  8, _ '' uint
66  1, _ '' enum
67  8, _ '' bitfield
68  1, _ '' long
69  8, _ '' ulong
70  9, _ '' longint
71  10, _ '' ulongint
72  11, _ '' single
73  12, _ '' double
74  13, _ '' string
75  14 _ '' fix-len string
76  }
77 
78  dim shared stabsTb(0 to 14) as const zstring ptr = _
79  { _
80  @"integer:t1=-1", _
81  @"void:t7=-11", _
82  @"byte:t2=-6", _
83  @"ubyte:t3=-5", _
84  @"char:t4=-2", _
85  @"short:t5=-3", _
86  @"ushort:t6=-7", _
87  @"uinteger:t8=-8", _
88  @"longint:t9=-31", _
89  @"ulongint:t10=-32", _
90  @"single:t11=-12", _
91  @"double:t12=-13", _
92  @"string:t13=s12data:15,0,32;len:1,32,32;size:1,64,32;;", _
93  @"fixstr:t14=-2", _
94  @"pchar:t15=*4;" _
95  }
96 
97 sub edbgInit( )
98  '' Remap wchar to target-specific type
99  remapTB(FB_DATATYPE_WCHAR) = remapTB(env.target.wchar)
100 
101  '' The above tables assume 32bit, but that's ok because -gen gas
102  '' currently only supports 32bit x86 anyways, and this stabs emitter
103  '' is only used with -gen gas.
104  assert( fbCpuTypeIs64bit( ) = FALSE )
105 end sub
106 
107 '':::::
108 sub hEmitSTABS _
109  ( _
110  byval _type as integer, _
111  byval _string as const zstring ptr, _
112  byval _other as integer = 0, _
113  byval _desc as integer = 0, _
114  byval _value as const zstring ptr = @"0" _
115  ) static
116 
117  dim as string ostr
118 
119  ostr = ".stabs " + QUOTE
120  ostr += *hEscape( _string )
121  ostr += QUOTE + ","
122  ostr += str( _type )
123  ostr += ","
124  ostr += str( _other )
125  ostr += ","
126  ostr += str( _desc )
127  ostr += ","
128  ostr += *_value
129 
130  emitWriteStr( ostr, TRUE )
131 
132 end sub
133 
134 '':::::
135 function hMakeSTABN _
136  ( _
137  byval _type as integer, _
138  byval _other as integer = 0, _
139  byval _desc as integer = 0, _
140  byval _value as const zstring ptr _
141  ) as zstring ptr static
142 
143  static as string ostr
144 
145  ostr = ".stabn "
146  ostr += str( _type )
147  ostr += ","
148  ostr += str( _other )
149  ostr += ","
150  ostr += str( _desc )
151  ostr += ","
152  ostr += *_value
153 
154  function = strptr( ostr )
155 
156 end function
157 
158 '':::::
159 sub hEmitSTABN _
160  ( _
161  byval _type as integer, _
162  byval _other as integer = 0, _
163  byval _desc as integer = 0, _
164  byval _value as const zstring ptr = @"0" _
165  ) static
166 
167 
168  emitWriteStr( hMakeSTABN( _type, _other, _desc, _value ), TRUE )
169 
170 end sub
171 
172 '':::::
173 sub hEmitSTABD _
174  ( _
175  byval _type as integer, _
176  byval _other as integer = 0, _
177  byval _desc as integer = 0 _
178  ) static
179 
180  dim as string ostr
181 
182  ostr = ".stabd "
183  ostr += str( _type )
184  ostr += ","
185  ostr += str( _other )
186  ostr += ","
187  ostr += str( _desc )
188 
189  emitWriteStr( ostr, TRUE )
190 
191 end sub
192 
193 '':::::
194 sub hLABEL _
195  ( _
196  byval label as zstring ptr _
197  ) static
198 
199  dim ostr as string
200 
201  ostr = *label
202  ostr += ":"
203  emitWriteStr( ostr )
204 
205 end sub
206 
207 sub edbgEmitHeader( byval filename as zstring ptr )
208  dim as string lname
209 
210  if( env.clopt.debug = FALSE ) then
211  exit sub
212  end if
213 
214  ctx.typecnt = 1
215  ctx.label = NULL
216  ctx.incfile = NULL
218 
219  '' emit source file name
220  lname = *symbUniqueLabel( )
221  emitWriteStr( ".file " + QUOTE + *hEscape( filename ) + QUOTE, TRUE )
222 
223  '' directory
224  if( pathIsAbsolute( filename ) = FALSE ) then
225  hEmitSTABS( STAB_TYPE_SO, hCurDir( ) + FB_HOST_PATHDIV, 0, 0, lname )
226  end if
227 
228  '' file name
229  hEmitSTABS( STAB_TYPE_SO, filename, 0, 0, lname )
230 
231  ''
232  emitSECTION( IR_SECTION_CODE, 0 )
233  hLABEL( lname )
234 
235  '' (known) type definitions
236  for i as integer = lbound( stabsTb ) to ubound( stabsTb )
237  hEmitSTABS( STAB_TYPE_LSYM, stabsTb(i), 0, 0, "0" )
238  ctx.typecnt += 1
239  next
240 
241  emitWriteStr( "" )
242 
243  hEmitSTABS( STAB_TYPE_BINCL, filename, 0, 0 )
244 end sub
245 
246 '':::::
247 sub edbgEmitFooter( ) static
248  dim as string lname
249 
250  if( env.clopt.debug = FALSE ) then
251  exit sub
252  end if
253 
254  emitSECTION( IR_SECTION_CODE, 0 )
255 
256  '' no checkings after this
257  lname = *symbUniqueLabel( )
258  hEmitSTABS( STAB_TYPE_SO, "", 0, 0, lname )
259 
260  hLABEL( lname )
261 
262 end sub
263 
264 '':::::
265 sub edbgLineBegin _
266  ( _
267  byval proc as FBSYMBOL ptr, _
268  byval lnum as integer, _
269  byval pos_ as integer _
270  )
271 
272  if( env.clopt.debug = FALSE ) then
273  exit sub
274  end if
275 
276  if( ctx.lnum > 0 ) then
277  ctx.pos = pos_ - ctx.pos
278  if( ctx.pos > 0 ) then
280  ctx.isnewline = TRUE
281  end if
282  end if
283 
284  ctx.pos = pos_
285  ctx.lnum = lnum
286  if( ctx.isnewline ) then
290  end if
291 
292 end sub
293 
294 '':::::
295 sub edbgLineEnd _
296  ( _
297  byval proc as FBSYMBOL ptr, _
298  byval lnum as integer, _
299  byval pos_ as integer _
300  )
301 
302  if( env.clopt.debug = FALSE ) then
303  exit sub
304  end if
305 
306  if( ctx.lnum > 0 ) then
307  ctx.pos = pos_ - ctx.pos
308  if( ctx.pos > 0 ) then
310  ctx.isnewline = TRUE
311  end if
312  ctx.lnum = 0
313  end if
314 
315 end sub
316 
317 '':::::
318 sub edbgEmitLine _
319  ( _
320  byval proc as FBSYMBOL ptr, _
321  byval lnum as integer, _
322  byval label as FBSYMBOL ptr _
323  ) static
324 
325  dim as zstring ptr s
326 
327  if( env.clopt.debug = FALSE ) then
328  exit sub
329  end if
330 
331  if( ctx.firstline = -1 ) then
332  ctx.firstline = lnum
333  end if
334 
335  ctx.lastline = lnum
336 
337  '' emit current line
338  s = hMakeSTABN( STAB_TYPE_SLINE, _
339  0, _
340  lnum, _
342 
343  emitWriteStr( s )
344 
345 end sub
346 
347 '':::::
348 sub edbgEmitLineFlush _
349  ( _
350  byval proc as FBSYMBOL ptr, _
351  byval lnum as integer, _
352  byval label as FBSYMBOL ptr _
353  ) static
354 
355  if( env.clopt.debug = FALSE ) then
356  exit sub
357  end if
358 
359  hEmitSTABN( STAB_TYPE_SLINE, _
360  0, _
361  lnum, _
363 
364 end sub
365 
366 '':::::
367 sub edbgScopeBegin _
368  ( _
369  byval s as FBSYMBOL ptr _
370  ) static
371 
372  '' called by ir->ast
373 
374  if( env.clopt.debug = FALSE ) then
375  exit sub
376  end if
377 
378  s->scp.dbg.iniline = lexLineNum( )
379  s->scp.dbg.inilabel = symbAddLabel( NULL )
380 
381 end sub
382 
383 '':::::
384 sub edbgScopeEnd _
385  ( _
386  byval s as FBSYMBOL ptr _
387  ) static
388 
389  '' called by ir->ast
390 
391  if( env.clopt.debug = FALSE ) then
392  exit sub
393  end if
394 
395  s->scp.dbg.endline = lexLineNum( )
396  s->scp.dbg.endlabel = symbAddLabel( NULL )
397 
398 end sub
399 
400 '':::::
401 sub edbgEmitScopeINI _
402  ( _
403  byval s as FBSYMBOL ptr _
404  ) static
405 
406  if( env.clopt.debug = FALSE ) then
407  exit sub
408  end if
409 
410  hLABEL( symbGetMangledName( s->scp.dbg.inilabel ) )
411 
412 end sub
413 
414 '':::::
415 sub edbgEmitScopeEND _
416  ( _
417  byval s as FBSYMBOL ptr _
418  ) static
419 
420  if( env.clopt.debug = FALSE ) then
421  exit sub
422  end if
423 
424  hLABEL( symbGetMangledName( s->scp.dbg.endlabel ) )
425 
426 end sub
427 
428 '':::::
429 sub edbgProcBegin _
430  ( _
431  byval proc as FBSYMBOL ptr _
432  ) static
433 
434  '' called by ir->ast
435 
436  proc->proc.ext->dbg.iniline = lexLineNum( )
437 
438 end sub
439 
440 '':::::
441 sub edbgProcEnd _
442  ( _
443  byval proc as FBSYMBOL ptr _
444  ) static
445 
446  '' called by ir->ast
447 
448  proc->proc.ext->dbg.endline = lexLineNum( )
449 
450 end sub
451 
452 '':::::
453 sub edbgProcEmitBegin _
454  ( _
455  byval proc as FBSYMBOL ptr _
456  ) static
457 
458  '' called by emit->ir
459 
460  ctx.firstline = -1
461  ctx.lastline = -1
462 
463 end sub
464 
465 sub hDeclArgs(byval proc as FBSYMBOL ptr)
466  dim as FBSYMBOL ptr s = symbGetProcSymbTbHead( proc )
467  while (s)
468  if (symbIsVar(s)) then
469  '' Parameter?
470  if (symbIsParam(s)) then
471  edbgEmitProcArg(s)
472  end if
473  end if
474  s = s->next
475  wend
476 end sub
477 
478 '':::::
479 sub edbgEmitProcHeader _
480  ( _
481  byval proc as FBSYMBOL ptr _
482  ) static
483 
484  dim as string desc, procname
485 
486  if( env.clopt.debug = FALSE ) then
487  exit sub
488  end if
489 
490  '' For procs defined in include files we must emit corresponding
491  '' include file blocks, so they appear as being declared in the include
492  '' file rather than the toplevel .bas file name.
493  edbgInclude( symbGetProcIncFile( proc ) )
494 
495  '' main?
496  if( symbGetIsMainProc( proc ) ) then
497  '' main proc (the entry point)
498  hEmitSTABS( STAB_TYPE_MAIN, _
499  fbGetEntryPoint( ), _
500  0, _
501  1, _
503 
504  '' set the entry line
505  hEmitSTABD( STAB_TYPE_SLINE, 0, 1 )
506 
507  '' also correct the end and start lines
508  proc->proc.ext->dbg.iniline = 1
509  proc->proc.ext->dbg.endline = lexLineNum( )
510 
511  desc = fbGetEntryPoint( )
512  else
513  desc = *symbGetDBGName( proc )
514  end if
515 
516  ''
517  procname = *symbGetMangledName( proc )
518 
519  if( symbIsPublic( proc ) ) then
520  desc += ":F"
521  else
522  desc += ":f"
523  end if
524 
525  desc += hGetDataType( proc )
526 
527  hEmitSTABS( STAB_TYPE_FUN, desc, 0, proc->proc.ext->dbg.iniline, procname )
528 
529  hDeclArgs( proc )
530 
531  ''
532  ctx.isnewline = TRUE
533  ctx.lnum = 0
534  ctx.pos = 0
535  ctx.label = NULL
536 
537 end sub
538 
539 '':::::
540 sub hDeclLocalVars _
541  ( _
542  byval proc as FBSYMBOL ptr, _
543  byval blk as FBSYMBOL ptr, _
544  byval inilabel as FBSYMBOL ptr, _
545  byval endlabel as FBSYMBOL ptr _
546  )
547 
548  dim as FBSYMBOL ptr shead, s
549  static as integer scopecnt
550 
551  '' proc?
552  if( symbIsProc( blk ) ) then
553  shead = symbGetProcSymbTbHead( blk )
554 
555  '' scope block..
556  else
557  shead = symbGetScopeSymbTbHead( blk )
558  end if
559 
560  '' for each symbol..
561  scopecnt = 0
562  s = shead
563  do while( s <> NULL )
564 
565  select case symbGetClass( s )
566  '' variable?
567  case FB_SYMBCLASS_VAR
568 
569  '' not an argument, temporary, descriptor or func result?
570  if( (symbGetAttrib( s ) and _
571  (FB_SYMBATTRIB_PARAMBYDESC or _
572  FB_SYMBATTRIB_PARAMBYVAL or _
573  FB_SYMBATTRIB_PARAMBYREF or _
574  FB_SYMBATTRIB_TEMP or _
575  FB_SYMBATTRIB_DESCRIPTOR or _
576  FB_SYMBATTRIB_FUNCRESULT)) = 0 ) then
577  '' And nothing marked IMPLICIT either (e.g. symbAddImplicitVar(),
578  '' some implicitly generated vars are not TEMPs)
579  if( symbGetIsImplicit( s ) = FALSE ) then
580  edbgEmitLocalVar( s, symbIsStatic( s ) )
581  end if
582  end if
583 
584  '' scope? must be emitted later, due the GDB quirks
585  case FB_SYMBCLASS_SCOPE
586  scopecnt += 1
587  end select
588 
589  s = s->next
590  loop
591 
592  '' emit block (change the scope)
593  hEmitSTABN( STAB_TYPE_LBRAC, _
594  0, _
595  0, _
596  *symbGetMangledName( inilabel ) + "-" + *symbGetMangledName( proc ) )
597 
598  if( scopecnt > 0 ) then
599  '' for each scope..
600  s = shead
601  do while( s <> NULL )
602  if( symbIsScope( s ) ) then
603  hDeclLocalVars( proc, s, s->scp.dbg.inilabel, s->scp.dbg.endlabel )
604  end if
605 
606  s = s->next
607  loop
608  end if
609 
610  hEmitSTABN( STAB_TYPE_RBRAC, _
611  0, _
612  0, _
613  *symbGetMangledName( endlabel ) + "-" + *symbGetMangledName( proc ) )
614 
615 end sub
616 
617 '':::::
618 sub edbgEmitProcFooter _
619  ( _
620  byval proc as FBSYMBOL ptr, _
621  byval initlabel as FBSYMBOL ptr, _
622  byval exitlabel as FBSYMBOL ptr _
623  ) static
624 
625  dim as string procname, lname
626 
627  if( env.clopt.debug = FALSE ) then
628  exit sub
629  end if
630 
631  ''
632  procname = *symbGetMangledName( proc )
633 
634  ''
635  hDeclLocalVars( proc, proc, initlabel, exitlabel )
636 
637  lname = *symbUniqueLabel( )
638  hLABEL( lname )
639 
640  '' emit end proc (FUN with a null string)
641  hEmitSTABS( STAB_TYPE_FUN, "", 0, 0, lname + "-" + procname )
642 
643  ''
644  ctx.isnewline = TRUE
645  ctx.lnum = 0
646  ctx.pos = 0
647  ctx.label = NULL
648 
649 end sub
650 
651 function hDeclUdtField _
652  ( _
653  byval fld as FBSYMBOL ptr, _
654  byval stypeopt as zstring ptr = NULL, _
655  byval idprefix as zstring ptr = NULL, _
656  byval baseoffset as integer = 0 _
657  ) as string
658 
659  dim as string desc
660  dim as integer dtype = any
661 
662  if( idprefix ) then
663  desc += *idprefix
664  end if
665 
666  desc += *symbGetName( fld )
667  desc += ":"
668 
669  dtype = symbGetType( fld )
670  if( typeIsPtr( dtype ) ) then
671  desc += hDeclPointer( dtype )
672  end if
673 
674  if( stypeopt = NULL ) then
675  desc += str( remapTB(dtype) )
676  else
677  desc += *stypeopt
678  end if
679 
680  desc += "," + str( (baseoffset + symbGetOfs( fld )) * 8 )
681  desc += "," + str( symbGetLen( fld ) * 8 )
682  desc += ";"
683 
684  function = desc
685 end function
686 
687 function hDeclDynArray( byval sym as FBSYMBOL ptr ) as string static
688  dim as string desc, dimdesc
689  dim as FBVARDIM ptr d = any
690  dim as integer baseoffset = any, i = any
691  dim as FBSYMBOL ptr fld = any
692 
693  '' declare the array descriptor
694  desc = str( ctx.typecnt ) + "=s" + str( symbGetLen( symb.fbarray ) )
695  ctx.typecnt += 1
696 
697  dimdesc = hDeclArrayDims( sym )
698 
699  dimdesc += hGetDataType( sym, TRUE )
700 
701  '' FBARRAY fields
702 
703  '' data
704  fld = symbUdtGetFirstField( symb.fbarray )
705  desc += hDeclUdtField( fld, strptr( dimdesc ) )
706 
707  '' ptr
708  fld = symbUdtGetNextField( fld )
709  desc += hDeclUdtField( fld, strptr( dimdesc ) )
710 
711  '' size
712  fld = symbUdtGetNextField( fld )
713  desc += hDeclUdtField( fld )
714 
715  '' element_len
716  fld = symbUdtGetNextField( fld )
717  desc += hDeclUdtField( fld )
718 
719  '' dimensions
720  fld = symbUdtGetNextField( fld )
721  desc += hDeclUdtField( fld )
722 
723  '' dimTB
724  fld = symbUdtGetNextField( fld )
725  baseoffset = symbGetOfs( fld )
726  i = 1
727  d = symbGetArrayFirstDim( sym )
728  do
729  dimdesc = "dim" + str( i ) + "_"
730 
731  '' FBARRAYDIM fields
732 
733  '' elements
734  fld = symbUdtGetFirstField( symb.fbarraydim )
735  desc += hDeclUdtField( fld, , dimdesc, baseoffset )
736 
737  '' lbound
738  fld = symbUdtGetNextField( fld )
739  desc += hDeclUdtField( fld, , dimdesc, baseoffset )
740 
741  '' ubound
742  fld = symbUdtGetNextField( fld )
743  desc += hDeclUdtField( fld, , dimdesc, baseoffset )
744 
745  baseoffset += symbGetLen( symb.fbarraydim )
746 
747  if( d = NULL ) then
748  exit do
749  end if
750 
751  d = d->next
752  loop while( d )
753 
754  desc += ";"
755 
756  function = desc
757 end function
758 
759 '':::::
760 function hDeclPointer _
761  ( _
762  byref dtype as integer _
763  ) as string static
764 
765  dim as string desc
766 
767  desc = ""
768  do while( typeIsPtr( dtype ) )
769  dtype = typeDeref( dtype )
770  desc += str( ctx.typecnt ) + "=*"
771  ctx.typecnt += 1
772  loop
773 
774  function = desc
775 
776 end function
777 
778 '':::::
779 function hDeclArrayDims _
780  ( _
781  byval sym as FBSYMBOL ptr _
782  ) as string static
783 
784  dim as FBVARDIM ptr d
785  dim as string desc
786 
787  desc = str( ctx.typecnt ) + "="
788  ctx.typecnt += 1
789 
790  d = symbGetArrayFirstDim( sym )
791  do while( d <> NULL )
792  desc += "ar1;"
793  desc += str( d->lower ) + ";"
794  desc += str( d->upper ) + ";"
795  d = d->next
796  loop
797 
798  function = desc
799 
800 end function
801 
802 '':::::
803 function hGetDataType _
804  ( _
805  byval sym as FBSYMBOL ptr, _
806  byval do_array_typing as integer _
807  ) as string
808 
809  dim as integer dtype
810  dim as FBSYMBOL ptr subtype
811  dim as string desc
812 
813  if( sym = NULL ) then
814  return str( remapTB(FB_DATATYPE_VOID) )
815  end if
816 
817  '' array?
818  if( do_array_typing = FALSE ) then
819  if( symbIsArray( sym ) ) then
820  '' dynamic?
821  if( symbIsDynamic( sym ) or symbIsParamByDesc( sym ) ) then
822  desc = hDeclDynArray( sym )
823  else
824  desc = hDeclArrayDims( sym )
825  end if
826  else
827  desc = ""
828  end if
829  else
830  desc = ""
831  end if
832 
833  dtype = symbGetType( sym )
834  subtype = symbGetSubtype( sym )
835 
836  if( do_array_typing ) then
837  dtype = typeAddrOf( dtype )
838  end if
839 
840  '' pointer?
841  if( typeIsPtr( dtype ) ) then
842  desc += hDeclPointer( dtype )
843  end if
844 
845  '' the const qualifier isn't taken into account
846  dtype = typeUnsetIsConst( dtype )
847 
848  select case as const dtype
849  '' UDT?
850  case FB_DATATYPE_STRUCT
851  if( symbIsDescriptor( sym ) = FALSE ) then
852  if( subtype->udt.dbg.typenum = INVALID ) then
853  hDeclUDT( subtype )
854  end if
855 
856  desc += str( subtype->udt.dbg.typenum )
857  end if
858 
859  '' ENUM?
860  case FB_DATATYPE_ENUM
861  if( subtype->enum_.dbg.typenum = INVALID ) then
862  hDeclENUM( subtype )
863  end if
864 
865  desc += str( subtype->enum_.dbg.typenum )
866 
867  '' function pointer?
868  case FB_DATATYPE_FUNCTION
869  desc += str( ctx.typecnt ) + "=f"
870  ctx.typecnt += 1
871  desc += hGetDataType( subtype )
872 
873  '' forward reference?
874  case FB_DATATYPE_FWDREF
875  desc += str( remapTB(FB_DATATYPE_VOID) )
876 
877  '' bitfield?
878  case FB_DATATYPE_BITFIELD
879  desc += hGetDataType( subtype )
880 
881  '' ordinary type..
882  case else
883  desc += str( remapTB(dtype) )
884 
885  end select
886 
887  function = desc
888 
889 end function
890 
891 sub hDeclUDT( byval sym as FBSYMBOL ptr )
892  dim as FBSYMBOL ptr fld = any
893  dim as string desc
894 
895  sym->udt.dbg.typenum = ctx.typecnt
896  ctx.typecnt += 1
897 
898  desc = *symbGetDBGName( sym )
899 
900  desc += ":Tt" + str( sym->udt.dbg.typenum ) + "=s" + str( symbGetLen( sym ) )
901 
902  fld = symbUdtGetFirstField( sym )
903  while( fld )
904  desc += *symbGetName( fld ) + ":" + hGetDataType( fld )
905  desc += "," + str( symbGetUDTElmBitOfs( fld ) )
906  desc += "," + str( symbGetUDTElmBitLen( fld ) )
907  desc += ";"
908  fld = symbUdtGetNextField( fld )
909  wend
910 
911  desc += ";"
912 
913  hEmitSTABS( STAB_TYPE_LSYM, desc, 0, 0, "0" )
914 end sub
915 
916 '':::::
917 sub hDeclENUM _
918  ( _
919  byval sym as FBSYMBOL ptr _
920  )
921 
922  dim as FBSYMBOL ptr e
923  dim as string desc
924 
925  sym->enum_.dbg.typenum = ctx.typecnt
926  ctx.typecnt += 1
927 
928  desc = *symbGetDBGName( sym )
929 
930  desc += ":T" + str( sym->enum_.dbg.typenum ) + "=e"
931 
932  e = symbGetENUMFirstElm( sym )
933  do while( e <> NULL )
934  desc += *symbGetName( e ) + ":" + str( symbGetConstInt( e ) ) + ","
935 
936  e = symbGetENUMNextElm( e )
937  loop
938 
939  desc += ";"
940 
941  hEmitSTABS( STAB_TYPE_LSYM, desc, 0, 0, "0" )
942 
943 end sub
944 
945 '':::::
946 sub edbgEmitGlobalVar _
947  ( _
948  byval sym as FBSYMBOL ptr, _
949  byval section as integer _
950  ) static
951 
952  dim as integer t, attrib
953  dim as string desc
954  dim as zstring ptr sname
955 
956  if( env.clopt.debug = FALSE ) then
957  exit sub
958  end if
959 
960  '' temporary?
961  if( symbIsTemp( sym ) ) then
962  exit sub
963  end if
964 
965  '' really global? (because the static local vars)
966  if( symbIsLocal( sym ) ) then
967  exit sub
968  end if
969 
970  '' depends on section
971  select case section
972  case IR_SECTION_CONST
973  t = STAB_TYPE_FUN
974  case IR_SECTION_DATA
975  t = STAB_TYPE_STSYM
976  case IR_SECTION_BSS
977  t = STAB_TYPE_LCSYM
978  end select
979 
980  '' allocation type (static, global, etc)
981  desc = *symbGetDBGName( sym )
982 
983  attrib = symbGetAttrib( sym )
984  if( (attrib and (FB_SYMBATTRIB_PUBLIC or FB_SYMBATTRIB_COMMON)) > 0 ) then
985  desc += ":G"
986  elseif( (attrib and FB_SYMBATTRIB_STATIC) > 0 ) then
987  desc += ":S"
988  else
989  desc += ":"
990  end if
991 
992  '' data type
993  desc += hGetDataType( sym )
994 
995  '' hack to fix the stabs data for global redim-arrays
996  '' see: http://www.freebasic.net/forum/viewtopic.php?p=117584#117584
997  #if 1 ''SARG BEGIN
998  '' workaround in case redim shared : use of back link !!!
999  if( right(desc, 2) = ":S" ) then
1000  desc = *symbGetDBGName( sym->var_.desc.array ) + ":S" + hGetDataType( sym->var_.desc.array )
1001  end if
1002  #endif ''SARG END
1003 
1004  ''
1005  if( symbIsDynamic( sym ) ) then
1006  sname = symbGetMangledName( symbGetArrayDescriptor( sym ) )
1007  else
1008  sname = symbGetMangledName( sym )
1009  end if
1010 
1011  ''
1012  hEmitSTABS( t, desc, 0, 0, *sname )
1013 
1014 end sub
1015 
1016 '':::::
1017 sub edbgEmitLocalVar _
1018  ( _
1019  byval sym as FBSYMBOL ptr, _
1020  byval isstatic as integer _
1021  ) static
1022 
1023  dim as integer t
1024  dim as string desc, value
1025 
1026  if( env.clopt.debug = FALSE ) then
1027  exit sub
1028  end if
1029 
1030  desc = *symbGetName( sym )
1031 
1032  ''
1033  if( isstatic ) then
1034  '' never referenced?
1035  if( symbGetIsAccessed( sym ) = FALSE ) then
1036  '' locals can't be public, don't check
1037  exit sub
1038  end if
1039 
1040  if( symbGetIsInitialized( sym ) ) then
1041  t = STAB_TYPE_STSYM
1042  else
1043  t = STAB_TYPE_LCSYM
1044  end if
1045  desc += ":V"
1046 
1047  '' dynamic array? use the descriptor
1048  if( symbIsDynamic( sym ) ) then
1049  value = *symbGetMangledName( symbGetArrayDescriptor( sym ) )
1050  else
1051  value = *symbGetMangledName( sym )
1052  end if
1053 
1054  else
1055  t = STAB_TYPE_LSYM
1056  desc += ":"
1057  '' dynamic array? use the descriptor
1058  if( symbIsDynamic( sym ) ) then
1059  value = str( symbGetOfs( symbGetArrayDescriptor( sym ) ) )
1060  else
1061  value = str( symbGetOfs( sym ) )
1062  end if
1063  end if
1064 
1065  '' data type
1066  desc += hGetDataType( sym )
1067 
1068  ''
1069  hEmitSTABS( t, desc, 0, 0, value )
1070 
1071 end sub
1072 
1073 '':::::
1074 sub edbgEmitProcArg _
1075  ( _
1076  byval sym as FBSYMBOL ptr _
1077  ) static
1078 
1079  dim as string desc
1080 
1081  if( env.clopt.debug = FALSE ) then
1082  exit sub
1083  end if
1084 
1085  desc = *symbGetName( sym ) + ":"
1086 
1087  if( symbIsParamByVal( sym ) ) then
1088  desc += "p"
1089 
1090  elseif( symbIsParamByRef( sym ) ) then
1091  desc += "v"
1092 
1093  elseif( symbIsParamByDesc( sym ) ) then
1094  desc += "v"
1095  end if
1096 
1097  '' data type
1098  desc += hGetDataType( sym )
1099 
1100  ''
1101  hEmitSTABS( STAB_TYPE_PSYM, desc, 0, 0, str( symbGetOfs( sym ) ) )
1102 
1103 end sub
1104 
1105 sub edbgInclude( byval incfile as zstring ptr )
1106  dim as string lname
1107 
1108  '' incfile is the new include file for which we should open a block.
1109  '' incfile can be NULL to indicate that no next include file is coming,
1110  '' in which case we just want to return to the toplevel .bas file name,
1111  '' if we previously opened an include file block.
1112 
1113  '' Already in the correct block?
1114  '' (same include file, or NULL for toplevel)
1115  if( incfile = ctx.incfile ) then
1116  exit sub
1117  end if
1118 
1119  '' Currently in an include file block?
1120  if( ctx.incfile ) then
1121  '' Close it
1122  hEmitSTABS( STAB_TYPE_EINCL, "", 0, 0 )
1123 
1124  '' "Return" to the main filename, if no new include file block
1125  '' will be opened
1126  if( incfile = NULL ) then
1127  emitSECTION( IR_SECTION_CODE, 0 )
1128  lname = *symbUniqueLabel( )
1129  hEmitSTABS( STAB_TYPE_SO, ctx.filename, 0, 0, lname )
1130  hLABEL( lname )
1131  end if
1132  end if
1133 
1134  ctx.incfile = incfile
1135 
1136  '' Open new include file block if needed
1137  if( incfile ) then
1138  hEmitSTABS( STAB_TYPE_BINCL, incfile, 0, 0 )
1139  emitSECTION( IR_SECTION_CODE, 0 )
1140  lname = *symbUniqueLabel( )
1141  hEmitSTABS( STAB_TYPE_SOL, incfile, 0, 0, lname )
1142  hLABEL( lname )
1143  end if
1144 end sub
1145