Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DWARF] Does not generate nested enumerations. #45811

Open
CarlosAlbertoEnciso opened this issue Jun 26, 2020 · 6 comments
Open

[DWARF] Does not generate nested enumerations. #45811

CarlosAlbertoEnciso opened this issue Jun 26, 2020 · 6 comments
Labels
bugzilla Issues migrated from bugzilla debuginfo

Comments

@CarlosAlbertoEnciso
Copy link
Member

Bugzilla Link 46466
Version trunk
OS All
CC @dwblaikie,@gregbedwell,@JDevlieghere,@jmorse,@walkerkd,@OCHyams,@pogo59,@rnk

Extended Description

For the given test:

//----------------------------------------------------------

struct Struct {
union Union {
enum NestedEnum { RED, BLUE };
};
Union U;
};

Struct S;
int test() {
return S.U.BLUE;
}

//----------------------------------------------------------

The DWARF generated does not include any references to the enumerators 'RED' and 'BLUE'.

DWARF generated by GCC, CodeView generated by Clang and MSVC, it does include such references.

@CarlosAlbertoEnciso
Copy link
Member Author


llvm-dwarf output - Clang

0x00: DW_TAG_compile_unit
DW_AT_producer ("clang version 11.0.0")

0x2a: DW_TAG_variable
DW_AT_name ("S")
DW_AT_type (0x0000003f "Struct")

0x3f: DW_TAG_structure_type
DW_AT_name ("Struct")

0x48: DW_TAG_member
DW_AT_name ("U")
DW_AT_type (0x00000054 "Union")

0x54: DW_TAG_union_type
DW_AT_name ("Union")


llvm-dwarf output - GCC

0x0b: DW_TAG_compile_unit
DW_AT_producer ("GNU C++ 5.5.0 20171010")

0x2d: DW_TAG_structure_type
DW_AT_name ("Struct")

0x39: DW_TAG_union_type
DW_AT_name ("Union")

0x45: DW_TAG_enumeration_type
DW_AT_name ("NestedEnum")

0x51: DW_TAG_enumerator
DW_AT_name ("RED")
DW_AT_const_value (0x00)

0x57: DW_TAG_enumerator
DW_AT_name ("BLUE")
DW_AT_const_value (0x01)

0x5f: DW_TAG_member
DW_AT_name ("U")

@CarlosAlbertoEnciso
Copy link
Member Author

This is the output from llvm-diva (Sony's tool under development).

llvm-diva --print=scopes,symbols,types test.o --attribute=level,format

DWARF Logical View: (Clang)

Logical View:
[000] {File} 'test.o' -> elf64-x86-64
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'clang version 11.0.0'
[002] 9 {Function} extern not_inlined 'test' -> 'int'
[002] 1 {Struct} 'Struct'
[003] 5 {Member} public 'U' -> 'Union'
[003] 2 {Union} 'Union'
[002] 8 {Variable} extern 'S' -> 'Struct'

DWARF Logical View: (GCC)

Logical View:
[000] {File} 'test.o' -> elf32-littlearm
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'GNU C++14 9.2.1 20191025'
[002] 9 {Function} extern not_inlined 'test' -> 'int'
[002] 1 {Struct} 'Struct'
[003] 5 {Member} public 'U' -> 'Union'
[003] 2 {Union} 'Union'
[004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int'
[005] {Enumerator} 'BLUE' = '0x1'
[005] {Enumerator} 'RED' = '0x0'
[002] 8 {Variable} extern 'S' -> 'Struct'

CodeView Logical View: (Clang)

Logical View:
[000] {File} 'test.o' -> COFF-x86-64
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'clang version 11.0.0'
[002] {Function} extern not_inlined 'test' -> 'int'
[002] 1 {Struct} 'Struct'
[003] {Member} public 'U' -> 'Union'
[003] 2 {Union} 'Union'
[004] 3 {Enumeration} 'NestedEnum' -> 'int'
[005] {Enumerator} 'BLUE' = '0x1'
[005] {Enumerator} 'RED' = '0x0'
[002] {Variable} extern 'S' -> 'Struct'

CodeView Logical View: (MSVC)

Logical View:
[000] {File} 'test.o' -> COFF-i386
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'Microsoft (R) Optimizing Compiler'
[002] {Function} extern not_inlined 'test' -> 'int'
[002] 1 {Struct} 'Struct'
[003] {Member} public 'U' -> 'Union'
[003] 2 {Union} 'Union'
[004] 3 {Enumeration} 'NestedEnum' -> 'int'
[005] {Enumerator} 'BLUE' = '0x1'
[005] {Enumerator} 'RED' = '0x0'
[002] {Variable} extern 'S' -> 'Struct'

The logical views for the objects generated by GCC (DWARF), Clang (CodeView) and MSVC (CodeView) contains references to the enumerators 'BLUE' and 'RED'.

@dwblaikie
Copy link
Collaborator

A simpler example:

struct Struct {
enum NestedEnum { RED, BLUE };
};

Struct S;
int test() {
return Struct::BLUE; // enum is emitted in DWARF
// S.BLUE; // enum not emitted in DWARF
}

If you're interested in fixing this I'd suggest comparing/contrasting these two cases, and perhaps comparing/contrasting the CodeView case too (But I think the CV case works by emitting the nested enum because the outer struct is emitted - whereas I don't think we want to do that in DWARF (eg: "return Struct().BLUE;" should probably emit the enum even though the "Struct" type is not otherwise needed in the DWARF (& should probably be emitted as a declaration) & that probably doesn't produce struct or enum in CodeView - and having the global "Struct S;" should produce the Struct but no enum in DWARF (I'd bet this is GCC's behavior) if the enum is unreferenced (unlike in CodeView, where it's emitted regardless))

@CarlosAlbertoEnciso
Copy link
Member Author

For your simpler example, with both variations:

  • return Struct::BLUE;
  • return S.BLUE;

The CodeView generated by MSVC and Clang, looks the same:

 0 | S_GDATA32 `S`
     type = 0x1009 (Struct)

0x1009 | LF_STRUCTURE Struct
field list: 0x1008
0x1008 | LF_FIELDLIST
- LF_NESTTYPE [name = NestedEnum, parent = 0x1005]
0x1005 | LF_ENUM Struct::NestedEnum
field list: 0x1004
0x1004 | LF_FIELDLIST
- LF_ENUMERATE [RED = 0]
- LF_ENUMERATE [BLUE = 1]

The nested enum is emitted as part of the enclosing scope 'Struct'.

@CarlosAlbertoEnciso
Copy link
Member Author

Changing the enum to be enum class:

struct Struct {
enum class NestedEnum { RED, BLUE };
};

int test() {
return (int)Struct::NestedEnum::BLUE;
}

Only Clang (DWARF) emits the nested enum:

DWARF Logical View: (Clang)

[000] {File} 'test.o' -> elf64-x86-64
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'clang version 11.0.0'
[002] 5 {Function} extern not_inlined 'test' -> 'int'
[002] 1 {Struct} 'Struct'
[003] 2 {Enumeration} class 'NestedEnum' -> 'int'
[004] {Enumerator} 'BLUE' = '0x1'
[004] {Enumerator} 'RED' = '0x0'

DWARF Logical View: (GCC)

Logical View:
[000] {File} 'test.o' -> elf32-littlearm
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'GNU C++14 9.2.1 20191025'
[002] 5 {Function} extern not_inlined 'test' -> 'int'

CodeView Logical View: (Clang)

Logical View:
[000] {File} 'test.o' -> COFF-x86-64
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'clang version 11.0.0'
[002] {Function} extern not_inlined 'test' -> 'int'

CodeView Logical View: (MSVC)

[000] {File} 'test.o' -> COFF-i386
[001] {CompileUnit} 'test.cpp'
[002] {Producer} 'Microsoft (R) Optimizing Compiler'
[002] {Function} extern not_inlined 'test' -> 'int'

@dwblaikie
Copy link
Collaborator

For your simpler example, with both variations:

  • return Struct::BLUE;
  • return S.BLUE;

The CodeView generated by MSVC and Clang, looks the same

Yes, that'd be my expectation - I believe CodeView/MSVC/Clang-cl needs the full definition of the nested type (how it deals with a forward declaration of a nested type (eg: pimpl idiom), I don't know - be nice if we could use that representation for all nested enums on CV, because that's my philosophy for the DWARF output "imagine the nested types were always defined out of line")

Confirming what I was saying here: "comparing/contrasting the CodeView case too (But I think the CV case works by emitting the nested enum because the outer struct is emitted - whereas I don't think we want to do that in DWARF"(In reply to

Carlos Alberto Enciso from comment #​5)

Changing the enum to be enum class:

struct Struct {
enum class NestedEnum { RED, BLUE };
};

int test() {
return (int)Struct::NestedEnum::BLUE;
}

Only Clang (DWARF) emits the nested enum

Sure - I'd probably classify that as a bug/missed opportunity for other compilers.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla debuginfo
Projects
None yet
Development

No branches or pull requests

2 participants