From: Fariborz Jahanian Date: Wed, 21 Jan 2009 22:04:16 +0000 (+0000) Subject: Refactoring ObjC Next's runtime classes in preparation for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ee0af74d1e0990c7b66d32657f3e4e54b8691552;p=clang Refactoring ObjC Next's runtime classes in preparation for the new ObjC's abi. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62721 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 1fec6fa3d3..900e0a0390 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -483,6 +483,9 @@ LaxVectorConversions("flax-vector-conversions", static llvm::cl::opt EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature")); +static llvm::cl::opt +ObjCModernABI("fobjc-modern-abi", llvm::cl::desc("enable objective-c's modern abi")); + // FIXME: This (and all GCC -f options) really come in -f... and // -fno-... forms, and additionally support automagic behavior when @@ -614,6 +617,9 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, Options.NeXTRuntime = 1; else if (GNURuntime) Options.NeXTRuntime = 0; + + if (ObjCModernABI) + Options.ObjCModernABI = 1; } static llvm::cl::opt diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 4b5355282e..d19db4b404 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -38,6 +38,7 @@ struct LangOptions { unsigned ObjC1 : 1; // Objective-C 1 support enabled. unsigned ObjC2 : 1; // Objective-C 2 support enabled. + unsigned ObjCModernABI : 1; // Objective-C modern abi enabled unsigned PascalStrings : 1; // Allow Pascal strings unsigned Boolean : 1; // Allow bool/true/false @@ -62,7 +63,7 @@ public: Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0; ImplicitInt = Digraphs = 0; HexFloats = 0; - GC = ObjC1 = ObjC2 = 0; + GC = ObjC1 = ObjC2 = ObjCModernABI = 0; C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0; CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0; LaxVectorConversions = Exceptions = NeXTRuntime = 0; diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 871d9417d1..c2b160091b 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -35,20 +35,14 @@ namespace { // FIXME: We should find a nicer way to make the labels for // metadata, string concatenation is lame. -/// ObjCTypesHelper - Helper class that encapsulates lazy -/// construction of varies types used during ObjC generation. -class ObjCTypesHelper { -private: - CodeGen::CodeGenModule &CGM; +class ObjCCommonTypesHelper { +protected: + CodeGen::CodeGenModule &CGM; - llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn; - llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn, - *MessageSendSuperFpretFn; - public: const llvm::Type *ShortTy, *IntTy, *LongTy; const llvm::Type *Int8PtrTy; - + /// ObjectPtrTy - LLVM type for object handles (typeof(id)) const llvm::Type *ObjectPtrTy; @@ -60,17 +54,31 @@ public: /// ProtocolPtrTy - LLVM type for external protocol handles /// (typeof(Protocol)) const llvm::Type *ExternalProtocolPtrTy; - + // SuperCTy - clang type for struct objc_super. QualType SuperCTy; // SuperPtrCTy - clang type for struct objc_super *. QualType SuperPtrCTy; - + /// SuperTy - LLVM type for struct objc_super. const llvm::StructType *SuperTy; /// SuperPtrTy - LLVM type for struct objc_super *. const llvm::Type *SuperPtrTy; + + ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); + ~ObjCCommonTypesHelper(){} +}; +/// ObjCTypesHelper - Helper class that encapsulates lazy +/// construction of varies types used during ObjC generation. +class ObjCTypesHelper : public ObjCCommonTypesHelper { +private: + + llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn; + llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn, + *MessageSendSuperFpretFn; + +public: /// SymtabTy - LLVM type for struct objc_symtab. const llvm::StructType *SymtabTy; /// SymtabPtrTy - LLVM type for struct objc_symtab *. @@ -183,7 +191,7 @@ public: public: ObjCTypesHelper(CodeGen::CodeGenModule &cgm); - ~ObjCTypesHelper(); + ~ObjCTypesHelper() {} llvm::Function *getSendFn(bool IsSuper) { @@ -199,13 +207,20 @@ public: } }; -class CGObjCMac : public CodeGen::CGObjCRuntime { -private: - CodeGen::CodeGenModule &CGM; - ObjCTypesHelper ObjCTypes; - /// ObjCABI - FIXME: Not sure yet. +/// ObjCModernTypesHelper - will have all types needed by objective-c's +/// modern abi +class ObjCModernTypesHelper : public ObjCCommonTypesHelper { +public: + ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm); + ~ObjCModernTypesHelper(){} +}; + +class CGObjCCommonMac : public CodeGen::CGObjCRuntime { +protected: + CodeGen::CodeGenModule &CGM; + // FIXME! May not be needing this after all. unsigned ObjCABI; - + /// LazySymbols - Symbols to generate a lazy reference for. See /// DefinedSymbols and FinishModule(). std::set LazySymbols; @@ -215,49 +230,57 @@ private: /// special linker symbols which ensure that Objective-C modules are /// linked properly. std::set DefinedSymbols; - + /// ClassNames - uniqued class names. llvm::DenseMap ClassNames; - + /// MethodVarNames - uniqued method variable names. llvm::DenseMap MethodVarNames; - + /// MethodVarTypes - uniqued method type signatures. We have to use /// a StringMap here because have no other unique reference. llvm::StringMap MethodVarTypes; - + /// MethodDefinitions - map of methods which have been defined in /// this translation unit. llvm::DenseMap MethodDefinitions; - + /// PropertyNames - uniqued method variable names. llvm::DenseMap PropertyNames; - + /// ClassReferences - uniqued class references. llvm::DenseMap ClassReferences; - + /// SelectorReferences - uniqued selector references. llvm::DenseMap SelectorReferences; - + /// Protocols - Protocols for which an objc_protocol structure has /// been emitted. Forward declarations are handled by creating an /// empty structure whose initializer is filled in when/if defined. llvm::DenseMap Protocols; - + /// DefinedProtocols - Protocols which have actually been /// defined. We should not need this, see FIXME in GenerateProtocol. llvm::DenseSet DefinedProtocols; - + /// DefinedClasses - List of defined classes. std::vector DefinedClasses; - + /// DefinedCategories - List of defined categories. std::vector DefinedCategories; - + /// UsedGlobals - List of globals to pack into the llvm.used metadata /// to prevent them from being clobbered. std::vector UsedGlobals; +public: + CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) + { } +}; + +class CGObjCMac : public CGObjCCommonMac { +private: + ObjCTypesHelper ObjCTypes; /// EmitImageInfo - Emit the image info marker used to encode some module /// level information. void EmitImageInfo(); @@ -467,6 +490,14 @@ public: virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); }; + +class CGObjCModernMac : public CGObjCCommonMac { +private: + ObjCModernTypesHelper ObjCTypes; +public: + CGObjCModernMac(CodeGen::CodeGenModule &cgm); +}; + } // end anonymous namespace /* *** Helper Functions *** */ @@ -484,15 +515,10 @@ static llvm::Constant *getConstantGEP(llvm::Constant *C, /* *** CGObjCMac Public Interface *** */ -CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) - : CGM(cgm), - ObjCTypes(cgm), - ObjCABI(1) +CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), + ObjCTypes(cgm) { - // FIXME: How does this get set in GCC? And what does it even mean? - if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy)) - ObjCABI = 2; - + ObjCABI = 1; EmitImageInfo(); } @@ -2229,14 +2255,21 @@ void CGObjCMac::FinishModule() { CGM.getModule().appendModuleInlineAsm(s.str()); } +CGObjCModernMac::CGObjCModernMac(CodeGen::CodeGenModule &cgm) + : CGObjCCommonMac(cgm), + ObjCTypes(cgm) +{ + ObjCABI = 2; +} + /* *** */ -ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) - : CGM(cgm) +ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) +: CGM(cgm) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); - + ShortTy = Types.ConvertType(Ctx.ShortTy); IntTy = Types.ConvertType(Ctx.IntTy); LongTy = Types.ConvertType(Ctx.LongTy); @@ -2250,7 +2283,41 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) // that the IR comes out a bit cleaner. const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); + + // I'm not sure I like this. The implicit coordination is a bit + // gross. We should solve this in a reasonable fashion because this + // is a pretty common task (match some runtime data structure with + // an LLVM data structure). + + // FIXME: This is leaked. + // FIXME: Merge with rewriter code? + + // struct _objc_super { + // id self; + // Class cls; + // } + RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, + SourceLocation(), + &Ctx.Idents.get("_objc_super")); + RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, + Ctx.getObjCIdType(), 0, false)); + RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, + Ctx.getObjCClassType(), 0, false)); + RD->completeDefinition(Ctx); + + SuperCTy = Ctx.getTagDeclType(RD); + SuperPtrCTy = Ctx.getPointerType(SuperCTy); + + SuperTy = cast(Types.ConvertType(SuperCTy)); + SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); +} +ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) + : ObjCCommonTypesHelper(cgm) +{ + CodeGen::CodeGenTypes &Types = CGM.getTypes(); + ASTContext &Ctx = CGM.getContext(); + // struct _objc_method_description { // SEL name; // char *types; @@ -2326,10 +2393,11 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(); llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); - T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), - LongTy, - llvm::ArrayType::get(ProtocolTyHolder, 0), - NULL); + const llvm::Type *T = + llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), + LongTy, + llvm::ArrayType::get(ProtocolTyHolder, 0), + NULL); cast(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); // struct _objc_protocol { @@ -2458,33 +2526,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) NULL); CGM.getModule().addTypeName("struct._objc_category", CategoryTy); - // I'm not sure I like this. The implicit coordination is a bit - // gross. We should solve this in a reasonable fashion because this - // is a pretty common task (match some runtime data structure with - // an LLVM data structure). - - // FIXME: This is leaked. - // FIXME: Merge with rewriter code? - - // struct _objc_super { - // id self; - // Class cls; - // } - RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, - SourceLocation(), - &Ctx.Idents.get("_objc_super")); - RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, - Ctx.getObjCIdType(), 0, false)); - RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, - Ctx.getObjCClassType(), 0, false)); - RD->completeDefinition(Ctx); - - SuperCTy = Ctx.getTagDeclType(RD); - SuperPtrCTy = Ctx.getPointerType(SuperCTy); - - SuperTy = cast(Types.ConvertType(SuperCTy)); - SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); - // Global metadata structures // struct _objc_symtab { @@ -2711,7 +2752,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) } -ObjCTypesHelper::~ObjCTypesHelper() { +ObjCModernTypesHelper::ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm) +: ObjCCommonTypesHelper(cgm) +{ } /* *** */ @@ -2720,3 +2763,9 @@ CodeGen::CGObjCRuntime * CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { return new CGObjCMac(CGM); } + +CodeGen::CGObjCRuntime * +CodeGen::CreateMacModernObjCRuntime(CodeGen::CodeGenModule &CGM) { + return 0; + // return new CGObjCModernMac(CGM); +} diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index ac50e79fca..409ae37221 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -161,6 +161,7 @@ public: //TODO: This should include some way of selecting which runtime to target. CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM); CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM); +CGObjCRuntime *CreateMacModernObjCRuntime(CodeGenModule &CGM); } } #endif diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 7856b076d2..79f00dec97 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -39,7 +39,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, if (Features.ObjC1) { if (Features.NeXTRuntime) { - Runtime = CreateMacObjCRuntime(*this); + Runtime = Features.ObjCModernABI ? CreateMacModernObjCRuntime(*this) + : CreateMacObjCRuntime(*this); } else { Runtime = CreateGNUObjCRuntime(*this); }