<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - ObjC++ type encodings can be very large (20K+)"
   href="https://bugs.llvm.org/show_bug.cgi?id=38346">38346</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>ObjC++ type encodings can be very large (20K+)
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>neuberger@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>ObjC uses type encoding to facilitate message passing. When you pass a C++ type
to an ObjC method, the encoding recurses the C++ type and for complex C++
objects it can be really huge (we have a few ObjC++ methods that result in
130KB added to our final binary).

If you run "objdump -macho -objc-meta-data SomeObjectFile.o" on an object file
that has an ObjC method that takes a C++ parameter, you'll see something like:

types 0x6112 v40@0:8{shared_ptr<Foo::Bar>=^{Bar}^{__shared_weak_count}}16@32

This is a really small one, but if you take it out of the shared_ptr and pass
it as a raw pointer, this type would grow to be 20,000 characters long for our
Foo class. There's no compression or deduplication, so if you have 5 ObjC
methods that take this C++ type as a param, the type encoding will appear 5
times.

It seems you can prevent the C++ type from being recursed by hiding it behind a
pointer (which is what shared_ptr ends up doing above). I do that with a simple
helper class:

template<class T>
class ObjCppPtrWrapper {
public:
    T* o;
    ObjCppPtrWrapper(T* t) : o(t) {}
    ObjCppPtrWrapper() {
        o = nullptr;
    }
};

Can clang just put the class name into the type encoding, instead of recursing
into the type? Is it possible that some code to support anonymous structs is
being accidentally called for all C/C++ types? The relevant code I believe is
here:
<a href="https://github.com/llvm-mirror/clang/blob/580f7daabc7696d50ad09d9643b2afeadbd387d8/lib/AST/ASTContext.cpp#L6514">https://github.com/llvm-mirror/clang/blob/580f7daabc7696d50ad09d9643b2afeadbd387d8/lib/AST/ASTContext.cpp#L6514</a></pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>