From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 12E0638582B1 for ; Wed, 14 Sep 2022 11:31:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 12E0638582B1 Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-49-iLZOlp1mOu-DtmjnfPsfLw-1; Wed, 14 Sep 2022 07:31:53 -0400 X-MC-Unique: iLZOlp1mOu-DtmjnfPsfLw-1 Received: by mail-qk1-f197.google.com with SMTP id x22-20020a05620a259600b006b552a69231so12656189qko.18 for ; Wed, 14 Sep 2022 04:31:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date; bh=TNXTk6VIvoXnH8jQUmvHZSindI1IqGDKTVCwtvO69GY=; b=V0UDH119bFK3BY9W6cBOR8wChNPXix6iSBgUpwrWSob7Eirp6FhvER2RbwekTdBrug jsiN4RZTSVmWBXieGdyeTIxHSKFbxZtljMetFJjHuNB4w/V+rpCtF5IFbnECElWckdYe /sKMxqjAXGus2raIjFQMBZh6OWp67Gua9sHH9ICYLiqrp9XU1EMjMkIipb0MswIMEof4 tnqDBG3zOAT0SgtjpV118i/TRJp5zfHvXciBjXncqw/F/lug92+mAPnDrhbJF6B7ueLO bK67kfLqRXwURGg9dq6ajSssxJMPCn44tbKwvZtqaJOppOGoqFt7ZO9FLjmXV2E9F/3e YmNw== X-Gm-Message-State: ACgBeo1IhR4eFyl/TMFjxE89ncQSYSG7HDU3jo1MUayqC49pBoO1oQrE zzIxNDuC1j6Z0TWDrP4ps4Cgs5nN0t37Insim2frfHjPXBvM7QXJebImEm58GiHwsUnX7pc6CyE vOesAAkYKWloQaJOGi/F3Cg== X-Received: by 2002:ac8:4e86:0:b0:35b:ae0b:cb1b with SMTP id 6-20020ac84e86000000b0035bae0bcb1bmr16077884qtp.373.1663155112849; Wed, 14 Sep 2022 04:31:52 -0700 (PDT) X-Google-Smtp-Source: AA6agR6ntTnLpQROT3wax+y0socPGRqfKUQ9LAbqHeAB/qeLykuUIFMIBA9BdyORppMU29GdRkjwvg== X-Received: by 2002:ac8:4e86:0:b0:35b:ae0b:cb1b with SMTP id 6-20020ac84e86000000b0035bae0bcb1bmr16077862qtp.373.1663155112440; Wed, 14 Sep 2022 04:31:52 -0700 (PDT) Received: from [192.168.0.45] (ip-213-220-232-121.bb.vodafone.cz. [213.220.232.121]) by smtp.gmail.com with ESMTPSA id de42-20020a05620a372a00b006b945519488sm1719502qkb.88.2022.09.14.04.31.50 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 14 Sep 2022 04:31:51 -0700 (PDT) Message-ID: Date: Wed, 14 Sep 2022 13:31:49 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.1 Subject: Re: [PATCH v4 13/15] gdb/testsuite: fix gdb.base/info-types-c++ with clang To: Andrew Burgess , gdb-patches@sourceware.org References: <20220720194441.168906-1-blarsen@redhat.com> <20220720194441.168906-15-blarsen@redhat.com> <875yhslkxj.fsf@redhat.com> From: Bruno Larsen In-Reply-To: <875yhslkxj.fsf@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Sep 2022 11:31:58 -0000 On 12/09/2022 16:35, Andrew Burgess wrote: > Bruno Larsen via Gdb-patches writes: > >> When g++ compiles nameles structs defined in a typedef, it adds a >> DW_AT_linkage_name with the name defined in the typedef. So when >> running gdb.base/info-types-c++.exp by default, we get the following >> output >> >> All defined types: >> >> File ../../../common/git-repos/binutils-gdb/gdb/testsuite/gdb.base/info-types.c: >> 98: CL; >> 42: anon_struct_t; >> 65: anon_union_t; >> 21: baz_t; >> 33: enum_t; >> 56: union_t; >> 52: typedef enum {...} anon_enum_t; >> 45: typedef anon_struct_t anon_struct_t; >> 68: typedef anon_union_t anon_union_t; >> >> Clang[++] does not add DW_AT_linkage_name, and so it's output looks like >> this: >> >> All defined types: >> >> File ../../../common/git-repos/binutils-gdb/gdb/testsuite/gdb.base/info-types.c: >> 98: CL; >> 21: baz_t; >> 33: enum_t; >> 56: union_t; >> 52: typedef enum {...} anon_enum_t; >> 45: typedef struct {...} anon_struct_t; >> 68: typedef union {...} anon_union_t; >> >> Which is still correct output for GDB, but shows up as a failure when >> running the test. This commit changes the test to allow for this output >> when the compiler is clang. >> --- >> gdb/testsuite/gdb.base/info-types.exp.tcl | 109 +++++++++++++++------- >> 1 file changed, 73 insertions(+), 36 deletions(-) >> >> diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl >> index 2dd9b9e5489..b6a03276f69 100644 >> --- a/gdb/testsuite/gdb.base/info-types.exp.tcl >> +++ b/gdb/testsuite/gdb.base/info-types.exp.tcl >> @@ -41,42 +41,79 @@ proc run_test { lang } { >> set file_re "File .*[string_to_regexp $srcfile]:" >> >> if { $lang == "c++" } { >> - set output_lines \ >> - [list \ >> - "^All defined types:" \ >> - ".*" \ >> - $file_re \ >> - "98:\[\t \]+CL;" \ >> - "42:\[\t \]+anon_struct_t;" \ >> - "65:\[\t \]+anon_union_t;" \ >> - "21:\[\t \]+baz_t;" \ >> - "33:\[\t \]+enum_t;" \ >> - "56:\[\t \]+union_t;" \ >> - "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \ >> - "45:\[\t \]+typedef anon_struct_t anon_struct_t;" \ >> - "68:\[\t \]+typedef anon_union_t anon_union_t;" \ >> - "28:\[\t \]+typedef baz_t baz;" \ >> - "31:\[\t \]+typedef baz_t \\* baz_ptr;" \ >> - "27:\[\t \]+typedef baz_t baz_t;" \ >> - "\[\t \]+double" \ >> - "\[\t \]+float" \ >> - "\[\t \]+int" \ >> - "103:\[\t \]+typedef CL my_cl;" \ >> - "38:\[\t \]+typedef enum_t my_enum_t;" \ >> - "17:\[\t \]+typedef float my_float_t;" \ >> - "16:\[\t \]+typedef int my_int_t;" \ >> - "104:\[\t \]+typedef CL \\* my_ptr;" \ >> - "54:\[\t \]+typedef enum {\\.\\.\\.} nested_anon_enum_t;" \ >> - "47:\[\t \]+typedef anon_struct_t nested_anon_struct_t;" \ >> - "70:\[\t \]+typedef anon_union_t nested_anon_union_t;" \ >> - "30:\[\t \]+typedef baz_t nested_baz;" \ >> - "29:\[\t \]+typedef baz_t nested_baz_t;" \ >> - "39:\[\t \]+typedef enum_t nested_enum_t;" \ >> - "19:\[\t \]+typedef float nested_float_t;" \ >> - "18:\[\t \]+typedef int nested_int_t;" \ >> - "62:\[\t \]+typedef union_t nested_union_t;(" \ >> - "\[\t \]+unsigned int)?" \ >> - "($|\r\n.*)"] >> + if { [test_compiler_info "clang-*"] } { >> + set output_lines \ >> + [list \ >> + "^All defined types:" \ >> + ".*" \ >> + $file_re \ >> + "98:\[\t \]+CL;" \ >> + "21:\[\t \]+baz_t;" \ >> + "33:\[\t \]+enum_t;" \ >> + "56:\[\t \]+union_t;" \ >> + "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \ >> + "45:\[\t \]+typedef struct {\\.\\.\\.} anon_struct_t;" \ >> + "68:\[\t \]+typedef union {\\.\\.\\.} anon_union_t;" \ >> + "28:\[\t \]+typedef baz_t baz;" \ >> + "31:\[\t \]+typedef baz_t \\* baz_ptr;" \ >> + "27:\[\t \]+typedef baz_t baz_t;" \ >> + "\[\t \]+double" \ >> + "\[\t \]+float" \ >> + "\[\t \]+int" \ >> + "103:\[\t \]+typedef CL my_cl;" \ >> + "38:\[\t \]+typedef enum_t my_enum_t;" \ >> + "17:\[\t \]+typedef float my_float_t;" \ >> + "16:\[\t \]+typedef int my_int_t;" \ >> + "104:\[\t \]+typedef CL \\* my_ptr;" \ >> + "54:\[\t \]+typedef enum {\\.\\.\\.} nested_anon_enum_t;" \ >> + "47:\[\t \]+typedef struct {\\.\\.\\.} nested_anon_struct_t;" \ >> + "70:\[\t \]+typedef union {\\.\\.\\.} nested_anon_union_t;" \ >> + "30:\[\t \]+typedef baz_t nested_baz;" \ >> + "29:\[\t \]+typedef baz_t nested_baz_t;" \ >> + "39:\[\t \]+typedef enum_t nested_enum_t;" \ >> + "19:\[\t \]+typedef float nested_float_t;" \ >> + "18:\[\t \]+typedef int nested_int_t;" \ >> + "62:\[\t \]+typedef union_t nested_union_t;(" \ >> + "\[\t \]+unsigned int)?" \ >> + "($|\r\n.*)"] >> + } else { >> + set output_lines \ >> + [list \ >> + "^All defined types:" \ >> + ".*" \ >> + $file_re \ >> + "98:\[\t \]+CL;" \ >> + "42:\[\t \]+anon_struct_t;" \ >> + "65:\[\t \]+anon_union_t;" \ >> + "21:\[\t \]+baz_t;" \ >> + "33:\[\t \]+enum_t;" \ >> + "56:\[\t \]+union_t;" \ >> + "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \ >> + "45:\[\t \]+typedef anon_struct_t anon_struct_t;" \ >> + "68:\[\t \]+typedef anon_union_t anon_union_t;" \ >> + "28:\[\t \]+typedef baz_t baz;" \ >> + "31:\[\t \]+typedef baz_t \\* baz_ptr;" \ >> + "27:\[\t \]+typedef baz_t baz_t;" \ >> + "\[\t \]+double" \ >> + "\[\t \]+float" \ >> + "\[\t \]+int" \ >> + "103:\[\t \]+typedef CL my_cl;" \ >> + "38:\[\t \]+typedef enum_t my_enum_t;" \ >> + "17:\[\t \]+typedef float my_float_t;" \ >> + "16:\[\t \]+typedef int my_int_t;" \ >> + "104:\[\t \]+typedef CL \\* my_ptr;" \ >> + "54:\[\t \]+typedef enum {\\.\\.\\.} nested_anon_enum_t;" \ >> + "47:\[\t \]+typedef anon_struct_t nested_anon_struct_t;" \ >> + "70:\[\t \]+typedef anon_union_t nested_anon_union_t;" \ >> + "30:\[\t \]+typedef baz_t nested_baz;" \ >> + "29:\[\t \]+typedef baz_t nested_baz_t;" \ >> + "39:\[\t \]+typedef enum_t nested_enum_t;" \ >> + "19:\[\t \]+typedef float nested_float_t;" \ >> + "18:\[\t \]+typedef int nested_int_t;" \ >> + "62:\[\t \]+typedef union_t nested_union_t;(" \ >> + "\[\t \]+unsigned int)?" \ >> + "($|\r\n.*)"] >> + } >> } else { >> set output_lines \ >> [list \ >> -- >> 2.31.1 > > Rather than duplicating the whole pattern block like this, I wondered if > we could rewrite the test to, I hope, make things a little clearer. > > Below is my attempt to do this. This patch applies instead of your > patch above, and I believe results in the test passing with GCC and > Clang. > > I wonder what you think of this as an alternative approach? I think this approach is definitely better. It is much more readable in the end, and re-uses as much code as possible, like you said. I'll remove my patch for this test from my series, and I encourage you to either approve your own patch or post it as a standalone, if you want more eyes on it. Cheers, Bruno > > Thanks, > Andrew > > --- > > commit 313bcb258d6a1e00dd8e93fbbbaa2df2d4a49e61 > Author: Andrew Burgess > Date: Mon Sep 12 15:24:14 2022 +0100 > > gdb: rewrite gdb.base/info-types.exp.tcl > > This patch was inspired by this proposed change: > > https://sourceware.org/pipermail/gdb-patches/2022-July/190926.html > > the goal of that change was to make the info-types tests pass when > using Clang as a compiler. The difference between g++ and Clang, is > that g++ will give a (made up) name to an anonymous struct or union > that is used in a typedef, Clang doesn't. The solution proposed in > the patch above is to create a third test pattern to be used for > C++/Clang, at this point the test script seemed to be getting a little > bloated. > > In this commit I rewrite the test. Instead of running the 'info > types' command and expecting a specific set of lines in a particular > order, we now read all the lines from the command output, and place > the lines into a dictionary. We can then query the dictionary to > check the all the expected lines are present. > > Checking for each output line independently has a couple of > advantages: > > 1. We no longer care about the output order. I don't think the > ordering is particularly important for this test, so long as all the > expected lines are present, > > 2. For lines that are present in both C and C++ we can now share the > code to check these patterns, I think this makes it clearer what is > going on, and > > 3. It is easy to place a few lines within an `if` block, and so, only > check for those lines when using a specific compiler. > > I've check gdb.base/info-types-c.exp and gdb.base/info-types-c++.exp > using both GCC and Clang. > > diff --git a/gdb/testsuite/gdb.base/info-types.exp.tcl b/gdb/testsuite/gdb.base/info-types.exp.tcl > index 2dd9b9e5489..8aa006d0179 100644 > --- a/gdb/testsuite/gdb.base/info-types.exp.tcl > +++ b/gdb/testsuite/gdb.base/info-types.exp.tcl > @@ -16,6 +16,113 @@ > # Check that 'info types' produces the expected output for an inferior > # containing a number of different types. > > + > +# Run the 'info types' command, and place the results into RESULT_VAR, > +# which should be the name of a variable in the callers scope. > +# > +# RESULT_VAR will be cleared, and set to an associative array, the > +# keys of this associative array will be the line numbers, and the > +# value for each line number will be a list of the types GDB > +# understands to be declared on that line. > +# > +# Some types don't have a line number for their declartion > +# (e.g. builtin types), these are placed into a list for the special > +# line number 'NONE'. > +# > +# Finally, only types from the reported in SRCFILE are collected, any > +# types reported from other files (e.g. libraries linked into the > +# test) should be ignored. > +proc collect_output { result_var } { > + upvar $result_var result_obj > + > + array set result_obj {} > + > + set collect_lines false > + gdb_test_multiple "info types" "" { > + -re "^info types\r\n" { > + exp_continue > + } > + > + -re "^\r\n" { > + exp_continue > + } > + > + -re "^All defined types:\r\n" { > + exp_continue > + } > + > + -re "^File (\[^\r\n\]+)\r\n" { > + set filename $expect_out(1,string) > + set collect_lines [regexp [string_to_regexp $::srcfile] $filename] > + exp_continue > + } > + > + -re "^($::decimal):\\s+(\[^\r\n\]+);\r\n" { > + set lineno $expect_out(1,string) > + set text $expect_out(2,string) > + if { $collect_lines } { > + if { ! [info exists result_obj($lineno)] } { > + set result_obj($lineno) [list] > + } > + lappend result_obj($lineno) $text > + } > + exp_continue > + } > + > + -re "^\\s+(\[^\r\n;\]+)\r\n" { > + set text $expect_out(1,string) > + if { $collect_lines } { > + if { ![info exists result_obj(NONE)] } { > + set result_obj(NONE) [list] > + } > + lappend result_obj(NONE) $text > + } > + exp_continue > + } > + > + -re "^$::gdb_prompt $" { > + } > + } > +} > + > +# RESULT_VAR is the name of a variable in the parent scope that > +# contains an associative array of results as returned from the > +# collect_output proc. > +# > +# LINE is a line number, or the empty string, and TEXT is the > +# declaration of a type that GDB should have seen on that line. > +# > +# This proc checks in RESULT_VAR for a matching entry to LINE and > +# TEXT, and, if a matching entry is found, calls pass, otherwise, fail > +# is called. The testname used for the pass/fail call is based on > +# LINE and TEXT. > +# > +# If LINE is the empty string then this proc looks for a result > +# associated with the special line number 'NONE', see collect_output > +# for more details. > +proc require_line { result_var line text } { > + upvar $result_var result_obj > + > + set testname "check for $text" > + if { $line != "" } { > + set testname "$testname on line $line" > + } else { > + set line "NONE" > + } > + > + if { ![info exists result_obj($line)] } { > + fail $testname > + return > + } > + > + if { [lsearch -exact $result_obj($line) $text] < 0 } { > + fail $testname > + return > + } > + > + pass $testname > +} > + > # Run 'info types' test, compiling the test file for language LANG, > # which should be either 'c' or 'c++'. > proc run_test { lang } { > @@ -38,79 +145,71 @@ proc run_test { lang } { > return 0 > } > > - set file_re "File .*[string_to_regexp $srcfile]:" > + # Run 'info types' and place the results in RESULT_OBJ. > + collect_output result_obj > + > + # Some results are common to C and C++. These are the builtin > + # types which are not declared on any specific line. > + require_line result_obj "" "double" > + require_line result_obj "" "float" > + require_line result_obj "" "int" > + > + # These typedefs are common to C and C++, but GDB should see a > + # specific line number for these type declarations. > + require_line result_obj "16" "typedef int my_int_t" > + require_line result_obj "17" "typedef float my_float_t" > + require_line result_obj "18" "typedef int nested_int_t" > + require_line result_obj "19" "typedef float nested_float_t" > > if { $lang == "c++" } { > - set output_lines \ > - [list \ > - "^All defined types:" \ > - ".*" \ > - $file_re \ > - "98:\[\t \]+CL;" \ > - "42:\[\t \]+anon_struct_t;" \ > - "65:\[\t \]+anon_union_t;" \ > - "21:\[\t \]+baz_t;" \ > - "33:\[\t \]+enum_t;" \ > - "56:\[\t \]+union_t;" \ > - "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \ > - "45:\[\t \]+typedef anon_struct_t anon_struct_t;" \ > - "68:\[\t \]+typedef anon_union_t anon_union_t;" \ > - "28:\[\t \]+typedef baz_t baz;" \ > - "31:\[\t \]+typedef baz_t \\* baz_ptr;" \ > - "27:\[\t \]+typedef baz_t baz_t;" \ > - "\[\t \]+double" \ > - "\[\t \]+float" \ > - "\[\t \]+int" \ > - "103:\[\t \]+typedef CL my_cl;" \ > - "38:\[\t \]+typedef enum_t my_enum_t;" \ > - "17:\[\t \]+typedef float my_float_t;" \ > - "16:\[\t \]+typedef int my_int_t;" \ > - "104:\[\t \]+typedef CL \\* my_ptr;" \ > - "54:\[\t \]+typedef enum {\\.\\.\\.} nested_anon_enum_t;" \ > - "47:\[\t \]+typedef anon_struct_t nested_anon_struct_t;" \ > - "70:\[\t \]+typedef anon_union_t nested_anon_union_t;" \ > - "30:\[\t \]+typedef baz_t nested_baz;" \ > - "29:\[\t \]+typedef baz_t nested_baz_t;" \ > - "39:\[\t \]+typedef enum_t nested_enum_t;" \ > - "19:\[\t \]+typedef float nested_float_t;" \ > - "18:\[\t \]+typedef int nested_int_t;" \ > - "62:\[\t \]+typedef union_t nested_union_t;(" \ > - "\[\t \]+unsigned int)?" \ > - "($|\r\n.*)"] > + # These results are specific to 'C++'. > + require_line result_obj "21" "baz_t" > + require_line result_obj "27" "typedef baz_t baz_t" > + require_line result_obj "28" "typedef baz_t baz" > + require_line result_obj "29" "typedef baz_t nested_baz_t" > + require_line result_obj "30" "typedef baz_t nested_baz" > + require_line result_obj "31" "typedef baz_t * baz_ptr" > + require_line result_obj "33" "enum_t" > + require_line result_obj "38" "typedef enum_t my_enum_t" > + require_line result_obj "39" "typedef enum_t nested_enum_t" > + require_line result_obj "52" "typedef enum {...} anon_enum_t" > + require_line result_obj "54" "typedef enum {...} nested_anon_enum_t" > + require_line result_obj "56" "union_t" > + require_line result_obj "62" "typedef union_t nested_union_t" > + require_line result_obj "98" "CL" > + require_line result_obj "103" "typedef CL my_cl" > + require_line result_obj "104" "typedef CL * my_ptr" > + > + if { [test_compiler_info "gcc-*"] } { > + # GCC give a name to anonymous structs and unions. Not > + # all compilers do this, e.g. Clang does not. > + require_line result_obj "42" "anon_struct_t" > + require_line result_obj "45" "typedef anon_struct_t anon_struct_t" > + require_line result_obj "47" "typedef anon_struct_t nested_anon_struct_t" > + require_line result_obj "65" "anon_union_t" > + require_line result_obj "68" "typedef anon_union_t anon_union_t" > + require_line result_obj "70" "typedef anon_union_t nested_anon_union_t" > + } > + > } else { > - set output_lines \ > - [list \ > - "^All defined types:" \ > - ".*" \ > - $file_re \ > - "52:\[\t \]+typedef enum {\\.\\.\\.} anon_enum_t;" \ > - "45:\[\t \]+typedef struct {\\.\\.\\.} anon_struct_t;" \ > - "68:\[\t \]+typedef union {\\.\\.\\.} anon_union_t;" \ > - "28:\[\t \]+typedef struct baz_t baz;" \ > - "31:\[\t \]+typedef struct baz_t \\* baz_ptr;" \ > - "21:\[\t \]+struct baz_t;" \ > - "\[\t \]+double" \ > - "33:\[\t \]+enum enum_t;" \ > - "\[\t \]+float" \ > - "\[\t \]+int" \ > - "38:\[\t \]+typedef enum enum_t my_enum_t;" \ > - "17:\[\t \]+typedef float my_float_t;" \ > - "16:\[\t \]+typedef int my_int_t;" \ > - "54:\[\t \]+typedef enum {\\.\\.\\.} nested_anon_enum_t;" \ > - "47:\[\t \]+typedef struct {\\.\\.\\.} nested_anon_struct_t;" \ > - "70:\[\t \]+typedef union {\\.\\.\\.} nested_anon_union_t;" \ > - "30:\[\t \]+typedef struct baz_t nested_baz;" \ > - "29:\[\t \]+typedef struct baz_t nested_baz_t;" \ > - "39:\[\t \]+typedef enum enum_t nested_enum_t;" \ > - "19:\[\t \]+typedef float nested_float_t;" \ > - "18:\[\t \]+typedef int nested_int_t;" \ > - "62:\[\t \]+typedef union union_t nested_union_t;" \ > - "56:\[\t \]+union union_t;(" \ > - "\[\t \]+unsigned int)?" \ > - "($|\r\n.*)"] > + # These results are specific to 'C'. > + require_line result_obj "21" "struct baz_t" > + require_line result_obj "28" "typedef struct baz_t baz" > + require_line result_obj "29" "typedef struct baz_t nested_baz_t" > + require_line result_obj "30" "typedef struct baz_t nested_baz" > + require_line result_obj "31" "typedef struct baz_t * baz_ptr" > + require_line result_obj "33" "enum enum_t" > + require_line result_obj "38" "typedef enum enum_t my_enum_t" > + require_line result_obj "39" "typedef enum enum_t nested_enum_t" > + require_line result_obj "45" "typedef struct {...} anon_struct_t" > + require_line result_obj "47" "typedef struct {...} nested_anon_struct_t" > + require_line result_obj "52" "typedef enum {...} anon_enum_t" > + require_line result_obj "54" "typedef enum {...} nested_anon_enum_t" > + require_line result_obj "56" "union union_t" > + require_line result_obj "62" "typedef union union_t nested_union_t" > + require_line result_obj "68" "typedef union {...} anon_union_t" > + require_line result_obj "70" "typedef union {...} nested_anon_union_t" > } > - > - gdb_test_lines "info types" "" [multi_line {*}$output_lines] > } > > run_test $lang >