aschwaighofer updated this revision to Diff 253712.
aschwaighofer added a comment.

- Change API name to emitObjCProtocolObject.
- Make stuff compile on current ToT.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77077/new/

https://reviews.llvm.org/D77077

Files:
  clang/include/clang/CodeGen/CodeGenABITypes.h
  clang/lib/CodeGen/CGObjCGNU.cpp
  clang/lib/CodeGen/CGObjCMac.cpp
  clang/lib/CodeGen/CGObjCRuntime.cpp
  clang/lib/CodeGen/CGObjCRuntime.h

Index: clang/lib/CodeGen/CGObjCRuntime.h
===================================================================
--- clang/lib/CodeGen/CGObjCRuntime.h
+++ clang/lib/CodeGen/CGObjCRuntime.h
@@ -211,6 +211,16 @@
   /// implementations.
   virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
 
+  /// getOrEmitProtocol - Get the protocol object for the given
+  /// declaration, emitting it if necessary. The return value has type
+  /// ProtocolPtrTy.
+  /// \p getProtocolReference is called by the implementation when a
+  /// reference to another protocol is needed.
+  virtual llvm::Constant *getOrEmitProtocol(
+      const ObjCProtocolDecl *OPD,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          getProtocolReference) = 0;
+
   /// Generate a function preamble for a method with the specified
   /// types.
 
Index: clang/lib/CodeGen/CGObjCRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGObjCRuntime.cpp
+++ clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -13,14 +13,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "CGObjCRuntime.h"
-#include "CGCleanup.h"
 #include "CGCXXABI.h"
+#include "CGCleanup.h"
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
 #include "llvm/Support/SaveAndRestore.h"
 
 using namespace clang;
@@ -383,3 +384,11 @@
     CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
   return MessageSendInfo(argsInfo, signatureType);
 }
+
+llvm::Constant *clang::CodeGen::emitObjCProtocolObject(
+    CodeGenModule &CGM, const ObjCProtocolDecl *protocol,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        createProtocolReference) {
+  return CGM.getObjCRuntime().getOrEmitProtocol(protocol,
+                                                createProtocolReference);
+}
Index: clang/lib/CodeGen/CGObjCMac.cpp
===================================================================
--- clang/lib/CodeGen/CGObjCMac.cpp
+++ clang/lib/CodeGen/CGObjCMac.cpp
@@ -1110,7 +1110,7 @@
   /// GetOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
   /// ProtocolPtrTy.
-  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
+  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
 
   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
   /// object for the given declaration, emitting it if needed. These
@@ -1288,10 +1288,15 @@
   llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
                                  ArrayRef<const ObjCMethodDecl *> Methods);
 
-  /// GetOrEmitProtocol - Get the protocol object for the given
+  /// getOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
   /// ProtocolPtrTy.
-  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
+  /// \p getProtocolReference is called by the implementation when a
+  /// reference to another protocol is needed.
+  llvm::Constant *getOrEmitProtocol(
+      const ObjCProtocolDecl *OPD,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          getProtocolReference) override;
 
   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
   /// object for the given declaration, emitting it if needed. These
@@ -1309,9 +1314,11 @@
 
   /// EmitProtocolList - Generate the list of referenced
   /// protocols. The return value has type ProtocolListPtrTy.
-  llvm::Constant *EmitProtocolList(Twine Name,
-                                   ObjCProtocolDecl::protocol_iterator begin,
-                                   ObjCProtocolDecl::protocol_iterator end);
+  llvm::Constant *EmitProtocolList(
+      Twine Name, ObjCProtocolDecl::protocol_iterator begin,
+      ObjCProtocolDecl::protocol_iterator end,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          getProtocolRef);
 
   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
   /// for the given selector.
@@ -1471,10 +1478,15 @@
                                     const ObjCIvarDecl *Ivar,
                                     unsigned long int offset);
 
-  /// GetOrEmitProtocol - Get the protocol object for the given
+  /// getOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
   /// ProtocolPtrTy.
-  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
+  /// \p getProtocolReference is called by the implementation when a
+  /// reference to another protocol is needed.
+  llvm::Constant *getOrEmitProtocol(
+      const ObjCProtocolDecl *OPD,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          createProtocolReference) override;
 
   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
   /// object for the given declaration, emitting it if needed. These
@@ -1484,9 +1496,11 @@
 
   /// EmitProtocolList - Generate the list of referenced
   /// protocols. The return value has type ProtocolListPtrTy.
-  llvm::Constant *EmitProtocolList(Twine Name,
-                                   ObjCProtocolDecl::protocol_iterator begin,
-                                   ObjCProtocolDecl::protocol_iterator end);
+  llvm::Constant *EmitProtocolList(
+      Twine Name, ObjCProtocolDecl::protocol_iterator begin,
+      ObjCProtocolDecl::protocol_iterator end,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          getProtocolRef);
 
   CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
                                         ReturnValueSlot Return,
@@ -3040,6 +3054,13 @@
   return GetOrEmitProtocolRef(PD);
 }
 
+llvm::Constant *CGObjCCommonMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
+  return getOrEmitProtocol(
+      PD, [this](const ObjCProtocolDecl *p) -> llvm::Constant * {
+        return this->GetProtocolRef(p);
+      });
+}
+
 llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
                CodeGenFunction &CGF,
                const ObjCInterfaceDecl *ID,
@@ -3072,7 +3093,10 @@
 
 See EmitProtocolExtension().
 */
-llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
+llvm::Constant *CGObjCMac::getOrEmitProtocol(
+    const ObjCProtocolDecl *PD,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        getProtocolRef) {
   llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
 
   // Early exit if a defining object has already been generated.
@@ -3095,7 +3119,8 @@
   values.add(EmitProtocolExtension(PD, methodLists));
   values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
   values.add(EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
-                              PD->protocol_begin(), PD->protocol_end()));
+                              PD->protocol_begin(), PD->protocol_end(),
+                              getProtocolRef));
   values.add(methodLists.emitMethodList(this, PD,
                               ProtocolMethodLists::RequiredInstanceMethods));
   values.add(methodLists.emitMethodList(this, PD,
@@ -3202,10 +3227,11 @@
     Protocol *list[];
   };
 */
-llvm::Constant *
-CGObjCMac::EmitProtocolList(Twine name,
-                            ObjCProtocolDecl::protocol_iterator begin,
-                            ObjCProtocolDecl::protocol_iterator end) {
+llvm::Constant *CGObjCMac::EmitProtocolList(
+    Twine name, ObjCProtocolDecl::protocol_iterator begin,
+    ObjCProtocolDecl::protocol_iterator end,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        getProtocolRef) {
   // Just return null for empty protocol lists
   if (begin == end)
     return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
@@ -3221,7 +3247,11 @@
 
   auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
   for (; begin != end; ++begin) {
-    refsArray.add(GetProtocolRef(*begin));
+    auto protocolRef = getProtocolRef(*begin);
+    if (protocolRef->getType() != ObjCTypes.ProtocolPtrTy)
+      protocolRef =
+          llvm::ConstantExpr::getBitCast(protocolRef, ObjCTypes.ProtocolPtrTy);
+    refsArray.add(protocolRef);
   }
   auto count = refsArray.size();
 
@@ -3421,7 +3451,10 @@
   if (Category) {
     Values.add(
         EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
-                         Category->protocol_begin(), Category->protocol_end()));
+                         Category->protocol_begin(), Category->protocol_end(),
+                         [this](const ObjCProtocolDecl *p) -> llvm::Constant * {
+                           return this->GetProtocolRef(p);
+                         }));
   } else {
     Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
   }
@@ -3563,7 +3596,10 @@
   llvm::Constant *Protocols =
       EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
                        Interface->all_referenced_protocol_begin(),
-                       Interface->all_referenced_protocol_end());
+                       Interface->all_referenced_protocol_end(),
+                       [this](const ObjCProtocolDecl *p) -> llvm::Constant * {
+                         return this->GetProtocolRef(p);
+                       });
   unsigned Flags = FragileABI_Class_Factory;
   if (ID->hasNonZeroConstructors() || ID->hasDestructors())
     Flags |= FragileABI_Class_HasCXXStructors;
@@ -6423,10 +6459,12 @@
 
   const ObjCInterfaceDecl *OID = ID->getClassInterface();
   assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
-  values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_"
-                                + OID->getObjCRuntimeNameAsString(),
-                              OID->all_referenced_protocol_begin(),
-                              OID->all_referenced_protocol_end()));
+  values.add(EmitProtocolList(
+      "_OBJC_CLASS_PROTOCOLS_$_" + OID->getObjCRuntimeNameAsString(),
+      OID->all_referenced_protocol_begin(), OID->all_referenced_protocol_end(),
+      [this](const ObjCProtocolDecl *p) -> llvm::Constant * {
+        return this->GetProtocolRef(p);
+      }));
 
   if (flags & NonFragileABI_Class_Meta) {
     values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
@@ -6753,11 +6791,14 @@
     SmallString<256> ExtName;
     llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
                                        << OCD->getName();
-    values.add(EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_"
-                                   + Interface->getObjCRuntimeNameAsString() + "_$_"
-                                   + Category->getName(),
-                                Category->protocol_begin(),
-                                Category->protocol_end()));
+    values.add(
+        EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_" +
+                             Interface->getObjCRuntimeNameAsString() + "_$_" +
+                             Category->getName(),
+                         Category->protocol_begin(), Category->protocol_end(),
+                         [this](const ObjCProtocolDecl *p) -> llvm::Constant * {
+                           return this->GetProtocolRef(p);
+                         }));
     values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
                                 OCD, Category, ObjCTypes, false));
     values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
@@ -7050,7 +7091,7 @@
   return Entry;
 }
 
-/// GetOrEmitProtocol - Generate the protocol meta-data:
+/// getOrEmitProtocol - Generate the protocol meta-data:
 /// @code
 /// struct _protocol_t {
 ///   id isa;  // NULL
@@ -7070,8 +7111,10 @@
 /// @endcode
 ///
 
-llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
-  const ObjCProtocolDecl *PD) {
+llvm::Constant *CGObjCNonFragileABIMac::getOrEmitProtocol(
+    const ObjCProtocolDecl *PD,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        getProtocolRef) {
   llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
 
   // Early exit if a defining object has already been generated.
@@ -7091,10 +7134,9 @@
   // isa is NULL
   values.addNullPointer(ObjCTypes.ObjectPtrTy);
   values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
-  values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_"
-                                + PD->getObjCRuntimeNameAsString(),
-                               PD->protocol_begin(),
-                               PD->protocol_end()));
+  values.add(EmitProtocolList(
+      "_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
+      PD->protocol_begin(), PD->protocol_end(), getProtocolRef));
   values.add(methodLists.emitMethodList(this, PD,
                                  ProtocolMethodLists::RequiredInstanceMethods));
   values.add(methodLists.emitMethodList(this, PD,
@@ -7171,10 +7213,11 @@
 /// }
 /// @endcode
 ///
-llvm::Constant *
-CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
-                                      ObjCProtocolDecl::protocol_iterator begin,
-                                      ObjCProtocolDecl::protocol_iterator end) {
+llvm::Constant *CGObjCNonFragileABIMac::EmitProtocolList(
+    Twine Name, ObjCProtocolDecl::protocol_iterator begin,
+    ObjCProtocolDecl::protocol_iterator end,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        getProtocolRef) {
   SmallVector<llvm::Constant *, 16> ProtocolRefs;
 
   // Just return null for empty protocol lists
@@ -7195,8 +7238,13 @@
 
   // A null-terminated array of protocols.
   auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
-  for (; begin != end; ++begin)
-    array.add(GetProtocolRef(*begin));  // Implemented???
+  for (; begin != end; ++begin) {
+    auto protocolRef = getProtocolRef(*begin);
+    if (protocolRef->getType() != ObjCTypes.ProtocolnfABIPtrTy)
+      protocolRef = llvm::ConstantExpr::getBitCast(
+          protocolRef, ObjCTypes.ProtocolnfABIPtrTy);
+    array.add(protocolRef);
+  }
   auto count = array.size();
   array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
 
Index: clang/lib/CodeGen/CGObjCGNU.cpp
===================================================================
--- clang/lib/CodeGen/CGObjCGNU.cpp
+++ clang/lib/CodeGen/CGObjCGNU.cpp
@@ -617,6 +617,11 @@
   llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
                                    const ObjCProtocolDecl *PD) override;
   void GenerateProtocol(const ObjCProtocolDecl *PD) override;
+
+  llvm::Constant *getOrEmitProtocol(
+      const ObjCProtocolDecl *OPD,
+      llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+          createProtocolReference) override;
   llvm::Function *ModuleInitFunction() override;
   llvm::FunctionCallee GetPropertyGetFunction() override;
   llvm::FunctionCallee GetPropertySetFunction() override;
@@ -3048,6 +3053,13 @@
   return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
 }
 
+llvm::Constant *CGObjCGNU::getOrEmitProtocol(
+    const ObjCProtocolDecl *PD,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        createProtocolReference) {
+  llvm_unreachable("not implemented");
+}
+
 llvm::Constant *
 CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) {
   llvm::Constant *ProtocolList = GenerateProtocolList({});
Index: clang/include/clang/CodeGen/CodeGenABITypes.h
===================================================================
--- clang/include/clang/CodeGen/CodeGenABITypes.h
+++ clang/include/clang/CodeGen/CodeGenABITypes.h
@@ -28,6 +28,7 @@
 #include "clang/CodeGen/CGFunctionInfo.h"
 
 namespace llvm {
+  class Constant;
   class DataLayout;
   class Module;
   class Function;
@@ -44,6 +45,7 @@
 class DiagnosticsEngine;
 class HeaderSearchOptions;
 class ObjCMethodDecl;
+class ObjCProtocolDecl;
 class PreprocessorOptions;
 
 namespace CodeGen {
@@ -137,6 +139,17 @@
                                                CharUnits DstAlignment,
                                                bool IsVolatile, QualType QT);
 
+/// Get a pointer to a protocol object for the given declaration, emitting it if
+/// it hasn't already been emitted in this translation unit. Note that the ABI
+/// for emitting a protocol reference in code (e.g. for a @protocol expression)
+/// in most runtimes is not as simple as just materializing a pointer to this
+/// object.
+/// \p createProtocolReference is called by the implementation when the protocol
+/// \p p references another protocol.
+llvm::Constant *emitObjCProtocolObject(
+    CodeGenModule &CGM, const ObjCProtocolDecl *p,
+    llvm::function_ref<llvm::Constant *(const ObjCProtocolDecl *)>
+        createProtocolReference);
 }  // end namespace CodeGen
 }  // end namespace clang
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to