<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Overview</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">=======</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">We are planning to open source our internal implementation of Objective-C metadata reader library to LLVM. Unlike the C style objective-c metadata reader in llvm-objdump, it is designed to be a reusable C++ library to parse objective-c metadata from binaries with LLVM style error handling. The current implementation has an interface that resembles libObject in and it supports parsing objective-c metadata from MachO object file or LLVM bitcode that is generated by clang/swift compiler. It has the flexibility to be extended to support other objective-c metadata format if needed.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">You can find an old open-source version of implementation here[1]. The version we planned to open source has the same design but it will come with some bug fixes and improvements, and it will be rebased to the trunk.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Background</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">=========</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">We think it is very beneficial to have an objective-c metadata library in LLVM. We use the library in many tools, including tapi which we are currently in the process of open sourcing. Some have been asking for this libraries on the list or off the list to use it in the contexts like JIT[2] or macports. </div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Originally, the open source of this library is delayed because we thought it would be good if we can achieve following two goals before upstreaming:</div>
<ul class="">
<li style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class=""><span style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class=""></span>An improved libObject interface: we are expecting libObject interfaces to be changed which ObjCMetadata library should be updated to match.</li>
<li style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class=""><span style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class=""></span>Replace the parser inside llvm-objdump.</li>
</ul><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">The first one has been talked for years but never put into action. The second one requires a strict output match because llvm-objdump is a replacement for otool-classic on darwin platform, and doing so will require LLVM infrastructure improvements on how to handle errors. With some discussion, we believe both tasks can be done in trunk when it is time, rather than waiting for all the requirements are met.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Design</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">=====</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">ObjCMetadata library comes with headers (in llvm/include/llvm/ObjCMetadata)[3], implementations (in llvm/lib/ObjCMetadata)[4] and we will also implement a tool similar to a stripped down version of [5] for testing. </div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Here is an example how to use the library by extracting and printing the objc class names:</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">```</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">  MachOMetadata ObjCInfo(InputObject);</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">  <b class="">if</b> (<b class="">auto</b> ObjCClasses = ObjCInfo.classes()) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">    <b class="">for</b> (<b class="">auto</b> c : *ObjCClasses) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      <b class="">auto</b> ObjCClass = *c;</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      <b class="">if</b> (!ObjCClass) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">        handleError(ObjCClass.takeError());</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">        <b class="">continue</b>;</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      <b class="">auto</b> name = ObjCClass->getName();</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      <b class="">if</b> (!name) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">        handleError(name.takeError());</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">        <b class="">continue</b>;</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">      outs() << *name << "\n";</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">  }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">```</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">I am preparing a patch and will send out when it is ready. Let me know if you have any questions or feedbacks.</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Thanks</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">Steven</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue"; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">[1] <a href="https://opensource.apple.com/source/clang/clang-800.0.38" class="">https://opensource.apple.com/source/clang/clang-800.0.38</a></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">[2] <a href="http://lists.llvm.org/pipermail/llvm-dev/2016-November/106995.html" class="">http://lists.llvm.org/pipermail/llvm-dev/2016-November/106995.html</a></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">[3] <a href="https://opensource.apple.com/source/clang/clang-800.0.38/src/lib/ObjCMetadata/" class="">https://opensource.apple.com/source/clang/clang-800.0.38/src/lib/ObjCMetadata/</a></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">[4] <a href="https://opensource.apple.com/source/clang/clang-800.0.38/src/include/llvm/ObjCMetadata/" class="">https://opensource.apple.com/source/clang/clang-800.0.38/src/include/llvm/ObjCMetadata/</a></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: "Helvetica Neue";" class="">[5] <a href="https://opensource.apple.com/source/clang/clang-800.0.38/src/tools/api-analyzer/" class="">https://opensource.apple.com/source/clang/clang-800.0.38/src/tools/api-analyzer/</a></div><div class=""><br class=""></div></body></html>