From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 115358 invoked by alias); 25 Jan 2018 15:09:26 -0000 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 Received: (qmail 115342 invoked by uid 89); 25 Jan 2018 15:09:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-34.4 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS,T_RP_MATCHES_RCVD,USER_IN_DEF_SPF_WL autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f202.google.com Received: from mail-qt0-f202.google.com (HELO mail-qt0-f202.google.com) (209.85.216.202) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 25 Jan 2018 15:09:22 +0000 Received: by mail-qt0-f202.google.com with SMTP id l6so11480357qtj.0 for ; Thu, 25 Jan 2018 07:09:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:date:in-reply-to:message-id :references:subject:from:to:cc; bh=sfRqJF5ibLBjElzaoJFEUTlo4+xJU8bVRPNIkMFtkIQ=; b=TrmXYdx6GEfAedrdozH9gpG/8w+rssGPghcMEBxwv3vRIQmB3WU7GU5BmLRHCQmcE9 YqpmJbFRcbNXzpsaDWlTOLqrPB4AygNg2NneDg3PMAZYMIIa1KatpPTi4FSxTYmKNh0B XFPDgkPac/5pGis3U+yLchRBqWoPROsSFUck5nR+F0vQSNl0NB85Jw39T5Xmw93a3kMW 0b851/PvYyNcE0AdiyeHjo3W5rX5KX8O7HJ97n9/f7ky227lxbpqvNXumOmb+70+q+oU iWtEYK3nlHqkCEkDZ+vGEo5uCFzOQEJGSfjNdce+FecZhGxDclLdoFgWugDhEnLRX/qb FzpQ== X-Gm-Message-State: AKwxytcYbdVqGHhyJ/ozLu3ecEW8oH0Fd/k2p9IypNqyPaI2CCQDK+ac O+lO+d+pzNByj1pK4YjIczGNTonNqwuHstTvOgt4yeb6O05mMM1MlseMb7nI6rEiXazOycB+wNj XwL/rDkC97Z+UzEsZ7tVE6kpXWidnl70PAYyAXBQbQZBcG8465cp8ulKtspfS2w2GQi7Cew== X-Google-Smtp-Source: AH8x227V44UOPkC05ua77gVpPF7d89+3YUvimsD4VUU1AhCmNqHYe8+Sa5GH5rizndENt1jblzmk6U0PZq3j MIME-Version: 1.0 X-Received: by 10.237.53.199 with SMTP id d7mr1685982qte.33.1516892960737; Thu, 25 Jan 2018 07:09:20 -0800 (PST) Date: Thu, 25 Jan 2018 15:09:00 -0000 In-Reply-To: <7e304815dd4d3f8e8ab89fa718854ccc@polymtl.ca> Message-Id: <20180125150915.91427-1-leszeks@google.com> References: <7e304815dd4d3f8e8ab89fa718854ccc@polymtl.ca> Subject: [PATCH v3] Do not classify C struct members as a filename From: "Leszek Swirski via gdb-patches" Reply-To: Leszek Swirski To: gdb-patches@sourceware.org Cc: Simon Marchi , Leszek Swirski Content-Type: text/plain; charset="UTF-8" X-SW-Source: 2018-01/txt/msg00529.txt.bz2 There is existing logic in C/C++ expression parsing to avoid classifying names as a filename when they are a field on the this object. This change extends this logic to also avoid classifying names after a struct-op (-> or .) as a filename, which otherwise causes a syntax error. Thus, it is now possible in the file #include struct D { void map(); } D d; to call (gdb) print d.map() where previously this would have been a syntax error. Tested on gdb.cp/*.exp gdb/ChangeLog: * c-exp.y (lex_one_token, classify_name, yylex): Don't classify names after a structop as a filename gdb/testsuite/ChangeLog: * gdb.cp/filename.cc, gdb.cp/filename.exp: Test that member functions with the same name as an include file are parsed correctly. --- Updated ints to bools (including some opportunistic updates of existing arguments), and expanded test. gdb/ChangeLog | 5 +++++ gdb/c-exp.y | 43 +++++++++++++++++++++------------------ gdb/testsuite/ChangeLog | 6 ++++++ gdb/testsuite/gdb.cp/filename.cc | 22 +++++++++++++++++++- gdb/testsuite/gdb.cp/filename.exp | 20 ++++++++++++++++-- 5 files changed, 73 insertions(+), 23 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2b6d1d6d6b..17a5a84b0c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2018-01-24 Leszek Swirski + + * c-exp.y (lex_one_token, classify_name, yylex): Don't classify + names after a structop as a filename + 2018-01-23 Philipp Rudo * s390-linux-tdep.c (s390_record_address_mask) diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 0482e85ce8..5802a6d746 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -2447,24 +2447,23 @@ static struct macro_scope *expression_macro_scope; static int saw_name_at_eof; /* This is set if the previously-returned token was a structure - operator -- either '.' or ARROW. This is used only when parsing to - do field name completion. */ -static int last_was_structop; + operator -- either '.' or ARROW. */ +static bool last_was_structop; /* Read one token, getting characters through lexptr. */ static int -lex_one_token (struct parser_state *par_state, int *is_quoted_name) +lex_one_token (struct parser_state *par_state, bool *is_quoted_name) { int c; int namelen; unsigned int i; const char *tokstart; - int saw_structop = last_was_structop; + bool saw_structop = last_was_structop; char *copy; - last_was_structop = 0; - *is_quoted_name = 0; + last_was_structop = false; + *is_quoted_name = false; retry: @@ -2505,7 +2504,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) lexptr += 2; yylval.opcode = tokentab2[i].opcode; - if (parse_completion && tokentab2[i].token == ARROW) + if (tokentab2[i].token == ARROW) last_was_structop = 1; return tokentab2[i].token; } @@ -2569,8 +2568,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) /* Might be a floating point number. */ if (lexptr[1] < '0' || lexptr[1] > '9') { - if (parse_completion) - last_was_structop = 1; + last_was_structop = true; goto symbol; /* Nope, must be a symbol. */ } /* FALL THRU into number case. */ @@ -2711,7 +2709,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) { ++tokstart; namelen = lexptr - tokstart - 1; - *is_quoted_name = 1; + *is_quoted_name = true; goto tryname; } @@ -2859,11 +2857,12 @@ auto_obstack name_obstack; Updates yylval and returns the new token type. BLOCK is the block in which lookups start; this can be NULL to mean the global scope. IS_QUOTED_NAME is non-zero if the name token was originally quoted - in single quotes. */ + in single quotes. IS_AFTER_STRUCTOP is true if this name follows + a structure operator -- either '.' or ARROW */ static int classify_name (struct parser_state *par_state, const struct block *block, - int is_quoted_name) + bool is_quoted_name, bool is_after_structop) { struct block_symbol bsym; char *copy; @@ -2907,11 +2906,13 @@ classify_name (struct parser_state *par_state, const struct block *block, } } - /* If we found a field, then we want to prefer it over a + /* If we found a field on the "this" object, or we are looking + up a field on a struct, then we want to prefer it over a filename. However, if the name was quoted, then it is better to check for a filename or a block, since this is the only way the user has of requiring the extension to be used. */ - if (is_a_field_of_this.type == NULL || is_quoted_name) + if ((is_a_field_of_this.type == NULL && !is_after_structop) + || is_quoted_name) { /* See if it's a file name. */ struct symtab *symtab; @@ -2992,7 +2993,7 @@ classify_inner_name (struct parser_state *par_state, char *copy; if (context == NULL) - return classify_name (par_state, block, 0); + return classify_name (par_state, block, false, false); type = check_typedef (context); if (!type_aggregate_p (type)) @@ -3066,19 +3067,21 @@ yylex (void) struct type *context_type = NULL; int last_to_examine, next_to_examine, checkpoint; const struct block *search_block; - int is_quoted_name; + bool is_quoted_name, last_lex_was_structop; if (popping && !VEC_empty (token_and_value, token_fifo)) goto do_pop; popping = 0; + last_lex_was_structop = last_was_structop; + /* Read the first token and decide what to do. Most of the subsequent code is C++-only; but also depends on seeing a "::" or name-like token. */ current.token = lex_one_token (pstate, &is_quoted_name); if (current.token == NAME) current.token = classify_name (pstate, expression_context_block, - is_quoted_name); + is_quoted_name, last_lex_was_structop); if (parse_language (pstate)->la_language != language_cplus || (current.token != TYPENAME && current.token != COLONCOLON && current.token != FILENAME)) @@ -3091,7 +3094,7 @@ yylex (void) last_was_coloncolon = current.token == COLONCOLON; while (1) { - int ignore; + bool ignore; /* We ignore quoted names other than the very first one. Subsequent ones do not have any special meaning. */ @@ -3242,7 +3245,7 @@ c_parse (struct parser_state *par_state) parser_debug); /* Initialize some state used by the lexer. */ - last_was_structop = 0; + last_was_structop = false; saw_name_at_eof = 0; VEC_free (token_and_value, token_fifo); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0f02f4a97f..903d9f4cb6 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-01-24 Leszek Swirski + + * gdb.cp/filename.cc, gdb.cp/filename.exp: Test that member + functions with the same name as an include file are parsed + correctly. + 2018-01-22 Pedro Alves Sergio Durigan Junior diff --git a/gdb/testsuite/gdb.cp/filename.cc b/gdb/testsuite/gdb.cp/filename.cc index 45edf4efe9..d33ef78bcb 100644 --- a/gdb/testsuite/gdb.cp/filename.cc +++ b/gdb/testsuite/gdb.cp/filename.cc @@ -26,11 +26,31 @@ public: } void m() { - /* stop here */ + /* stop inside C */ } }; +class D { +public: + int includefile(); + + void m() { + /* stop inside D */ + } +}; + +int D::includefile() { + return 24; +} + int main() { C c; + C* pc = &c; c.m(); + + D d; + D* pd = &d; + d.m(); + + /* stop outside */ } diff --git a/gdb/testsuite/gdb.cp/filename.exp b/gdb/testsuite/gdb.cp/filename.exp index 971ffe715f..208179e7ca 100644 --- a/gdb/testsuite/gdb.cp/filename.exp +++ b/gdb/testsuite/gdb.cp/filename.exp @@ -26,8 +26,24 @@ if ![runto_main] then { continue } -gdb_breakpoint [gdb_get_line_number "stop here"] -gdb_continue_to_breakpoint "stop here" +gdb_breakpoint [gdb_get_line_number "stop inside C"] +gdb_continue_to_breakpoint "stop inside C" gdb_test "print includefile\[0\]" " = 23" +gdb_test "print this->includefile\[0\]" " = 23" gdb_test "print 'includefile'::some_global" " = 27" + +gdb_breakpoint [gdb_get_line_number "stop inside D"] +gdb_continue_to_breakpoint "stop inside D" + +gdb_test "print includefile()" " = 24" +gdb_test "print this->includefile()" " = 24" +gdb_test "print 'includefile'::some_global" " = 27" + +gdb_breakpoint [gdb_get_line_number "stop outside"] +gdb_continue_to_breakpoint "stop outside" + +gdb_test "print c.includefile\[0\]" " = 23" +gdb_test "print pc->includefile\[0\]" " = 23" +gdb_test "print d.includefile()" " = 24" +gdb_test "print pd->includefile()" " = 24" -- 2.16.0.rc1.238.g530d649a79-goog