]> granicus.if.org Git - clang/commitdiff
Change ObjCRuntime GenerateProtocol[Ref] methods to take
authorDaniel Dunbar <daniel@zuster.org>
Wed, 13 Aug 2008 00:59:25 +0000 (00:59 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 13 Aug 2008 00:59:25 +0000 (00:59 +0000)
    ObjCProtocolDecl directly.

Implement CodeGen support for forward protocol decls (no-ops are so
    nice to implement).

Also moved CGObjCRuntime.h out of CodeGenModule.h

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54709 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/ModuleBuilder.cpp

index 89f552225c1a31f386cf14e52961cba97b8dc0a1..6bfd5cb30999568eabf813f5a6f92d9f8eaec87b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/Target/TargetData.h"
index 3d530e8210f370461193b4f150f5c645112e32ed..12620e71014d4edf97a9a3ef3cfa06634ca2aaec 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/StmtVisitor.h"
 #include "llvm/Constants.h"
index 301f6935489f37dd60396b240b3b8354eca70a42..ff7a20aea710ad0e47312cfdd529d85376327c82 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/StmtVisitor.h"
@@ -509,7 +510,7 @@ Value *ScalarExprEmitter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
 
 Value *ScalarExprEmitter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   // FIXME: This should pass the Decl not the name.
-  return Runtime->GenerateProtocolRef(Builder, E->getProtocol()->getName());
+  return Runtime->GenerateProtocolRef(Builder, E->getProtocol());
 }
 
 Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
index 54aca0c96de851cfe66aee0a0b082a74e172d978..61552c45052e4b1a3f3162736f72eb60514ec29f 100644 (file)
@@ -18,6 +18,7 @@
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "llvm/Module.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/IRBuilder.h"
@@ -137,13 +138,8 @@ public:
            const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
            const llvm::SmallVectorImpl<std::string> &Protocols);
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
-                                           const char *ProtocolName);
-  virtual void GenerateProtocol(const char *ProtocolName,
-      const llvm::SmallVectorImpl<std::string> &Protocols,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodNames,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodNames,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes);
+                                           const ObjCProtocolDecl *PD);
+  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
   virtual llvm::Function *ModuleInitFunction();
 };
 } // end anonymous namespace
@@ -566,17 +562,39 @@ llvm::Constant *CGObjCGNU::GenerateProtocolList(
   return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
 }
 
-llvm::Value *CGObjCGNU::GenerateProtocolRef(llvm::IRBuilder<> &Builder, const
-    char *ProtocolName) {
-  return ExistingProtocols[ProtocolName];
+llvm::Value *CGObjCGNU::GenerateProtocolRef(llvm::IRBuilder<> &Builder, 
+                                            const ObjCProtocolDecl *PD) {
+  return ExistingProtocols[PD->getName()];
 }
 
-void CGObjCGNU::GenerateProtocol(const char *ProtocolName,
-    const llvm::SmallVectorImpl<std::string> &Protocols,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes) {
+void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
+  ASTContext &Context = CGM.getContext();
+  const char *ProtocolName = PD->getName();
+  llvm::SmallVector<std::string, 16> Protocols;
+  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
+       E = PD->protocol_end(); PI != E; ++PI)
+    Protocols.push_back((*PI)->getName());
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
+  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
+       E = PD->instmeth_end(); iter != E; iter++) {
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
+    InstanceMethodNames.push_back(
+        CGM.GetAddrOfConstantString((*iter)->getSelector().getName()));
+    InstanceMethodTypes.push_back(CGM.GetAddrOfConstantString(TypeStr));
+  }
+  // Collect information about class methods:
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
+  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
+  for (ObjCProtocolDecl::classmeth_iterator iter = PD->classmeth_begin(),
+      endIter = PD->classmeth_end() ; iter != endIter ; iter++) {
+    std::string TypeStr;
+    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    ClassMethodNames.push_back(
+        CGM.GetAddrOfConstantString((*iter)->getSelector().getName()));
+    ClassMethodTypes.push_back(CGM.GetAddrOfConstantString(TypeStr));
+  }
 
   llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
   llvm::Constant *InstanceMethodList =
index bd510899032120170178a7f59c3b032526706bbe..f6e32078877d6e75c19abd0a1ba8b12b99b4cc35 100644 (file)
@@ -168,14 +168,9 @@ public:
            const llvm::SmallVectorImpl<std::string> &Protocols);
 
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
-                                           const char *ProtocolName);
+                                           const ObjCProtocolDecl *PD);
 
-  virtual void GenerateProtocol(const char *ProtocolName,
-      const llvm::SmallVectorImpl<std::string> &Protocols,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodNames,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodNames,
-      const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes);
+  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
 
   virtual llvm::Function *ModuleInitFunction();
 };
@@ -300,18 +295,13 @@ llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
 }
 
 llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, 
-                                            const char *ProtocolName) {
+                                            const ObjCProtocolDecl *PD) {
   //  assert(0 && "Cannot get protocol reference on Mac runtime.");
   return llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy);
   return 0;
 }
 
-void CGObjCMac::GenerateProtocol(const char *ProtocolName,
-    const llvm::SmallVectorImpl<std::string> &Protocols,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes) {
+void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
   //  assert(0 && "Cannot generate protocol for Mac runtime.");
 }
 
index 07301b50dc7f47bbf89fbd946454981dce2f9e6e..a354aa19c2c8c1ab64ad235c35f2bfc96986165f 100644 (file)
@@ -29,8 +29,9 @@ namespace llvm {
 }
 
 namespace clang {
+  class ObjCProtocolDecl;
   class Selector;
-  
+
 namespace CodeGen {
   class CodeGenModule;
 
@@ -51,14 +52,18 @@ public:
                                            Selector Sel,
                                            llvm::Value** ArgV,
                                            unsigned ArgC) =0;
+
   /// Generate the function required to register all Objective-C components in
   /// this compilation unit with the runtime library.
   virtual llvm::Function *ModuleInitFunction() =0;
+
   /// Get a selector for the specified name and type values
   virtual llvm::Value *GetSelector(BuilderType &Builder,
                                    Selector Sel) =0;
+
   /// Generate a constant string object
   virtual llvm::Constant *GenerateConstantString(const std::string &String) = 0;
+
   /// Generate a category.  A category contains a list of methods (and
   /// accompanying metadata) and a list of protocols.
   virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
@@ -67,6 +72,7 @@ public:
              const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
              const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
              const llvm::SmallVectorImpl<std::string> &Protocols) =0;
+
   /// Generate a class stucture for this class.
   virtual void GenerateClass(
              const char *ClassName,
@@ -80,6 +86,7 @@ public:
              const llvm::SmallVectorImpl<Selector>  &ClassMethodSels,
              const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes,
              const llvm::SmallVectorImpl<std::string> &Protocols) =0;
+
   virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<true> &Builder,
                                                 const llvm::Type *ReturnTy,
                                                 const char *SuperClassName,
@@ -91,16 +98,12 @@ public:
   /// Emit the code to return the named protocol as an object, as in a
   /// @protocol expression.
   virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<true> &Builder,
-                                           const char *ProtocolName) = 0;
+                                           const ObjCProtocolDecl *PD) = 0;
 
   /// Generate the named protocol.  Protocols contain method metadata but no 
   /// implementations. 
-  virtual void GenerateProtocol(const char *ProtocolName,
-    const llvm::SmallVectorImpl<std::string> &Protocols,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &InstanceMethodTypes,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodNames,
-    const llvm::SmallVectorImpl<llvm::Constant *>  &ClassMethodTypes) =0;
+  virtual void GenerateProtocol(const ObjCProtocolDecl *PD) = 0;
+
   /// Generate a function preamble for a method with the specified types
   virtual llvm::Function *MethodPreamble(
                                          const std::string &ClassName,
@@ -112,9 +115,11 @@ public:
                                          unsigned ArgC,
                                          bool isClassMethod,
                                          bool isVarArg) = 0;
+
   /// Look up the class for the specified name
   virtual llvm::Value *LookupClass(BuilderType &Builder, 
                                    llvm::Value *ClassName) =0;
+
   /// If instance variable addresses are determined at runtime then this should
   /// return true, otherwise instance variables will be accessed directly from
   /// the structure.  If this returns true then @defs is invalid for this
index 633b7b8dad71957cf8948b03afd0db682fd23dcf..f575300b6dd5b19c8a2ce1f4c02c3e331f0dce84 100644 (file)
@@ -14,6 +14,7 @@
 #include "CGDebugInfo.h"
 #include "CodeGenModule.h"
 #include "CodeGenFunction.h"
+#include "CGObjCRuntime.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/Diagnostic.h"
@@ -247,33 +248,7 @@ void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) {
     CodeGenFunction(*this).GenerateObjCMethod(OMD);
 }
 void CodeGenModule::EmitObjCProtocolImplementation(const ObjCProtocolDecl *PD){
-  llvm::SmallVector<std::string, 16> Protocols;
-  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
-       E = PD->protocol_end(); PI != E; ++PI)
-    Protocols.push_back((*PI)->getName());
-  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
-  llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
-       E = PD->instmeth_end(); iter != E; iter++) {
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
-    InstanceMethodNames.push_back(
-        GetAddrOfConstantString((*iter)->getSelector().getName()));
-    InstanceMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
-  }
-  // Collect information about class methods:
-  llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
-  llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCProtocolDecl::classmeth_iterator iter = PD->classmeth_begin(),
-      endIter = PD->classmeth_end() ; iter != endIter ; iter++) {
-    std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    ClassMethodNames.push_back(
-        GetAddrOfConstantString((*iter)->getSelector().getName()));
-    ClassMethodTypes.push_back(GetAddrOfConstantString(TypeStr));
-  }
-  Runtime->GenerateProtocol(PD->getName(), Protocols, InstanceMethodNames,
-      InstanceMethodTypes, ClassMethodNames, ClassMethodTypes);
+  Runtime->GenerateProtocol(PD);
 }
 
 void CodeGenModule::EmitObjCCategoryImpl(const ObjCCategoryImplDecl *OCD) {
index 3f30cd32833099fd8f3287ea8aaef3bf94195bfa..a837b6369c320d8a42febb270d08318526243df0 100644 (file)
@@ -15,7 +15,6 @@
 #define CLANG_CODEGEN_CODEGENMODULE_H
 
 #include "CodeGenTypes.h"
-#include "CGObjCRuntime.h"
 #include "clang/AST/Attr.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
@@ -51,6 +50,7 @@ namespace CodeGen {
 
   class CodeGenFunction;
   class CGDebugInfo;
+  class CGObjCRuntime;
   
 /// CodeGenModule - This class organizes the cross-module state that is used
 /// while generating LLVM code.
index affef35f282f892a25bc89b707a18bb3e7e665d6..17ac0023f8dc665efafaef7968b4eace50849bd5 100644 (file)
@@ -72,7 +72,7 @@ namespace {
         Builder->EmitGlobal(FD);
       } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
         Builder->EmitGlobal(VD);
-      } else if (isa<ObjCClassDecl>(D)){
+      } else if (isa<ObjCClassDecl>(D) || isa<ObjCForwardProtocolDecl>(D)) {
         //Forward declaration.  Only used for type checking.
       } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)){
         // Generate Protocol object.