bool producer_is_icc : 1;
bool producer_is_icc_lt_14 : 1;
bool producer_is_codewarrior : 1;
+ bool producer_is_clang : 1;
/* When true, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
struct dwarf2_section_info *str_section,
struct dwarf2_section_info *str_offsets_section,
gdb::optional<ULONGEST> str_offsets_base,
- htab_t include_hash)
+ htab_t include_hash, struct dwarf2_cu *cu)
{
struct objfile *objfile = per_objfile->objfile;
enum dwarf_macro_record_type macinfo_type;
if (! current_file)
complaint (_("macro debug info has an unmatched "
"`close_file' directive"));
+ else if (current_file->included_by == nullptr
+ && producer_is_clang (cu))
+ {
+ /* Clang, until the current version, misplaces some macro
+ definitions - such as ones defined in the command line,
+ putting them after the last DW_MACRO_end_file instead of
+ before the first DW_MACRO_start_file. Since at the time
+ of writing there is no clang version with this bug fixed,
+ we check for any clang producer. This should be changed
+ to producer_is_clang_lt_XX when possible. */
+ }
else
{
current_file = current_file->included_by;
current_file, lh, section,
section_is_gnu, is_dwz, offset_size,
str_section, str_offsets_section,
- str_offsets_base, include_hash);
+ str_offsets_base, include_hash, cu);
htab_remove_elt (include_hash, (void *) new_mac_ptr);
}
unsigned int offset, struct dwarf2_section_info *str_section,
struct dwarf2_section_info *str_offsets_section,
gdb::optional<ULONGEST> str_offsets_base,
- int section_is_gnu)
+ int section_is_gnu, struct dwarf2_cu *cu)
{
bfd *abfd;
const gdb_byte *mac_ptr, *mac_end;
dwarf_decode_macro_bytes (per_objfile, builder, abfd, mac_ptr, mac_end,
current_file, lh, section, section_is_gnu, 0,
offset_size, str_section, str_offsets_section,
- str_offsets_base, include_hash.get ());
+ str_offsets_base, include_hash.get (), cu);
}
dwarf2_section_info *str_section,
dwarf2_section_info *str_offsets_section,
gdb::optional<ULONGEST> str_offsets_base,
- int section_is_gnu);
+ int section_is_gnu, struct dwarf2_cu *cu);
#endif /* GDB_DWARF2_MACRO_H */
return cu->producer_is_gcc_lt_4_3;
}
+/* See dwarf2/read.h. */
+bool
+producer_is_clang (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_clang;
+}
+
static file_and_directory &
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
{
}
else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
cu->producer_is_codewarrior = true;
+ else if (producer_is_clang (cu->producer, &major, &minor))
+ cu->producer_is_clang = true;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
dwarf_decode_macros (per_objfile, builder, section, lh,
offset_size, offset, str_section, str_offsets_section,
- str_offsets_base, section_is_gnu);
+ str_offsets_base, section_is_gnu, cu);
}
/* Return the .debug_loc section to use for CU.
asection **, const gdb_byte **,
bfd_size_type *);
+/* Return true if the producer of the inferior is clang. */
+extern bool producer_is_clang (struct dwarf2_cu *cu);
+
#endif /* DWARF2READ_H */
|| startswith (producer, " F90 Flang ")));
}
+/* See producer.h. */
+
+bool
+producer_is_clang (const char *producer, int *major, int *minor)
+{
+ if (producer != nullptr && startswith (producer, "clang version "))
+ {
+ int maj, min;
+ if (major == nullptr)
+ major = &maj;
+ if (minor == nullptr)
+ minor = &min;
+
+ /* The full producer string will look something like
+ "clang version XX.X.X ..."
+ So we can safely ignore all characters before the first digit. */
+ const char *cs = producer + strlen ("clang version ");
+
+ if (sscanf (cs, "%d.%d", major, minor) == 2)
+ return true;
+ }
+ return false;
+}
+
#if defined GDB_SELF_TEST
namespace selftests {
namespace producer {
false otherwise.*/
extern bool producer_is_llvm (const char *producer);
+/* Returns true if the given PRODUCER string is clang, false otherwise.
+ Sets MAJOR and MINOR accordingly, if not NULL. */
+extern bool producer_is_clang (const char *producer, int *major, int *minor);
+
#endif
}
# Print the macro that is defined on the command-line.
- if { [test_compiler_info "clang-*"] } {
- # This is really a clang bug, it puts the macros defined on the command
- # line after the main source file, in the macro table.
- setup_kfail "gdb/29034" "*-*-*"
- }
gdb_test "print ONE" " = 1"
# Print the macro that is defined in the main file.
--- /dev/null
+/* Copyright 2022 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+int
+main (void)
+{
+ asm ("main_label: .globl main_label");
+}
--- /dev/null
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2022 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Clang has this bug where it puts the macros defined on the command-line
+# after the main file portion (see PR 29034 and
+# https://github.com/llvm/llvm-project/issues/54506 )
+# Test that GDB is still able to print macros in clang versions that
+# have this bug.
+
+load_lib dwarf.exp
+
+if {![dwarf2_support]} {
+ return 0
+}
+if {![test_compiler_info gcc-*-*]} {
+ untested "dwarf assembler needs GCC"
+}
+
+standard_testfile .c .S
+
+lassign [function_range main $srcdir/$subdir/$srcfile] \
+ main_start main_len
+
+set asm_file [standard_output_file $srcfile2]
+
+Dwarf::assemble $asm_file {
+ declare_labels L cu_macros
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_producer "clang version 15.0.0"}
+ {DW_AT_language @DW_LANG_C11}
+ {DW_AT_name $::srcfile}
+ {DW_AT_macros $cu_macros DW_FORM_sec_offset}
+ {DW_AT_stmt_list $L DW_FORM_sec_offset}
+ } {
+ declare_labels int_type
+
+ int_type: DW_TAG_base_type {
+ {DW_AT_byte_size 4 DW_FORM_sdata}
+ {DW_AT_encoding @DW_ATE_signed}
+ {DW_AT_name int}
+ }
+ DW_TAG_subprogram {
+ {MACRO_AT_func {main}}
+ {type :$int_type}
+ }
+ }
+ }
+ lines {version 2} L {
+ file_name $::srcfile 1
+ program {
+ DW_LNE_set_address $::main_start
+ line 10
+ DW_LNS_copy
+ DW_LNE_set_address "$::main_start + $::main_len"
+ DW_LNE_end_sequence
+ }
+ }
+
+ # Define the .debug_macro section.
+ macro {
+ cu_macros: unit {
+ "debug-line-offset-label" $L
+ } {
+ start_file 0 1
+ # A macro defined at line 1 of the main file.
+ define 1 "TWO 2"
+ end_file
+ define 0 "ONE 1"
+ }
+ }
+}
+
+if {[prepare_for_testing "failed to prepare" $testfile [list $srcfile $asm_file] {nodebug}]} {
+ return
+}
+
+if {![runto_main]} {
+ return
+}
+
+gdb_test "print TWO" "= 2" "print simple macro"
+gdb_test "print ONE" "= 1" "print defined from CLI"