From: Victor Leschuk <vleschuk@accesssoftek.com>
Date: Mon, 31 Oct 2016 19:09:38 +0000 (+0000)
Subject: DebugInfo: make DW_TAG_atomic_type valid
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b33954931cf7a6632f477dcdb8c83f4eb5caa829;p=llvm

DebugInfo: make DW_TAG_atomic_type valid

DW_TAG_atomic_type was already included in Dwarf.defs and emitted correctly,
however Verifier didn't recognize it as valid.
Thus we introduce the following changes:

  * Make DW_TAG_atomic_type valid tag for IR and DWARF (enabled only with -gdwarf-5)
  * Add it to related docs
  * Add DebugInfo tests

Differential Revision: https://reviews.llvm.org/D26144



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285624 91177308-0d34-0410-b5e6-96231b3b80d8
---

diff --git a/docs/LangRef.rst b/docs/LangRef.rst
index 9351362c89e..5bcbb224812 100644
--- a/docs/LangRef.rst
+++ b/docs/LangRef.rst
@@ -4078,6 +4078,7 @@ The following ``tag:`` values are valid:
   DW_TAG_friend             = 42
   DW_TAG_volatile_type      = 53
   DW_TAG_restrict_type      = 55
+  DW_TAG_atomic_type        = 71
 
 .. _DIDerivedTypeMember:
 
@@ -4094,8 +4095,8 @@ friends.
 ``DW_TAG_typedef`` is used to provide a name for the ``baseType:``.
 
 ``DW_TAG_pointer_type``, ``DW_TAG_reference_type``, ``DW_TAG_const_type``,
-``DW_TAG_volatile_type`` and ``DW_TAG_restrict_type`` are used to qualify the
-``baseType:``.
+``DW_TAG_volatile_type``, ``DW_TAG_restrict_type`` and ``DW_TAG_atomic_type``
+are used to qualify the ``baseType:``.
 
 Note that the ``void *`` type is expressed as a type derived from NULL.
 
diff --git a/docs/SourceLevelDebugging.rst b/docs/SourceLevelDebugging.rst
index 6f22f54ce4d..6bde5a54d64 100644
--- a/docs/SourceLevelDebugging.rst
+++ b/docs/SourceLevelDebugging.rst
@@ -1264,6 +1264,7 @@ tag is one of:
 * DW_TAG_packed_type
 * DW_TAG_volatile_type
 * DW_TAG_restrict_type
+* DW_TAG_atomic_type
 * DW_TAG_interface_type
 * DW_TAG_unspecified_type
 * DW_TAG_shared_type
diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h
index 4cf04e66cfe..06ea42e0869 100644
--- a/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -276,6 +276,7 @@ enum class MethodOptions : uint16_t {
 CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions)
 
 /// Equivalent to CV_modifier_t.
+/// TODO: Add flag for _Atomic modifier
 enum class ModifierOptions : uint16_t {
   None = 0x0000,
   Const = 0x0001,
diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index a1fd0dc8869..5cc8b4e4555 100644
--- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1091,6 +1091,7 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) {
     return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
   case dwarf::DW_TAG_const_type:
   case dwarf::DW_TAG_volatile_type:
+  // TODO: add support for DW_TAG_atomic_type here
     return lowerTypeModifier(cast<DIDerivedType>(Ty));
   case dwarf::DW_TAG_subroutine_type:
     if (ClassTy) {
@@ -1399,7 +1400,7 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
   bool IsModifier = true;
   const DIType *BaseTy = Ty;
   while (IsModifier && BaseTy) {
-    // FIXME: Need to add DWARF tag for __unaligned.
+    // FIXME: Need to add DWARF tags for __unaligned and _Atomic
     switch (BaseTy->getTag()) {
     case dwarf::DW_TAG_const_type:
       Mods |= ModifierOptions::Const;
diff --git a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 357d67fa2e5..d30f106a939 100644
--- a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -98,7 +98,7 @@ uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
 
   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
-      Tag != dwarf::DW_TAG_restrict_type)
+      Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
     return DDTy->getSizeInBits();
 
   DIType *BaseType = DDTy->getBaseType().resolve();
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index d653f8da477..2dcb616a67f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -546,7 +546,7 @@ static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty) {
       return true;
     assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
            T == dwarf::DW_TAG_volatile_type ||
-           T == dwarf::DW_TAG_restrict_type);
+           T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
     DITypeRef Deriv = DTy->getBaseType();
     assert(Deriv && "Expected valid base type");
     return isUnsignedDIType(DD, DD->resolve(Deriv));
@@ -707,6 +707,10 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
   if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
     return getOrCreateTypeDIE(resolve(cast<DIDerivedType>(Ty)->getBaseType()));
 
+  // DW_TAG_atomic_type is not supported in DWARF < 5
+  if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5)
+    return getOrCreateTypeDIE(resolve(cast<DIDerivedType>(Ty)->getBaseType()));
+
   // Construct the context before querying for the existence of the DIE in case
   // such construction creates the DIE.
   auto *Context = resolve(Ty->getScope());
diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp
index 7eea5170b94..a8a1df3e8b4 100644
--- a/lib/IR/Verifier.cpp
+++ b/lib/IR/Verifier.cpp
@@ -864,6 +864,7 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
                N.getTag() == dwarf::DW_TAG_const_type ||
                N.getTag() == dwarf::DW_TAG_volatile_type ||
                N.getTag() == dwarf::DW_TAG_restrict_type ||
+               N.getTag() == dwarf::DW_TAG_atomic_type ||
                N.getTag() == dwarf::DW_TAG_member ||
                N.getTag() == dwarf::DW_TAG_inheritance ||
                N.getTag() == dwarf::DW_TAG_friend,
diff --git a/test/DebugInfo/X86/atomic-c11-dwarf-4.ll b/test/DebugInfo/X86/atomic-c11-dwarf-4.ll
new file mode 100644
index 00000000000..f55e1b20c33
--- /dev/null
+++ b/test/DebugInfo/X86/atomic-c11-dwarf-4.ll
@@ -0,0 +1,36 @@
+; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; REQUIRES: object-emission
+
+; Generated by clang -c -g -std=c11 -S -emit-llvm from the following C11 source
+;
+; _Atomic const int i;
+;
+
+; CHECK: DW_TAG_variable
+; CHECK: DW_TAG_const_type
+; CHECK-NOT: DW_TAG_atomic_type
+; CHECK: DW_TAG_base_type
+
+; ModuleID = 'atomic.c'
+source_filename = "atomic.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@i = common global i32 0, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!9, !10}
+!llvm.ident = !{!11}
+
+!0 = distinct !DIGlobalVariable(name: "i", scope: !1, file: !5, line: 1, type: !6, isLocal: false, isDefinition: true)
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git cd238117e3a8a57271a82d0bb03d6df6ad8f073e) (http://llvm.org/git/llvm.git 9fd063832c1541aad3907cd60ac344d36997905f)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
+!2 = !DIFile(filename: "atomic.c", directory: "/tmp")
+!3 = !{}
+!4 = !{!0}
+!5 = !DIFile(filename: "atomic.c", directory: "/tmp")
+!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
+!7 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !8)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!9 = !{i32 2, !"Dwarf Version", i32 4}
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git cd238117e3a8a57271a82d0bb03d6df6ad8f073e) (http://llvm.org/git/llvm.git 9fd063832c1541aad3907cd60ac344d36997905f)"}
diff --git a/test/DebugInfo/X86/atomic-c11-dwarf-5.ll b/test/DebugInfo/X86/atomic-c11-dwarf-5.ll
new file mode 100644
index 00000000000..d450a3bb13f
--- /dev/null
+++ b/test/DebugInfo/X86/atomic-c11-dwarf-5.ll
@@ -0,0 +1,37 @@
+; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; REQUIRES: object-emission
+
+; Generated by clang -c -g -std=c11 -S -emit-llvm from the following C11 source
+;
+; _Atomic const int i;
+;
+
+; CHECK: DW_TAG_variable
+; CHECK: DW_TAG_const_type
+; CHECK: DW_TAG_atomic_type
+; CHECK-NOT: NULL
+; CHECK: DW_TAG_base_type
+
+; ModuleID = 'atomic.c'
+source_filename = "atomic.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@i = common global i32 0, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!9, !10}
+!llvm.ident = !{!11}
+
+!0 = distinct !DIGlobalVariable(name: "i", scope: !1, file: !5, line: 1, type: !6, isLocal: false, isDefinition: true)
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git cd238117e3a8a57271a82d0bb03d6df6ad8f073e) (http://llvm.org/git/llvm.git 9fd063832c1541aad3907cd60ac344d36997905f)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
+!2 = !DIFile(filename: "atomic.c", directory: "/tmp")
+!3 = !{}
+!4 = !{!0}
+!5 = !DIFile(filename: "atomic.c", directory: "/tmp")
+!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
+!7 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !8)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!9 = !{i32 2, !"Dwarf Version", i32 5}
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git cd238117e3a8a57271a82d0bb03d6df6ad8f073e) (http://llvm.org/git/llvm.git 9fd063832c1541aad3907cd60ac344d36997905f)"}
diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp
index 778c76043ae..9c446f4a036 100644
--- a/tools/dsymutil/DwarfLinker.cpp
+++ b/tools/dsymutil/DwarfLinker.cpp
@@ -2666,6 +2666,7 @@ static bool isTypeTag(uint16_t Tag) {
   case dwarf::DW_TAG_packed_type:
   case dwarf::DW_TAG_volatile_type:
   case dwarf::DW_TAG_restrict_type:
+  case dwarf::DW_TAG_atomic_type:
   case dwarf::DW_TAG_interface_type:
   case dwarf::DW_TAG_unspecified_type:
   case dwarf::DW_TAG_shared_type: