[BACK]Return to compile-c-symbols.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / gdb.old / dist / gdb / compile

Annotation of src/external/gpl3/gdb.old/dist/gdb/compile/compile-c-symbols.c, Revision 1.1

1.1     ! christos    1: /* Convert symbols from GDB to GCC
        !             2:
        !             3:    Copyright (C) 2014-2015 Free Software Foundation, Inc.
        !             4:
        !             5:    This file is part of GDB.
        !             6:
        !             7:    This program is free software; you can redistribute it and/or modify
        !             8:    it under the terms of the GNU General Public License as published by
        !             9:    the Free Software Foundation; either version 3 of the License, or
        !            10:    (at your option) any later version.
        !            11:
        !            12:    This program is distributed in the hope that it will be useful,
        !            13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15:    GNU General Public License for more details.
        !            16:
        !            17:    You should have received a copy of the GNU General Public License
        !            18:    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
        !            19:
        !            20:
        !            21: #include "defs.h"
        !            22: #include "compile-internal.h"
        !            23: #include "gdb_assert.h"
        !            24: #include "symtab.h"
        !            25: #include "parser-defs.h"
        !            26: #include "block.h"
        !            27: #include "objfiles.h"
        !            28: #include "compile.h"
        !            29: #include "value.h"
        !            30: #include "exceptions.h"
        !            31: #include "gdbtypes.h"
        !            32: #include "dwarf2loc.h"
        !            33:
        !            34: 
        !            35:
        !            36: /* Object of this type are stored in the compiler's symbol_err_map.  */
        !            37:
        !            38: struct symbol_error
        !            39: {
        !            40:   /* The symbol.  */
        !            41:
        !            42:   const struct symbol *sym;
        !            43:
        !            44:   /* The error message to emit.  This is malloc'd and owned by the
        !            45:      hash table.  */
        !            46:
        !            47:   char *message;
        !            48: };
        !            49:
        !            50: /* Hash function for struct symbol_error.  */
        !            51:
        !            52: static hashval_t
        !            53: hash_symbol_error (const void *a)
        !            54: {
        !            55:   const struct symbol_error *se = a;
        !            56:
        !            57:   return htab_hash_pointer (se->sym);
        !            58: }
        !            59:
        !            60: /* Equality function for struct symbol_error.  */
        !            61:
        !            62: static int
        !            63: eq_symbol_error (const void *a, const void *b)
        !            64: {
        !            65:   const struct symbol_error *sea = a;
        !            66:   const struct symbol_error *seb = b;
        !            67:
        !            68:   return sea->sym == seb->sym;
        !            69: }
        !            70:
        !            71: /* Deletion function for struct symbol_error.  */
        !            72:
        !            73: static void
        !            74: del_symbol_error (void *a)
        !            75: {
        !            76:   struct symbol_error *se = a;
        !            77:
        !            78:   xfree (se->message);
        !            79:   xfree (se);
        !            80: }
        !            81:
        !            82: /* Associate SYMBOL with some error text.  */
        !            83:
        !            84: static void
        !            85: insert_symbol_error (htab_t hash, const struct symbol *sym, const char *text)
        !            86: {
        !            87:   struct symbol_error e;
        !            88:   void **slot;
        !            89:
        !            90:   e.sym = sym;
        !            91:   slot = htab_find_slot (hash, &e, INSERT);
        !            92:   if (*slot == NULL)
        !            93:     {
        !            94:       struct symbol_error *e = XNEW (struct symbol_error);
        !            95:
        !            96:       e->sym = sym;
        !            97:       e->message = xstrdup (text);
        !            98:       *slot = e;
        !            99:     }
        !           100: }
        !           101:
        !           102: /* Emit the error message corresponding to SYM, if one exists, and
        !           103:    arrange for it not to be emitted again.  */
        !           104:
        !           105: static void
        !           106: error_symbol_once (struct compile_c_instance *context,
        !           107:                   const struct symbol *sym)
        !           108: {
        !           109:   struct symbol_error search;
        !           110:   struct symbol_error *err;
        !           111:   char *message;
        !           112:
        !           113:   if (context->symbol_err_map == NULL)
        !           114:     return;
        !           115:
        !           116:   search.sym = sym;
        !           117:   err = htab_find (context->symbol_err_map, &search);
        !           118:   if (err == NULL || err->message == NULL)
        !           119:     return;
        !           120:
        !           121:   message = err->message;
        !           122:   err->message = NULL;
        !           123:   make_cleanup (xfree, message);
        !           124:   error (_("%s"), message);
        !           125: }
        !           126:
        !           127: 
        !           128:
        !           129: /* Compute the name of the pointer representing a local symbol's
        !           130:    address.  */
        !           131:
        !           132: static char *
        !           133: symbol_substitution_name (struct symbol *sym)
        !           134: {
        !           135:   return concat ("__", SYMBOL_NATURAL_NAME (sym), "_ptr", (char *) NULL);
        !           136: }
        !           137:
        !           138: /* Convert a given symbol, SYM, to the compiler's representation.
        !           139:    CONTEXT is the compiler instance.  IS_GLOBAL is true if the
        !           140:    symbol came from the global scope.  IS_LOCAL is true if the symbol
        !           141:    came from a local scope.  (Note that the two are not strictly
        !           142:    inverses because the symbol might have come from the static
        !           143:    scope.)  */
        !           144:
        !           145: static void
        !           146: convert_one_symbol (struct compile_c_instance *context,
        !           147:                    struct symbol *sym,
        !           148:                    int is_global,
        !           149:                    int is_local)
        !           150: {
        !           151:   gcc_type sym_type;
        !           152:   const char *filename = symbol_symtab (sym)->filename;
        !           153:   unsigned short line = SYMBOL_LINE (sym);
        !           154:
        !           155:   error_symbol_once (context, sym);
        !           156:
        !           157:   if (SYMBOL_CLASS (sym) == LOC_LABEL)
        !           158:     sym_type = 0;
        !           159:   else
        !           160:     sym_type = convert_type (context, SYMBOL_TYPE (sym));
        !           161:
        !           162:   if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN)
        !           163:     {
        !           164:       /* Binding a tag, so we don't need to build a decl.  */
        !           165:       C_CTX (context)->c_ops->tagbind (C_CTX (context),
        !           166:                                       SYMBOL_NATURAL_NAME (sym),
        !           167:                                       sym_type, filename, line);
        !           168:     }
        !           169:   else
        !           170:     {
        !           171:       gcc_decl decl;
        !           172:       enum gcc_c_symbol_kind kind;
        !           173:       CORE_ADDR addr = 0;
        !           174:       char *symbol_name = NULL;
        !           175:
        !           176:       switch (SYMBOL_CLASS (sym))
        !           177:        {
        !           178:        case LOC_TYPEDEF:
        !           179:          kind = GCC_C_SYMBOL_TYPEDEF;
        !           180:          break;
        !           181:
        !           182:        case LOC_LABEL:
        !           183:          kind = GCC_C_SYMBOL_LABEL;
        !           184:          addr = SYMBOL_VALUE_ADDRESS (sym);
        !           185:          break;
        !           186:
        !           187:        case LOC_BLOCK:
        !           188:          kind = GCC_C_SYMBOL_FUNCTION;
        !           189:          addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
        !           190:          break;
        !           191:
        !           192:        case LOC_CONST:
        !           193:          if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM)
        !           194:            {
        !           195:              /* Already handled by convert_enum.  */
        !           196:              return;
        !           197:            }
        !           198:          C_CTX (context)->c_ops->build_constant (C_CTX (context), sym_type,
        !           199:                                                  SYMBOL_NATURAL_NAME (sym),
        !           200:                                                  SYMBOL_VALUE (sym),
        !           201:                                                  filename, line);
        !           202:          return;
        !           203:
        !           204:        case LOC_CONST_BYTES:
        !           205:          error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
        !           206:                 SYMBOL_PRINT_NAME (sym));
        !           207:
        !           208:        case LOC_UNDEF:
        !           209:          internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."),
        !           210:                          SYMBOL_PRINT_NAME (sym));
        !           211:
        !           212:        case LOC_COMMON_BLOCK:
        !           213:          error (_("Fortran common block is unsupported for compilation "
        !           214:                   "evaluaton of symbol \"%s\"."),
        !           215:                 SYMBOL_PRINT_NAME (sym));
        !           216:
        !           217:        case LOC_OPTIMIZED_OUT:
        !           218:          error (_("Symbol \"%s\" cannot be used for compilation evaluation "
        !           219:                   "as it is optimized out."),
        !           220:                 SYMBOL_PRINT_NAME (sym));
        !           221:
        !           222:        case LOC_COMPUTED:
        !           223:          if (is_local)
        !           224:            goto substitution;
        !           225:          /* Probably TLS here.  */
        !           226:          warning (_("Symbol \"%s\" is thread-local and currently can only "
        !           227:                     "be referenced from the current thread in "
        !           228:                     "compiled code."),
        !           229:                   SYMBOL_PRINT_NAME (sym));
        !           230:          /* FALLTHROUGH */
        !           231:        case LOC_UNRESOLVED:
        !           232:          /* 'symbol_name' cannot be used here as that one is used only for
        !           233:             local variables from compile_dwarf_expr_to_c.
        !           234:             Global variables can be accessed by GCC only by their address, not
        !           235:             by their name.  */
        !           236:          {
        !           237:            struct value *val;
        !           238:            struct frame_info *frame = NULL;
        !           239:
        !           240:            if (symbol_read_needs_frame (sym))
        !           241:              {
        !           242:                frame = get_selected_frame (NULL);
        !           243:                if (frame == NULL)
        !           244:                  error (_("Symbol \"%s\" cannot be used because "
        !           245:                           "there is no selected frame"),
        !           246:                         SYMBOL_PRINT_NAME (sym));
        !           247:              }
        !           248:
        !           249:            val = read_var_value (sym, frame);
        !           250:            if (VALUE_LVAL (val) != lval_memory)
        !           251:              error (_("Symbol \"%s\" cannot be used for compilation "
        !           252:                       "evaluation as its address has not been found."),
        !           253:                     SYMBOL_PRINT_NAME (sym));
        !           254:
        !           255:            kind = GCC_C_SYMBOL_VARIABLE;
        !           256:            addr = value_address (val);
        !           257:          }
        !           258:          break;
        !           259:
        !           260:
        !           261:        case LOC_REGISTER:
        !           262:        case LOC_ARG:
        !           263:        case LOC_REF_ARG:
        !           264:        case LOC_REGPARM_ADDR:
        !           265:        case LOC_LOCAL:
        !           266:        substitution:
        !           267:          kind = GCC_C_SYMBOL_VARIABLE;
        !           268:          symbol_name = symbol_substitution_name (sym);
        !           269:          break;
        !           270:
        !           271:        case LOC_STATIC:
        !           272:          kind = GCC_C_SYMBOL_VARIABLE;
        !           273:          addr = SYMBOL_VALUE_ADDRESS (sym);
        !           274:          break;
        !           275:
        !           276:        case LOC_FINAL_VALUE:
        !           277:        default:
        !           278:          gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");
        !           279:
        !           280:        }
        !           281:
        !           282:       /* Don't emit local variable decls for a raw expression.  */
        !           283:       if (context->base.scope != COMPILE_I_RAW_SCOPE
        !           284:          || symbol_name == NULL)
        !           285:        {
        !           286:          decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
        !           287:                                                     SYMBOL_NATURAL_NAME (sym),
        !           288:                                                     kind,
        !           289:                                                     sym_type,
        !           290:                                                     symbol_name, addr,
        !           291:                                                     filename, line);
        !           292:
        !           293:          C_CTX (context)->c_ops->bind (C_CTX (context), decl, is_global);
        !           294:        }
        !           295:
        !           296:       xfree (symbol_name);
        !           297:     }
        !           298: }
        !           299:
        !           300: /* Convert a full symbol to its gcc form.  CONTEXT is the compiler to
        !           301:    use, IDENTIFIER is the name of the symbol, SYM is the symbol
        !           302:    itself, and DOMAIN is the domain which was searched.  */
        !           303:
        !           304: static void
        !           305: convert_symbol_sym (struct compile_c_instance *context, const char *identifier,
        !           306:                    struct symbol *sym, domain_enum domain)
        !           307: {
        !           308:   const struct block *static_block, *found_block;
        !           309:   int is_local_symbol;
        !           310:
        !           311:   found_block = block_found;
        !           312:
        !           313:   /* If we found a symbol and it is not in the  static or global
        !           314:      scope, then we should first convert any static or global scope
        !           315:      symbol of the same name.  This lets this unusual case work:
        !           316:
        !           317:      int x; // Global.
        !           318:      int func(void)
        !           319:      {
        !           320:      int x;
        !           321:      // At this spot, evaluate "extern int x; x"
        !           322:      }
        !           323:   */
        !           324:
        !           325:   static_block = block_static_block (found_block);
        !           326:   /* STATIC_BLOCK is NULL if FOUND_BLOCK is the global block.  */
        !           327:   is_local_symbol = (found_block != static_block && static_block != NULL);
        !           328:   if (is_local_symbol)
        !           329:     {
        !           330:       struct symbol *global_sym;
        !           331:
        !           332:       global_sym = lookup_symbol (identifier, NULL, domain, NULL);
        !           333:       /* If the outer symbol is in the static block, we ignore it, as
        !           334:         it cannot be referenced.  */
        !           335:       if (global_sym != NULL
        !           336:          && block_found != block_static_block (block_found))
        !           337:        {
        !           338:          if (compile_debug)
        !           339:            fprintf_unfiltered (gdb_stdout,
        !           340:                                "gcc_convert_symbol \"%s\": global symbol\n",
        !           341:                                identifier);
        !           342:          convert_one_symbol (context, global_sym, 1, 0);
        !           343:        }
        !           344:     }
        !           345:
        !           346:   if (compile_debug)
        !           347:     fprintf_unfiltered (gdb_stdout,
        !           348:                        "gcc_convert_symbol \"%s\": local symbol\n",
        !           349:                        identifier);
        !           350:   convert_one_symbol (context, sym, 0, is_local_symbol);
        !           351: }
        !           352:
        !           353: /* Convert a minimal symbol to its gcc form.  CONTEXT is the compiler
        !           354:    to use and BMSYM is the minimal symbol to convert.  */
        !           355:
        !           356: static void
        !           357: convert_symbol_bmsym (struct compile_c_instance *context,
        !           358:                      struct bound_minimal_symbol bmsym)
        !           359: {
        !           360:   struct minimal_symbol *msym = bmsym.minsym;
        !           361:   struct objfile *objfile = bmsym.objfile;
        !           362:   struct type *type;
        !           363:   enum gcc_c_symbol_kind kind;
        !           364:   gcc_type sym_type;
        !           365:   gcc_decl decl;
        !           366:   CORE_ADDR addr;
        !           367:
        !           368:   /* Conversion copied from write_exp_msymbol.  */
        !           369:   switch (MSYMBOL_TYPE (msym))
        !           370:     {
        !           371:     case mst_text:
        !           372:     case mst_file_text:
        !           373:     case mst_solib_trampoline:
        !           374:       type = objfile_type (objfile)->nodebug_text_symbol;
        !           375:       kind = GCC_C_SYMBOL_FUNCTION;
        !           376:       break;
        !           377:
        !           378:     case mst_text_gnu_ifunc:
        !           379:       type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
        !           380:       kind = GCC_C_SYMBOL_FUNCTION;
        !           381:       break;
        !           382:
        !           383:     case mst_data:
        !           384:     case mst_file_data:
        !           385:     case mst_bss:
        !           386:     case mst_file_bss:
        !           387:       type = objfile_type (objfile)->nodebug_data_symbol;
        !           388:       kind = GCC_C_SYMBOL_VARIABLE;
        !           389:       break;
        !           390:
        !           391:     case mst_slot_got_plt:
        !           392:       type = objfile_type (objfile)->nodebug_got_plt_symbol;
        !           393:       kind = GCC_C_SYMBOL_FUNCTION;
        !           394:       break;
        !           395:
        !           396:     default:
        !           397:       type = objfile_type (objfile)->nodebug_unknown_symbol;
        !           398:       kind = GCC_C_SYMBOL_VARIABLE;
        !           399:       break;
        !           400:     }
        !           401:
        !           402:   sym_type = convert_type (context, type);
        !           403:   addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
        !           404:   decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
        !           405:                                             MSYMBOL_NATURAL_NAME (msym),
        !           406:                                             kind, sym_type, NULL, addr,
        !           407:                                             NULL, 0);
        !           408:   C_CTX (context)->c_ops->bind (C_CTX (context), decl, 1 /* is_global */);
        !           409: }
        !           410:
        !           411: /* See compile-internal.h.  */
        !           412:
        !           413: void
        !           414: gcc_convert_symbol (void *datum,
        !           415:                    struct gcc_c_context *gcc_context,
        !           416:                    enum gcc_c_oracle_request request,
        !           417:                    const char *identifier)
        !           418: {
        !           419:   struct compile_c_instance *context = datum;
        !           420:   domain_enum domain;
        !           421:   volatile struct gdb_exception e;
        !           422:   int found = 0;
        !           423:
        !           424:   switch (request)
        !           425:     {
        !           426:     case GCC_C_ORACLE_SYMBOL:
        !           427:       domain = VAR_DOMAIN;
        !           428:       break;
        !           429:     case GCC_C_ORACLE_TAG:
        !           430:       domain = STRUCT_DOMAIN;
        !           431:       break;
        !           432:     case GCC_C_ORACLE_LABEL:
        !           433:       domain = LABEL_DOMAIN;
        !           434:       break;
        !           435:     default:
        !           436:       gdb_assert_not_reached ("Unrecognized oracle request.");
        !           437:     }
        !           438:
        !           439:   /* We can't allow exceptions to escape out of this callback.  Safest
        !           440:      is to simply emit a gcc error.  */
        !           441:   TRY_CATCH (e, RETURN_MASK_ALL)
        !           442:     {
        !           443:       struct symbol *sym;
        !           444:
        !           445:       sym = lookup_symbol (identifier, context->base.block, domain, NULL);
        !           446:       if (sym != NULL)
        !           447:        {
        !           448:          convert_symbol_sym (context, identifier, sym, domain);
        !           449:          found = 1;
        !           450:        }
        !           451:       else if (domain == VAR_DOMAIN)
        !           452:        {
        !           453:          struct bound_minimal_symbol bmsym;
        !           454:
        !           455:          bmsym = lookup_minimal_symbol (identifier, NULL, NULL);
        !           456:          if (bmsym.minsym != NULL)
        !           457:            {
        !           458:              convert_symbol_bmsym (context, bmsym);
        !           459:              found = 1;
        !           460:            }
        !           461:        }
        !           462:     }
        !           463:
        !           464:   if (e.reason < 0)
        !           465:     C_CTX (context)->c_ops->error (C_CTX (context), e.message);
        !           466:
        !           467:   if (compile_debug && !found)
        !           468:     fprintf_unfiltered (gdb_stdout,
        !           469:                        "gcc_convert_symbol \"%s\": lookup_symbol failed\n",
        !           470:                        identifier);
        !           471:   return;
        !           472: }
        !           473:
        !           474: /* See compile-internal.h.  */
        !           475:
        !           476: gcc_address
        !           477: gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
        !           478:                    const char *identifier)
        !           479: {
        !           480:   struct compile_c_instance *context = datum;
        !           481:   volatile struct gdb_exception e;
        !           482:   gcc_address result = 0;
        !           483:   int found = 0;
        !           484:
        !           485:   /* We can't allow exceptions to escape out of this callback.  Safest
        !           486:      is to simply emit a gcc error.  */
        !           487:   TRY_CATCH (e, RETURN_MASK_ERROR)
        !           488:     {
        !           489:       struct symbol *sym;
        !           490:
        !           491:       /* We only need global functions here.  */
        !           492:       sym = lookup_symbol (identifier, NULL, VAR_DOMAIN, NULL);
        !           493:       if (sym != NULL && SYMBOL_CLASS (sym) == LOC_BLOCK)
        !           494:        {
        !           495:          if (compile_debug)
        !           496:            fprintf_unfiltered (gdb_stdout,
        !           497:                                "gcc_symbol_address \"%s\": full symbol\n",
        !           498:                                identifier);
        !           499:          result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
        !           500:          found = 1;
        !           501:        }
        !           502:       else
        !           503:        {
        !           504:          struct bound_minimal_symbol msym;
        !           505:
        !           506:          msym = lookup_bound_minimal_symbol (identifier);
        !           507:          if (msym.minsym != NULL)
        !           508:            {
        !           509:              if (compile_debug)
        !           510:                fprintf_unfiltered (gdb_stdout,
        !           511:                                    "gcc_symbol_address \"%s\": minimal "
        !           512:                                    "symbol\n",
        !           513:                                    identifier);
        !           514:              result = BMSYMBOL_VALUE_ADDRESS (msym);
        !           515:              found = 1;
        !           516:            }
        !           517:        }
        !           518:     }
        !           519:
        !           520:   if (e.reason < 0)
        !           521:     C_CTX (context)->c_ops->error (C_CTX (context), e.message);
        !           522:
        !           523:   if (compile_debug && !found)
        !           524:     fprintf_unfiltered (gdb_stdout,
        !           525:                        "gcc_symbol_address \"%s\": failed\n",
        !           526:                        identifier);
        !           527:   return result;
        !           528: }
        !           529:
        !           530: 
        !           531:
        !           532: /* A hash function for symbol names.  */
        !           533:
        !           534: static hashval_t
        !           535: hash_symname (const void *a)
        !           536: {
        !           537:   const struct symbol *sym = a;
        !           538:
        !           539:   return htab_hash_string (SYMBOL_NATURAL_NAME (sym));
        !           540: }
        !           541:
        !           542: /* A comparison function for hash tables that just looks at symbol
        !           543:    names.  */
        !           544:
        !           545: static int
        !           546: eq_symname (const void *a, const void *b)
        !           547: {
        !           548:   const struct symbol *syma = a;
        !           549:   const struct symbol *symb = b;
        !           550:
        !           551:   return strcmp (SYMBOL_NATURAL_NAME (syma), SYMBOL_NATURAL_NAME (symb)) == 0;
        !           552: }
        !           553:
        !           554: /* If a symbol with the same name as SYM is already in HASHTAB, return
        !           555:    1.  Otherwise, add SYM to HASHTAB and return 0.  */
        !           556:
        !           557: static int
        !           558: symbol_seen (htab_t hashtab, struct symbol *sym)
        !           559: {
        !           560:   void **slot;
        !           561:
        !           562:   slot = htab_find_slot (hashtab, sym, INSERT);
        !           563:   if (*slot != NULL)
        !           564:     return 1;
        !           565:
        !           566:   *slot = sym;
        !           567:   return 0;
        !           568: }
        !           569:
        !           570: /* Generate C code to compute the length of a VLA.  */
        !           571:
        !           572: static void
        !           573: generate_vla_size (struct compile_c_instance *compiler,
        !           574:                   struct ui_file *stream,
        !           575:                   struct gdbarch *gdbarch,
        !           576:                   unsigned char *registers_used,
        !           577:                   CORE_ADDR pc,
        !           578:                   struct type *type,
        !           579:                   struct symbol *sym)
        !           580: {
        !           581:   type = check_typedef (type);
        !           582:
        !           583:   if (TYPE_CODE (type) == TYPE_CODE_REF)
        !           584:     type = check_typedef (TYPE_TARGET_TYPE (type));
        !           585:
        !           586:   switch (TYPE_CODE (type))
        !           587:     {
        !           588:     case TYPE_CODE_RANGE:
        !           589:       {
        !           590:        if (TYPE_HIGH_BOUND_KIND (type) == PROP_LOCEXPR
        !           591:            || TYPE_HIGH_BOUND_KIND (type) == PROP_LOCLIST)
        !           592:          {
        !           593:            const struct dynamic_prop *prop = &TYPE_RANGE_DATA (type)->high;
        !           594:            char *name = c_get_range_decl_name (prop);
        !           595:            struct cleanup *cleanup = make_cleanup (xfree, name);
        !           596:
        !           597:            dwarf2_compile_property_to_c (stream, name,
        !           598:                                          gdbarch, registers_used,
        !           599:                                          prop, pc, sym);
        !           600:            do_cleanups (cleanup);
        !           601:          }
        !           602:       }
        !           603:       break;
        !           604:
        !           605:     case TYPE_CODE_ARRAY:
        !           606:       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
        !           607:                         TYPE_INDEX_TYPE (type), sym);
        !           608:       generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
        !           609:                         TYPE_TARGET_TYPE (type), sym);
        !           610:       break;
        !           611:
        !           612:     case TYPE_CODE_UNION:
        !           613:     case TYPE_CODE_STRUCT:
        !           614:       {
        !           615:        int i;
        !           616:
        !           617:        for (i = 0; i < TYPE_NFIELDS (type); ++i)
        !           618:          if (!field_is_static (&TYPE_FIELD (type, i)))
        !           619:            generate_vla_size (compiler, stream, gdbarch, registers_used, pc,
        !           620:                               TYPE_FIELD_TYPE (type, i), sym);
        !           621:       }
        !           622:       break;
        !           623:     }
        !           624: }
        !           625:
        !           626: /* Generate C code to compute the address of SYM.  */
        !           627:
        !           628: static void
        !           629: generate_c_for_for_one_variable (struct compile_c_instance *compiler,
        !           630:                                 struct ui_file *stream,
        !           631:                                 struct gdbarch *gdbarch,
        !           632:                                 unsigned char *registers_used,
        !           633:                                 CORE_ADDR pc,
        !           634:                                 struct symbol *sym)
        !           635: {
        !           636:   volatile struct gdb_exception e;
        !           637:
        !           638:   TRY_CATCH (e, RETURN_MASK_ERROR)
        !           639:     {
        !           640:       if (is_dynamic_type (SYMBOL_TYPE (sym)))
        !           641:        {
        !           642:          struct ui_file *size_file = mem_fileopen ();
        !           643:          struct cleanup *cleanup = make_cleanup_ui_file_delete (size_file);
        !           644:
        !           645:          generate_vla_size (compiler, size_file, gdbarch, registers_used, pc,
        !           646:                             SYMBOL_TYPE (sym), sym);
        !           647:          ui_file_put (size_file, ui_file_write_for_put, stream);
        !           648:
        !           649:          do_cleanups (cleanup);
        !           650:        }
        !           651:
        !           652:       if (SYMBOL_COMPUTED_OPS (sym) != NULL)
        !           653:        {
        !           654:          char *generated_name = symbol_substitution_name (sym);
        !           655:          struct cleanup *cleanup = make_cleanup (xfree, generated_name);
        !           656:          /* We need to emit to a temporary buffer in case an error
        !           657:             occurs in the middle.  */
        !           658:          struct ui_file *local_file = mem_fileopen ();
        !           659:
        !           660:          make_cleanup_ui_file_delete (local_file);
        !           661:          SYMBOL_COMPUTED_OPS (sym)->generate_c_location (sym, local_file,
        !           662:                                                          gdbarch,
        !           663:                                                          registers_used,
        !           664:                                                          pc, generated_name);
        !           665:          ui_file_put (local_file, ui_file_write_for_put, stream);
        !           666:
        !           667:          do_cleanups (cleanup);
        !           668:        }
        !           669:       else
        !           670:        {
        !           671:          switch (SYMBOL_CLASS (sym))
        !           672:            {
        !           673:            case LOC_REGISTER:
        !           674:            case LOC_ARG:
        !           675:            case LOC_REF_ARG:
        !           676:            case LOC_REGPARM_ADDR:
        !           677:            case LOC_LOCAL:
        !           678:              error (_("Local symbol unhandled when generating C code."));
        !           679:
        !           680:            case LOC_COMPUTED:
        !           681:              gdb_assert_not_reached (_("LOC_COMPUTED variable "
        !           682:                                        "missing a method."));
        !           683:
        !           684:            default:
        !           685:              /* Nothing to do for all other cases, as they don't represent
        !           686:                 local variables.  */
        !           687:              break;
        !           688:            }
        !           689:        }
        !           690:     }
        !           691:
        !           692:   if (e.reason >= 0)
        !           693:     return;
        !           694:
        !           695:   if (compiler->symbol_err_map == NULL)
        !           696:     compiler->symbol_err_map = htab_create_alloc (10,
        !           697:                                                  hash_symbol_error,
        !           698:                                                  eq_symbol_error,
        !           699:                                                  del_symbol_error,
        !           700:                                                  xcalloc,
        !           701:                                                  xfree);
        !           702:   insert_symbol_error (compiler->symbol_err_map, sym, e.message);
        !           703: }
        !           704:
        !           705: /* See compile-internal.h.  */
        !           706:
        !           707: unsigned char *
        !           708: generate_c_for_variable_locations (struct compile_c_instance *compiler,
        !           709:                                   struct ui_file *stream,
        !           710:                                   struct gdbarch *gdbarch,
        !           711:                                   const struct block *block,
        !           712:                                   CORE_ADDR pc)
        !           713: {
        !           714:   struct cleanup *cleanup, *outer;
        !           715:   htab_t symhash;
        !           716:   const struct block *static_block = block_static_block (block);
        !           717:   unsigned char *registers_used;
        !           718:
        !           719:   /* If we're already in the static or global block, there is nothing
        !           720:      to write.  */
        !           721:   if (static_block == NULL || block == static_block)
        !           722:     return NULL;
        !           723:
        !           724:   registers_used = XCNEWVEC (unsigned char, gdbarch_num_regs (gdbarch));
        !           725:   outer = make_cleanup (xfree, registers_used);
        !           726:
        !           727:   /* Ensure that a given name is only entered once.  This reflects the
        !           728:      reality of shadowing.  */
        !           729:   symhash = htab_create_alloc (1, hash_symname, eq_symname, NULL,
        !           730:                               xcalloc, xfree);
        !           731:   cleanup = make_cleanup_htab_delete (symhash);
        !           732:
        !           733:   while (1)
        !           734:     {
        !           735:       struct symbol *sym;
        !           736:       struct block_iterator iter;
        !           737:
        !           738:       /* Iterate over symbols in this block, generating code to
        !           739:         compute the location of each local variable.  */
        !           740:       for (sym = block_iterator_first (block, &iter);
        !           741:           sym != NULL;
        !           742:           sym = block_iterator_next (&iter))
        !           743:        {
        !           744:          if (!symbol_seen (symhash, sym))
        !           745:            generate_c_for_for_one_variable (compiler, stream, gdbarch,
        !           746:                                             registers_used, pc, sym);
        !           747:        }
        !           748:
        !           749:       /* If we just finished the outermost block of a function, we're
        !           750:         done.  */
        !           751:       if (BLOCK_FUNCTION (block) != NULL)
        !           752:        break;
        !           753:       block = BLOCK_SUPERBLOCK (block);
        !           754:     }
        !           755:
        !           756:   do_cleanups (cleanup);
        !           757:   discard_cleanups (outer);
        !           758:   return registers_used;
        !           759: }

CVSweb <webmaster@jp.NetBSD.org>