mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
DebugInfo: Ensure imported entities at the top level of an inlined function don't cause degenerate concrete definitions
Local imported entities at the top level of a subprogram were being handled differently from those in nested scopes - that different handling would cause pseudo concrete out-of-line definitions to be created (but without any of their attributes, nor an abstract_origin) in the case where there was no real concrete definition. These local imported entities also only appeared in the concrete definition where those imported entities in nested scopes appear in all cases (abstract, concrete, and inlined). This change at least makes top level case handle the same as the others - though there's a FIXME to improve this to /only/ emit them into the abstract origin (though this requires more plumbing - like the abstract subprogram and variable handling that must defer population until the end of the unit to discover if there is an abstract origin, or only a standalone concrete definition). llvm-svn: 309237
This commit is contained in:
parent
92b99af10e
commit
37a7f2ee7b
@ -336,23 +336,15 @@ void DwarfCompileUnit::constructScopeDIE(
|
||||
if (DD->isLexicalScopeDIENull(Scope))
|
||||
return;
|
||||
|
||||
unsigned ChildScopeCount;
|
||||
bool HasNonScopeChildren = false;
|
||||
|
||||
// We create children here when we know the scope DIE is not going to be
|
||||
// null and the children will be added to the scope DIE.
|
||||
createScopeChildrenDIE(Scope, Children, &ChildScopeCount);
|
||||
|
||||
// Skip imported directives in gmlt-like data.
|
||||
if (!includeMinimalInlineScopes()) {
|
||||
// There is no need to emit empty lexical block DIE.
|
||||
for (const auto *IE : ImportedEntities[DS])
|
||||
Children.push_back(
|
||||
constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
|
||||
}
|
||||
createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren);
|
||||
|
||||
// If there are only other scopes as children, put them directly in the
|
||||
// parent instead, as this scope would serve no purpose.
|
||||
if (Children.size() == ChildScopeCount) {
|
||||
if (!HasNonScopeChildren) {
|
||||
FinalChildren.insert(FinalChildren.end(),
|
||||
std::make_move_iterator(Children.begin()),
|
||||
std::make_move_iterator(Children.end()));
|
||||
@ -557,20 +549,27 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
|
||||
|
||||
DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
|
||||
SmallVectorImpl<DIE *> &Children,
|
||||
unsigned *ChildScopeCount) {
|
||||
bool *HasNonScopeChildren) {
|
||||
assert(Children.empty());
|
||||
DIE *ObjectPointer = nullptr;
|
||||
|
||||
for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
|
||||
Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer));
|
||||
|
||||
unsigned ChildCountWithoutScopes = Children.size();
|
||||
// Skip imported directives in gmlt-like data.
|
||||
if (!includeMinimalInlineScopes()) {
|
||||
// There is no need to emit empty lexical block DIE.
|
||||
for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
|
||||
Children.push_back(
|
||||
constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
|
||||
}
|
||||
|
||||
if (HasNonScopeChildren)
|
||||
*HasNonScopeChildren = !Children.empty();
|
||||
|
||||
for (LexicalScope *LS : Scope->getChildren())
|
||||
constructScopeDIE(LS, Children);
|
||||
|
||||
if (ChildScopeCount)
|
||||
*ChildScopeCount = Children.size() - ChildCountWithoutScopes;
|
||||
|
||||
return ObjectPointer;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ public:
|
||||
/// A helper function to create children of a Scope DIE.
|
||||
DIE *createScopeChildrenDIE(LexicalScope *Scope,
|
||||
SmallVectorImpl<DIE *> &Children,
|
||||
unsigned *ChildScopeCount = nullptr);
|
||||
bool *HasNonScopeChildren = nullptr);
|
||||
|
||||
/// \brief Construct a DIE for this subprogram scope.
|
||||
void constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope);
|
||||
|
@ -494,6 +494,8 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
|
||||
|
||||
void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
|
||||
const DIImportedEntity *N) {
|
||||
if (isa<DILocalScope>(N->getScope()))
|
||||
return;
|
||||
if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope()))
|
||||
D->addChild(TheCU.constructImportedEntityDIE(N));
|
||||
}
|
||||
|
69
test/DebugInfo/Generic/imported-name-inlined.ll
Normal file
69
test/DebugInfo/Generic/imported-name-inlined.ll
Normal file
@ -0,0 +1,69 @@
|
||||
; REQUIRES: object-emission
|
||||
|
||||
; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
|
||||
|
||||
; Generated from the following source:
|
||||
; namespace ns {
|
||||
; void f();
|
||||
; }
|
||||
; inline __attribute__((always_inline)) void f1() {
|
||||
; using ns::f;
|
||||
; f();
|
||||
; }
|
||||
; void f2() { f1(); }
|
||||
|
||||
; Ensure that top level imported declarations don't produce an extra degenerate
|
||||
; concrete subprogram definition.
|
||||
|
||||
; FIXME: imported entities should only be emitted to the abstract origin if one is present
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name {{.*}} "f1"
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name {{.*}} "f2"
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
; Function Attrs: noinline optnone uwtable
|
||||
define void @_Z2f2v() #0 !dbg !14 {
|
||||
entry:
|
||||
call void @_ZN2ns1fEv(), !dbg !15
|
||||
ret void, !dbg !17
|
||||
}
|
||||
|
||||
declare void @_ZN2ns1fEv() #1
|
||||
|
||||
attributes #0 = { noinline optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!10, !11, !12}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 (trunk 309061) (llvm/trunk 309076)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, imports: !3)
|
||||
!1 = !DIFile(filename: "imported-name-inlined.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
!4 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !5, entity: !8, file: !1, line: 5)
|
||||
!5 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DISubprogram(name: "f", linkageName: "_ZN2ns1fEv", scope: !9, file: !1, line: 2, type: !6, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: false)
|
||||
!9 = !DINamespace(name: "ns", scope: null)
|
||||
!10 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!11 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!12 = !{i32 1, !"wchar_size", i32 4}
|
||||
!13 = !{!"clang version 6.0.0 (trunk 309061) (llvm/trunk 309076)"}
|
||||
!14 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 8, type: !6, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
|
||||
!15 = !DILocation(line: 6, column: 3, scope: !5, inlinedAt: !16)
|
||||
!16 = distinct !DILocation(line: 8, column: 13, scope: !14)
|
||||
!17 = !DILocation(line: 8, column: 19, scope: !14)
|
@ -23,6 +23,11 @@
|
||||
; CHECK-NOT: NULL
|
||||
; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
|
||||
; CHECK-NEXT: DW_AT_name{{.*}}= "bar"
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_MIPS_linkage_name
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}= "f1"
|
||||
; CHECK: [[FUNC1:.*]]: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_MIPS_linkage_name
|
||||
@ -45,11 +50,6 @@
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}= "func_fwd"
|
||||
; CHECK-NOT: DW_AT_declaration
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_MIPS_linkage_name
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name{{.*}}= "f1"
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK-NOT: NULL
|
||||
@ -66,6 +66,8 @@
|
||||
; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]})
|
||||
; CHECK-NOT: NULL
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: {{DW_TAG|NULL}}
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_MIPS_linkage_name
|
||||
|
Loading…
Reference in New Issue
Block a user