From patchwork Fri Oct 12 18:43:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 983264 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-487486-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="imTWDAfp"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42WxZN4hjmz9s3C for ; Sat, 13 Oct 2018 05:44:11 +1100 (AEDT) Received: (qmail 123519 invoked by alias); 12 Oct 2018 18:44:03 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 123466 invoked by uid 89); 12 Oct 2018 18:44:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Received:sk:f3-v6mr, translated, Declarations, HX-Received:1f03 X-HELO: mail-yw1-f51.google.com Received: from mail-yw1-f51.google.com (HELO mail-yw1-f51.google.com) (209.85.161.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 12 Oct 2018 18:43:58 +0000 Received: by mail-yw1-f51.google.com with SMTP id e201-v6so5325417ywa.3 for ; Fri, 12 Oct 2018 11:43:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=Z7pgQnxeCCar1Zv2GFpOb4n7prxM2UtQ1w0DMOdEX6M=; b=imTWDAfpZaxZqH6YP7hAjoakgC/5v7WbyU7mA/0GtpFUq+KkeeRuQ+3uwkb1o4zMDC 7KWjRxzUraTT+Hrgs8Nm5WIA3zTq6xwye4IVEqTkWRM7LfZWFWaCPTPwlxn/nVC6ggbP PhVCP4/3XbwNADeXhFfLIKUzcFoz8JEkWk3xu4IfeB1em8nx/bKcV5tpzX61jM/dJK6a iubuF5lH9Y2BG4DKRAm/PriB0V8V0ZuFsRv/hJNmbsY50B4/txdO4Z2/FTA/BeT0/n4M MuD+yqpA2o600ioRMgFfR3ODTeoFSaAs2pI2f3QsMHsnin1mDH+erXL1yJiKOdlS7yxx U6MA== Received: from ?IPv6:2620:10d:c0a3:20fb::822? ([2620:10d:c091:200::5:24da]) by smtp.googlemail.com with ESMTPSA id w129-v6sm464974ywe.43.2018.10.12.11.43.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Oct 2018 11:43:55 -0700 (PDT) Sender: Nathan Sidwell To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] more TU parsing refactoring Message-ID: <90e86a51-ab6d-b805-b97b-b36dff99b62b@acm.org> Date: Fri, 12 Oct 2018 14:43:54 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0 MIME-Version: 1.0 This patch does a bit more refactoring to yesterday's cleanup. Rather than have cp_parser_translation_unit use cp_parser_declaration_seq_opt, I break out the guts of the latter function to cp_parser_toplevel_declaration, and call that from both places. Further, the implicit_extern_c processing is moved to cp_parser_translation_unit. If you're switching between differently IEC headers inside a namespace, or extern-C region, you're doing it very wrong. Built and tested on x86_64-linux and powerpc8-aix (the remaining implicit extern C target). nathan 2018-10-12 Nathan Sidwell * parser.h (struct cp_parser): Drop implicit_extern_c. * parser.c (cp_debug_parser): Drop implicit_extern_c. (cp_parser_new): Likewise. (cp_parser_translation_unit): Handle implicit extern c here. Call cp_parser_toplevel_declaration. (cp_parser_toplevel_declaration): New, broken out of ... (cp_parser_declaration_seq_opt): ... here. Call it. Drop implicit extern C handling. Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 265055) +++ gcc/cp/parser.c (working copy) @@ -556,8 +556,6 @@ cp_debug_parser (FILE *file, cp_parser * parser->in_statement & IN_IF_STMT); cp_debug_print_flag (file, "Parsing a type-id in an expression " "context", parser->in_type_id_in_expr_p); - cp_debug_print_flag (file, "Declarations are implicitly extern \"C\"", - parser->implicit_extern_c); cp_debug_print_flag (file, "String expressions should be translated " "to execution character set", parser->translate_strings_p); @@ -2135,6 +2133,8 @@ static void cp_parser_declaration_seq_op (cp_parser *); static void cp_parser_declaration (cp_parser *); +static void cp_parser_toplevel_declaration + (cp_parser *); static void cp_parser_block_declaration (cp_parser *, bool); static void cp_parser_simple_declaration @@ -3923,9 +3923,6 @@ cp_parser_new (void) /* We are not parsing a type-id inside an expression. */ parser->in_type_id_in_expr_p = false; - /* Declarations aren't implicitly extern "C". */ - parser->implicit_extern_c = false; - /* String literals should be translated to the execution character set. */ parser->translate_strings_p = true; @@ -4601,31 +4598,45 @@ cp_parser_translation_unit (cp_parser* p /* Remember where the base of the declarator obstack lies. */ void *declarator_obstack_base = obstack_next_free (&declarator_obstack); + bool implicit_extern_c = false; + for (;;) { - cp_parser_declaration_seq_opt (parser); - gcc_assert (!cp_parser_parsing_tentatively (parser)); - if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) + cp_token *token = cp_lexer_peek_token (parser->lexer); + + /* If we're entering or exiting a region that's implicitly + extern "C", modify the lang context appropriately. */ + if (implicit_extern_c + != cp_lexer_peek_token (parser->lexer)->implicit_extern_c) + { + implicit_extern_c = !implicit_extern_c; + if (implicit_extern_c) + push_lang_context (lang_name_c); + else + pop_lang_context (); + } + + if (token->type == CPP_EOF) break; - /* Must have been an extra close-brace. */ - cp_parser_error (parser, "expected declaration"); - cp_lexer_consume_token (parser->lexer); - /* If the next token is now a `;', consume it. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) - cp_lexer_consume_token (parser->lexer); + + if (token->type == CPP_CLOSE_BRACE) + { + cp_parser_error (parser, "expected declaration"); + cp_lexer_consume_token (parser->lexer); + /* If the next token is now a `;', consume it. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + cp_lexer_consume_token (parser->lexer); + } + else + cp_parser_toplevel_declaration (parser); } /* Get rid of the token array; we don't need it any more. */ cp_lexer_destroy (parser->lexer); parser->lexer = NULL; - - /* This file might have been a context that's implicitly extern - "C". If so, pop the lang context. (Only relevant for PCH.) */ - if (parser->implicit_extern_c) - { - pop_lang_context (); - parser->implicit_extern_c = false; - } + + /* The EOF should have reset this. */ + gcc_checking_assert (!implicit_extern_c); /* Make sure the declarator obstack was fully cleaned up. */ gcc_assert (obstack_next_free (&declarator_obstack) @@ -12732,50 +12743,13 @@ cp_parser_declaration_seq_opt (cp_parser { while (true) { - cp_token *token; - - token = cp_lexer_peek_token (parser->lexer); + cp_token *token = cp_lexer_peek_token (parser->lexer); if (token->type == CPP_CLOSE_BRACE - || token->type == CPP_EOF - || token->type == CPP_PRAGMA_EOL) + || token->type == CPP_EOF) break; - - if (token->type == CPP_SEMICOLON) - { - /* A declaration consisting of a single semicolon is - invalid. Allow it unless we're being pedantic. */ - cp_lexer_consume_token (parser->lexer); - if (!in_system_header_at (input_location)) - pedwarn (input_location, OPT_Wpedantic, "extra %<;%>"); - continue; - } - - /* If we're entering or exiting a region that's implicitly - extern "C", modify the lang context appropriately. */ - if (!parser->implicit_extern_c && token->implicit_extern_c) - { - push_lang_context (lang_name_c); - parser->implicit_extern_c = true; - } - else if (parser->implicit_extern_c && !token->implicit_extern_c) - { - pop_lang_context (); - parser->implicit_extern_c = false; - } - - if (token->type == CPP_PRAGMA) - { - /* A top-level declaration can consist solely of a #pragma. - A nested declaration cannot, so this is done here and not - in cp_parser_declaration. (A #pragma at block scope is - handled in cp_parser_statement.) */ - cp_parser_pragma (parser, pragma_external, NULL); - continue; - } - - /* Parse the declaration itself. */ - cp_parser_declaration (parser); + else + cp_parser_toplevel_declaration (parser); } } @@ -12905,6 +12879,32 @@ cp_parser_declaration (cp_parser* parser obstack_free (&declarator_obstack, p); } +/* Parse a namespace-scope declaration. */ + +static void +cp_parser_toplevel_declaration (cp_parser* parser) +{ + cp_token *token = cp_lexer_peek_token (parser->lexer); + + if (token->type == CPP_PRAGMA) + /* A top-level declaration can consist solely of a #pragma. A + nested declaration cannot, so this is done here and not in + cp_parser_declaration. (A #pragma at block scope is + handled in cp_parser_statement.) */ + cp_parser_pragma (parser, pragma_external, NULL); + else if (token->type == CPP_SEMICOLON) + { + /* A declaration consisting of a single semicolon is + invalid. Allow it unless we're being pedantic. */ + cp_lexer_consume_token (parser->lexer); + if (!in_system_header_at (input_location)) + pedwarn (input_location, OPT_Wpedantic, "extra %<;%>"); + } + else + /* Parse the declaration itself. */ + cp_parser_declaration (parser); +} + /* Parse a block-declaration. block-declaration: Index: gcc/cp/parser.h =================================================================== --- gcc/cp/parser.h (revision 265035) +++ gcc/cp/parser.h (working copy) @@ -321,10 +321,6 @@ struct GTY(()) cp_parser { alternatives. */ bool in_type_id_in_expr_p; - /* TRUE if we are currently in a header file where declarations are - implicitly extern "C". */ - bool implicit_extern_c; - /* TRUE if strings in expressions should be translated to the execution character set. */ bool translate_strings_p;