From patchwork Sun Mar 1 03:00:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 38358 Received: (qmail 20011 invoked by alias); 1 Mar 2020 03:01:02 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 19821 invoked by uid 89); 1 Mar 2020 03:00:45 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=sk:follow_, sk:make_re, 3312 X-HELO: gateway21.websitewelcome.com Received: from gateway21.websitewelcome.com (HELO gateway21.websitewelcome.com) (192.185.45.38) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 01 Mar 2020 03:00:21 +0000 Received: from cm11.websitewelcome.com (cm11.websitewelcome.com [100.42.49.5]) by gateway21.websitewelcome.com (Postfix) with ESMTP id 27FCC40107074 for ; Sat, 29 Feb 2020 21:00:15 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id 8EpzjYfdZSl8q8EpzjCH9s; Sat, 29 Feb 2020 21:00:15 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version :Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=l2QVSERCWZVn1Rj4fHhIlxyQWOfh1yNwiZjnx/BHaNk=; b=Y52JSnFJRTZTA83YJJ60ZJSboa WE76qNzUT1g/TtAswfce+0u6QkHMS4B4H6hIZEUXyHjl4T07kWS5ZJpZlw/b70Fb/d/BjLgpox2RX ud+6D6t+Niwnb9iZ1cDoiGNUV; Received: from 75-166-123-50.hlrn.qwest.net ([75.166.123.50]:44980 helo=bapiya.Home) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from ) id 1j8Epy-004Jc7-Uj; Sat, 29 Feb 2020 20:00:15 -0700 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Add C parser support for "restrict" and "_Atomic" Date: Sat, 29 Feb 2020 20:00:13 -0700 Message-Id: <20200301030013.4619-1-tom@tromey.com> A user noticed that "watch -location" would fail with a "restrict" pointer. The issue here is that if the DWARF mentions "restrict", gdb will put this into the type name -- but then the C parser will not be able to parse this type. This patch adds support for "restrict" and "_Atomic" to the C parser. It is done only for C and Objective C, not C++. I wasn't sure if "restrict" should be marked FLAG_SHADOW to support older dialects of C, where this was not a keyword. gdb/ChangeLog 2020-02-29 Tom Tromey * type-stack.h (enum type_pieces) : New constants. * type-stack.c (type_stack::insert): Handle tp_atomic and tp_restrict. (type_stack::follow_type_instance_flags): Likewise. (type_stack::follow_types): Likewise. Merge type-following code. * c-exp.y (RESTRICT, ATOMIC): New tokens. (space_identifier, cv_with_space_id) (const_or_volatile_or_space_identifier_noopt) (const_or_volatile_or_space_identifier): Remove. (single_qualifier, qualifier_seq_noopt, qualifier_seq): New rules. (ptr_operator, typebase): Update. (enum token_flag) : New constant. (ident_tokens): Add "restrict" and "_Atomic". (lex_one_token): Handle FLAG_C. gdb/testsuite/ChangeLog 2020-02-29 Tom Tromey * gdb.base/cvexpr.exp: Add test for _Atomic and restrict. --- gdb/ChangeLog | 19 ++++++++ gdb/c-exp.y | 52 ++++++++++++++------- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/cvexpr.exp | 4 ++ gdb/type-stack.c | 76 +++++++++++++++---------------- gdb/type-stack.h | 2 + 6 files changed, 101 insertions(+), 56 deletions(-) diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 3403a857a83..1b35ef2e60a 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -237,6 +237,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); /* Special type cases, put in to allow the parser to distinguish different legal basetypes. */ %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD +%token RESTRICT ATOMIC %token DOLLAR_VARIABLE @@ -1169,36 +1170,43 @@ variable: name_not_typename } ; -space_identifier : '@' NAME - { - cpstate->type_stack.insert (pstate, - copy_name ($2.stoken).c_str ()); - } - ; - const_or_volatile: const_or_volatile_noopt | ; -cv_with_space_id : const_or_volatile space_identifier const_or_volatile +single_qualifier: + CONST_KEYWORD + { cpstate->type_stack.insert (tp_const); } + | VOLATILE_KEYWORD + { cpstate->type_stack.insert (tp_volatile); } + | ATOMIC + { cpstate->type_stack.insert (tp_atomic); } + | RESTRICT + { cpstate->type_stack.insert (tp_restrict); } + | '@' NAME + { + cpstate->type_stack.insert (pstate, + copy_name ($2.stoken).c_str ()); + } ; -const_or_volatile_or_space_identifier_noopt: cv_with_space_id - | const_or_volatile_noopt +qualifier_seq_noopt: + single_qualifier + | qualifier_seq single_qualifier ; -const_or_volatile_or_space_identifier: - const_or_volatile_or_space_identifier_noopt +qualifier_seq: + qualifier_seq_noopt | ; ptr_operator: ptr_operator '*' { cpstate->type_stack.insert (tp_pointer); } - const_or_volatile_or_space_identifier + qualifier_seq | '*' { cpstate->type_stack.insert (tp_pointer); } - const_or_volatile_or_space_identifier + qualifier_seq | '&' { cpstate->type_stack.insert (tp_reference); } | '&' ptr_operator @@ -1472,9 +1480,9 @@ typebase (copy_name($2).c_str (), $4, pstate->expression_context_block); } - | const_or_volatile_or_space_identifier_noopt typebase + | qualifier_seq_noopt typebase { $$ = cpstate->type_stack.follow_types ($2); } - | typebase const_or_volatile_or_space_identifier_noopt + | typebase qualifier_seq_noopt { $$ = cpstate->type_stack.follow_types ($1); } ; @@ -2345,6 +2353,10 @@ enum token_flag FLAG_CXX = 1, + /* If this bit is set, the token is C-only. */ + + FLAG_C = 1, + /* If this bit is set, the token is conditional: if there is a symbol of the same name, then the token is a symbol; otherwise, the token is a keyword. */ @@ -2416,6 +2428,8 @@ static const struct token ident_tokens[] = {"union", UNION, OP_NULL, 0}, {"short", SHORT, OP_NULL, 0}, {"const", CONST_KEYWORD, OP_NULL, 0}, + {"restrict", RESTRICT, OP_NULL, 0}, + {"_Atomic", ATOMIC, OP_NULL, 0}, {"enum", ENUM, OP_NULL, 0}, {"long", LONG, OP_NULL, 0}, {"true", TRUEKEYWORD, OP_NULL, FLAG_CXX}, @@ -2550,6 +2564,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if ((tokentab3[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + gdb_assert ((tokentab3[i].flags & FLAG_C) == 0); pstate->lexptr += 3; yylval.opcode = tokentab3[i].opcode; @@ -2563,6 +2578,7 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if ((tokentab2[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + gdb_assert ((tokentab3[i].flags & FLAG_C) == 0); pstate->lexptr += 2; yylval.opcode = tokentab2[i].opcode; @@ -2857,6 +2873,10 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) if ((ident_tokens[i].flags & FLAG_CXX) != 0 && par_state->language ()->la_language != language_cplus) break; + if ((ident_tokens[i].flags & FLAG_C) != 0 + && par_state->language ()->la_language != language_c + && par_state->language ()->la_language != language_objc) + break; if ((ident_tokens[i].flags & FLAG_SHADOW) != 0) { diff --git a/gdb/testsuite/gdb.base/cvexpr.exp b/gdb/testsuite/gdb.base/cvexpr.exp index 92a073a774e..cf5d2c4a553 100644 --- a/gdb/testsuite/gdb.base/cvexpr.exp +++ b/gdb/testsuite/gdb.base/cvexpr.exp @@ -509,3 +509,7 @@ foreach testspec $specs { do_test $prefix $opts } } + +# These tests don't rely on the debug format. +gdb_test "ptype _Atomic int" "type = _Atomic int" +gdb_test "ptype int * restrict" "type = int \\* restrict" diff --git a/gdb/type-stack.c b/gdb/type-stack.c index ab7e0261cad..73b7d5a8dfc 100644 --- a/gdb/type-stack.c +++ b/gdb/type-stack.c @@ -33,12 +33,14 @@ type_stack::insert (enum type_pieces tp) gdb_assert (tp == tp_pointer || tp == tp_reference || tp == tp_rvalue_reference || tp == tp_const - || tp == tp_volatile); + || tp == tp_volatile || tp == tp_restrict + || tp == tp_atomic); /* If there is anything on the stack (we know it will be a tp_pointer), insert the qualifier above it. Otherwise, simply push this on the top of the stack. */ - if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile)) + if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile + || tp == tp_restrict)) slot = 1; else slot = 0; @@ -88,6 +90,12 @@ type_stack::follow_type_instance_flags () case tp_volatile: flags |= TYPE_INSTANCE_FLAG_VOLATILE; break; + case tp_atomic: + flags |= TYPE_INSTANCE_FLAG_ATOMIC; + break; + case tp_restrict: + flags |= TYPE_INSTANCE_FLAG_RESTRICT; + break; default: gdb_assert_not_reached ("unrecognized tp_ value in follow_types"); } @@ -102,6 +110,8 @@ type_stack::follow_types (struct type *follow_type) int make_const = 0; int make_volatile = 0; int make_addr_space = 0; + bool make_restrict = false; + bool make_atomic = false; int array_size; while (!done) @@ -109,19 +119,7 @@ type_stack::follow_types (struct type *follow_type) { case tp_end: done = 1; - if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), - follow_type, 0); - if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, - follow_type, 0); - if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, - make_addr_space); - make_const = make_volatile = 0; - make_addr_space = 0; + goto process_qualifiers; break; case tp_const: make_const = 1; @@ -132,41 +130,39 @@ type_stack::follow_types (struct type *follow_type) case tp_space_identifier: make_addr_space = pop_int (); break; + case tp_atomic: + make_atomic = true; + break; + case tp_restrict: + make_restrict = true; + break; case tp_pointer: follow_type = lookup_pointer_type (follow_type); + goto process_qualifiers; + case tp_reference: + follow_type = lookup_lvalue_reference_type (follow_type); + goto process_qualifiers; + case tp_rvalue_reference: + follow_type = lookup_rvalue_reference_type (follow_type); + process_qualifiers: if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), + follow_type = make_cv_type (make_const, + TYPE_VOLATILE (follow_type), follow_type, 0); if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, + follow_type = make_cv_type (TYPE_CONST (follow_type), + make_volatile, follow_type, 0); if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, + follow_type = make_type_with_address_space (follow_type, make_addr_space); + if (make_restrict) + follow_type = make_restrict_type (follow_type); + if (make_atomic) + follow_type = make_atomic_type (follow_type); make_const = make_volatile = 0; make_addr_space = 0; - break; - case tp_reference: - follow_type = lookup_lvalue_reference_type (follow_type); - goto process_reference; - case tp_rvalue_reference: - follow_type = lookup_rvalue_reference_type (follow_type); - process_reference: - if (make_const) - follow_type = make_cv_type (make_const, - TYPE_VOLATILE (follow_type), - follow_type, 0); - if (make_volatile) - follow_type = make_cv_type (TYPE_CONST (follow_type), - make_volatile, - follow_type, 0); - if (make_addr_space) - follow_type = make_type_with_address_space (follow_type, - make_addr_space); - make_const = make_volatile = 0; - make_addr_space = 0; + make_restrict = make_atomic = false; break; case tp_array: array_size = pop_int (); diff --git a/gdb/type-stack.h b/gdb/type-stack.h index ee004d1be8d..8060f2fea78 100644 --- a/gdb/type-stack.h +++ b/gdb/type-stack.h @@ -40,6 +40,8 @@ enum type_pieces tp_const, tp_volatile, tp_space_identifier, + tp_atomic, + tp_restrict, tp_type_stack, tp_kind };