From 96a8853a477148534aa29ba97c791f3f23e55452 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 24 Sep 2010 11:15:55 +0000 Subject: [PATCH] * objfiles.h (ALL_OBJSECTIONS): Handle breaks in the inner loop. --- gdb/ChangeLog | 4 ++++ gdb/objfiles.h | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4b1b74e6e8..e335b68c2a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2010-09-24 Pedro Alves + + * objfiles.h (ALL_OBJSECTIONS): Handle breaks in the inner loop. + 2010-09-22 Joel Brobecker * ada-tasks.c (read_atcb): Do not compute the task ptid when diff --git a/gdb/objfiles.h b/gdb/objfiles.h index b3e2e26faa..8b47d2bbfa 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -611,9 +611,44 @@ extern int gdb_bfd_close_or_warn (struct bfd *abfd); #define ALL_OBJFILE_OSECTIONS(objfile, osect) \ for (osect = objfile->sections; osect < objfile->sections_end; osect++) -#define ALL_OBJSECTIONS(objfile, osect) \ - ALL_OBJFILES (objfile) \ - ALL_OBJFILE_OSECTIONS (objfile, osect) +/* Traverse all obj_sections in all objfiles in the current program + space. + + Note that this detects a "break" in the inner loop, and exits + immediately from the outer loop as well, thus, client code doesn't + need to know that this is implemented with a double for. The extra + hair is to make sure that a "break;" stops the outer loop iterating + as well, and both OBJFILE and OSECT are left unmodified: + + - The outer loop learns about the inner loop's end condition, and + stops iterating if it detects the inner loop didn't reach its + end. In other words, the outer loop keeps going only if the + inner loop reached its end cleanly [(osect) == + (objfile)->sections_end]. + + - OSECT is initialized in the outer loop initialization + expressions, such as if the inner loop has reached its end, so + the check mentioned above succeeds the first time. + + - The trick to not clearing OBJFILE on a "break;" is, in the outer + loop's loop expression, advance OBJFILE, but iff the inner loop + reached its end. If not, there was a "break;", so leave OBJFILE + as is; the outer loop's conditional will break immediately as + well (as OSECT will be different from OBJFILE->sections_end). +*/ + +#define ALL_OBJSECTIONS(objfile, osect) \ + for ((objfile) = current_program_space->objfiles, \ + (objfile) != NULL ? ((osect) = (objfile)->sections_end) : 0; \ + (objfile) != NULL \ + && (osect) == (objfile)->sections_end; \ + ((osect) == (objfile)->sections_end \ + ? ((objfile) = (objfile)->next, \ + (objfile) != NULL ? (osect) = (objfile)->sections_end : 0) \ + : 0)) \ + for ((osect) = (objfile)->sections; \ + (osect) < (objfile)->sections_end; \ + (osect)++) #define SECT_OFF_DATA(objfile) \ ((objfile->sect_index_data == -1) \