forked from OSchip/llvm-project
DebugInfo: Emit ranges for functions with DISubprograms but lacking locations on any instructions
This seems more consistent, and helps tidy up/simplify some other code in this change. llvm-svn: 289889
This commit is contained in:
parent
890e850348
commit
3e3eb33ed7
|
@ -568,25 +568,24 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
|
|||
return ObjectPointer;
|
||||
}
|
||||
|
||||
void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
|
||||
assert(Scope && Scope->getScopeNode());
|
||||
assert(!Scope->getInlinedAt());
|
||||
assert(!Scope->isAbstractScope());
|
||||
auto *Sub = cast<DISubprogram>(Scope->getScopeNode());
|
||||
|
||||
void DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope) {
|
||||
DD->getProcessedSPNodes().insert(Sub);
|
||||
|
||||
DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
|
||||
|
||||
if (Scope) {
|
||||
assert(!Scope->getInlinedAt());
|
||||
assert(!Scope->isAbstractScope());
|
||||
// Collect lexical scope children first.
|
||||
// ObjectPointer might be a local (non-argument) local variable if it's a
|
||||
// block's synthetic this pointer.
|
||||
if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
|
||||
addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
|
||||
}
|
||||
|
||||
// If this is a variadic function, add an unspecified parameter.
|
||||
DITypeRefArray FnArgs = Sub->getType()->getTypeArray();
|
||||
|
||||
// Collect lexical scope children first.
|
||||
// ObjectPointer might be a local (non-argument) local variable if it's a
|
||||
// block's synthetic this pointer.
|
||||
if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE))
|
||||
addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
|
||||
|
||||
// If we have a single element of null, it is a function that returns void.
|
||||
// If we have more than one elements and the last one is null, it is a
|
||||
// variadic function.
|
||||
|
@ -678,11 +677,7 @@ void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
|
|||
// If this subprogram has an abstract definition, reference that
|
||||
addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
|
||||
} else {
|
||||
if (!D && !includeMinimalInlineScopes())
|
||||
// Lazily construct the subprogram if we didn't see either concrete or
|
||||
// inlined versions during codegen. (except in -gmlt ^ where we want
|
||||
// to omit these entirely)
|
||||
D = getOrCreateSubprogramDIE(SP);
|
||||
assert(D || includeMinimalInlineScopes());
|
||||
if (D)
|
||||
// And attach the attributes
|
||||
applySubprogramAttributesToDefinition(SP, *D);
|
||||
|
|
|
@ -172,7 +172,7 @@ public:
|
|||
unsigned *ChildScopeCount = nullptr);
|
||||
|
||||
/// \brief Construct a DIE for this subprogram scope.
|
||||
void constructSubprogramScopeDIE(LexicalScope *Scope);
|
||||
void constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope);
|
||||
|
||||
DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);
|
||||
|
||||
|
|
|
@ -1155,18 +1155,14 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
|||
"endFunction should be called with the same function as beginFunction");
|
||||
|
||||
const DISubprogram *SP = MF->getFunction()->getSubprogram();
|
||||
if (!MMI->hasDebugInfo() || LScopes.empty() || !SP ||
|
||||
if (!MMI->hasDebugInfo() || !SP ||
|
||||
SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) {
|
||||
// If we don't have a lexical scope for this function then there will
|
||||
// be a hole in the range information. Keep note of this by setting the
|
||||
// previously used section to nullptr.
|
||||
// If we don't have a subprogram for this function then there will be a hole
|
||||
// in the range information. Keep note of this by setting the previously
|
||||
// used section to nullptr.
|
||||
PrevCU = nullptr;
|
||||
CurFn = nullptr;
|
||||
DebugHandlerBase::endFunction(MF);
|
||||
// Mark functions with no debug info on any instructions, but a
|
||||
// valid DISubprogram as processed.
|
||||
if (SP)
|
||||
ProcessedSPNodes.insert(SP);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1174,7 +1170,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
|||
Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
|
||||
|
||||
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
|
||||
SP = cast<DISubprogram>(FnScope->getScopeNode());
|
||||
assert(!FnScope || SP == FnScope->getScopeNode());
|
||||
DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
|
||||
|
||||
DenseSet<InlinedVariable> ProcessedVars;
|
||||
|
@ -1216,11 +1212,11 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
|||
constructAbstractSubprogramScopeDIE(AScope);
|
||||
}
|
||||
|
||||
TheCU.constructSubprogramScopeDIE(FnScope);
|
||||
TheCU.constructSubprogramScopeDIE(SP, FnScope);
|
||||
if (auto *SkelCU = TheCU.getSkeleton())
|
||||
if (!LScopes.getAbstractScopesList().empty() &&
|
||||
TheCU.getCUNode()->getSplitDebugInlining())
|
||||
SkelCU->constructSubprogramScopeDIE(FnScope);
|
||||
SkelCU->constructSubprogramScopeDIE(SP, FnScope);
|
||||
|
||||
// Clear debug info
|
||||
// Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the
|
||||
|
|
|
@ -13,7 +13,7 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32,
|
|||
|
||||
!llvm.dbg.cu = !{!2}
|
||||
!llvm.module.flags = !{!27}
|
||||
!0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2, file: !1, scope: null)
|
||||
!0 = distinct !DISubprogram(name: "CGRectStandardize", linkageName: "CGRectStandardize", line: 54, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !2, file: !1, scope: null, type: !28)
|
||||
!1 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop")
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 2.9 (trunk 115292)", isOptimized: true, runtimeVersion: 1, emissionKind: FullDebug, file: !25, enums: !26, retainedTypes: !26)
|
||||
!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "CGRect", line: 49, file: !25, baseType: null)
|
||||
|
@ -22,3 +22,5 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32,
|
|||
!25 = !DIFile(filename: "GSFusedSilica.m", directory: "/Volumes/Data/Users/sabre/Desktop")
|
||||
!26 = !{}
|
||||
!27 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!28 = !DISubroutineType(types: !29)
|
||||
!29 = !{null}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
; REQUIRES: object-emission
|
||||
|
||||
; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s
|
||||
|
||||
; Just because there are no scopes/locations on any instructions in the
|
||||
; function doesn't mean we can't describe the address range of the function.
|
||||
; Check that we do that
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: TAG
|
||||
; CHECK: DW_AT_low_pc
|
||||
|
||||
; ModuleID = 'noscopes.c'
|
||||
source_filename = "noscopes.c"
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @f() #0 !dbg !6 {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind 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" }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
!llvm.ident = !{!5}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 289692) (llvm/trunk 289697)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
||||
!1 = !DIFile(filename: "noscopes.c", directory: "/tmp/dbginfo")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!5 = !{!"clang version 4.0.0 (trunk 289692) (llvm/trunk 289697)"}
|
||||
!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2)
|
||||
!7 = !DISubroutineType(types: !8)
|
||||
!8 = !{null}
|
||||
!9 = !DILocation(line: 2, column: 1, scope: !6)
|
||||
|
Loading…
Reference in New Issue