From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30794 invoked by alias); 14 Jun 2010 15:59:54 -0000 Received: (qmail 30783 invoked by uid 22791); 14 Jun 2010 15:59:52 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL,BAYES_05,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 14 Jun 2010 15:59:44 +0000 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o5EFxhqo021982 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 14 Jun 2010 11:59:43 -0400 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o5EFxexl001120 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 14 Jun 2010 11:59:42 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id o5EFxejZ027540; Mon, 14 Jun 2010 17:59:40 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id o5EFxdeh027537; Mon, 14 Jun 2010 17:59:39 +0200 Date: Mon, 14 Jun 2010 15:59:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Cc: Sami Wagiaalla Subject: [patch 1/2] Search typedefs in namespaces also in other files Message-ID: <20100614155939.GA23639@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-06/txt/msg00312.txt.bz2 Hi, currently you can access static symbols from not-current CUs (Compilation Units). In some cases you cannot if it is a name contained in namespace. ==> ns.C <== int main () { extern int f (); return f (); } ==> ns2.C <== typedef short i_t; static i_t i = 1; namespace N { typedef long j_t; j_t j = 2; } int f () { return i + N::j; } (gdb) start (gdb) ptype i_t type = short (gdb) ptype N::j_t No symbol "j_t" in namespace "N". -> with the patch: type = long (gdb) ptype ::N::j_t No symbol "j_t" in current context. -> with the patch: type = long (gdb) ptype j_t No symbol "j_t" in current context. (gdb) adv f f () at ns2.C:11 (gdb) ptype N::j_t type = long (gdb) _ That is type gets resolvable only if we are currently in its CU. It is questionable how it should behave. Such access is already not compliant with the C++ standard. The implementation tries only to search for the fully qualified names - without any attempts for imported namespaces. New types are always local to its CU. You cannot use type from some .o file without having its types defined for each new compiled CU from a .h file. Therefore all the types get normally duplicated by each new CU. While one can use cross-CU references those are AFAIK (seen it only at Portland Group compiled output) only de-duplicated after the compilation is done. That means DW_TAG_typedef has never DW_AT_external (is it really true?) and C++ standard non-compliant other-file lookup makes sense. While I tried I have not found any proper coding scheme so I just patched some functions to make it working. I may have missed some design points. Already the C++ parser calls various functions in not so correct way IMHO and there also now exists at least the archer-cpparser effort to make it more sane. Filed two KFAILed GDB Bugs for it, they are not regressions but rather the unfixed parts: [Bug c++/11702] New: static const member is not printed - it is unrelated to the issue this(ese) patch(es) try to solve. [Bug c++/11703] New: root namespace sometimes not working - Leading :: works only for types, not other objects. - IMHO a fix requires patching the C++ parser: -> archer-cpparser No regressions on {x86_64,x86_64-m32,i686}-fedora13-linux-gnu (gcc-4.4-rh). For proper testing avoiding some XFAILs one needs at least gcc-4.5. Thanks, Jan gdb/ 2010-06-14 Jan Kratochvil * cp-namespace.c (cp_lookup_symbol_namespace): Call also lookup_static_symbol_aux if we failed otherwise. (cp_lookup_nested_type): New variable concatenated_name. Turn the current return condition into a reverse one. Call also lookup_static_symbol_aux on the constructed qualified name. * symtab.c (lookup_symbol_aux): Move variable objfile and searching in other files into a called ... (lookup_static_symbol_aux): ... new function here. * symtab.h (lookup_static_symbol_aux): New prototype. gdb/testsuite/ 2010-06-14 Jan Kratochvil * gdb.cp/namespace.exp (whatis C::cOtherFileType) (whatis ::C::cOtherFileType, whatis C::cOtherFileVar) (whatis ::C::cOtherFileVar, print C::cOtherFileVar) (print ::C::cOtherFileVar) (whatis C::OtherFileClass::cOtherFileClassType) (whatis ::C::OtherFileClass::cOtherFileClassType) (print C::OtherFileClass::cOtherFileClassVar) (print ::C::OtherFileClass::cOtherFileClassVar): New tests. (ptype OtherFileClass, ptype ::C::OtherFileClass): Permit arbitrary trailing content. * gdb.cp/namespace1.cc (C::OtherFileClass::cOtherFileClassType) (C::OtherFileClass::cOtherFileClassVar) (C::OtherFileClass::cOtherFileClassVar_use, C::cOtherFileType) (C::cOtherFileVar, C::cOtherFileVar_use): New. --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -440,6 +440,27 @@ cp_lookup_symbol_namespace (const char *scope, block = BLOCK_SUPERBLOCK (block); } + /* Now search all static file-level symbols. Not strictly correct, + but more useful than an error. We do not try to guess any imported + namespace as even the fully specified namespace seach is is already not + C++ compliant and more assumptions could make it too magic. */ + + if (scope[0] == '\0') + { + sym = lookup_static_symbol_aux (name, domain); + if (sym != NULL) + return sym; + } + else + { + char *concatenated_name = alloca (strlen (scope) + 2 + strlen (name) + 1); + + sprintf (concatenated_name, "%s::%s", scope, name); + sym = lookup_static_symbol_aux (concatenated_name, domain); + if (sym != NULL) + return sym; + } + return NULL; } @@ -578,11 +599,24 @@ cp_lookup_nested_type (struct type *parent_type, nested_name, block, VAR_DOMAIN); + char *concatenated_name; - if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF) - return NULL; - else + if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) return SYMBOL_TYPE (sym); + + /* Now search all static file-level symbols. Not strictly correct, + but more useful than an error. We do not try to guess any imported + namespace as even the fully specified namespace seach is is already + not C++ compliant and more assumptions could make it too magic. */ + + concatenated_name = alloca (strlen (parent_name) + 2 + + strlen (nested_name) + 1); + sprintf (concatenated_name, "%s::%s", parent_name, nested_name); + sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN); + if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + return SYMBOL_TYPE (sym); + + return NULL; } default: internal_error (__FILE__, __LINE__, --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1054,7 +1054,6 @@ lookup_symbol_aux (const char *name, const struct block *block, { struct symbol *sym; const struct language_defn *langdef; - struct objfile *objfile; /* Make sure we do something sensible with is_a_field_of_this, since the callers that set this parameter to some non-null value will @@ -1121,11 +1120,20 @@ lookup_symbol_aux (const char *name, const struct block *block, if (sym != NULL) return sym; - /* Now search all static file-level symbols. Not strictly correct, - but more useful than an error. Do the symtabs first, then check - the psymtabs. If a psymtab indicates the existence of the - desired name as a file-level static, then do psymtab-to-symtab - conversion on the fly and return the found symbol. */ + return lookup_static_symbol_aux (name, domain); +} + +/* Now search all static file-level symbols. Not strictly correct, + but more useful than an error. Do the symtabs first, then check + the psymtabs. If a psymtab indicates the existence of the + desired name as a file-level static, then do psymtab-to-symtab + conversion on the fly and return the found symbol. */ + +struct symbol * +lookup_static_symbol_aux (const char *name, const domain_enum domain) +{ + struct objfile *objfile; + struct symbol *sym; sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain); if (sym != NULL) --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -886,6 +886,12 @@ extern struct symbol *lookup_symbol_aux_block (const char *name, const struct block *block, const domain_enum domain); +/* Lookup a symbol only in the file static scope of all the objfiles. */ + +struct symbol *lookup_static_symbol_aux (const char *name, + const domain_enum domain); + + /* lookup a symbol by name, within a specified block */ extern struct symbol *lookup_block_symbol (const struct block *, const char *, --- a/gdb/testsuite/gdb.cp/namespace.exp +++ b/gdb/testsuite/gdb.cp/namespace.exp @@ -165,6 +165,66 @@ gdb_test "print BBB::Class::xyzq" \ gdb_test "break BBB::Class::xyzq" \ "Breakpoint.*at $hex: file.*namespace.cc, line 68\\." +# Tests accessing static elements in namespace of other file. + +gdb_test "whatis C::cOtherFileType" "type = short" +gdb_test "whatis ::C::cOtherFileType" "type = short" +gdb_test "whatis C::cOtherFileVar" "type = const C::cOtherFileType" +setup_kfail "c++/11703" "*-*-*" +gdb_test "whatis ::C::cOtherFileVar" "type = const C::cOtherFileType" +gdb_test "print C::cOtherFileVar" "\\$\[0-9\].* = 319" +setup_kfail "c++/11703" "*-*-*" +gdb_test "print ::C::cOtherFileVar" "\\$\[0-9\].* = 319" + +if {[test_compiler_info {gcc-[0-3]-*}] + || [test_compiler_info {gcc-4-[0-4]-*}]} { + # The type in class is missing in older GCCs. + setup_xfail *-*-* +} +gdb_test "whatis C::OtherFileClass::cOtherFileClassType" "type = short" +if {[test_compiler_info {gcc-[0-3]-*}] + || [test_compiler_info {gcc-4-[0-4]-*}]} { + # The type in class is missing in older GCCs. + setup_xfail *-*-* +} +gdb_test "whatis ::C::OtherFileClass::cOtherFileClassType" "type = short" + +set test "print C::OtherFileClass::cOtherFileClassVar" +gdb_test_multiple $test $test { + -re "\\$\[0-9\].* = 318\r\n$gdb_prompt $" { + pass $test + } + -re "static field cOtherFileClassVar has been optimized out\r\n$gdb_prompt $" { + setup_kfail "c++/11702" "*-*-*" + fail $test + } +} +if {[test_compiler_info {gcc-[0-3]-*}] + || [test_compiler_info {gcc-4-[0-4]-*}]} { + # Older GCCs create unqualified DIE "cOtherFileClassVar" ignoring the + # namespace the same way GDB does. + setup_xfail *-*-* +} else { + setup_kfail "c++/11703" "*-*-*" +} +set test "print ::C::OtherFileClass::cOtherFileClassVar" +gdb_test_multiple $test $test { + -re "\\$\[0-9\].* = 318\r\n$gdb_prompt $" { + if {[test_compiler_info {gcc-[0-3]-*}] + || [test_compiler_info {gcc-4-[0-4]-*}]} { + # Older GCCs create unqualified DIE "cOtherFileClassVar" ignoring the + # namespace the same way GDB does. + xfail $test + } else { + pass $test + } + } + -re "$gdb_prompt $" { + setup_kfail "c++/11703" "*-*-*" + fail $test + } +} + # Test to see if the appropriate namespaces are in scope when trying # to print out stuff from within a function defined within a # namespace. @@ -201,8 +261,8 @@ gdb_test "ptype C::NestedClass" "No symbol \"NestedClass\" in namespace \"C::C\" # Tests involving multiple files gdb_test "print cOtherFile" "\\$\[0-9\].* = 316" -gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n\}" -gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n\}" +gdb_test "ptype OtherFileClass" "type = (class C::OtherFileClass \{\r\n public:|struct C::OtherFileClass \{)\r\n int z;\r\n.*\}" +gdb_test "ptype ::C::OtherFileClass" "type = class C::OtherFileClass \{\r\n public:\r\n int z;\r\n.*\}" gdb_test "ptype C::OtherFileClass" "No symbol \"OtherFileClass\" in namespace \"C::C\"." # Some anonymous namespace tests. --- a/gdb/testsuite/gdb.cp/namespace1.cc +++ b/gdb/testsuite/gdb.cp/namespace1.cc @@ -21,7 +21,15 @@ namespace C class OtherFileClass { public: int z; + + typedef short cOtherFileClassType; + static const cOtherFileClassType cOtherFileClassVar = 318; + cOtherFileClassType cOtherFileClassVar_use (); }; + OtherFileClass::cOtherFileClassType OtherFileClass::cOtherFileClassVar_use () + { + return cOtherFileClassVar; + } namespace { int cXOtherFile = 29; @@ -35,6 +43,13 @@ namespace C static OtherFileClass *c = new OtherFileClass(); c->z = cOtherFile + cXOtherFile; } + + typedef short cOtherFileType; + static const cOtherFileType cOtherFileVar = 319; + cOtherFileType cOtherFileVar_use () + { + return cOtherFileVar; + } } namespace {