diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 50 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.h | 21 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 2 |
9 files changed, 59 insertions, 68 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 89f552225c1..6bfd5cb3099 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -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" diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 3d530e8210f..12620e71014 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -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" diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 301f6935489..ff7a20aea71 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -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) { diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 54aca0c96de..61552c45052 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -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 = diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index bd510899032..f6e32078877 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -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."); } diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 07301b50dc7..a354aa19c2c 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -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 diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 633b7b8dad7..f575300b6dd 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 3f30cd32833..a837b6369c3 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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. diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index affef35f282..17ac0023f8d 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -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. |