<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 11, 2015 at 9:45 AM, Adrian Prantl <span dir="ltr"><<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: adrian<br>
Date: Wed Feb 11 11:45:15 2015<br>
New Revision: 228855<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228855&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228855&view=rev</a><br>
Log:<br>
Fix PR19351. While building up a composite type it is important to use<br>
a non-uniqueable temporary node that is only turned into a permanent<br>
unique or distinct node after it is finished.<br>
Otherwise an intermediate node may get accidentally uniqued with another<br>
node as illustrated by the testcase.<br></blockquote><div><br>Awesome - thanks!<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Paired commit with LLVM.<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGen/debug-info-same-line.c<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=228855&r1=228854&r2=228855&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=228855&r1=228854&r2=228855&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Feb 11 11:45:15 2015<br>
@@ -621,6 +621,21 @@ static SmallString<256> getUniqueTagType<br>
   return FullName;<br>
 }<br>
<br>
+static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {<br>
+   llvm::dwarf::Tag Tag;<br>
+  if (RD->isStruct() || RD->isInterface())<br>
+    Tag = llvm::dwarf::DW_TAG_structure_type;<br>
+  else if (RD->isUnion())<br>
+    Tag = llvm::dwarf::DW_TAG_union_type;<br>
+  else {<br>
+    // FIXME: This could be a struct type giving a default visibility different<br>
+    // than C++ class type, but needs llvm metadata changes first.<br>
+    assert(RD->isClass());<br>
+    Tag = llvm::dwarf::DW_TAG_class_type;<br>
+  }<br>
+  return Tag;<br>
+}<br>
+<br>
 // Creates a forward declaration for a RecordDecl in the given context.<br>
 llvm::DICompositeType<br>
 CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,<br>
@@ -632,20 +647,12 @@ CGDebugInfo::getOrCreateRecordFwdDecl(co<br>
   unsigned Line = getLineNumber(RD->getLocation());<br>
   StringRef RDName = getClassName(RD);<br>
<br>
-  llvm::dwarf::Tag Tag;<br>
-  if (RD->isStruct() || RD->isInterface())<br>
-    Tag = llvm::dwarf::DW_TAG_structure_type;<br>
-  else if (RD->isUnion())<br>
-    Tag = llvm::dwarf::DW_TAG_union_type;<br>
-  else {<br>
-    assert(RD->isClass());<br>
-    Tag = llvm::dwarf::DW_TAG_class_type;<br>
-  }<br>
<br>
   // Create the type.<br>
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);<br>
-  llvm::DICompositeType RetTy = DBuilder.createReplaceableForwardDecl(<br>
-      Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, FullName);<br>
+  llvm::DICompositeType RetTy = DBuilder.createReplaceableCompositeType(<br>
+      getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, 0, 0,<br>
+      llvm::DIDescriptor::FlagFwdDecl, FullName);<br>
   ReplaceMap.emplace_back(<br>
       std::piecewise_construct, std::make_tuple(Ty),<br>
       std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));<br>
@@ -1567,7 +1574,8 @@ llvm::DIType CGDebugInfo::CreateTypeDefi<br>
   assert(FwdDecl.isCompositeType() &&<br>
          "The debug type of a RecordType should be a llvm::DICompositeType");<br>
<br>
-  if (FwdDecl.isForwardDecl())<br>
+  const RecordDecl *D = RD->getDefinition();<br>
+  if (!D || !D->isCompleteDefinition())<br>
     return FwdDecl;<br>
<br>
   if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))<br>
@@ -1602,6 +1610,10 @@ llvm::DIType CGDebugInfo::CreateTypeDefi<br>
   llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);<br>
   DBuilder.replaceArrays(FwdDecl, Elements);<br>
<br>
+  if (FwdDecl->isTemporary())<br>
+    FwdDecl = llvm::DICompositeType(llvm::MDNode::replaceWithPermanent(<br>
+      llvm::TempMDNode(FwdDecl.get())));<br>
+<br>
   RegionMap[Ty->getDecl()].reset(FwdDecl);<br>
   return FwdDecl;<br>
 }<br>
@@ -1653,7 +1665,7 @@ llvm::DIType CGDebugInfo::CreateType(con<br>
   // debug type since we won't be able to lay out the entire type.<br>
   ObjCInterfaceDecl *Def = ID->getDefinition();<br>
   if (!Def || !Def->getImplementation()) {<br>
-    llvm::DIType FwdDecl = DBuilder.createReplaceableForwardDecl(<br>
+    llvm::DIType FwdDecl = DBuilder.createReplaceableCompositeType(<br>
         llvm::dwarf::DW_TAG_structure_type, ID->getName(), TheCU, DefUnit, Line,<br>
         RuntimeLang);<br>
     ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));<br>
@@ -1933,9 +1945,9 @@ llvm::DIType CGDebugInfo::CreateEnumType<br>
     llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());<br>
     unsigned Line = getLineNumber(ED->getLocation());<br>
     StringRef EDName = ED->getName();<br>
-    llvm::DIType RetTy = DBuilder.createReplaceableForwardDecl(<br>
+    llvm::DIType RetTy = DBuilder.createReplaceableCompositeType(<br>
         llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,<br>
-        0, Size, Align, FullName);<br>
+        0, Size, Align, llvm::DIDescriptor::FlagFwdDecl, FullName);<br>
     ReplaceMap.emplace_back(<br>
         std::piecewise_construct, std::make_tuple(Ty),<br>
         std::make_tuple(static_cast<llvm::Metadata *>(RetTy)));<br>
@@ -2249,19 +2261,8 @@ llvm::DICompositeType CGDebugInfo::Creat<br>
<br>
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);<br>
<br>
-  if (RD->isUnion())<br>
-    RealDecl = DBuilder.createUnionType(RDContext, RDName, DefUnit, Line, Size,<br>
-                                        Align, 0, llvm::DIArray(), 0, FullName);<br>
-  else if (RD->isClass()) {<br>
-    // FIXME: This could be a struct type giving a default visibility different<br>
-    // than C++ class type, but needs llvm metadata changes first.<br>
-    RealDecl = DBuilder.createClassType(<br>
-        RDContext, RDName, DefUnit, Line, Size, Align, 0, 0, llvm::DIType(),<br>
-        llvm::DIArray(), llvm::DIType(), llvm::DIArray(), FullName);<br>
-  } else<br>
-    RealDecl = DBuilder.createStructType(<br>
-        RDContext, RDName, DefUnit, Line, Size, Align, 0, llvm::DIType(),<br>
-        llvm::DIArray(), 0, llvm::DIType(), FullName);<br>
+  RealDecl = DBuilder.createReplaceableCompositeType(getTagForRecord(RD),<br>
+      RDName, RDContext, DefUnit, Line, 0, Size, Align, 0, FullName);<br>
<br>
   RegionMap[Ty->getDecl()].reset(RealDecl);<br>
   TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);<br>
<br>
Added: cfe/trunk/test/CodeGen/debug-info-same-line.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-same-line.c?rev=228855&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-same-line.c?rev=228855&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/debug-info-same-line.c (added)<br>
+++ cfe/trunk/test/CodeGen/debug-info-same-line.c Wed Feb 11 11:45:15 2015<br>
@@ -0,0 +1,7 @@<br>
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -g -o - | FileCheck %s<br>
+// Here two temporary nodes are identical (but should not get uniqued) while<br>
+// building the full debug type.<br>
+typedef struct { long x; } foo; typedef struct {  foo *x; } bar;<br>
+// CHECK: [ DW_TAG_structure_type ] [line 4, size 64,<br>
+// CHECK: [ DW_TAG_structure_type ] [line 4, size 64,<br>
+bar b;<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>