From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 3B24F385BF83 for ; Tue, 14 Apr 2020 13:11:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3B24F385BF83 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tdevries@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 149B4AC19; Tue, 14 Apr 2020 13:11:10 +0000 (UTC) Subject: Re: [PATCH][gdb] Expand symbolless symtabs using maint expand-symtabs From: Tom de Vries To: Tom Tromey Cc: gdb-patches@sourceware.org References: <20200329160050.GA24275@delia> <87eet70z32.fsf@tromey.com> Autocrypt: addr=tdevries@suse.de; keydata= xsBNBF0ltCcBCADDhsUnMMdEXiHFfqJdXeRvgqSEUxLCy/pHek88ALuFnPTICTwkf4g7uSR7 HvOFUoUyu8oP5mNb4VZHy3Xy8KRZGaQuaOHNhZAT1xaVo6kxjswUi3vYgGJhFMiLuIHdApoc u5f7UbV+egYVxmkvVLSqsVD4pUgHeSoAcIlm3blZ1sDKviJCwaHxDQkVmSsGXImaAU+ViJ5l CwkvyiiIifWD2SoOuFexZyZ7RUddLosgsO0npVUYbl6dEMq2a5ijGF6/rBs1m3nAoIgpXk6P TCKlSWVW6OCneTaKM5C387972qREtiArTakRQIpvDJuiR2soGfdeJ6igGA1FZjU+IsM5ABEB AAHNH1RvbSBkZSBWcmllcyA8dGRldnJpZXNAc3VzZS5kZT7CwKsEEwEIAD4WIQSsnSe5hKbL MK1mGmjuhV2rbOJEoAUCXSW0JwIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAh CRDuhV2rbOJEoBYhBKydJ7mEpsswrWYaaO6FXats4kSgc48H/Ra2lq5p3dHsrlQLqM7N68Fo eRDf3PMevXyMlrCYDGLVncQwMw3O/AkousktXKQ42DPJh65zoXB22yUt8m0g12xkLax98KFJ 5NyUloa6HflLl+wQL/uZjIdNUQaHQLw3HKwRMVi4l0/Jh/TygYG1Dtm8I4o708JS4y8GQxoQ UL0z1OM9hyM3gI2WVTTyprsBHy2EjMOu/2Xpod95pF8f90zBLajy6qXEnxlcsqreMaqmkzKn 3KTZpWRxNAS/IH3FbGQ+3RpWkNGSJpwfEMVCeyK5a1n7yt1podd1ajY5mA1jcaUmGppqx827 8TqyteNe1B/pbiUt2L/WhnTgW1NC1QDOwE0EXSW0JwEIAM99H34Bu4MKM7HDJVt864MXbx7B 1M93wVlpJ7Uq+XDFD0A0hIal028j+h6jA6bhzWto4RUfDl/9mn1StngNVFovvwtfzbamp6+W pKHZm9X5YvlIwCx131kTxCNDcF+/adRW4n8CU3pZWYmNVqhMUiPLxElA6QhXTtVBh1RkjCZQ Kmbd1szvcOfaD8s+tJABJzNZsmO2hVuFwkDrRN8Jgrh92a+yHQPd9+RybW2l7sJv26nkUH5Z 5s84P6894ebgimcprJdAkjJTgprl1nhgvptU5M9Uv85Pferoh2groQEAtRPlCGrZ2/2qVNe9 XJfSYbiyedvApWcJs5DOByTaKkcAEQEAAcLAkwQYAQgAJhYhBKydJ7mEpsswrWYaaO6FXats 4kSgBQJdJbQnAhsMBQkDwmcAACEJEO6FXats4kSgFiEErJ0nuYSmyzCtZhpo7oVdq2ziRKD3 twf7BAQBZ8TqR812zKAD7biOnWIJ0McV72PFBxmLIHp24UVe0ZogtYMxSWKLg3csh0yLVwc7 H3vldzJ9AoK3Qxp0Q6K/rDOeUy3HMqewQGcqrsRRh0NXDIQk5CgSrZslPe47qIbe3O7ik/MC q31FNIAQJPmKXX25B115MMzkSKlv4udfx7KdyxHrTSkwWZArLQiEZj5KG4cCKhIoMygPTA3U yGaIvI/BGOtHZ7bEBVUCFDFfOWJ26IOCoPnSVUvKPEOH9dv+sNy7jyBsP5QxeTqwxC/1ZtNS DUCSFQjqA6bEGwM22dP8OUY6SC94x1G81A9/xbtm9LQxKm0EiDH8KBMLfQ== Message-ID: <752bb1c3-ae45-3ca6-d808-38c9c0bb2c2a@suse.de> Date: Tue, 14 Apr 2020 15:09:42 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------334C91004A904A95A8B2B954" Content-Language: en-US X-Spam-Status: No, score=-29.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Apr 2020 13:11:17 -0000 This is a multi-part message in MIME format. --------------334C91004A904A95A8B2B954 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit On 02-04-2020 10:44, Tom de Vries wrote: > On 01-04-2020 21:45, Tom Tromey wrote: >>>>>>> "Tom" == Tom de Vries writes: >> >> Tom> When trying to expand the partial symtab for hello.h: >> Tom> ... >> Tom> $ gdb -batch \ >> Tom> -iex "set language c" \ >> Tom> a.out \ >> Tom> -ex "maint expand-symtabs hello.h" \ >> Tom> -ex "maint info psymtabs" >> Tom> ... >> Tom> we in fact find that the partial symtab has not been expanded: >> Tom> ... >> Tom> { psymtab hello.h ((struct partial_symtab *) 0x27cf070) >> Tom> readin no >> Tom> ... >> >> Does this matter, though? >> I thought include psymtabs like these were kind of placeholders. >> > > Right, but the includer symtab they're pointing towards are also not > expanded. > I've updated the log message to reflect this, as well as the test-case. > Concretely, it does matter for dwarf assembly test-cases, in the sense > that this patch allows me to have the symtab effect of setting a > breakpoint in a certain file, without actually setting the breakpoint, > which means there's no need to flesh out the .debug_line section in > detail, or indeed even create the file. > > [ I mentioned this patch as a prerequisite for a dwarf assembly > test-case here : > https://sourceware.org/pipermail/gdb-patches/2020-March/167152.html ] > > Furthermore, I found this problem originally not with include psymtabs, > but with this type of one-DIE CUs: > ... > <0>: Abbrev Number: 1 (DW_TAG_compile_unit) > DW_AT_stmt_list : 0x0 > <10> DW_AT_low_pc : 0x400430 > <18> DW_AT_high_pc : 0x40045b > <20> DW_AT_name : ../sysdeps/x86_64/start.S > <24> DW_AT_comp_dir : /home/abuild/rpmbuild/BUILD/glibc-2.26/csu > <28> DW_AT_producer : GNU AS 2.31.1 > <2c> DW_AT_language : 32769 (MIPS assembler) > ... > which I get in every exec on openSUSE Leap 15.1. > > In that case, the problem means that "maint expand-symtabs" doesn't > expand the symtab, in violation of the "maint expand-symtabs" > documentation, while also being inconsistent with -readnow which does > create a symbolless symtab. > I've also noted this in the log message. > I used the include psymtabs as test-case and running example because it > reproduces on all platforms in a standard test-case. > >> Tom> Fix this by passing a NULL symbol_matcher and lookup_name to >> Tom> expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call >> Tom> to recursively_search_psymtabs if symbol_matcher == NULL and >> Tom> lookup_name == NULL. >> >> Could this code use map_symtabs_matching_filename instead? >> > > I can see how that would help with "maint expand-symtabs ", but > still "maint expand-symtabs" would not expand the partial symtab for > ../sysdeps/x86_64/start.S. > > Thanks, > - Tom > >> I guess I'm not super fond of turning the reference arguments to >> pointers, unless there's really no other way. Unfortunately I don't see another way atm, so I'm committing this as attached below. [ FWIW, something I'm not very happy with myself is the undoing of the micro-optimization of having this outside of the partial symtabs loop: ... lookup_name_info lookup_name = lookup_name_in.make_ignore_params (); ... but I'm not sure how to address that. ] Thanks, - Tom --------------334C91004A904A95A8B2B954 Content-Type: text/x-patch; charset=UTF-8; name="0001-gdb-Expand-symbolless-symtabs-using-maint-expand-symtabs.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename*0="0001-gdb-Expand-symbolless-symtabs-using-maint-expand-symtab"; filename*1="s.patch" [gdb] Expand symbolless symtabs using maint expand-symtabs Consider this test-case, consisting of header file hello.h: ... inline static const char* foo (void) { return "foo"; } ... and source file hello.c: ... int main (void) { printf ("hello: %s\n", foo ()); return 0; } ... compiled with -g: ... $ gcc hello.c -g ... When trying to expand the partial symtab for hello.h: ... $ gdb -batch \ -iex "set language c" \ a.out \ -ex "maint expand-symtabs hello.h" \ -ex "maint info psymtabs" ... we in fact find that the partial symtab for hello.h (and corresponding includer partial symtab hello.c) have not been expanded: ... { psymtab hello.h ((struct partial_symtab *) 0x27cf070) readin no ... { psymtab hello.c ((struct partial_symtab *) 0x2cf09e0) readin no ... This is due to the recursively_search_psymtabs call in psym_expand_symtabs_matching: ... if (recursively_search_psymtabs (ps, objfile, domain, lookup_name, symbol_matcher)) ... which always returns false for symbolless partial symtabs. The same problem occurs with CUs where the dwarf is generated by gas --gdwarf-2 for a foo.S: if we read such a test-case with -readnow, we'll have a symbolless symtab for foo.S. But if we read the test-case with partial symtabs, and expand those using "maint expand-symtabs", the foo.S psymtab remains unexpanded. Fix this by passing a NULL symbol_matcher and lookup_name to expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call to recursively_search_psymtabs if symbol_matcher == NULL and lookup_name == NULL. Build and tested on x86_64-linux, with native. In addition, tested test-case with target boards cc-with-gdb-index.exp, cc-with-debug-names.exp and readnow.exp. gdb/ChangeLog: 2020-03-29 Tom de Vries PR symtab/25720 * symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching with NULL symbol_matcher and lookup_name. * psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher and lookup_name. * dwarf2/read.c (dw2_expand_symtabs_matching) (dw2_debug_names_expand_symtabs_matching): Same. * symfile.h (struct quick_symbol_functions::expand_symtabs_matching): Make lookup_name a pointer. Update comment. * symtab.c (global_symbol_searcher::expand_symtabs): Handle lookup_name being a pointer. * symfile.c (expand_symtabs_matching): Same. * symfile-debug.c (debug_qf_expand_symtabs_matching): Same. * linespec.c (iterate_over_all_matching_symtabs): Same. gdb/testsuite/ChangeLog: 2020-03-29 Tom de Vries PR symtab/25720 * gdb.base/maint-expand-symbols-header-file.c: New test. * gdb.base/maint-expand-symbols-header-file.exp: New file. * gdb.base/maint-expand-symbols-header-file.h: New test. --- gdb/dwarf2/read.c | 32 +++++++++++++-- gdb/linespec.c | 2 +- gdb/psymtab.c | 10 ++--- gdb/symfile-debug.c | 2 +- gdb/symfile.c | 2 +- gdb/symfile.h | 13 +++--- gdb/symmisc.c | 8 +--- gdb/symtab.c | 2 +- .../gdb.base/maint-expand-symbols-header-file.c | 26 ++++++++++++ .../gdb.base/maint-expand-symbols-header-file.exp | 46 ++++++++++++++++++++++ .../gdb.base/maint-expand-symbols-header-file.h | 22 +++++++++++ 11 files changed, 141 insertions(+), 24 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index da702205c6..9fa4970556 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -4603,7 +4603,7 @@ static void dw2_expand_symtabs_matching (struct objfile *objfile, gdb::function_view file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind) @@ -4617,9 +4617,21 @@ dw2_expand_symtabs_matching dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher); + if (symbol_matcher == NULL && lookup_name == NULL) + { + for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units) + { + QUIT; + + dw2_expand_symtabs_matching_one (per_cu, file_matcher, + expansion_notify); + } + return; + } + mapped_index &index = *dwarf2_per_objfile->index_table; - dw2_expand_symtabs_matching_symbol (index, lookup_name, + dw2_expand_symtabs_matching_symbol (index, *lookup_name, symbol_matcher, kind, [&] (offset_type idx) { @@ -5612,7 +5624,7 @@ static void dw2_debug_names_expand_symtabs_matching (struct objfile *objfile, gdb::function_view file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind) @@ -5626,9 +5638,21 @@ dw2_debug_names_expand_symtabs_matching dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher); + if (symbol_matcher == NULL && lookup_name == NULL) + { + for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units) + { + QUIT; + + dw2_expand_symtabs_matching_one (per_cu, file_matcher, + expansion_notify); + } + return; + } + mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table; - dw2_expand_symtabs_matching_symbol (map, lookup_name, + dw2_expand_symtabs_matching_symbol (map, *lookup_name, symbol_matcher, kind, [&] (offset_type namei) { diff --git a/gdb/linespec.c b/gdb/linespec.c index d853e02d8f..e1349e78a0 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1149,7 +1149,7 @@ iterate_over_all_matching_symtabs if (objfile->sf) objfile->sf->qf->expand_symtabs_matching (objfile, NULL, - lookup_name, + &lookup_name, NULL, NULL, search_domain); diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 44d4978d53..d952f453d9 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1304,13 +1304,11 @@ static void psym_expand_symtabs_matching (struct objfile *objfile, gdb::function_view file_matcher, - const lookup_name_info &lookup_name_in, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain domain) { - lookup_name_info lookup_name = lookup_name_in.make_ignore_params (); - /* Clear the search flags. */ for (partial_symtab *ps : require_partial_symbols (objfile, true)) ps->searched_flag = PST_NOT_SEARCHED; @@ -1347,8 +1345,10 @@ psym_expand_symtabs_matching continue; } - if (recursively_search_psymtabs (ps, objfile, domain, - lookup_name, symbol_matcher)) + if ((symbol_matcher == NULL && lookup_name == NULL) + || recursively_search_psymtabs (ps, objfile, domain, + lookup_name->make_ignore_params (), + symbol_matcher)) { struct compunit_symtab *symtab = psymtab_to_symtab (objfile, ps); diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c index 19dc83a8bd..75e6f2d0d8 100644 --- a/gdb/symfile-debug.c +++ b/gdb/symfile-debug.c @@ -254,7 +254,7 @@ static void debug_qf_expand_symtabs_matching (struct objfile *objfile, gdb::function_view file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind) diff --git a/gdb/symfile.c b/gdb/symfile.c index 61053298a8..8c002ebfab 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -3777,7 +3777,7 @@ expand_symtabs_matching { if (objfile->sf) objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher, - lookup_name, + &lookup_name, symbol_matcher, expansion_notify, kind); } diff --git a/gdb/symfile.h b/gdb/symfile.h index 84fa283e85..5ada6c370e 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -253,11 +253,14 @@ struct quick_symbol_functions names (the passed file name is already only the lbasename'd part). - Otherwise, if KIND does not match, this symbol is skipped. + If the file is not skipped, and SYMBOL_MATCHER and LOOKUP_NAME are NULL, + the symbol table is expanded. - If even KIND matches, SYMBOL_MATCHER is called for each symbol - defined in the file. The symbol "search" name is passed to - SYMBOL_MATCHER. + Otherwise, individual symbols are considered. + + If KIND does not match, the symbol is skipped. + + If the symbol name does not match LOOKUP_NAME, the symbol is skipped. If SYMBOL_MATCHER returns false, then the symbol is skipped. @@ -265,7 +268,7 @@ struct quick_symbol_functions void (*expand_symtabs_matching) (struct objfile *objfile, gdb::function_view file_matcher, - const lookup_name_info &lookup_name, + const lookup_name_info *lookup_name, gdb::function_view symbol_matcher, gdb::function_view expansion_notify, enum search_domain kind); diff --git a/gdb/symmisc.c b/gdb/symmisc.c index bee136ed46..1076a0bcaf 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -977,12 +977,8 @@ maintenance_expand_symtabs (const char *args, int from_tty) return (!basenames && (regexp == NULL || re_exec (filename))); }, - lookup_name_info::match_any (), - [] (const char *symname) - { - /* Since we're not searching on symbols, just return true. */ - return true; - }, + NULL, + NULL, NULL, ALL_DOMAIN); } diff --git a/gdb/symtab.c b/gdb/symtab.c index 13a5a108e6..45d75a3cd1 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4540,7 +4540,7 @@ global_symbol_searcher::expand_symtabs { return file_matches (filename, filenames, basenames); }, - lookup_name_info::match_any (), + &lookup_name_info::match_any (), [&] (const char *symname) { return (!preg.has_value () diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c new file mode 100644 index 0000000000..649c5b97c5 --- /dev/null +++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "maint-expand-symbols-header-file.h" + +int +main (void) +{ + printf ("hello: %s\n", foo ()); + return 0; +} diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp new file mode 100644 index 0000000000..f73be404c9 --- /dev/null +++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp @@ -0,0 +1,46 @@ +# Copyright 2020 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Test-case to verify that symbol-less symtabs are expanded by +# "maint expand-symtabs". + +standard_testfile .c + +if {[prepare_for_testing "failed to prepare" $testfile \ + $srcfile {debug nowarnings}]} { + return -1 +} + +set test "verify no symtabs are expanded" +if { [readnow] } { + unsupported $test + return -1 +} +gdb_test_no_output "maint info symtabs" $test + +# Expand the header file symtab. +gdb_test_no_output "maint expand-symtabs maint-expand-symbols-header-file.h" + +# Check that the include symtab was in fact expanded. +set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.h" +gdb_test "maint info symtabs" \ + "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \ + "check header file psymtab expansion" + +# Check that the symtab the include symtab was referring to was expanded. +set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.c" +gdb_test "maint info symtabs" \ + "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \ + "check source file psymtab expansion" diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h new file mode 100644 index 0000000000..d8d2517c7b --- /dev/null +++ b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +inline static const char* +foo (void) +{ + return "foo"; +} --------------334C91004A904A95A8B2B954--