Provide standalone cmake project file that allows compilation outside the LLVM source tree and installs the headers as well. Tune other CMakeLists for out-of-tree build. Provide missing isDynamic() method for Objective C properties. (Best-guess implementation based on https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html and llvm-objdump -m -objc-meta-data output). Does not seem to be used anywhere anyways - but the control flow of the code is somewhat encrypted. Adjust to some minor API differencies between Apple clang 8.0.0 and upstream LLVM 5.0.1. --- objcmetadata-800.0.42.1/CMakeLists.txt.orig 2017-12-25 22:23:41.000000000 +0100 +++ objcmetadata-800.0.42.1/CMakeLists.txt 2017-12-25 20:54:39.000000000 +0100 @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.4.3) +project(ObjCMetadata) + +find_package(LLVM REQUIRED CONFIG) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${LLVM_CMAKE_DIR}) +include(AddLLVM) + +include_directories(${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) +set(LLVM_COMMON_LIBS Object Support Analysis Core) + +include_directories(BEFORE + ${CMAKE_CURRENT_BINARY_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/include + ) + +install(FILES + include/llvm/${PROJECT_NAME}/ObjCBitcode.h + include/llvm/${PROJECT_NAME}/ObjCMachOBinary.h + include/llvm/${PROJECT_NAME}/ObjCMetadata.h + DESTINATION include/llvm/${PROJECT_NAME} + ) + +add_subdirectory(lib/${PROJECT_NAME}) --- objcmetadata-800.0.42.1/include/llvm/ObjCMetadata/ObjCMetadata.h.orig 2017-12-25 20:09:28.000000000 +0100 +++ objcmetadata-800.0.42.1/include/llvm/ObjCMetadata/ObjCMetadata.h 2017-12-25 20:10:11.000000000 +0100 @@ -110,6 +110,7 @@ // Return empty string if doesn't exists. Expected getGetter() const; Expected getSetter() const; + Expected isDynamic() const; }; class ObjCMethod : public ObjCInfoBase { --- objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCMetadata.cpp.orig 2017-12-25 20:09:11.000000000 +0100 +++ objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCMetadata.cpp 2017-12-25 20:13:33.000000000 +0100 @@ -164,6 +164,20 @@ return setter; } +Expected ObjCProperty::isDynamic() const { + auto Attr = getAttribute(); + if (!Attr) + return Attr.takeError(); + // Find setter attribute. + SmallVector Attrs; + Attr->split(Attrs, ','); + for (auto a : Attrs) { + if (a == "D") + return true; + } + return false; +} + Expected ObjCMethod::getName() const { return MetadataReader->getMethodName(*this); } --- objcmetadata-800.0.42.1/lib/ObjCMetadata/CMakeLists.txt.orig 2017-12-25 17:29:01.000000000 +0100 +++ objcmetadata-800.0.42.1/lib/ObjCMetadata/CMakeLists.txt 2017-12-25 20:59:31.000000000 +0100 @@ -1,3 +1,10 @@ +set(LLVM_LINK_COMPONENTS + Object + Support + Analysis + Core +) + add_llvm_library(LLVMObjCMetadata ObjCBitcode.cpp ObjCMetadata.cpp @@ -5,7 +12,4 @@ ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/ObjCMetadata - - DEPENDS - intrinsics_gen ) --- objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCBitcode.cpp.orig 2017-12-25 17:14:29.000000000 +0100 +++ objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCBitcode.cpp 2017-12-25 17:17:51.000000000 +0100 @@ -20,7 +20,7 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Operator.h" -#include "llvm/Support/Error.h" +#include "llvm/Object/Error.h" #include "macho-obj.h" @@ -75,7 +75,7 @@ Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast(V)->getOperand(0); } else if (GlobalAlias *GA = dyn_cast(V)) { - if (GA->mayBeOverridden()) + if (GA->isInterposable()) return V; V = GA->getAliasee(); } else if (PtrToIntOperator *PTI = dyn_cast(V)) { --- objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCMachOBinary.cpp.orig 2017-12-25 17:24:23.000000000 +0100 +++ objcmetadata-800.0.42.1/lib/ObjCMetadata/ObjCMachOBinary.cpp 2017-12-25 17:27:15.000000000 +0100 @@ -1262,9 +1262,9 @@ const char *SymbolName = nullptr; if (reloc_found && isExtern) { offset = Symbol.getValue(); - ErrorOr NameOrError = Symbol.getName(); + Expected NameOrError = Symbol.getName(); if (!NameOrError) { - return errorOrToExpected(std::move(NameOrError)); + return NameOrError; } StringRef Name = *NameOrError; if (!Name.empty()) {