To provide basic functionality, the LLVM debugger does have to make some
assumptions about the source-level language being debugged, though it keeps
these to a minimum. The only common features that the LLVM debugger assumes
-exist are `source files <LangRef.html#MDFile>`_, and `program objects
-<LangRef.html#MDGlobalVariable>`_. These abstract objects are used by a
+exist are `source files <LangRef.html#difile>`_, and `program objects
+<LangRef.html#diglobalvariable>`_. These abstract objects are used by a
debugger to form stack traces, show information about local variables, etc.
This section of the documentation first describes the representation aspects
.. code-block:: llvm
- void %llvm.dbg.declare(metadata, metadata, metadata)
+ void @llvm.dbg.declare(metadata, metadata, metadata)
This intrinsic provides information about a local element (e.g., variable).
The first argument is metadata holding the alloca for the variable. The second
-argument is a `local variable <LangRef.html#MDLocalVariable>`_ containing a
+argument is a `local variable <LangRef.html#dilocalvariable>`_ containing a
description of the variable. The third argument is a `complex expression
-<LangRef.html#MDExpression>`_.
+<LangRef.html#diexpression>`_.
``llvm.dbg.value``
^^^^^^^^^^^^^^^^^^
.. code-block:: llvm
- void %llvm.dbg.value(metadata, i64, metadata, metadata)
+ void @llvm.dbg.value(metadata, i64, metadata, metadata)
This intrinsic provides information when a user source variable is set to a new
value. The first argument is the new value (wrapped as metadata). The second
argument is the offset in the user source variable where the new value is
written. The third argument is a `local variable
-<LangRef.html#MDLocalVariable>`_ containing a description of the variable. The
-third argument is a `complex expression <LangRef.html#MDExpression>`_.
+<LangRef.html#dilocalvariable>`_ containing a description of the variable. The
+third argument is a `complex expression <LangRef.html#diexpression>`_.
Object lifetimes and scoping
============================
.. code-block:: llvm
; Function Attrs: nounwind ssp uwtable
- define void @foo() #0 {
+ define void @foo() #0 !dbg !4 {
entry:
%X = alloca i32, align 4
%Y = alloca i32, align 4
!llvm.module.flags = !{!7, !8, !9}
!llvm.ident = !{!10}
- !0 = !MDCompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
- !1 = !MDFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
+ !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+ !1 = !DIFile(filename: "/dev/stdin", directory: "/Users/dexonsmith/data/llvm/debug-info")
!2 = !{}
!3 = !{!4}
- !4 = !MDSubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, function: void ()* @foo, variables: !2)
- !5 = !MDSubroutineType(types: !6)
+ !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
+ !5 = !DISubroutineType(types: !6)
!6 = !{null}
!7 = !{i32 2, !"Dwarf Version", i32 2}
!8 = !{i32 2, !"Debug Info Version", i32 3}
!9 = !{i32 1, !"PIC Level", i32 2}
!10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"}
- !11 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "X", scope: !4, file: !1, line: 2, type: !12)
- !12 = !MDBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
- !13 = !MDExpression()
- !14 = !MDLocation(line: 2, column: 9, scope: !4)
- !15 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "Y", scope: !4, file: !1, line: 3, type: !12)
- !16 = !MDLocation(line: 3, column: 9, scope: !4)
- !17 = !MDLocalVariable(tag: DW_TAG_auto_variable, name: "Z", scope: !18, file: !1, line: 5, type: !12)
- !18 = distinct !MDLexicalBlock(scope: !4, file: !1, line: 4, column: 5)
- !19 = !MDLocation(line: 5, column: 11, scope: !18)
- !20 = !MDLocation(line: 6, column: 11, scope: !18)
- !21 = !MDLocation(line: 6, column: 9, scope: !18)
- !22 = !MDLocation(line: 8, column: 9, scope: !4)
- !23 = !MDLocation(line: 8, column: 7, scope: !4)
- !24 = !MDLocation(line: 9, column: 3, scope: !4)
+ !11 = !DILocalVariable(name: "X", scope: !4, file: !1, line: 2, type: !12)
+ !12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+ !13 = !DIExpression()
+ !14 = !DILocation(line: 2, column: 9, scope: !4)
+ !15 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12)
+ !16 = !DILocation(line: 3, column: 9, scope: !4)
+ !17 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12)
+ !18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
+ !19 = !DILocation(line: 5, column: 11, scope: !18)
+ !20 = !DILocation(line: 6, column: 11, scope: !18)
+ !21 = !DILocation(line: 6, column: 9, scope: !18)
+ !22 = !DILocation(line: 8, column: 9, scope: !4)
+ !23 = !DILocation(line: 8, column: 7, scope: !4)
+ !24 = !DILocation(line: 9, column: 3, scope: !4)
This example illustrates a few important details about LLVM debugging
.. code-block:: llvm
- !14 = !MDLocation(line: 2, column: 9, scope: !4)
- !4 = !MDSubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
- isLocal: false, isDefinition: true, scopeLine: 1,
- isOptimized: false, function: void ()* @foo,
- variables: !2)
+ !14 = !DILocation(line: 2, column: 9, scope: !4)
+ !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5,
+ isLocal: false, isDefinition: true, scopeLine: 1,
+ isOptimized: false, variables: !2)
Here ``!14`` is metadata providing `location information
-<LangRef.html#MDLocation>`_. In this example, scope is encoded by ``!4``, a
-`subprogram descriptor <LangRef.html#MDSubprogram>`_. This way the location
+<LangRef.html#dilocation>`_. In this example, scope is encoded by ``!4``, a
+`subprogram descriptor <LangRef.html#disubprogram>`_. This way the location
information attached to the intrinsics indicates that the variable ``X`` is
declared at line number 2 at a function level scope in function ``foo``.
.. code-block:: llvm
- !18 = distinct !MDLexicalBlock(scope: !4, file: !1, line: 4, column: 5)
- !19 = !MDLocation(line: 5, column: 11, scope: !18)
+ !18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5)
+ !19 = !DILocation(line: 5, column: 11, scope: !18)
Here ``!19`` indicates that ``Z`` is declared at line number 5 and column
number 0 inside of lexical scope ``!18``. The lexical scope itself resides
``llvm::Instruction`` provides easy access to metadata attached with an
instruction. One can extract line number information encoded in LLVM IR using
-``Instruction::getMetadata()`` and ``DILocation::getLineNumber()``.
+``Instruction::getDebugLoc()`` and ``DILocation::getLine()``.
.. code-block:: c++
- if (MDNode *N = I->getMetadata("dbg")) { // Here I is an LLVM instruction
- DILocation Loc(N); // DILocation is in DebugInfo.h
- unsigned Line = Loc.getLineNumber();
- StringRef File = Loc.getFilename();
- StringRef Dir = Loc.getDirectory();
+ if (DILocation *Loc = I->getDebugLoc()) { // Here I is an LLVM instruction
+ unsigned Line = Loc->getLine();
+ StringRef File = Loc->getFilename();
+ StringRef Dir = Loc->getDirectory();
}
C/C++ global variable information
!llvm.module.flags = !{!6, !7}
;; Define the compile unit.
- !0 = !MDCompileUnit(language: DW_LANG_C99, file: !1,
+ !0 = !DICompileUnit(language: DW_LANG_C99, file: !1,
producer:
"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)",
isOptimized: false, runtimeVersion: 0, emissionKind: 1,
;;
;; Define the file
;;
- !1 = !MDFile(filename: "/dev/stdin",
+ !1 = !DIFile(filename: "/dev/stdin",
directory: "/Users/dexonsmith/data/llvm/debug-info")
;; An empty array.
;;
;; Define the global variable itself.
;;
- !4 = !MDGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1,
+ !4 = !DIGlobalVariable(name: "MyGlobal", scope: !0, file: !1, line: 1,
type: !5, isLocal: false, isDefinition: true,
variable: i32* @MyGlobal)
;;
;; Define the type
;;
- !5 = !MDBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+ !5 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
;; Dwarf version to output.
!6 = !{i32 2, !"Dwarf Version", i32 2}
;;
;; Define the anchor for subprograms.
;;
- !4 = !MDSubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
+ !4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !5,
isLocal: false, isDefinition: true, scopeLine: 1,
flags: DIFlagPrototyped, isOptimized: false,
- function: i32 (i32, i8**)* @main, variables: !2)
+ variables: !2)
;;
;; Define the subprogram itself.
;;
- define i32 @main(i32 %argc, i8** %argv) {
+ define i32 @main(i32 %argc, i8** %argv) !dbg !4 {
...
}
"``a::b::c``". So the name entered in the name table must be demangled in
order to chop it up appropriately and additional names must be manually entered
into the table to make it effective as a name lookup table for debuggers to
-se.
+use.
All debuggers currently ignore the "``.debug_pubnames``" table as a result of
its inconsistent and useless public-only name content making it a waste of