Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -4731,10 +4731,12 @@ DILocalVariable """"""""""""""" -``DILocalVariable`` nodes represent local variables in the source language. If -the ``arg:`` field is set to non-zero, then this variable is a subprogram -parameter, and it will be included in the ``variables:`` field of its -:ref:`DISubprogram`. +``DILocalVariable`` nodes represent local variables in the source +language. If the ``arg:`` field is set to non-zero, then this variable +is a subprogram parameter, and it will be included in the +``variables:`` field of its :ref:`DISubprogram`. If the flag +``DIFlagConstant`` is set the variable is a named constant in the +source language. .. code-block:: text Index: llvm/include/llvm/IR/DebugInfoFlags.def =================================================================== --- llvm/include/llvm/IR/DebugInfoFlags.def +++ llvm/include/llvm/IR/DebugInfoFlags.def @@ -31,8 +31,7 @@ HANDLE_DI_FLAG(3, Public) HANDLE_DI_FLAG((1 << 2), FwdDecl) HANDLE_DI_FLAG((1 << 3), AppleBlock) -// Used to be BlockByRef, can be reused for anything except DICompositeType. -HANDLE_DI_FLAG((1 << 4), ReservedBit4) +HANDLE_DI_FLAG((1 << 4), Constant) HANDLE_DI_FLAG((1 << 5), Virtual) HANDLE_DI_FLAG((1 << 6), Artificial) HANDLE_DI_FLAG((1 << 7), Explicit) Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2806,6 +2806,7 @@ unsigned getArg() const { return Arg; } DIFlags getFlags() const { return Flags; } + bool isConstant() const { return getFlags() & FlagConstant; } bool isArtificial() const { return getFlags() & FlagArtificial; } bool isObjectPointer() const { return getFlags() & FlagObjectPointer; } Index: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -181,13 +181,12 @@ bool hasFrameIndexExprs() const { return !FrameIndexExprs.empty(); } void addMMIEntry(const DbgVariable &V); - // Translate tag to proper Dwarf tag. + /// Determine the appropriate tag for this variable. dwarf::Tag getTag() const { - // FIXME: Why don't we just infer this tag and store it all along? if (getVariable()->isParameter()) return dwarf::DW_TAG_formal_parameter; - - return dwarf::DW_TAG_variable; + return getVariable()->isConstant() ? dwarf::DW_TAG_constant + : dwarf::DW_TAG_variable; } /// Return true if DbgVariable is artificial. Index: llvm/test/DebugInfo/Generic/constants.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/Generic/constants.ll @@ -0,0 +1,32 @@ +; RUN: %llc_dwarf -O0 -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s +; REQUIRES: object-emission +; CHECK: DW_TAG_constant +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: DW_AT_name {{.*}}"local_constant" + +; Function Attrs: noinline nounwind optnone ssp uwtable +define void @foo() !dbg !14 { + %1 = alloca i32, align 4 + call void @llvm.dbg.declare(metadata i32* %1, metadata !17, metadata !DIExpression()), !dbg !18 + store i32 23, i32* %1, align 4, !dbg !18 + ret void, !dbg !18 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #1 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!9, !10} +!llvm.dbg.cu = !{!2} + +!2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, producer: "handwritten", isOptimized: false, emissionKind: FullDebug) +!3 = !DIFile(filename: "t.swift", directory: "/") +!4 = !{} +!7 = !DIBasicType(name: "Int32", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!14 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 2, type: !15, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4) +!15 = !DISubroutineType(types: !16) +!16 = !{null} +!17 = !DILocalVariable(name: "local_constant", flags: DIFlagConstant, scope: !14, file: !3, line: 3, type: !7) +!18 = !DILocation(line: 3, scope: !14)