// CHECK-NEXT: DW_AT_name{{.*}}"Foo"
// CHECK-NOT: DW_TAG
// CHECK: DW_TAG_typedef
+// CHECK-NOT: DW_TAG
+// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]])
+// CHECK: DW_TAG_structure_type
+// CHECK-NEXT: DW_AT_name{{.*}}"S"
+// CHECK-NOT: DW_TAG
+// CHECK: 0x0[[INTERFACE:.*]]: DW_TAG_structure_type
+// CHECK-NEXT: DW_AT_name{{.*}}"Foo"
@import Bar;
typedef struct Bar Bar;
#else
// ---------------------------------------------------------------------
-// CHECK: DW_TAG_compile_unit
-// CHECK: DW_TAG_module
-// CHECK-NEXT: DW_AT_name{{.*}}"Bar"
+// CHECK: DW_TAG_compile_unit
+// CHECK: DW_AT_low_pc
+// CHECK-NOT:DW_TAG
// CHECK: DW_TAG_module
// CHECK-NEXT: DW_AT_name{{.*}}"Foo"
// CHECK-NOT: DW_TAG
// CHECK: DW_TAG_typedef
// CHECK-NOT: DW_TAG
-// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]])
-// CHECK: 0x0[[INTERFACE:.*]]: DW_TAG_structure_type
-// CHECK-NOT: DW_TAG
-// CHECK: DW_AT_name{{.*}}"Foo"
-
+// CHECK: NULL
//
// CHECK: DW_TAG_imported_declaration
// CHECK-NOT: DW_TAG
Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr))
continue;
- Info.Prune = false;
+ // Keep a module forward declaration if there is no definition.
+ if (!(isODRAttribute(AttrSpec.Attr) && Info.Ctxt &&
+ Info.Ctxt->getCanonicalDIEOffset()))
+ Info.Prune = false;
+
unsigned ODRFlag = UseODR ? TF_ODR : 0;
lookForDIEsToKeep(RelocMgr, *RefDIE, DMO, *ReferencedCU,
TF_Keep | TF_DependencyWalk | ODRFlag);
Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset);
}
+ // Determine whether there are any children that we want to keep.
+ bool HasChildren = false;
+ for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL();
+ Child = Child->getSibling()) {
+ unsigned Idx = U.getDIEIndex(Child);
+ if (Unit.getInfo(Idx).Keep) {
+ HasChildren = true;
+ break;
+ }
+ }
+
DIEAbbrev NewAbbrev = Die->generateAbbrev();
- // If a scope DIE is kept, we must have kept at least one child. If
- // it's not the case, we'll just be emitting one wasteful end of
- // children marker, but things won't break.
- if (InputDIE.hasChildren())
+ if (HasChildren)
NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
// Assign a permanent abbrev number
Linker.AssignAbbrev(NewAbbrev);
// Add the size of the abbreviation number to the output offset.
OutOffset += getULEB128Size(Die->getAbbrevNumber());
- if (!Abbrev->hasChildren()) {
+ if (!HasChildren) {
// Update our size.
Die->setSize(OutOffset - Die->getOffset());
return Die;