<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 1, 2013 at 12:52 PM, Manman Ren <span dir="ltr"><<a href="mailto:manman.ren@gmail.com" target="_blank">manman.ren@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mren<br>
Date: Tue Oct 1 14:52:23 2013<br>
New Revision: 191792<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191792&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191792&view=rev</a><br>
Log:<br>
Debug Info: remove duplication of DIEs when a DIE is part of the type system<br>
and it is shared across CUs.<br></blockquote><div><br></div><div>This may require some discussion/consideration.</div><div><br></div><div>The first thing that comes to my mind is that this is changing the DIE structure from trees to DAGs and, perhaps importantly, is going to make parent/child relationships incomplete (ie: A child of B no longer implies that B is the parent of A) which is a bit concerning.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
We add a few maps in DwarfDebug to map MDNodes for the type system to the<br>
corresponding DIEs: MDTypeNodeToDieMap, MDSPNodeToDieMap, and<br>
MDStaticMemberNodeToDieMap. These DIEs can be shared across CUs, that is why we<br>
keep the maps in DwarfDebug instead of CompileUnit.<br></blockquote><div><br></div><div>Why nod simply map MDNode* to DIE the same as we do in the CompileUnit? We should be able to do this for all DIEs, no? (essentially just move the map up from CompileUnit to DwarfDebug)<br>
<br>But I'm not sure how effective this would be - like I said, might need some thought/discussion to understand your solution & consider alternatives.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Sometimes, when we try to add an attribute to a DIE, the DIE is not yet added<br>
to its owner yet, so we don't know whether we should use ref_addr or ref4.<br>
We create a worklist that will be processed during finalization to add<br>
attributes with the correct form (ref_addr or ref4).<br></blockquote><div><br></div><div>Do you have an example of this as a test case? (I really wish we had an easy way to see test coverage - so I could just tell at a glance whether the worklist code is being exercised by your test cases... oh well)</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
We add addDIEEntry to DwarfDebug to be a wrapper around DIE->addValue. It checks<br>
whether we know the correct form, if not, we update the worklist<br>
(DIEEntryWorklist).<br>
<br>
A testing case is added to show that we only create a single DIE for a type<br>
MDNode and we use ref_addr to refer to the type DIE.<br>
<br>
Modified:<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
llvm/trunk/test/Linker/type-unique-simple-a.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp Tue Oct 1 14:52:23 2013<br>
@@ -113,13 +113,21 @@ DIE::~DIE() {<br>
/// Climb up the parent chain to get the compile unit DIE to which this DIE<br>
/// belongs.<br>
DIE *DIE::getCompileUnit() {<br>
+ DIE *Cu = checkCompileUnit();<br>
+ assert(Cu && "We should not have orphaned DIEs.");<br>
+ return Cu;<br>
+}<br>
+<br>
+/// Climb up the parent chain to get the compile unit DIE this DIE belongs<br>
+/// to. Return NULL if DIE is not added to an owner yet.<br>
+DIE *DIE::checkCompileUnit() {<br>
DIE *p = this;<br>
while (p) {<br>
if (p->getTag() == dwarf::DW_TAG_compile_unit)<br>
return p;<br>
p = p->getParent();<br>
}<br>
- llvm_unreachable("We should not have orphaned DIEs.");<br>
+ return NULL; </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
}<br>
<br>
DIEValue *DIE::findAttribute(uint16_t Attribute) {<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h Tue Oct 1 14:52:23 2013<br>
@@ -152,6 +152,9 @@ namespace llvm {<br>
/// Climb up the parent chain to get the compile unit DIE this DIE belongs<br>
/// to.<br>
DIE *getCompileUnit();<br>
+ /// Similar to getCompileUnit, returns null when DIE is not added to an<br>
+ /// owner yet.<br>
+ DIE *checkCompileUnit();<br></blockquote><div><br></div><div>Why is this not just "getParent() == NULL"? Why do you need a walk for the DIE?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
void setTag(uint16_t Tag) { Abbrev.setTag(Tag); }<br>
void setOffset(unsigned O) { Offset = O; }<br>
void setSize(unsigned S) { Size = S; }<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Oct 1 14:52:23 2013<br>
@@ -242,7 +242,7 @@ void CompileUnit::addDelta(DIE *Die, uin<br>
///<br>
void CompileUnit::addDIEEntry(DIE *Die, uint16_t Attribute, uint16_t Form,<br>
DIE *Entry) {<br>
- Die->addValue(Attribute, Form, createDIEEntry(Entry));<br>
+ DD->addDIEEntry(Die, Attribute, Form, createDIEEntry(Entry));<br>
}<br>
<br>
/// addBlock - Add block data.<br>
@@ -784,13 +784,13 @@ DIE *CompileUnit::getOrCreateTypeDIE(con<br>
DIType Ty(TyNode);<br>
if (!Ty.isType())<br>
return NULL;<br>
- DIE *TyDIE = getDIE(Ty);<br>
+ DIE *TyDIE = DD->getTypeDIE(Ty);<br>
if (TyDIE)<br>
return TyDIE;<br>
<br>
// Create new type.<br>
TyDIE = new DIE(dwarf::DW_TAG_base_type);<br>
- insertDIE(Ty, TyDIE);<br>
+ DD->insertTypeDIE(Ty, TyDIE);<br>
if (Ty.isBasicType())<br>
constructTypeDIE(*TyDIE, DIBasicType(Ty));<br>
else if (Ty.isCompositeType())<br>
@@ -826,7 +826,7 @@ void CompileUnit::addType(DIE *Entity, D<br>
DIEEntry *Entry = getDIEEntry(Ty);<br>
// If it exists then use the existing value.<br>
if (Entry) {<br>
- Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);<br>
+ DD->addDIEEntry(Entity, Attribute, dwarf::DW_FORM_ref4, Entry);<br>
return;<br>
}<br>
<br>
@@ -836,7 +836,7 @@ void CompileUnit::addType(DIE *Entity, D<br>
// Set up proxy.<br>
Entry = createDIEEntry(Buffer);<br>
insertDIEEntry(Ty, Entry);<br>
- Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);<br>
+ DD->addDIEEntry(Entity, Attribute, dwarf::DW_FORM_ref4, Entry);<br>
<br>
// If this is a complete composite type then include it in the<br>
// list of global types.<br>
@@ -1268,14 +1268,14 @@ DIE *CompileUnit::getOrCreateNameSpace(D<br>
<br>
/// getOrCreateSubprogramDIE - Create new DIE using SP.<br>
DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {<br>
- DIE *SPDie = getDIE(SP);<br>
+ DIE *SPDie = DD->getSPDIE(SP);<br>
if (SPDie)<br>
return SPDie;<br>
<br>
SPDie = new DIE(dwarf::DW_TAG_subprogram);<br>
<br>
// DW_TAG_inlined_subroutine may refer to this DIE.<br>
- insertDIE(SP, SPDie);<br>
+ DD->insertSPDIE(SP, SPDie);<br>
<br>
DISubprogram SPDecl = SP.getFunctionDeclaration();<br>
DIE *DeclDie = NULL;<br>
@@ -1422,7 +1422,7 @@ void CompileUnit::createGlobalVariableDI<br>
// But that class might not exist in the DWARF yet.<br>
// Creating the class will create the static member decl DIE.<br>
getOrCreateContextDIE(DD->resolve(SDMDecl.getContext()));<br>
- VariableDIE = getDIE(SDMDecl);<br>
+ VariableDIE = DD->getStaticMemberDIE(SDMDecl);<br>
assert(VariableDIE && "Static member decl has no context?");<br>
IsStaticMember = true;<br>
}<br>
@@ -1616,7 +1616,7 @@ void CompileUnit::constructContainingTyp<br>
DIE *SPDie = CI->first;<br>
const MDNode *N = CI->second;<br>
if (!N) continue;<br>
- DIE *NDie = getDIE(N);<br>
+ DIE *NDie = DD->getTypeDIE(N);<br>
if (!NDie) continue;<br>
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);<br>
}<br>
@@ -1819,6 +1819,6 @@ DIE *CompileUnit::createStaticMemberDIE(<br>
if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT.getConstant()))<br>
addConstantFPValue(StaticMemberDIE, CFP);<br>
<br>
- insertDIE(DT, StaticMemberDIE);<br>
+ DD->insertStaticMemberDIE(DT, StaticMemberDIE);<br>
return StaticMemberDIE;<br>
}<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Oct 1 14:52:23 2013<br>
@@ -357,7 +357,7 @@ bool DwarfDebug::isSubprogramContext(con<br>
// scope then create and insert DIEs for these variables.<br>
DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU,<br>
const MDNode *SPNode) {<br>
- DIE *SPDie = SPCU->getDIE(SPNode);<br>
+ DIE *SPDie = getSPDIE(SPNode);<br>
<br>
assert(SPDie && "Unable to find subprogram DIE!");<br>
DISubprogram SP(SPNode);<br>
@@ -511,7 +511,7 @@ DIE *DwarfDebug::constructInlinedScopeDI<br>
return NULL;<br>
DIScope DS(Scope->getScopeNode());<br>
DISubprogram InlinedSP = getDISubprogram(DS);<br>
- DIE *OriginDIE = TheCU->getDIE(InlinedSP);<br>
+ DIE *OriginDIE = getSPDIE(InlinedSP);<br>
if (!OriginDIE) {<br>
DEBUG(dbgs() << "Unable to find original DIE for an inlined subprogram.");<br>
return NULL;<br>
@@ -616,7 +616,7 @@ DIE *DwarfDebug::constructScopeDIE(Compi<br>
else if (DS.isSubprogram()) {<br>
ProcessedSPNodes.insert(DS);<br>
if (Scope->isAbstractScope()) {<br>
- ScopeDIE = TheCU->getDIE(DS);<br>
+ ScopeDIE = getSPDIE(DS);<br>
// Note down abstract DIE.<br>
if (ScopeDIE)<br>
AbstractSPDies.insert(std::make_pair(DS, ScopeDIE));<br>
@@ -992,7 +992,7 @@ void DwarfDebug::collectDeadVariables()<br>
CompileUnit *SPCU = CUMap.lookup(TheCU);<br>
assert(SPCU && "Unable to find Compile Unit!");<br>
constructSubprogramDIE(SPCU, SP);<br>
- DIE *ScopeDIE = SPCU->getDIE(SP);<br>
+ DIE *ScopeDIE = getSPDIE(SP);<br>
for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {<br>
DIVariable DV(Variables.getElement(vi));<br>
if (!DV.isVariable()) continue;<br>
@@ -1065,6 +1065,15 @@ void DwarfDebug::finalizeModuleInfo() {<br>
Hash.computeDIEODRSignature(Die));<br>
}<br>
<br>
+ // Process the worklist to add attributes with the correct form (ref_addr or<br>
+ // ref4).<br>
+ for (unsigned I = 0, E = DIEEntryWorklist.size(); I < E; I++) {<br>
+ addDIEEntry(DIEEntryWorklist[I].Die, DIEEntryWorklist[I].Attribute,<br>
+ dwarf::DW_FORM_ref4, DIEEntryWorklist[I].Entry);<br>
+ assert(E == DIEEntryWorklist.size() &&<br>
+ "We should not add to the worklist during finalization.");<br>
+ }<br>
+<br>
// Handle anything that needs to be done on a per-cu basis.<br>
for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),<br>
CUE = CUMap.end();<br>
@@ -2042,7 +2051,11 @@ void DwarfDebug::emitDIE(DIE *Die, std::<br>
Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));<br>
<br>
switch (Attr) {<br>
- case dwarf::DW_AT_abstract_origin: {<br>
+ case dwarf::DW_AT_abstract_origin:<br>
+ case dwarf::DW_AT_type:<br>
+ case dwarf::DW_AT_friend:<br>
+ case dwarf::DW_AT_specification:<br>
+ case dwarf::DW_AT_containing_type: {<br>
DIEEntry *E = cast<DIEEntry>(Values[i]);<br>
DIE *Origin = E->getEntry();<br>
unsigned Addr = Origin->getOffset();<br>
@@ -3031,3 +3044,24 @@ void DwarfDebug::emitDebugStrDWO() {<br>
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),<br>
OffSec, StrSym);<br>
}<br>
+<br>
+/// When we don't know whether the correct form is ref4 or ref_addr, we create<br>
+/// a worklist item and insert it to DIEEntryWorklist.<br>
+void DwarfDebug::addDIEEntry(DIE *Die, uint16_t Attribute, uint16_t Form,<br>
+ DIEEntry *Entry) {<br>
+ /// Early exit when we only have a single CU.<br>
+ if (GlobalCUIndexCount == 1 || Form != dwarf::DW_FORM_ref4) {<br>
+ Die->addValue(Attribute, Form, Entry);<br>
+ return;<br>
+ }<br>
+ DIE *DieCU = Die->checkCompileUnit();<br>
+ DIE *EntryCU = Entry->getEntry()->checkCompileUnit();<br>
+ if (!DieCU || !EntryCU) {<br>
+ // Die or Entry is not added to an owner yet.<br>
+ insertDIEEntryWorklist(Die, Attribute, Entry);<br>
+ return;<br>
+ }<br>
+ Die->addValue(Attribute,<br>
+ EntryCU == DieCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,<br>
+ Entry);<br>
+}<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Oct 1 14:52:23 2013<br>
@@ -326,6 +326,30 @@ class DwarfDebug {<br>
// Maps subprogram MDNode with its corresponding CompileUnit.<br>
DenseMap <const MDNode *, CompileUnit *> SPMap;<br>
<br>
+ /// Maps type MDNode with its corresponding DIE. These DIEs can be<br>
+ /// shared across CUs, that is why we keep the map here instead<br>
+ /// of in CompileUnit.<br>
+ DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap;<br>
+ /// Maps subprogram MDNode with its corresponding DIE.<br>
+ DenseMap<const MDNode *, DIE *> MDSPNodeToDieMap;<br>
+ /// Maps static member MDNode with its corresponding DIE.<br>
+ DenseMap<const MDNode *, DIE *> MDStaticMemberNodeToDieMap;<br>
+<br>
+ /// Specifies a worklist item. Sometimes, when we try to add an attribute to<br>
+ /// a DIE, the DIE is not yet added to its owner yet, so we don't know whether<br>
+ /// we should use ref_addr or ref4. We create a worklist that will be<br>
+ /// processed during finalization to add attributes with the correct form<br>
+ /// (ref_addr or ref4).<br>
+ struct DIEEntryWorkItem {<br>
+ DIE *Die;<br>
+ uint16_t Attribute;<br>
+ DIEEntry *Entry;<br>
+ DIEEntryWorkItem(DIE *D, uint16_t A, DIEEntry *E) :<br>
+ Die(D), Attribute(A), Entry(E) {<br>
+ }<br>
+ };<br>
+ SmallVector<DIEEntryWorkItem, 64> DIEEntryWorklist;<br>
+<br>
// Used to uniquely define abbreviations.<br>
FoldingSet<DIEAbbrev> AbbreviationsSet;<br>
<br>
@@ -660,6 +684,28 @@ public:<br>
DwarfDebug(AsmPrinter *A, Module *M);<br>
~DwarfDebug();<br>
<br>
+ void insertTypeDIE(const MDNode *TypeMD, DIE *Die) {<br>
+ MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));<br>
+ }<br>
+ DIE *getTypeDIE(const MDNode *TypeMD) {<br>
+ return MDTypeNodeToDieMap.lookup(TypeMD);<br>
+ }<br>
+ void insertSPDIE(const MDNode *SPMD, DIE *Die) {<br>
+ MDSPNodeToDieMap.insert(std::make_pair(SPMD, Die));<br>
+ }<br>
+ DIE *getSPDIE(const MDNode *SPMD) {<br>
+ return MDSPNodeToDieMap.lookup(SPMD);<br>
+ }<br>
+ void insertStaticMemberDIE(const MDNode *StaticMD, DIE *Die) {<br>
+ MDStaticMemberNodeToDieMap.insert(std::make_pair(StaticMD, Die));<br>
+ }<br>
+ DIE *getStaticMemberDIE(const MDNode *StaticMD) {<br>
+ return MDStaticMemberNodeToDieMap.lookup(StaticMD);<br>
+ }<br>
+ void insertDIEEntryWorklist(DIE *Die, uint16_t Attribute, DIEEntry *Entry) {<br>
+ DIEEntryWorklist.push_back(DIEEntryWorkItem(Die, Attribute, Entry));<br>
+ }<br>
+<br>
/// \brief Emit all Dwarf sections that should come prior to the<br>
/// content.<br>
void beginModule();<br>
@@ -722,6 +768,11 @@ public:<br>
return Ref.resolve(TypeIdentifierMap);<br>
}<br>
<br>
+ /// When we don't know whether the correct form is ref4 or ref_addr, we create<br>
+ /// a worklist item and insert it to DIEEntryWorklist.<br>
+ void addDIEEntry(DIE *Die, uint16_t Attribute, uint16_t Form,<br>
+ DIEEntry *Entry);<br>
+<br>
/// isSubprogramContext - Return true if Context is either a subprogram<br>
/// or another context nested inside a subprogram.<br>
bool isSubprogramContext(const MDNode *Context);<br>
<br>
Modified: llvm/trunk/test/Linker/type-unique-simple-a.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple-a.ll?rev=191792&r1=191791&r2=191792&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-simple-a.ll?rev=191792&r1=191791&r2=191792&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Linker/type-unique-simple-a.ll (original)<br>
+++ llvm/trunk/test/Linker/type-unique-simple-a.ll Tue Oct 1 14:52:23 2013<br>
@@ -1,7 +1,22 @@<br>
-; RUN: llvm-link %s %p/type-unique-simple-b.ll -S -o - | FileCheck %s<br>
+; REQUIRES: object-emission<br>
<br>
-; CHECK: DW_TAG_structure_type<br>
+; RUN: llvm-link %s %p/type-unique-simple-b.ll -S -o %t<br>
+; RUN: cat %t | FileCheck %s -check-prefix=LINK<br>
+; RUN: llc -filetype=obj -O0 < %t > %t2<br>
+; RUN: llvm-dwarfdump -debug-dump=info %t2 | FileCheck %s<br>
+; CHECK: 0x[[INT:.*]]: DW_TAG_base_type<br>
+; CHECK-NEXT: DW_AT_name {{.*}} = "int"<br>
+; CHECK-NOT: DW_TAG_base_type<br>
+; CHECK: 0x[[BASE:.*]]: DW_TAG_structure_type<br>
+; CHECK-NEXT: DW_AT_name {{.*}} = "Base"<br>
; CHECK-NOT: DW_TAG_structure_type<br>
+; CHECK: DW_TAG_formal_parameter<br>
+; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[INT]])<br>
+; CHECK: DW_TAG_variable<br>
+; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[BASE]])<br>
+<br>
+; LINK: DW_TAG_structure_type<br>
+; LINK-NOT: DW_TAG_structure_type<br>
; Content of header files:<br>
; struct Base {<br>
; int a;<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>