<div dir="ltr">Can you comment on this a bit more now? Also, FWIW, gcc (and we're using it) use a different kind of format that includes some useful information in lookup tables that we might want to support outputting. Also, why have the tool able to output pubnames/pubtypes at all. I don't think lldb is using it?<br><div><br></div><div>-eric</div></div><br><div class="gmail_quote">On Sun, Mar 15, 2015 at 7:10 PM Frederic Riss <<a href="mailto:friss@apple.com">friss@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: friss<br>
Date: Sun Mar 15 21:05:10 2015<br>
New Revision: 232342<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=232342&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=232342&view=rev</a><br>
Log:<br>
[dsymutil] Add support to generate .debug_pubnames and .debug_pubtypes<br>
<br>
The information gathering part of the patch stores a bit more information<br>
than what is strictly necessary for these 2 sections. The rest will<br>
become useful when we start emitting __apple_* type accelerator tables.<br>
<br>
Modified:<br>
    llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-linking-<u></u>x86.test<br>
    llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-dw4-<u></u>linking-x86.test<br>
    llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-<u></u>linking-x86.test<br>
    llvm/trunk/tools/dsymutil/<u></u>DwarfLinker.cpp<br>
<br>
Modified: llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-linking-<u></u>x86.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test?rev=232342&r1=232341&r2=232342&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-linking-<u></u>x86.test?rev=232342&r1=232341&<u></u>r2=232342&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-linking-<u></u>x86.test (original)<br>
+++ llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-linking-<u></u>x86.test Sun Mar 15 21:05:10 2015<br>
@@ -186,4 +186,32 @@ CHECK-NEXT: 0x0000000100000f7b     20<br>
 CHECK-NEXT: 0x0000000100000f84     20      0      1   0             0  is_stmt end_sequence<br>
 CHECK-NEXT: 0x0000000100000f90     11      0      1   0             0  is_stmt<br>
 CHECK-NEXT: 0x0000000100000f9b     12      0      1   0             0  is_stmt prologue_end<br>
-CHECK-NEXT: 0x0000000100000fa9     12      0      1   0             0  is_stmt end_sequence<br>
\ No newline at end of file<br>
+CHECK-NEXT: 0x0000000100000fa9     12      0      1   0             0  is_stmt end_sequence<br>
+<br>
+CHECK: .debug_pubnames contents:<br>
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "main"<br>
+CHECK-NEXT: length = 0x00000036 version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000a5<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x0000002d "private_int"<br>
+CHECK-NEXT: 0x00000042 "baz"<br>
+CHECK-NEXT: 0x00000057 "foo"<br>
+CHECK-NEXT: 0x00000086 "inc"<br>
+CHECK-NEXT: length = 0x00000026 version = 0x0002 unit_offset = 0x00000126 unit_size = 0x00000096<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "val"<br>
+CHECK-NEXT: 0x00000048 "bar"<br>
+CHECK-NEXT: 0x00000077 "inc"<br>
+<br>
+CHECK: .debug_pubtypes contents:<br>
+CHECK-NEXT: length = 0x0000001f version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000063 "int"<br>
+CHECK-NEXT: 0x00000079 "char"<br>
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000a5<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "int"<br>
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000126 unit_size = 0x00000096<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000041 "int"<br>
<br>
Modified: llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-dw4-<u></u>linking-x86.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-dw4-linking-x86.test?rev=232342&r1=232341&r2=232342&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-dw4-<u></u>linking-x86.test?rev=232342&<u></u>r1=232341&r2=232342&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-dw4-<u></u>linking-x86.test (original)<br>
+++ llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-dw4-<u></u>linking-x86.test Sun Mar 15 21:05:10 2015<br>
@@ -179,3 +179,25 @@ CHECK-NEXT: 0x0000000100000fa9     19<br>
 CHECK-NEXT: 0x0000000100000fab     19     10      1   0             0<br>
 CHECK-NEXT: 0x0000000100000fb2     20      1      1   0             0  is_stmt<br>
 CHECK-NEXT: 0x0000000100000fb4     20      1      1   0             0  is_stmt end_sequence<br>
+<br>
+CHECK: .debug_pubnames contents:<br>
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000077<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x0000002a "main"<br>
+CHECK-NEXT: length = 0x0000002e version = 0x0002 unit_offset = 0x00000077 unit_size = 0x000000a4<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000031 "baz"<br>
+CHECK-NEXT: 0x00000046 "private_int"<br>
+CHECK-NEXT: 0x00000067 "foo"<br>
+CHECK-NEXT: length = 0x0000001e version = 0x0002 unit_offset = 0x0000011b unit_size = 0x00000085<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x0000002a "val"<br>
+CHECK-NEXT: 0x00000050 "bar"<br>
+<br>
+CHECK: .debug_pubtypes contents:<br>
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000077<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x0000006f "char"<br>
+CHECK-NEXT: length = 0x00000016 version = 0x0002 unit_offset = 0x00000077 unit_size = 0x000000a4<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x0000002a "int"<br>
<br>
Modified: llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-<u></u>linking-x86.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test?rev=232342&r1=232341&r2=232342&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-<u></u>linking-x86.test?rev=232342&<u></u>r1=232341&r2=232342&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-<u></u>linking-x86.test (original)<br>
+++ llvm/trunk/test/tools/<u></u>dsymutil/X86/basic-lto-<u></u>linking-x86.test Sun Mar 15 21:05:10 2015<br>
@@ -184,3 +184,23 @@ CHECK-NEXT: 0x0000000100000fa7     20<br>
 CHECK-NEXT: 0x0000000100000fa9     19      0      1   0             0  is_stmt<br>
 CHECK-NEXT: 0x0000000100000fb2     20      0      1   0             0  is_stmt<br>
 CHECK-NEXT: 0x0000000100000fb4     20      0      1   0             0  is_stmt end_sequence<br>
+<br>
+CHECK: .debug_pubnames contents:<br>
+CHECK-NEXT: length = 0x00000017 version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "main"<br>
+CHECK-NEXT: length = 0x0000002e version = 0x0002 unit_offset = 0x00000081 unit_size = 0x000000b9<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "private_int"<br>
+CHECK-NEXT: 0x0000003f "baz"<br>
+CHECK-NEXT: 0x00000058 "foo"<br>
+CHECK-NEXT: length = 0x0000001e version = 0x0002 unit_offset = 0x0000013a unit_size = 0x000000ac<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000026 "val"<br>
+CHECK-NEXT: 0x00000045 "bar"<br>
+<br>
+CHECK: .debug_pubtypes contents:<br>
+CHECK-NEXT: length = 0x0000001f version = 0x0002 unit_offset = 0x00000000 unit_size = 0x00000081<br>
+CHECK-NEXT: Offset     Name<br>
+CHECK-NEXT: 0x00000063 "int"<br>
+CHECK-NEXT: 0x00000079 "char"<br>
<br>
Modified: llvm/trunk/tools/dsymutil/<u></u>DwarfLinker.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=232342&r1=232341&r2=232342&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/tools/<u></u>dsymutil/DwarfLinker.cpp?rev=<u></u>232342&r1=232341&r2=232342&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/tools/dsymutil/<u></u>DwarfLinker.cpp (original)<br>
+++ llvm/trunk/tools/dsymutil/<u></u>DwarfLinker.cpp Sun Mar 15 21:05:10 2015<br>
@@ -143,6 +143,30 @@ public:<br>
   /// list in the debug_loc section.<br>
   void noteLocationAttribute(<u></u>DIEInteger *Attr, int64_t PcOffset);<br>
<br>
+  /// \brief Add a name accelerator entry for \p Die with \p Name<br>
+  /// which is stored in the string table at \p Offset.<br>
+  void addNameAccelerator(const DIE *Die, const char *Name, uint32_t Offset,<br>
+                          bool SkipPubnamesSection = false);<br>
+<br>
+  /// \brief Add a type accelerator entry for \p Die with \p Name<br>
+  /// which is stored in the string table at \p Offset.<br>
+  void addTypeAccelerator(const DIE *Die, const char *Name, uint32_t Offset);<br>
+<br>
+  struct AccelInfo {<br>
+    StringRef Name; ///< Name of the entry.<br>
+    const DIE *Die; ///< DIE this entry describes.<br>
+    uint32_t NameOffset; ///< Offset of Name in the string pool.<br>
+    bool SkipPubSection; ///< Emit this entry only in the apple_* sections.<br>
+<br>
+    AccelInfo(StringRef Name, const DIE *Die, uint32_t NameOffset,<br>
+              bool SkipPubSection = false)<br>
+        : Name(Name), Die(Die), NameOffset(NameOffset),<br>
+          SkipPubSection(SkipPubSection) {}<br>
+  };<br>
+<br>
+  const std::vector<AccelInfo> &getPubnames() const { return Pubnames; }<br>
+  const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; }<br>
+<br>
 private:<br>
   DWARFUnit &OrigUnit;<br>
   unsigned ID;<br>
@@ -182,6 +206,13 @@ private:<br>
   /// along with the PC offset that is to be applied to their<br>
   /// function's address.<br>
   std::vector<std::pair<<u></u>DIEInteger *, int64_t>> LocationAttributes;<br>
+<br>
+  /// \brief Accelerator entries for the unit, both for the pub*<br>
+  /// sections and the apple* ones.<br>
+  /// @{<br>
+  std::vector<AccelInfo> Pubnames;<br>
+  std::vector<AccelInfo> Pubtypes;<br>
+  /// @}<br>
 };<br>
<br>
 uint64_t CompileUnit::<u></u>computeNextUnitOffset() {<br>
@@ -230,6 +261,20 @@ void CompileUnit::<u></u>noteLocationAttribute(<br>
   LocationAttributes.emplace_<u></u>back(Attr, PcOffset);<br>
 }<br>
<br>
+/// \brief Add a name accelerator entry for \p Die with \p Name<br>
+/// which is stored in the string table at \p Offset.<br>
+void CompileUnit::<u></u>addNameAccelerator(const DIE *Die, const char *Name,<br>
+                                     uint32_t Offset, bool SkipPubSection) {<br>
+  Pubnames.emplace_back(Name, Die, Offset, SkipPubSection);<br>
+}<br>
+<br>
+/// \brief Add a type accelerator entry for \p Die with \p Name<br>
+/// which is stored in the string table at \p Offset.<br>
+void CompileUnit::<u></u>addTypeAccelerator(const DIE *Die, const char *Name,<br>
+                                     uint32_t Offset) {<br>
+  Pubtypes.emplace_back(Name, Die, Offset, false);<br>
+}<br>
+<br>
 /// \brief A string table that doesn't need relocations.<br>
 ///<br>
 /// We are doing a final link, no need for a string table that<br>
@@ -342,6 +387,12 @@ class DwarfStreamer {<br>
   uint32_t LocSectionSize;<br>
   uint32_t LineSectionSize;<br>
<br>
+  /// \brief Emit the pubnames or pubtypes section contribution for \p<br>
+  /// Unit into \p Sec. The data is provided in \p Names.<br>
+  void emitPubSectionForUnit(const MCSection *Sec, StringRef Name,<br>
+                             const CompileUnit &Unit,<br>
+                             const std::vector<CompileUnit::<u></u>AccelInfo> &Names);<br>
+<br>
 public:<br>
   /// \brief Actually create the streamer and the ouptut file.<br>
   ///<br>
@@ -402,6 +453,12 @@ public:<br>
                             unsigned AdddressSize);<br>
<br>
   uint32_t getLineSectionSize() const { return LineSectionSize; }<br>
+<br>
+  /// \brief Emit the .debug_pubnames contribution for \p Unit.<br>
+  void emitPubNamesForUnit(const CompileUnit &Unit);<br>
+<br>
+  /// \brief Emit the .debug_pubtypes contribution for \p Unit.<br>
+  void emitPubTypesForUnit(const CompileUnit &Unit);<br>
 };<br>
<br>
 bool DwarfStreamer::init(Triple TheTriple, StringRef OutputFilename) {<br>
@@ -851,6 +908,59 @@ void DwarfStreamer::<u></u>emitLineTableForUnit<br>
   MS->EmitLabel(LineEndSym);<br>
 }<br>
<br>
+/// \brief Emit the pubnames or pubtypes section contribution for \p<br>
+/// Unit into \p Sec. The data is provided in \p Names.<br>
+void DwarfStreamer::<u></u>emitPubSectionForUnit(<br>
+    const MCSection *Sec, StringRef SecName, const CompileUnit &Unit,<br>
+    const std::vector<CompileUnit::<u></u>AccelInfo> &Names) {<br>
+  if (Names.empty())<br>
+    return;<br>
+<br>
+  // Start the dwarf pubnames section.<br>
+  Asm->OutStreamer.<u></u>SwitchSection(Sec);<br>
+  MCSymbol *BeginLabel =<br>
+      Asm->GetTempSymbol("pub" + SecName + "_begin", Unit.getUniqueID());<br>
+  MCSymbol *EndLabel =<br>
+      Asm->GetTempSymbol("pub" + SecName + "_end", Unit.getUniqueID());<br>
+<br>
+  bool HeaderEmitted = false;<br>
+  // Emit the pubnames for this compilation unit.<br>
+  for (const auto &Name : Names) {<br>
+    if (Name.SkipPubSection)<br>
+      continue;<br>
+<br>
+    if (!HeaderEmitted) {<br>
+      // Emit the header.<br>
+      Asm->EmitLabelDifference(<u></u>EndLabel, BeginLabel, 4); // Length<br>
+      Asm->OutStreamer.EmitLabel(<u></u>BeginLabel);<br>
+      Asm->EmitInt16(dwarf::DW_<u></u>PUBNAMES_VERSION); // Version<br>
+      Asm->EmitInt32(Unit.<u></u>getStartOffset()); // Unit offset<br>
+      Asm->EmitInt32(Unit.<u></u>getNextUnitOffset() - Unit.getStartOffset()); // Size<br>
+      HeaderEmitted = true;<br>
+    }<br>
+    Asm->EmitInt32(Name.Die-><u></u>getOffset());<br>
+    Asm->OutStreamer.EmitBytes(<br>
+        StringRef(Name.Name.data(), Name.Name.size() + 1));<br>
+  }<br>
+<br>
+  if (!HeaderEmitted)<br>
+    return;<br>
+  Asm->EmitInt32(0); // End marker.<br>
+  Asm->OutStreamer.EmitLabel(<u></u>EndLabel);<br>
+}<br>
+<br>
+/// \brief Emit .debug_pubnames for \p Unit.<br>
+void DwarfStreamer::<u></u>emitPubNamesForUnit(const CompileUnit &Unit) {<br>
+  emitPubSectionForUnit(MC-><u></u>getObjectFileInfo()-><u></u>getDwarfPubNamesSection(),<br>
+                        "names", Unit, Unit.getPubnames());<br>
+}<br>
+<br>
+/// \brief Emit .debug_pubtypes for \p Unit.<br>
+void DwarfStreamer::<u></u>emitPubTypesForUnit(const CompileUnit &Unit) {<br>
+  emitPubSectionForUnit(MC-><u></u>getObjectFileInfo()-><u></u>getDwarfPubTypesSection(),<br>
+                        "types", Unit, Unit.getPubtypes());<br>
+}<br>
+<br>
 /// \brief The core of the Dwarf linking logic.<br>
 ///<br>
 /// The link of the dwarf information from the object files will be<br>
@@ -989,10 +1099,19 @@ private:<br>
   /// \brief Information gathered and exchanged between the various<br>
   /// clone*Attributes helpers about the attributes of a particular DIE.<br>
   struct AttributesInfo {<br>
+    const char *Name, *MangledName;         ///< Names.<br>
+    uint32_t NameOffset, MangledNameOffset; ///< Offsets in the string pool.<br>
+<br>
     uint64_t OrigHighPc; ///< Value of AT_high_pc in the input DIE<br>
     int64_t PCOffset;    ///< Offset to apply to PC addresses inside a function.<br>
<br>
-    AttributesInfo() : OrigHighPc(0), PCOffset(0) {}<br>
+    bool HasLowPc;      ///< Does the DIE have a low_pc attribute?<br>
+    bool IsDeclaration; ///< Is this DIE only a declaration?<br>
+<br>
+    AttributesInfo()<br>
+        : Name(nullptr), MangledName(nullptr), NameOffset(0),<br>
+          MangledNameOffset(0), OrigHighPc(0), PCOffset(0), HasLowPc(false),<br>
+          IsDeclaration(false) {}<br>
   };<br>
<br>
   /// \brief Helper for cloneDIE.<br>
@@ -1026,7 +1145,7 @@ private:<br>
                                 const DWARFDebugInfoEntryMinimal &InputDIE,<br>
                                 CompileUnit &U, AttributeSpec AttrSpec,<br>
                                 const DWARFFormValue &Val, unsigned AttrSize,<br>
-                                const AttributesInfo &Info);<br>
+                                AttributesInfo &Info);<br>
<br>
   /// \brief Helper for cloneDIE.<br>
   bool applyValidRelocs(<u></u>MutableArrayRef<char> Data, uint32_t BaseOffset,<br>
@@ -1055,6 +1174,9 @@ private:<br>
   /// emit the result in the debug_line section.<br>
   void patchLineTableForUnit(<u></u>CompileUnit &Unit, DWARFContext &OrigDwarf);<br>
<br>
+  /// \brief Emit the accelerator entries for \p Unit.<br>
+  void emitAcceleratorEntriesForUnit(<u></u>CompileUnit &Unit);<br>
+<br>
   /// \brief DIELoc objects that need to be destructed (but not freed!).<br>
   std::vector<DIELoc *> DIELocs;<br>
   /// \brief DIEBlock objects that need to be destructed (but not freed!).<br>
@@ -1073,6 +1195,9 @@ private:<br>
<br>
   CompileUnit *getUnitForOffset(unsigned Offset);<br>
<br>
+  bool getDIENames(const DWARFDebugInfoEntryMinimal &Die, DWARFUnit &U,<br>
+                   AttributesInfo &Info);<br>
+<br>
   void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,<br>
                      const DWARFDebugInfoEntryMinimal *DIE = nullptr) const;<br>
<br>
@@ -1132,6 +1257,24 @@ const DWARFDebugInfoEntryMinimal *DwarfL<br>
   return nullptr;<br>
 }<br>
<br>
+/// \brief Get the potential name and mangled name for the entity<br>
+/// described by \p Die and store them in \Info if they are not<br>
+/// already there.<br>
+/// \returns is a name was found.<br>
+bool DwarfLinker::getDIENames(const DWARFDebugInfoEntryMinimal &Die,<br>
+                              DWARFUnit &U, AttributesInfo &Info) {<br>
+  // FIXME: a bit wastefull as the first getName might return the<br>
+  // short name.<br>
+  if (!Info.MangledName &&<br>
+      (Info.MangledName = Die.getName(&U, DINameKind::LinkageName)))<br>
+    Info.MangledNameOffset = StringPool.getStringOffset(<u></u>Info.MangledName);<br>
+<br>
+  if (!Info.Name && (Info.Name = Die.getName(&U, DINameKind::ShortName)))<br>
+    Info.NameOffset = StringPool.getStringOffset(<u></u>Info.Name);<br>
+<br>
+  return Info.Name || Info.MangledName;<br>
+}<br>
+<br>
 /// \brief Report a warning to the user, optionaly including<br>
 /// information about a specific \p DIE related to the warning.<br>
 void DwarfLinker::reportWarning(<u></u>const Twine &Warning, const DWARFUnit *Unit,<br>
@@ -1735,6 +1878,7 @@ unsigned DwarfLinker::<u></u>cloneAddressAttrib<br>
       if (Addr == UINT64_MAX)<br>
         return 0;<br>
     }<br>
+    Info.HasLowPc = true;<br>
   } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) {<br>
     if (Die.getTag() == dwarf::DW_TAG_compile_unit) {<br>
       if (uint64_t HighPc = Unit.getHighPc())<br>
@@ -1759,7 +1903,7 @@ unsigned DwarfLinker::<u></u>cloneAddressAttrib<br>
 unsigned DwarfLinker::<u></u>cloneScalarAttribute(<br>
     DIE &Die, const DWARFDebugInfoEntryMinimal &InputDIE, CompileUnit &Unit,<br>
     AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize,<br>
-    const AttributesInfo &Info) {<br>
+    AttributesInfo &Info) {<br>
   uint64_t Value;<br>
   if (AttrSpec.Attr == dwarf::DW_AT_high_pc &&<br>
       Die.getTag() == dwarf::DW_TAG_compile_unit) {<br>
@@ -1787,6 +1931,8 @@ unsigned DwarfLinker::<u></u>cloneScalarAttribu<br>
   else if (AttrSpec.Attr == dwarf::DW_AT_location ||<br>
            AttrSpec.Attr == dwarf::DW_AT_frame_base)<br>
     Unit.noteLocationAttribute(<u></u>Attr, Info.PCOffset);<br>
+  else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value)<br>
+    Info.IsDeclaration = true;<br>
<br>
   Die.addValue(dwarf::Attribute(<u></u>AttrSpec.Attr), dwarf::Form(AttrSpec.Form),<br>
                Attr);<br>
@@ -1886,6 +2032,39 @@ bool DwarfLinker::applyValidRelocs(<u></u>Mutab<br>
   return Applied;<br>
 }<br>
<br>
+static bool isTypeTag(uint16_t Tag) {<br>
+  switch (Tag) {<br>
+  case dwarf::DW_TAG_array_type:<br>
+  case dwarf::DW_TAG_class_type:<br>
+  case dwarf::DW_TAG_enumeration_<u></u>type:<br>
+  case dwarf::DW_TAG_pointer_type:<br>
+  case dwarf::DW_TAG_reference_type:<br>
+  case dwarf::DW_TAG_string_type:<br>
+  case dwarf::DW_TAG_structure_type:<br>
+  case dwarf::DW_TAG_subroutine_type:<br>
+  case dwarf::DW_TAG_typedef:<br>
+  case dwarf::DW_TAG_union_type:<br>
+  case dwarf::DW_TAG_ptr_to_member_<u></u>type:<br>
+  case dwarf::DW_TAG_set_type:<br>
+  case dwarf::DW_TAG_subrange_type:<br>
+  case dwarf::DW_TAG_base_type:<br>
+  case dwarf::DW_TAG_const_type:<br>
+  case dwarf::DW_TAG_constant:<br>
+  case dwarf::DW_TAG_file_type:<br>
+  case dwarf::DW_TAG_namelist:<br>
+  case dwarf::DW_TAG_packed_type:<br>
+  case dwarf::DW_TAG_volatile_type:<br>
+  case dwarf::DW_TAG_restrict_type:<br>
+  case dwarf::DW_TAG_interface_type:<br>
+  case dwarf::DW_TAG_unspecified_<u></u>type:<br>
+  case dwarf::DW_TAG_shared_type:<br>
+    return true;<br>
+  default:<br>
+    break;<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
 /// \brief Recursively clone \p InputDIE's subtrees that have been<br>
 /// selected to appear in the linked output.<br>
 ///<br>
@@ -1958,6 +2137,26 @@ DIE *DwarfLinker::cloneDIE(const DWARFDe<br>
         cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo);<br>
   }<br>
<br>
+  // Look for accelerator entries.<br>
+  uint16_t Tag = InputDIE.getTag();<br>
+  // FIXME: This is slightly wrong. An inline_subroutine without a<br>
+  // low_pc, but with AT_ranges might be interesting to get into the<br>
+  // accelerator tables too. For now stick with dsymutil's behavior.<br>
+  if ((Info.InDebugMap || AttrInfo.HasLowPc) &&<br>
+      Tag != dwarf::DW_TAG_compile_unit &&<br>
+      getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {<br>
+    if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)<br>
+      Unit.addNameAccelerator(Die, AttrInfo.MangledName,<br>
+                              AttrInfo.MangledNameOffset,<br>
+                              Tag == dwarf::DW_TAG_inlined_<u></u>subroutine);<br>
+    if (AttrInfo.Name)<br>
+      Unit.addNameAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset,<br>
+                              Tag == dwarf::DW_TAG_inlined_<u></u>subroutine);<br>
+  } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&<br>
+             getDIENames(InputDIE, Unit.getOrigUnit(), AttrInfo)) {<br>
+    Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset);<br>
+  }<br>
+<br>
   DIEAbbrev &NewAbbrev = Die->getAbbrev();<br>
   // If a scope DIE is kept, we must have kept at least one child. If<br>
   // it's not the case, we'll just be emitting one wasteful end of<br>
@@ -2218,6 +2417,11 @@ void DwarfLinker::<u></u>patchLineTableForUnit(<br>
                                    Unit.getOrigUnit().<u></u>getAddressByteSize());<br>
 }<br>
<br>
+void DwarfLinker::<u></u>emitAcceleratorEntriesForUnit(<u></u>CompileUnit &Unit) {<br>
+  Streamer->emitPubNamesForUnit(<u></u>Unit);<br>
+  Streamer->emitPubTypesForUnit(<u></u>Unit);<br>
+}<br>
+<br>
 bool DwarfLinker::link(const DebugMap &Map) {<br>
<br>
   if (Map.begin() == Map.end()) {<br>
@@ -2301,6 +2505,7 @@ bool DwarfLinker::link(const DebugMap &M<br>
           continue;<br>
         patchRangesForUnit(<u></u>CurrentUnit, DwarfContext);<br>
         Streamer-><u></u>emitLocationsForUnit(<u></u>CurrentUnit, DwarfContext);<br>
+        emitAcceleratorEntriesForUnit(<u></u>CurrentUnit);<br>
       }<br>
<br>
     // Emit all the compile unit's debug information.<br>
<br>
<br>
______________________________<u></u>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">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/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>