[Dwarf] Complete the list of type tags.

An incorrect verification error revealed that the list of type tags was
incomplete. This patch adds the missing types by adding a tag kind to
the Dwarf.def file, which is used by the `isType` function.

A test was added for the original verification error.

Differential revision: https://reviews.llvm.org/D65914

llvm-svn: 368718
This commit is contained in:
Jonas Devlieghere 2019-08-13 17:00:54 +00:00
parent 6d716ef181
commit 57ae300562
5 changed files with 109 additions and 112 deletions

View File

@ -26,7 +26,17 @@
#endif
#ifndef HANDLE_DW_TAG
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR)
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND)
#endif
// Note that DW_KIND is not a DWARF concept, but rather a way for us to
// generate a list of tags that belong together.
#ifndef DW_KIND_NONE
#define DW_KIND_NONE 0
#endif
#ifndef DW_KIND_TYPE
#define DW_KIND_TYPE 1
#endif
#ifndef HANDLE_DW_AT
@ -109,94 +119,94 @@
#define HANDLE_DW_END(ID, NAME)
#endif
HANDLE_DW_TAG(0x0000, null, 2, DWARF)
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF)
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF)
HANDLE_DW_TAG(0x0003, entry_point, 2, DWARF)
HANDLE_DW_TAG(0x0004, enumeration_type, 2, DWARF)
HANDLE_DW_TAG(0x0005, formal_parameter, 2, DWARF)
HANDLE_DW_TAG(0x0008, imported_declaration, 2, DWARF)
HANDLE_DW_TAG(0x000a, label, 2, DWARF)
HANDLE_DW_TAG(0x000b, lexical_block, 2, DWARF)
HANDLE_DW_TAG(0x000d, member, 2, DWARF)
HANDLE_DW_TAG(0x000f, pointer_type, 2, DWARF)
HANDLE_DW_TAG(0x0010, reference_type, 2, DWARF)
HANDLE_DW_TAG(0x0011, compile_unit, 2, DWARF)
HANDLE_DW_TAG(0x0012, string_type, 2, DWARF)
HANDLE_DW_TAG(0x0013, structure_type, 2, DWARF)
HANDLE_DW_TAG(0x0015, subroutine_type, 2, DWARF)
HANDLE_DW_TAG(0x0016, typedef, 2, DWARF)
HANDLE_DW_TAG(0x0017, union_type, 2, DWARF)
HANDLE_DW_TAG(0x0018, unspecified_parameters, 2, DWARF)
HANDLE_DW_TAG(0x0019, variant, 2, DWARF)
HANDLE_DW_TAG(0x001a, common_block, 2, DWARF)
HANDLE_DW_TAG(0x001b, common_inclusion, 2, DWARF)
HANDLE_DW_TAG(0x001c, inheritance, 2, DWARF)
HANDLE_DW_TAG(0x001d, inlined_subroutine, 2, DWARF)
HANDLE_DW_TAG(0x001e, module, 2, DWARF)
HANDLE_DW_TAG(0x001f, ptr_to_member_type, 2, DWARF)
HANDLE_DW_TAG(0x0020, set_type, 2, DWARF)
HANDLE_DW_TAG(0x0021, subrange_type, 2, DWARF)
HANDLE_DW_TAG(0x0022, with_stmt, 2, DWARF)
HANDLE_DW_TAG(0x0023, access_declaration, 2, DWARF)
HANDLE_DW_TAG(0x0024, base_type, 2, DWARF)
HANDLE_DW_TAG(0x0025, catch_block, 2, DWARF)
HANDLE_DW_TAG(0x0026, const_type, 2, DWARF)
HANDLE_DW_TAG(0x0027, constant, 2, DWARF)
HANDLE_DW_TAG(0x0028, enumerator, 2, DWARF)
HANDLE_DW_TAG(0x0029, file_type, 2, DWARF)
HANDLE_DW_TAG(0x002a, friend, 2, DWARF)
HANDLE_DW_TAG(0x002b, namelist, 2, DWARF)
HANDLE_DW_TAG(0x002c, namelist_item, 2, DWARF)
HANDLE_DW_TAG(0x002d, packed_type, 2, DWARF)
HANDLE_DW_TAG(0x002e, subprogram, 2, DWARF)
HANDLE_DW_TAG(0x002f, template_type_parameter, 2, DWARF)
HANDLE_DW_TAG(0x0030, template_value_parameter, 2, DWARF)
HANDLE_DW_TAG(0x0031, thrown_type, 2, DWARF)
HANDLE_DW_TAG(0x0032, try_block, 2, DWARF)
HANDLE_DW_TAG(0x0033, variant_part, 2, DWARF)
HANDLE_DW_TAG(0x0034, variable, 2, DWARF)
HANDLE_DW_TAG(0x0035, volatile_type, 2, DWARF)
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0003, entry_point, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0004, enumeration_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0005, formal_parameter, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0008, imported_declaration, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x000a, label, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x000b, lexical_block, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x000d, member, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x000f, pointer_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0010, reference_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0011, compile_unit, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0012, string_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0013, structure_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0015, subroutine_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0016, typedef, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0017, union_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0018, unspecified_parameters, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0019, variant, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001a, common_block, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001b, common_inclusion, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001c, inheritance, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001d, inlined_subroutine, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001e, module, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x001f, ptr_to_member_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0020, set_type, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0021, subrange_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0022, with_stmt, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0023, access_declaration, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0024, base_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0025, catch_block, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0026, const_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0027, constant, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0028, enumerator, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0029, file_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x002a, friend, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x002b, namelist, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x002c, namelist_item, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x002d, packed_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x002e, subprogram, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x002f, template_type_parameter, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0030, template_value_parameter, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0031, thrown_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0032, try_block, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0033, variant_part, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0034, variable, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0035, volatile_type, 2, DWARF, DW_KIND_TYPE)
// New in DWARF v3:
HANDLE_DW_TAG(0x0036, dwarf_procedure, 3, DWARF)
HANDLE_DW_TAG(0x0037, restrict_type, 3, DWARF)
HANDLE_DW_TAG(0x0038, interface_type, 3, DWARF)
HANDLE_DW_TAG(0x0039, namespace, 3, DWARF)
HANDLE_DW_TAG(0x003a, imported_module, 3, DWARF)
HANDLE_DW_TAG(0x003b, unspecified_type, 3, DWARF)
HANDLE_DW_TAG(0x003c, partial_unit, 3, DWARF)
HANDLE_DW_TAG(0x003d, imported_unit, 3, DWARF)
HANDLE_DW_TAG(0x003f, condition, 3, DWARF)
HANDLE_DW_TAG(0x0040, shared_type, 3, DWARF)
HANDLE_DW_TAG(0x0036, dwarf_procedure, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0037, restrict_type, 3, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0038, interface_type, 3, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0039, namespace, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x003a, imported_module, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x003b, unspecified_type, 3, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x003c, partial_unit, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x003d, imported_unit, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x003f, condition, 3, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0040, shared_type, 3, DWARF, DW_KIND_TYPE)
// New in DWARF v4:
HANDLE_DW_TAG(0x0041, type_unit, 4, DWARF)
HANDLE_DW_TAG(0x0042, rvalue_reference_type, 4, DWARF)
HANDLE_DW_TAG(0x0043, template_alias, 4, DWARF)
HANDLE_DW_TAG(0x0041, type_unit, 4, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0042, rvalue_reference_type, 4, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0043, template_alias, 4, DWARF, DW_KIND_NONE)
// New in DWARF v5:
HANDLE_DW_TAG(0x0044, coarray_type, 5, DWARF)
HANDLE_DW_TAG(0x0045, generic_subrange, 5, DWARF)
HANDLE_DW_TAG(0x0046, dynamic_type, 5, DWARF)
HANDLE_DW_TAG(0x0047, atomic_type, 5, DWARF)
HANDLE_DW_TAG(0x0048, call_site, 5, DWARF)
HANDLE_DW_TAG(0x0049, call_site_parameter, 5, DWARF)
HANDLE_DW_TAG(0x004a, skeleton_unit, 5, DWARF)
HANDLE_DW_TAG(0x004b, immutable_type, 5, DWARF)
HANDLE_DW_TAG(0x0044, coarray_type, 5, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0045, generic_subrange, 5, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0046, dynamic_type, 5, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0047, atomic_type, 5, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0048, call_site, 5, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0049, call_site_parameter, 5, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x004a, skeleton_unit, 5, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x004b, immutable_type, 5, DWARF, DW_KIND_TYPE)
// Vendor extensions:
HANDLE_DW_TAG(0x4081, MIPS_loop, 0, MIPS)
HANDLE_DW_TAG(0x4101, format_label, 0, GNU)
HANDLE_DW_TAG(0x4102, function_template, 0, GNU)
HANDLE_DW_TAG(0x4103, class_template, 0, GNU)
HANDLE_DW_TAG(0x4106, GNU_template_template_param, 0, GNU)
HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack, 0, GNU)
HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack, 0, GNU)
HANDLE_DW_TAG(0x4109, GNU_call_site, 0, GNU)
HANDLE_DW_TAG(0x410a, GNU_call_site_parameter, 0, GNU)
HANDLE_DW_TAG(0x4200, APPLE_property, 0, APPLE)
HANDLE_DW_TAG(0xb000, BORLAND_property, 0, BORLAND)
HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string, 0, BORLAND)
HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array, 0, BORLAND)
HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set, 0, BORLAND)
HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant, 0, BORLAND)
HANDLE_DW_TAG(0x4081, MIPS_loop, 0, MIPS, DW_KIND_NONE)
HANDLE_DW_TAG(0x4101, format_label, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4102, function_template, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4103, class_template, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4106, GNU_template_template_param, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4107, GNU_template_parameter_pack, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4108, GNU_formal_parameter_pack, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4109, GNU_call_site, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x410a, GNU_call_site_parameter, 0, GNU, DW_KIND_NONE)
HANDLE_DW_TAG(0x4200, APPLE_property, 0, APPLE, DW_KIND_NONE)
HANDLE_DW_TAG(0xb000, BORLAND_property, 0, BORLAND, DW_KIND_NONE)
HANDLE_DW_TAG(0xb001, BORLAND_Delphi_string, 0, BORLAND, DW_KIND_TYPE)
HANDLE_DW_TAG(0xb002, BORLAND_Delphi_dynamic_array, 0, BORLAND, DW_KIND_TYPE)
HANDLE_DW_TAG(0xb003, BORLAND_Delphi_set, 0, BORLAND, DW_KIND_TYPE)
HANDLE_DW_TAG(0xb004, BORLAND_Delphi_variant, 0, BORLAND, DW_KIND_TYPE)
// Attributes.
HANDLE_DW_AT(0x01, sibling, 2, DWARF)

View File

@ -80,7 +80,7 @@ const uint64_t DW64_CIE_ID = UINT64_MAX;
const uint32_t DW_INVALID_OFFSET = UINT32_MAX;
enum Tag : uint16_t {
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID,
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) DW_TAG_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
DW_TAG_lo_user = 0x4080,
DW_TAG_hi_user = 0xffff,
@ -89,29 +89,12 @@ enum Tag : uint16_t {
inline bool isType(Tag T) {
switch (T) {
case DW_TAG_array_type:
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_enumeration_type:
case DW_TAG_pointer_type:
case DW_TAG_reference_type:
case DW_TAG_rvalue_reference_type:
case DW_TAG_string_type:
case DW_TAG_structure_type:
case DW_TAG_subroutine_type:
case DW_TAG_union_type:
case DW_TAG_ptr_to_member_type:
case DW_TAG_set_type:
case DW_TAG_subrange_type:
case DW_TAG_base_type:
case DW_TAG_const_type:
case DW_TAG_file_type:
case DW_TAG_packed_type:
case DW_TAG_volatile_type:
case DW_TAG_typedef:
return true;
default:
return false;
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
case DW_TAG_##NAME: \
return (KIND == DW_KIND_TYPE);
#include "llvm/BinaryFormat/Dwarf.def"
}
}

View File

@ -234,7 +234,7 @@ template <> struct MappingTraits<DWARFYAML::InitialLength> {
static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
};
#define HANDLE_DW_TAG(unused, name, unused2, unused3) \
#define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
template <> struct ScalarEnumerationTraits<dwarf::Tag> {

View File

@ -22,7 +22,7 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
switch (Tag) {
default:
return StringRef();
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
case DW_TAG_##NAME: \
return "DW_TAG_" #NAME;
#include "llvm/BinaryFormat/Dwarf.def"
@ -31,7 +31,7 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
unsigned llvm::dwarf::getTag(StringRef TagString) {
return StringSwitch<unsigned>(TagString)
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
.Case("DW_TAG_" #NAME, DW_TAG_##NAME)
#include "llvm/BinaryFormat/Dwarf.def"
.Default(DW_TAG_invalid);
@ -41,7 +41,7 @@ unsigned llvm::dwarf::TagVersion(dwarf::Tag Tag) {
switch (Tag) {
default:
return 0;
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
case DW_TAG_##NAME: \
return VERSION;
#include "llvm/BinaryFormat/Dwarf.def"
@ -52,7 +52,7 @@ unsigned llvm::dwarf::TagVendor(dwarf::Tag Tag) {
switch (Tag) {
default:
return 0;
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR, KIND) \
case DW_TAG_##NAME: \
return DWARF_VENDOR_##VENDOR;
#include "llvm/BinaryFormat/Dwarf.def"

View File

@ -1,6 +1,7 @@
; REQUIRES: object-emission
; RUN: llc -mtriple=x86_64-linux -O0 -filetype=obj < %s | llvm-dwarfdump -v -debug-info - | FileCheck %s
; RUN: llc -mtriple=x86_64-linux -O0 -filetype=obj < %s | not llvm-dwarfdump -verify - | FileCheck %s --check-prefix VERIFY
; IR generated with `clang++ -g -emit-llvm -S` from the following code:
; template<int x, int*, template<typename> class y, decltype(nullptr) n, int ...z> int func() {
@ -11,6 +12,9 @@
; int glbl = func<3, &glbl, y_impl, nullptr, 1, 2>();
; y_impl<int>::nested n;
; VERIFY-NOT: error: DIE has DW_AT_type with incompatible tag DW_TAG_unspecified_type
; VERIFY: error: DIEs have overlapping address ranges
; CHECK: [[INT:0x[0-9a-f]*]]:{{ *}}DW_TAG_base_type
; CHECK-NEXT: DW_AT_name{{.*}} = "int"