From patchwork Wed Mar 20 00:30:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 229236 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 2E0AC2C00AF for ; Wed, 20 Mar 2013 11:31:18 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=lzRviQhEVYcMNy1D4qedK46WoOQ/kPa7Ws/p/OIEync 8GOWnh7WbOU1jclDsOBNoCuEMqsPgKKz/7c8lXkuq3SmxNWUOr6fIvASzLUc6Ezg DfYRkOs+D2mNkPaywayGCRneIWTtRW8wsa3eTL+ng4SbHqOfrVqKxWrTmycNuTdM = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=yofhJ4roxuW87umBDwYvNJYk3MA=; b=sYI6O8gtkcZYHgVYF xMx4rsDAnAptpOOnzxj5EmOrC+5CXkjqkSdKCMJ6XGAur9FYewko0XeQ2Q3c1VRn OKVNamiNSXN+/c9uFLjC0WtEuqOIcgqyOtjRCwFFjn10i2RZEnN/nIGOY7kIT+iu qZ97/k2bB75PoxXyrpSoBtb0mM= Received: (qmail 25630 invoked by alias); 20 Mar 2013 00:31:11 -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 25600 invoked by uid 89); 20 Mar 2013 00:31:00 -0000 X-Spam-SWARE-Status: No, score=-5.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_CD, TW_CX, TW_FN, TW_KF, TW_SF autolearn=ham version=3.3.1 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 20 Mar 2013 00:30:53 +0000 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r2K0Uobf019033 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 20 Mar 2013 00:30:51 GMT Received: from acsmt357.oracle.com (acsmt357.oracle.com [141.146.40.157]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r2K0Und7014034 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 20 Mar 2013 00:30:50 GMT Received: from abhmt102.oracle.com (abhmt102.oracle.com [141.146.116.54]) by acsmt357.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id r2K0UnsA032409; Tue, 19 Mar 2013 19:30:49 -0500 Received: from [192.168.1.4] (/79.52.211.80) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 19 Mar 2013 17:30:48 -0700 Message-ID: <51490336.7000509@oracle.com> Date: Wed, 20 Mar 2013 01:30:46 +0100 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130307 Thunderbird/17.0.4 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] Clean-up a bit grokdeclarator Hi, as I mentioned a few days ago, since this function grew rather big, I hope to clean it up a bit. For now at least nothing ground shaking: I moved together some declarations and initializations; in other cases exploited the opportunity C++ gives to defer declarations; consistently changed some int flags to bool (and avoiding names ending by *p for non bools); plus rather obvious stylistic tweaks (like wrapping way overlong lines). I'm also improving a bit the diagnostics - see the new testcases - telling apart and in two error messages. It's a start. How does it look to you? Tested x86_64-linux. Thanks, Paolo. ///////////////////////////// /cp 2013-03-20 Paolo Carlini * decl.c (grokdeclarator): Tidy. (bad_specifiers): Likewise. (grokfndecl): Likewise; improve error messages. /testsuite 2013-03-20 Paolo Carlini * g++.dg/cpp0x/constexpr-friend-2.C: New. * g++.dg/cpp0x/constexpr-main.C: Likewise. Index: cp/decl.c =================================================================== --- cp/decl.c (revision 196797) +++ cp/decl.c (working copy) @@ -77,8 +77,8 @@ static void record_unknown_type (tree, const char static tree builtin_function_1 (tree, tree, bool); static tree build_library_fn_1 (tree, enum tree_code, tree); static int member_function_or_else (tree, tree, enum overload_flags); -static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int, - int); +static void bad_specifiers (tree, enum bad_spec_place, bool, bool, bool, + bool, bool); static void check_for_uninitialized_const_var (tree); static hashval_t typename_hash (const void *); static int typename_compare (const void *, const void *); @@ -7154,11 +7154,11 @@ member_function_or_else (tree ctype, tree cur_type static void bad_specifiers (tree object, enum bad_spec_place type, - int virtualp, - int quals, - int inlinep, - int friendp, - int raises) + bool virtualp, + bool quals, + bool inlinep, + bool friendp, + bool raises) { switch (type) { @@ -7310,14 +7310,15 @@ grokfndecl (tree ctype, tree declarator, tree parms, tree orig_declarator, - int virtualp, + bool virtualp, enum overload_flags flags, cp_cv_quals quals, tree raises, int check, - int friendp, - int publicp, - int inlinep, + bool friendp, + bool publicp, + bool inlinep, + bool constexprp, special_function_kind sfk, bool funcdef_flag, int template_count, @@ -7326,7 +7327,7 @@ grokfndecl (tree ctype, location_t location) { tree decl; - int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; + bool staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; tree t; if (raises) @@ -7427,13 +7428,14 @@ grokfndecl (tree ctype, return NULL_TREE; } - if (inlinep) - { - error ("% is not allowed in declaration of friend " - "template specialization %qD", - decl); - return NULL_TREE; - } + if (inlinep) + error ("% is not allowed in declaration of friend " + "template specialization %qD", decl); + if (constexprp) + error ("% is not allowed in declaration of friend " + "template specialization %qD", decl); + if (inlinep || constexprp) + return NULL_TREE; } } @@ -7474,17 +7476,20 @@ grokfndecl (tree ctype, error ("cannot declare %<::main%> to be a template"); if (inlinep) error ("cannot declare %<::main%> to be inline"); + if (constexprp) + error ("cannot declare %<::main%> to be constexpr"); if (!publicp) error ("cannot declare %<::main%> to be static"); - inlinep = 0; - publicp = 1; + inlinep = false; + constexprp = false; + publicp = true; } /* Members of anonymous types and local classes have no linkage; make them internal. If a typedef is made later, this will be changed. */ if (ctype && (TYPE_ANONYMOUS_P (ctype) || decl_function_context (TYPE_MAIN_DECL (ctype)))) - publicp = 0; + publicp = false; if (publicp && cxx_dialect == cxx98) { @@ -7526,9 +7531,9 @@ grokfndecl (tree ctype, } /* If the declaration was declared inline, mark it as such. */ - if (inlinep) + if (inlinep || constexprp) DECL_DECLARED_INLINE_P (decl) = 1; - if (inlinep & 2) + if (constexprp) DECL_DECLARED_CONSTEXPR_P (decl) = true; DECL_EXTERNAL (decl) = 1; @@ -7611,7 +7616,7 @@ grokfndecl (tree ctype, decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * funcdef_flag + - 4 * (friendp != 0)); + 4 * friendp); if (decl == error_mark_node) return NULL_TREE; @@ -8591,21 +8596,13 @@ grokdeclarator (const cp_declarator *declarator, int initialized, tree* attrlist) { - tree type = NULL_TREE; - int longlong = 0; - int explicit_int128 = 0; - int virtualp, explicitp, friendp, inlinep, staticp; - int explicit_int = 0; - int explicit_char = 0; - int defaulted_int = 0; - tree typedef_decl = NULL_TREE; const char *name = NULL; tree typedef_type = NULL_TREE; /* True if this declarator is a function definition. */ bool funcdef_flag = false; cp_declarator_kind innermost_code = cdk_error; - int bitfield = 0; + bool bitfield_p = false; #if 0 /* See the code below that used this. */ tree decl_attr = NULL_TREE; @@ -8625,8 +8622,6 @@ grokdeclarator (const cp_declarator *declarator, /* virt-specifiers that apply to the declarator, for a declaration of a member function. */ cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED; - /* cv-qualifiers that apply to the type specified by the DECLSPECS. */ - int type_quals; tree raises = NULL_TREE; int template_count = 0; tree returned_attrs = NULL_TREE; @@ -8645,30 +8640,30 @@ grokdeclarator (const cp_declarator *declarator, this value will be NULL_TREE, even if the entity is located at namespace scope. */ tree in_namespace = NULL_TREE; - cp_storage_class storage_class; - bool unsigned_p, signed_p, short_p, long_p, thread_p; + bool unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned); + bool signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed); + bool short_p = decl_spec_seq_has_spec_p (declspecs, ds_short); + bool long_p = decl_spec_seq_has_spec_p (declspecs, ds_long); + bool longlong_p = decl_spec_seq_has_spec_p (declspecs, ds_long_long); + bool thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread); + bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef); + bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); + bool explicit_int = declspecs->explicit_int_p; + bool explicit_char = declspecs->explicit_char_p; + bool explicit_int128 = declspecs->explicit_int128_p; + bool defaulted_int = false; bool type_was_error_mark_node = false; - bool parameter_pack_p = declarator? declarator->parameter_pack_p : false; + bool parameter_pack_p = declarator ? declarator->parameter_pack_p : false; bool template_type_arg = false; bool template_parm_flag = false; - bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr); source_location saved_loc = input_location; - const char *errmsg; - signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed); - unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned); - short_p = decl_spec_seq_has_spec_p (declspecs, ds_short); - long_p = decl_spec_seq_has_spec_p (declspecs, ds_long); - longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long); - explicit_int128 = declspecs->explicit_int128_p; - thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread); - if (decl_context == FUNCDEF) funcdef_flag = true, decl_context = NORMAL; else if (decl_context == MEMFUNCDEF) funcdef_flag = true, decl_context = FIELD; else if (decl_context == BITFIELD) - bitfield = 1, decl_context = FIELD; + bitfield_p = true, decl_context = FIELD; else if (decl_context == TEMPLATE_TYPE_ARG) template_type_arg = true, decl_context = TYPENAME; else if (decl_context == TPARM) @@ -8751,8 +8746,6 @@ grokdeclarator (const cp_declarator *declarator, { case BIT_NOT_EXPR: { - tree type; - if (innermost_code != cdk_function) { error ("declaration of %qD as non-function", decl); @@ -8765,7 +8758,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } - type = TREE_OPERAND (decl, 0); + tree type = TREE_OPERAND (decl, 0); if (TYPE_P (type)) type = constructor_name (type); name = identifier_to_locale (IDENTIFIER_POINTER (type)); @@ -8862,7 +8855,7 @@ grokdeclarator (const cp_declarator *declarator, if (dname && IDENTIFIER_OPNAME_P (dname)) { - if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) + if (typedef_p) { error ("declaration of %qD as %", dname); return error_mark_node; @@ -8874,6 +8867,12 @@ grokdeclarator (const cp_declarator *declarator, } } + if (constexpr_p && typedef_p) + { + error ("% cannot appear in a typedef declaration"); + return error_mark_node; + } + /* Anything declared one level down from the top level must be one of the parameters of a function (because the body is at least two levels down). */ @@ -8900,12 +8899,6 @@ grokdeclarator (const cp_declarator *declarator, if (name == NULL) name = decl_context == PARM ? "parameter" : "type name"; - if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef)) - { - error ("% cannot appear in a typedef declaration"); - return error_mark_node; - } - /* If there were multiple types specified in the decl-specifier-seq, issue an error message. */ if (declspecs->multiple_types_p) @@ -8921,7 +8914,7 @@ grokdeclarator (const cp_declarator *declarator, } /* Extract the basic type from the decl-specifier-seq. */ - type = declspecs->type; + tree type = declspecs->type; if (type == error_mark_node) { type = NULL_TREE; @@ -8947,11 +8940,8 @@ grokdeclarator (const cp_declarator *declarator, { /* These imply 'int'. */ type = integer_type_node; - defaulted_int = 1; + defaulted_int = true; } - /* Gather flags. */ - explicit_int = declspecs->explicit_int_p; - explicit_char = declspecs->explicit_char_p; #if 0 /* See the code below that used this. */ @@ -8969,26 +8959,25 @@ grokdeclarator (const cp_declarator *declarator, ctor_return_type); else if (type == NULL_TREE) { - int is_main; - - explicit_int = -1; - /* We handle `main' specially here, because 'main () { }' is so common. With no options, it is allowed. With -Wreturn-type, it is a warning. It is only an error with -pedantic-errors. */ - is_main = (funcdef_flag - && dname && TREE_CODE (dname) == IDENTIFIER_NODE - && MAIN_NAME_P (dname) - && ctype == NULL_TREE - && in_namespace == NULL_TREE - && current_namespace == global_namespace); + bool is_main = (funcdef_flag + && dname && TREE_CODE (dname) == IDENTIFIER_NODE + && MAIN_NAME_P (dname) + && ctype == NULL_TREE + && in_namespace == NULL_TREE + && current_namespace == global_namespace); + explicit_int = true; + if (type_was_error_mark_node) /* We've already issued an error, don't complain more. */; else if (in_system_header || flag_ms_extensions) /* Allow it, sigh. */; else if (! is_main) - permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name); + permerror (input_location, + "ISO C++ forbids declaration of %qs with no type", name); else if (pedantic) pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids declaration of %qs with no type", name); @@ -9017,7 +9006,7 @@ grokdeclarator (const cp_declarator *declarator, and check for invalid combinations. */ /* Long double is a special combination. */ - if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node) + if (long_p && !longlong_p && TYPE_MAIN_VARIANT (type) == double_type_node) { long_p = false; type = cp_build_qualified_type (long_double_type_node, @@ -9028,13 +9017,13 @@ grokdeclarator (const cp_declarator *declarator, if (unsigned_p || signed_p || long_p || short_p) { - int ok = 0; + bool ok = false; if ((signed_p || unsigned_p) && TREE_CODE (type) != INTEGER_TYPE) error ("% or % invalid for %qs", name); else if (signed_p && unsigned_p) error ("% and % specified together for %qs", name); - else if (longlong && TREE_CODE (type) != INTEGER_TYPE) + else if (longlong_p && TREE_CODE (type) != INTEGER_TYPE) error ("% invalid for %qs", name); else if (long_p && TREE_CODE (type) == REAL_TYPE) error ("% invalid for %qs", name); @@ -9042,8 +9031,10 @@ grokdeclarator (const cp_declarator *declarator, error ("% invalid for %qs", name); else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE) error ("% or % invalid for %qs", name); - else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128) - error ("%, %, %, or % invalid for %qs", name); + else if ((long_p || short_p || explicit_char || explicit_int) + && explicit_int128) + error ("%, %, %, or % invalid for %qs", + name); else if ((long_p || short_p) && explicit_char) error ("% or % specified with char for %qs", name); else if (long_p && short_p) @@ -9057,14 +9048,15 @@ grokdeclarator (const cp_declarator *declarator, } else { - ok = 1; - if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic) + ok = true; + if (!explicit_int && !defaulted_int && !explicit_char + && !explicit_int128 && pedantic) { pedwarn (input_location, OPT_Wpedantic, "long, short, signed or unsigned used invalidly for %qs", name); if (flag_pedantic_errors) - ok = 0; + ok = false; } } @@ -9075,7 +9067,7 @@ grokdeclarator (const cp_declarator *declarator, signed_p = false; long_p = false; short_p = false; - longlong = 0; + longlong_p = false; } } @@ -9090,7 +9082,7 @@ grokdeclarator (const cp_declarator *declarator, Naturally, we extend this to long long as well. Note that this does not include wchar_t. */ - || (bitfield && !flag_signed_bitfields + || (bitfield_p && !flag_signed_bitfields && !signed_p /* A typedef for plain `int' without `signed' can be controlled just like plain `int', but a typedef for @@ -9102,7 +9094,7 @@ grokdeclarator (const cp_declarator *declarator, { if (explicit_int128) type = int128_unsigned_type_node; - else if (longlong) + else if (longlong_p) type = long_long_unsigned_type_node; else if (long_p) type = long_unsigned_type_node; @@ -9119,7 +9111,7 @@ grokdeclarator (const cp_declarator *declarator, type = signed_char_type_node; else if (explicit_int128) type = int128_integer_type_node; - else if (longlong) + else if (longlong_p) type = long_long_integer_type_node; else if (long_p) type = long_integer_type_node; @@ -9134,7 +9126,7 @@ grokdeclarator (const cp_declarator *declarator, "complex double", but if any modifiers at all are specified it is the complex form of TYPE. E.g, "complex short" is "complex short int". */ - else if (defaulted_int && ! longlong && ! explicit_int128 + else if (defaulted_int && ! longlong_p && ! explicit_int128 && ! (long_p || short_p || signed_p || unsigned_p)) type = complex_double_type_node; else if (type == integer_type_node) @@ -9149,7 +9141,8 @@ grokdeclarator (const cp_declarator *declarator, type = build_complex_type (type); } - type_quals = TYPE_UNQUALIFIED; + /* cv-qualifiers that apply to the type specified by the DECLSPECS. */ + int type_quals = TYPE_UNQUALIFIED; if (decl_spec_seq_has_spec_p (declspecs, ds_const)) type_quals |= TYPE_QUAL_CONST; if (decl_spec_seq_has_spec_p (declspecs, ds_volatile)) @@ -9178,27 +9171,27 @@ grokdeclarator (const cp_declarator *declarator, /* We might have ignored or rejected some of the qualifiers. */ type_quals = cp_type_quals (type); - staticp = 0; - inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline); - virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual); - explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit); + int staticv = 0; + int explicitv = decl_spec_seq_has_spec_p (declspecs, ds_explicit); + bool inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline); + bool virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual); + bool friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend); - storage_class = declspecs->storage_class; + cp_storage_class storage_class = declspecs->storage_class; if (storage_class == sc_static) - staticp = 1 + (decl_context == FIELD); + staticv = 1 + (decl_context == FIELD); - if (virtualp && staticp == 2) + if (virtualp && staticv == 2) { error ("member %qD cannot be declared both virtual and static", dname); storage_class = sc_none; - staticp = 0; + staticv = 0; } - friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend); /* Issue errors about use of storage classes for parameters. */ if (decl_context == PARM) { - if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) + if (typedef_p) { error ("typedef declaration invalid in parameter declaration"); return error_mark_node; @@ -9218,7 +9211,7 @@ grokdeclarator (const cp_declarator *declarator, if (constexpr_p) { error ("a parameter cannot be declared %"); - constexpr_p = 0; + constexpr_p = false; } } @@ -9227,11 +9220,11 @@ grokdeclarator (const cp_declarator *declarator, && (current_class_name == NULL_TREE || decl_context != FIELD)) { error ("% outside class declaration"); - virtualp = 0; + virtualp = false; } /* Static anonymous unions are dealt with here. */ - if (staticp && decl_context == TYPENAME + if (staticv && decl_context == TYPENAME && declspecs->type && ANON_AGGR_TYPE_P (declspecs->type)) decl_context = FIELD; @@ -9242,7 +9235,7 @@ grokdeclarator (const cp_declarator *declarator, && ((storage_class && storage_class != sc_extern && storage_class != sc_static) - || decl_spec_seq_has_spec_p (declspecs, ds_typedef))) + || typedef_p)) { error ("multiple storage classes in declaration of %qs", name); thread_p = false; @@ -9256,7 +9249,7 @@ grokdeclarator (const cp_declarator *declarator, && (storage_class == sc_register || storage_class == sc_auto)) ; - else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)) + else if (typedef_p) ; else if (decl_context == FIELD /* C++ allows static class elements. */ @@ -9302,14 +9295,14 @@ grokdeclarator (const cp_declarator *declarator, storage-class-specifier static is implied if it does not appear explicitly. */ storage_class = declspecs->storage_class = sc_static; - staticp = 1; + staticv = 1; } if (storage_class && friendp) { error ("storage class specifiers invalid in friend function declarations"); storage_class = sc_none; - staticp = 0; + staticv = 0; } if (!id_declarator) @@ -9355,9 +9348,8 @@ grokdeclarator (const cp_declarator *declarator, attrs = declarator->attributes; if (attrs) { - int attr_flags; + int attr_flags = 0; - attr_flags = 0; if (declarator == NULL || declarator->kind == cdk_id) attr_flags |= (int) ATTR_FLAG_DECL_NEXT; if (declarator->kind == cdk_function) @@ -9390,9 +9382,6 @@ grokdeclarator (const cp_declarator *declarator, case cdk_function: { - tree arg_types; - int funcdecl_p; - /* Declaring a function type. Make sure we have a valid type for the function to return. */ @@ -9405,7 +9394,7 @@ grokdeclarator (const cp_declarator *declarator, decl, but to its return type. */ type_quals = TYPE_UNQUALIFIED; } - errmsg = targetm.invalid_return_type (type); + const char *errmsg = targetm.invalid_return_type (type); if (errmsg) { error (errmsg); @@ -9442,7 +9431,8 @@ grokdeclarator (const cp_declarator *declarator, /* Say it's a definition only for the CALL_EXPR closest to the identifier. */ - funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id; + bool funcdecl_p = (inner_declarator + && inner_declarator->kind == cdk_id); /* Handle a late-specified return type. */ if (funcdecl_p) @@ -9488,7 +9478,7 @@ grokdeclarator (const cp_declarator *declarator, if (ctype == NULL_TREE && decl_context == FIELD && funcdecl_p - && (friendp == 0 || dname == current_class_name)) + && (! friendp || dname == current_class_name)) ctype = current_class_type; if (ctype && (sfk == sfk_constructor @@ -9506,7 +9496,7 @@ grokdeclarator (const cp_declarator *declarator, ISO C++ 12.1. A constructor may not be declared const or volatile. A constructor may not be virtual. A constructor may not be static. */ - if (staticp == 2) + if (staticv == 2) error ((flags == DTOR_FLAG) ? G_("destructor cannot be static member function") : G_("constructor cannot be static member function")); @@ -9527,19 +9517,20 @@ grokdeclarator (const cp_declarator *declarator, if (flags != DTOR_FLAG) { /* It's a constructor. */ - if (explicitp == 1) - explicitp = 2; + if (explicitv == 1) + explicitv = 2; if (virtualp) { - permerror (input_location, "constructors cannot be declared virtual"); - virtualp = 0; + permerror (input_location, + "constructors cannot be declared virtual"); + virtualp = false; } if (decl_context == FIELD && sfk != sfk_constructor) return error_mark_node; } if (decl_context == FIELD) - staticp = 0; + staticv = 0; } else if (friendp) { @@ -9549,7 +9540,7 @@ grokdeclarator (const cp_declarator *declarator, { /* Cannot be both friend and virtual. */ error ("virtual functions cannot be friends"); - friendp = 0; + friendp = false; } if (decl_context == NORMAL) error ("friend declaration not in class definition"); @@ -9560,15 +9551,15 @@ grokdeclarator (const cp_declarator *declarator, } else if (ctype && sfk == sfk_conversion) { - if (explicitp == 1) + if (explicitv == 1) { maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION); - explicitp = 2; + explicitv = 2; } } - arg_types = grokparms (declarator->u.function.parameters, - &parms); + tree arg_types = grokparms (declarator->u.function.parameters, + &parms); if (inner_declarator && inner_declarator->kind == cdk_id @@ -9823,8 +9814,9 @@ grokdeclarator (const cp_declarator *declarator, { if (friendp) { - permerror (input_location, "member functions are implicitly friends of their class"); - friendp = 0; + permerror (input_location, "member functions are implicitly " + "friends of their class"); + friendp = false; } else permerror (declarator->id_loc, @@ -9866,8 +9858,7 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } } - else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) - && current_class_type) + else if (typedef_p && current_class_type) { error ("cannot declare member %<%T::%s%> within %qT", ctype, name, current_class_type); @@ -9875,7 +9866,7 @@ grokdeclarator (const cp_declarator *declarator, } } - if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0) + if (ctype == NULL_TREE && decl_context == FIELD && !friendp) ctype = current_class_type; /* Now TYPE has the actual type. */ @@ -9929,12 +9920,12 @@ grokdeclarator (const cp_declarator *declarator, type = error_mark_node; } - if (explicitp == 1 || (explicitp && friendp)) + if (explicitv == 1 || (explicitv && friendp)) { /* [dcl.fct.spec] The explicit specifier shall only be used in declarations of constructors within a class definition. */ error ("only declarations of constructors can be %"); - explicitp = 0; + explicitv = 0; } if (storage_class == sc_mutable) @@ -9944,8 +9935,7 @@ grokdeclarator (const cp_declarator *declarator, error ("non-member %qs cannot be declared %", name); storage_class = sc_none; } - else if (decl_context == TYPENAME - || decl_spec_seq_has_spec_p (declspecs, ds_typedef)) + else if (decl_context == TYPENAME || typedef_p) { error ("non-object member %qs cannot be declared %", name); storage_class = sc_none; @@ -9956,7 +9946,7 @@ grokdeclarator (const cp_declarator *declarator, error ("function %qs cannot be declared %", name); storage_class = sc_none; } - else if (staticp) + else if (staticv) { error ("static %qs cannot be declared %", name); storage_class = sc_none; @@ -9975,7 +9965,7 @@ grokdeclarator (const cp_declarator *declarator, } /* If this is declaring a typedef name, return a TYPE_DECL. */ - if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context != TYPENAME) + if (typedef_p && decl_context != TYPENAME) { tree decl; @@ -10032,9 +10022,8 @@ grokdeclarator (const cp_declarator *declarator, } else if (current_class_type && constructor_name_p (unqualified_id, current_class_type)) - permerror (input_location, "ISO C++ forbids nested type %qD with same name " - "as enclosing class", - unqualified_id); + permerror (input_location, "ISO C++ forbids nested type %qD with " + "same name as enclosing class", unqualified_id); /* If the user declares "typedef struct {...} foo" then the struct will have an anonymous name. Fill that name in now. @@ -10048,10 +10037,8 @@ grokdeclarator (const cp_declarator *declarator, && declspecs->type_definition_p && cp_type_quals (type) == TYPE_UNQUALIFIED) { - tree t; - /* Replace the anonymous name with the real name everywhere. */ - for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) /* We do not rename the debug info representing the @@ -10111,9 +10098,8 @@ grokdeclarator (const cp_declarator *declarator, if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE) { tree decls = NULL_TREE; - tree args; - for (args = TYPE_ARG_TYPES (type); + for (tree args = TYPE_ARG_TYPES (type); args && args != void_list_node; args = TREE_CHAIN (args)) { @@ -10130,9 +10116,9 @@ grokdeclarator (const cp_declarator *declarator, /* A cv-qualifier-seq shall only be part of the function type for a non-static member function. [8.3.5/4 dcl.fct] */ if (type_memfn_quals (type) != TYPE_UNQUALIFIED - && (current_class_type == NULL_TREE || staticp) ) + && (current_class_type == NULL_TREE || staticv) ) { - error (staticp + error (staticv ? G_("qualified function types cannot be used to " "declare static member functions") : G_("qualified function types cannot be used to " @@ -10168,22 +10154,22 @@ grokdeclarator (const cp_declarator *declarator, if (inlinep) { error ("% specified for friend class declaration"); - inlinep = 0; + inlinep = false; } if (!current_aggr) { /* Don't allow friend declaration without a class-key. */ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) - permerror (input_location, "template parameters cannot be friends"); + permerror (input_location, + "template parameters cannot be friends"); else if (TREE_CODE (type) == TYPENAME_TYPE) - permerror (input_location, "friend declaration requires class-key, " - "i.e. %", + permerror (input_location, "friend declaration requires " + "class-key, i.e. %", TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type)); else - permerror (input_location, "friend declaration requires class-key, " - "i.e. %", - type); + permerror (input_location, "friend declaration requires " + "class-key, i.e. %", type); } /* Only try to do this stuff if we didn't already give up. */ @@ -10220,7 +10206,7 @@ grokdeclarator (const cp_declarator *declarator, else if (unqualified_id == NULL_TREE && decl_context != PARM && decl_context != CATCHPARM && TREE_CODE (type) != UNION_TYPE - && ! bitfield) + && ! bitfield_p) { error ("abstract declarator %qT used as declaration", type); return error_mark_node; @@ -10273,7 +10259,7 @@ grokdeclarator (const cp_declarator *declarator, type = build_pointer_type (type); } - if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2 + if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticv < 2 && !NEW_DELETE_OPNAME_P (unqualified_id)) { cp_cv_quals real_quals = memfn_quals; @@ -10295,7 +10281,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (decl_context == FIELD) { - if (!staticp && TREE_CODE (type) != METHOD_TYPE + if (!staticv && TREE_CODE (type) != METHOD_TYPE && type_uses_auto (type)) { error ("non-static data member declared %"); @@ -10303,7 +10289,7 @@ grokdeclarator (const cp_declarator *declarator, } /* The C99 flexible array extension. */ - if (!staticp && TREE_CODE (type) == ARRAY_TYPE + if (!staticv && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) { tree itype = compute_array_index_type (dname, integer_zero_node, @@ -10326,10 +10312,9 @@ grokdeclarator (const cp_declarator *declarator, else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) { - int publicp = 0; tree function_context; - if (friendp == 0) + if (!friendp) { /* This should never happen in pure C++ (the check could be an assert). It could happen in @@ -10363,7 +10348,7 @@ grokdeclarator (const cp_declarator *declarator, error ("%qD cannot be declared virtual, since it " "is always static", unqualified_id); - virtualp = 0; + virtualp = false; } } } @@ -10404,8 +10389,8 @@ grokdeclarator (const cp_declarator *declarator, /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ function_context = (ctype != NULL_TREE) ? decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE; - publicp = (! friendp || ! staticp) - && function_context == NULL_TREE; + bool publicp = ((! friendp || ! staticv) + && function_context == NULL_TREE); decl = grokfndecl (ctype, type, TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR ? unqualified_id : dname, @@ -10413,7 +10398,7 @@ grokdeclarator (const cp_declarator *declarator, unqualified_id, virtualp, flags, memfn_quals, raises, friendp ? -1 : 0, friendp, publicp, - inlinep | (2 * constexpr_p), + inlinep, constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); @@ -10433,10 +10418,10 @@ grokdeclarator (const cp_declarator *declarator, specifies a conversion from the type of its first parameter to the type of its class. Such a constructor is called a converting constructor. */ - if (explicitp == 2) + if (explicitv == 2) DECL_NONCONVERTING_P (decl) = 1; } - else if (!staticp && !dependent_type_p (type) + else if (!staticv && !dependent_type_p (type) && !COMPLETE_TYPE_P (complete_type (type)) && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0)) { @@ -10463,7 +10448,7 @@ grokdeclarator (const cp_declarator *declarator, { error ("%qE is neither function nor member function; " "cannot be declared friend", unqualified_id); - friendp = 0; + friendp = false; } decl = NULL_TREE; } @@ -10497,7 +10482,7 @@ grokdeclarator (const cp_declarator *declarator, if (decl == NULL_TREE) { - if (staticp) + if (staticv) { /* C++ allows static class members. All other work for this is done by grokfield. */ @@ -10533,8 +10518,8 @@ grokdeclarator (const cp_declarator *declarator, } decl = build_decl (input_location, FIELD_DECL, unqualified_id, type); - DECL_NONADDRESSABLE_P (decl) = bitfield; - if (bitfield && !unqualified_id) + DECL_NONADDRESSABLE_P (decl) = bitfield_p; + if (bitfield_p && !unqualified_id) TREE_NO_WARNING (decl) = 1; if (storage_class == sc_mutable) @@ -10550,7 +10535,7 @@ grokdeclarator (const cp_declarator *declarator, maybe_warn_cpp0x (CPP0X_NSDMI); /* If this has been parsed with static storage class, but - errors forced staticp to be cleared, ensure NSDMI is + errors forced staticv to be cleared, ensure NSDMI is not present. */ if (declspecs->storage_class == sc_static) DECL_INITIAL (decl) = error_mark_node; @@ -10566,7 +10551,6 @@ grokdeclarator (const cp_declarator *declarator, || TREE_CODE (type) == METHOD_TYPE) { tree original_name; - int publicp = 0; if (!unqualified_id) return error_mark_node; @@ -10591,7 +10575,8 @@ grokdeclarator (const cp_declarator *declarator, } if (virt_specifiers) - error ("virt-specifiers in %qs not allowed outside a class definition", name); + error ("virt-specifiers in %qs not allowed outside a class " + "definition", name); /* Function declaration not at top level. Storage classes other than `extern' are not allowed and `extern' makes no difference. */ @@ -10615,7 +10600,7 @@ grokdeclarator (const cp_declarator *declarator, if (virtualp) { error ("virtual non-class function %qs", name); - virtualp = 0; + virtualp = false; } else if (sfk == sfk_constructor || sfk == sfk_destructor) @@ -10628,41 +10613,42 @@ grokdeclarator (const cp_declarator *declarator, } /* Record whether the function is public. */ - publicp = (ctype != NULL_TREE - || storage_class != sc_static); + bool publicp = (ctype != NULL_TREE + || storage_class != sc_static); decl = grokfndecl (ctype, type, original_name, parms, unqualified_id, virtualp, flags, memfn_quals, raises, 1, friendp, - publicp, inlinep | (2 * constexpr_p), sfk, + publicp, inlinep, constexpr_p, sfk, funcdef_flag, template_count, in_namespace, attrlist, declarator->id_loc); if (decl == NULL_TREE) return error_mark_node; - if (staticp == 1) + if (staticv == 1) { - int invalid_static = 0; + bool invalid_static = false; /* Don't allow a static member function in a class, and forbid declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { - permerror (input_location, "cannot declare member function %qD to have " - "static linkage", decl); - invalid_static = 1; + permerror (input_location, "cannot declare member function %qD " + "to have static linkage", decl); + invalid_static = true; } else if (current_function_decl) { /* FIXME need arm citation */ - error ("cannot declare static function inside another function"); - invalid_static = 1; + error ("cannot declare static function inside another " + "function"); + invalid_static = true; } if (invalid_static) { - staticp = 0; + staticv = 0; storage_class = sc_none; } } @@ -10684,11 +10670,12 @@ grokdeclarator (const cp_declarator *declarator, if (ctype) { DECL_CONTEXT (decl) = ctype; - if (staticp == 1) + if (staticv == 1) { - permerror (input_location, "% may not be used when defining " + permerror (input_location, + "% may not be used when defining " "(as opposed to declaring) a static data member"); - staticp = 0; + staticv = 0; storage_class = sc_none; } if (storage_class == sc_register && TREE_STATIC (decl)) Index: testsuite/g++.dg/cpp0x/constexpr-friend-2.C =================================================================== --- testsuite/g++.dg/cpp0x/constexpr-friend-2.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-friend-2.C (working copy) @@ -0,0 +1,7 @@ +// { dg-do compile { target c++11 } } + +template void f(T); + +template class A { + friend constexpr void f<>(int); // { dg-error "'constexpr' is not allowed" } +}; Index: testsuite/g++.dg/cpp0x/constexpr-main.C =================================================================== --- testsuite/g++.dg/cpp0x/constexpr-main.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-main.C (working copy) @@ -0,0 +1,3 @@ +// { dg-do compile { target c++11 } } + +constexpr int main (); // { dg-error "constexpr" }