From 9bab2a0dc84e7c3e14cb44fcd6ac41df079baa0f Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 1 Oct 2020 05:05:06 -0700 Subject: [PATCH] c++: Refactor lookup_and_check_tag It turns out I'd already found lookup_and_check_tag's control flow confusing, and had refactored it on the modules branch. For instance, it continually checks 'if (decl &&$ condition)' before finally getting to 'else if (!decl)'. why not just check !decl first and be done? Well, it is done thusly. gcc/cp/ * decl.c (lookup_and_check_tag): Refactor. --- gcc/cp/decl.c | 116 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 14742c115ad..d2a8d4012ab 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14885,71 +14885,73 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, else decl = lookup_elaborated_type (name, how); - if (decl - && (DECL_CLASS_TEMPLATE_P (decl) - /* If scope is TAG_how::CURRENT_ONLY we're defining a class, - so ignore a template template parameter. */ - || (how != TAG_how::CURRENT_ONLY - && DECL_TEMPLATE_TEMPLATE_PARM_P (decl)))) - decl = DECL_TEMPLATE_RESULT (decl); - - if (decl && TREE_CODE (decl) == TYPE_DECL) - { - /* Look for invalid nested type: - class C { - class C {}; - }; */ - if (how == TAG_how::CURRENT_ONLY && DECL_SELF_REFERENCE_P (decl)) - { - error ("%qD has the same name as the class in which it is " - "declared", decl); - return error_mark_node; - } - - /* Two cases we need to consider when deciding if a class - template is allowed as an elaborated type specifier: - 1. It is a self reference to its own class. - 2. It comes with a template header. - For example: - - template class C { - class C *c1; // DECL_SELF_REFERENCE_P is true - class D; - }; - template class C; // template_header_p is true - template class C::D { - class C *c2; // DECL_SELF_REFERENCE_P is true - }; */ - - tree t = check_elaborated_type_specifier (tag_code, - decl, - template_header_p - | DECL_SELF_REFERENCE_P (decl)); - if (template_header_p && t && CLASS_TYPE_P (t) - && (!CLASSTYPE_TEMPLATE_INFO (t) - || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))))) - { - error ("%qT is not a template", t); - inform (location_of (t), "previous declaration here"); - if (TYPE_CLASS_SCOPE_P (t) - && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (t))) - inform (input_location, - "perhaps you want to explicitly add %<%T::%>", - TYPE_CONTEXT (t)); - t = error_mark_node; - } + if (!decl) + /* We found nothing. */ + return NULL_TREE; - return t; - } - else if (decl && TREE_CODE (decl) == TREE_LIST) + if (TREE_CODE (decl) == TREE_LIST) { error ("reference to %qD is ambiguous", name); print_candidates (decl); return error_mark_node; } - else + + if (DECL_CLASS_TEMPLATE_P (decl) + /* If scope is TAG_how::CURRENT_ONLY we're defining a class, + so ignore a template template parameter. */ + || (how != TAG_how::CURRENT_ONLY && DECL_TEMPLATE_TEMPLATE_PARM_P (decl))) + decl = DECL_TEMPLATE_RESULT (decl); + + if (TREE_CODE (decl) != TYPE_DECL) + /* Found not-a-type. */ return NULL_TREE; + + /* Look for invalid nested type: + class C { + class C {}; + }; */ + if (how == TAG_how::CURRENT_ONLY && DECL_SELF_REFERENCE_P (decl)) + { + error ("%qD has the same name as the class in which it is " + "declared", decl); + return error_mark_node; + } + + /* Two cases we need to consider when deciding if a class + template is allowed as an elaborated type specifier: + 1. It is a self reference to its own class. + 2. It comes with a template header. + + For example: + + template class C { + class C *c1; // DECL_SELF_REFERENCE_P is true + class D; + }; + template class C; // template_header_p is true + template class C::D { + class C *c2; // DECL_SELF_REFERENCE_P is true + }; */ + + tree t = check_elaborated_type_specifier (tag_code, decl, + template_header_p + | DECL_SELF_REFERENCE_P (decl)); + if (template_header_p && t && CLASS_TYPE_P (t) + && (!CLASSTYPE_TEMPLATE_INFO (t) + || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t))))) + { + error ("%qT is not a template", t); + inform (location_of (t), "previous declaration here"); + if (TYPE_CLASS_SCOPE_P (t) + && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (t))) + inform (input_location, + "perhaps you want to explicitly add %<%T::%>", + TYPE_CONTEXT (t)); + return error_mark_node; + } + + return t; } /* Get the struct, enum or union (TAG_CODE says which) with tag NAME. -- 2.30.2