[PATCH] D75545: [dsymutil] Fix template stripping in getDIENames(...) to account for overloaded operators

Shafik Yaghmour via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 3 10:56:31 PST 2020


shafik created this revision.
shafik added a reviewer: JDevlieghere.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
shafik edited the summary of this revision.

Currently dsymutil when generating accelerator tables will attempt to strip the template parameters from names for subroutines. For some overload operators which contain `<` in their names e.g. `operator<` the current method ends up stripping the operator name as well, so we just end up with the name `operator` in the table for each case.


https://reviews.llvm.org/D75545

Files:
  llvm/lib/DWARFLinker/DWARFLinker.cpp
  llvm/test/tools/dsymutil/Inputs/private/tmp/templated_operators/template_operators
  llvm/test/tools/dsymutil/Inputs/private/tmp/templated_operators/template_operators.o
  llvm/test/tools/dsymutil/X86/template_operators.test


Index: llvm/test/tools/dsymutil/X86/template_operators.test
===================================================================
--- /dev/null
+++ llvm/test/tools/dsymutil/X86/template_operators.test
@@ -0,0 +1,36 @@
+RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/templated_operators/template_operators -o %t.apple.dSYM
+
+RUN: llvm-dwarfdump -apple-names %t.apple.dSYM | FileCheck %s -check-prefix=NAMES
+
+The test was compiled from a single source:
+$ cat template_operators.cpp
+$ clang++ -g template_operators.cpp -c -o template_operators.o
+$ clang template_operators.o -o template_operators
+template <typename T>
+bool operator<(const T&, const T&){
+ return true;
+}
+
+template <typename T>
+bool operator<<(const T&, const T&){
+ return true;
+}
+
+template <typename T>
+bool operator==(const T&, const T&){
+ return true;
+}
+
+struct B{};
+
+int main() {
+  B b1;
+  B b2;
+
+   return b1 < b2 && b1 << b2 && b1 == b2;
+}
+
+
+NAMES-DAG: "operator<"
+NAMES-DAG: "operator<<"
+NAMES-DAG: "operator=="
Index: llvm/lib/DWARFLinker/DWARFLinker.cpp
===================================================================
--- llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -141,10 +141,33 @@
       Info.Name = StringPool.getEntry(Name);
 
   if (StripTemplate && Info.Name && Info.MangledName != Info.Name) {
-    // FIXME: dsymutil compatibility. This is wrong for operator<
-    auto Split = Info.Name.getString().split('<');
-    if (!Split.second.empty())
-      Info.NameWithoutTemplate = StringPool.getEntry(Split.first);
+    auto name = Info.Name.getString();
+
+    // If the name does not end with > we don't have a template.
+    if (name.endswith(">")) {
+      // If we have balanced < and > then we just have to find the first < to
+      // know where the template parameters start.
+      size_t num_left_angles_to_count = 1;
+
+      // Unless we have the spaceship operator <=> then we need to skip that <
+      // as well.
+      num_left_angles_to_count += name.count("<=>");
+
+      size_t right_angle_count = name.count('>');
+      size_t left_angle_count = name.count('<');
+
+      // If we are not balanced we either have one of the relational operators
+      // or shift operators overloaded.
+      if (left_angle_count > right_angle_count)
+        num_left_angles_to_count += left_angle_count - right_angle_count;
+
+      size_t start_of_template = 0;
+      while (num_left_angles_to_count--)
+        start_of_template = name.find('<', start_of_template) + 1;
+
+      Info.NameWithoutTemplate =
+          StringPool.getEntry(name.substr(0, start_of_template - 1));
+    }
   }
 
   return Info.Name || Info.MangledName;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D75545.247958.patch
Type: text/x-patch
Size: 2720 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200303/ad431e22/attachment.bin>


More information about the llvm-commits mailing list