From 4cc7493bac46a0351f4254b53e87fe962ed54081 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Fri, 25 Mar 2011 14:06:20 +0000 Subject: [PATCH] Added some doc comments. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128275 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCGNU.cpp | 277 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 263 insertions(+), 14 deletions(-) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index baf4ce4fb3..1701963366 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -112,31 +112,120 @@ class LazyRuntimeFunction { */ class CGObjCGNU : public CGObjCRuntime { protected: + /** + * The module that is using this class + */ CodeGenModule &CGM; + /** + * The LLVM module into which output is inserted + */ llvm::Module &TheModule; + /** + * strut objc_super. Used for sending messages to super. This structure + * contains the receiver (object) and the expected class. + */ const llvm::StructType *ObjCSuperTy; + /** + * struct objc_super*. The type of the argument to the superclass message + * lookup functions. + */ const llvm::PointerType *PtrToObjCSuperTy; + /** + * LLVM type for selectors. Opaque pointer (i8*) unless a header declaring + * SEL is included in a header somewhere, in which case it will be whatever + * type is declared in that header, most likely {i8*, i8*}. + */ const llvm::PointerType *SelectorTy; + /** + * LLVM i8 type. Cached here to avoid repeatedly getting it in all of the + * places where it's used + */ const llvm::IntegerType *Int8Ty; + /** + * Pointer to i8 - LLVM type of char*, for all of the places where the + * runtime needs to deal with C strings. + */ const llvm::PointerType *PtrToInt8Ty; + /** + * Instance Method Pointer type. This is a pointer to a function that takes, + * at a minimum, an object and a selector, and is the generic type for + * Objective-C methods. Due to differences between variadic / non-variadic + * calling conventions, it must always be cast to the correct type before + * actually being used. + */ const llvm::PointerType *IMPTy; + /** + * Type of an untyped Objective-C object. Clang treats id as a built-in type + * when compiling Objective-C code, so this may be an opaque pointer (i8*), + * but if the runtime header declaring it is included then it may be a + * pointer to a structure. + */ const llvm::PointerType *IdTy; + /** + * Pointer to a pointer to an Objective-C object. Used in the new ABI + * message lookup function and some GC-related functions. + */ const llvm::PointerType *PtrToIdTy; + /** + * The clang type of id. Used when using the clang CGCall infrastructure to + * call Objective-C methods. + */ CanQualType ASTIdTy; + /** + * LLVM type for C int type. + */ const llvm::IntegerType *IntTy; + /** + * LLVM type for an opaque pointer. This is identical to PtrToInt8Ty, but is + * used in the code to document the difference between i8* meaning a pointer + * to a C string and i8* meaning a pointer to some opaque type. + */ const llvm::PointerType *PtrTy; + /** + * LLVM type for C long type. The runtime uses this in a lot of places where + * it should be using intptr_t, but we can't fix this without breaking + * compatibility with GCC... + */ const llvm::IntegerType *LongTy; + /** + * LLVM type for C size_t. Used in various runtime data structures. + */ const llvm::IntegerType *SizeTy; + /** + * LLVM type for C ptrdiff_t. Mainly used in property accessor functions. + */ const llvm::IntegerType *PtrDiffTy; + /** + * LLVM type for C int*. Used for GCC-ABI-compatible non-fragile instance + * variables. + */ const llvm::PointerType *PtrToIntTy; + /** + * LLVM type for Objective-C BOOL type. + */ const llvm::Type *BoolTy; - /// Metadata kind used to tie method lookups to message sends. + /** + * Metadata kind used to tie method lookups to message sends. The GNUstep + * runtime provides some LLVM passes that can use this to do things like + * automatic IMP caching and speculative inlining. + */ unsigned msgSendMDKind; + /** + * Helper function that generates a constant string and returns a pointer to + * the start of the string. The result of this function can be used anywhere + * where the C code specifies const char*. + */ llvm::Constant *MakeConstantString(const std::string &Str, const std::string &Name="") { llvm::Constant *ConstStr = CGM.GetAddrOfConstantCString(Str, Name.c_str()); return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); } + /** + * Emits a linkonce_odr string, whose name is the prefix followed by the + * string value. This allows the linker to combine the strings between + * different modules. Used for EH typeinfo names, selector strings, and a + * few other things. + */ llvm::Constant *ExportUniqueString(const std::string &Str, const std::string prefix) { std::string name = prefix + Str; @@ -148,7 +237,11 @@ protected: } return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2); } - + /** + * Generates a global structure, initialized by the elements in the vector. + * The element types must match the types of the structure elements in the + * first argument. + */ llvm::GlobalVariable *MakeGlobal(const llvm::StructType *Ty, std::vector &V, llvm::StringRef Name="", @@ -158,7 +251,11 @@ protected: return new llvm::GlobalVariable(TheModule, Ty, false, linkage, C, Name); } - + /** + * Generates a global array. The vector must contain the same number of + * elements that the array type declares, of the type specified as the array + * element type. + */ llvm::GlobalVariable *MakeGlobal(const llvm::ArrayType *Ty, std::vector &V, llvm::StringRef Name="", @@ -168,6 +265,10 @@ protected: return new llvm::GlobalVariable(TheModule, Ty, false, linkage, C, Name); } + /** + * Generates a global array, inferring the array type from the specified + * element type and the size of the initialiser. + */ llvm::GlobalVariable *MakeGlobalArray(const llvm::Type *Ty, std::vector &V, llvm::StringRef Name="", @@ -191,14 +292,46 @@ protected: * Null pointer value. Mainly used as a terminator in various arrays. */ llvm::Constant *NULLPtr; + /** + * LLVM context. + */ llvm::LLVMContext &VMContext; private: + /** + * Placeholder for the class. Lots of things refer to the class before we've + * actually emitted it. We use this alias as a placeholder, and then replace + * it with a pointer to the class structure before finally emitting the module. + */ llvm::GlobalAlias *ClassPtrAlias; + /** + * Placeholder for the metaclass. Lots of things refer to the class before we've + * actually emitted it. We use this alias as a placeholder, and then replace + * it with a pointer to the metaclass structure before finally emitting the + * module. + */ llvm::GlobalAlias *MetaClassPtrAlias; + /** + * All of the classes that have been generated for this compilation units. + */ std::vector Classes; + /** + * All of the categories that have been generated for this compilation units. + */ std::vector Categories; + /** + * All of the Objective-C constant strings that have been generated for this + * compilation units. + */ std::vector ConstantStrings; + /** + * Map from string values to Objective-C constant strings in the output. + * Used to prevent emitting Objective-C strings more than once. This should + * not be required at all - CodeGenModule should manage this list. + */ llvm::StringMap ObjCStrings; + /** + * All of the protocols that have been declared. + */ llvm::StringMap ExistingProtocols; /** * For each variant of a selector, we store the type encoding and a @@ -209,61 +342,152 @@ private: */ typedef std::pair TypedSelector; /** - * A map from selectors to selector types. This allows us to emit all - * selectors of the same name and type together. + * Type of the selector map. This is roughly equivalent to the structure + * used in the GNUstep runtime, which maintains a list of all of the valid + * types for a selector in a table. */ typedef llvm::DenseMap > SelectorMap; + /** + * A map from selectors to selector types. This allows us to emit all + * selectors of the same name and type together. + */ SelectorMap SelectorTable; - // Selectors that we don't emit in GC mode + /** + * Selectors related to memory management. When compiling in GC mode, we + * omit these. + */ Selector RetainSel, ReleaseSel, AutoreleaseSel; - // Functions used for GC. + /** + * Runtime functions used for memory management in GC mode. Note that clang + * supports code generation for calling these functions, but neither GNU + * runtime actually supports this API properly yet. + */ LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, WeakAssignFn, GlobalAssignFn; protected: + /** + * Function used for throwing Objective-C exceptions. + */ LazyRuntimeFunction ExceptionThrowFn; + /** + * Function used for rethrowing exceptions, used at the end of @finally or + * @synchronize blocks. + */ LazyRuntimeFunction ExceptionReThrowFn; + /** + * Function called when entering a catch function. This is required for + * differentiating Objective-C exceptions and foreign exceptions. + */ LazyRuntimeFunction EnterCatchFn; + /** + * Function called when exiting from a catch block. Used to do exception + * cleanup. + */ LazyRuntimeFunction ExitCatchFn; + /** + * Function called when entering an @synchronize block. Acquires the lock. + */ LazyRuntimeFunction SyncEnterFn; + /** + * Function called when exiting an @synchronize block. Releases the lock. + */ LazyRuntimeFunction SyncExitFn; private: + /** + * Function called if fast enumeration detects that the collection is + * modified during the update. + */ LazyRuntimeFunction EnumerationMutationFn; + /** + * Function for implementing synthesized property getters that return an + * object. + */ LazyRuntimeFunction GetPropertyFn; + /** + * Function for implementing synthesized property setters that return an + * object. + */ LazyRuntimeFunction SetPropertyFn; + /** + * Function used for non-object declared property getters. + */ LazyRuntimeFunction GetStructPropertyFn; + /** + * Function used for non-object declared property setters. + */ LazyRuntimeFunction SetStructPropertyFn; - // The version of the runtime that this class targets. Must match the version - // in the runtime. + /** + * The version of the runtime that this class targets. Must match the + * version in the runtime. + */ const int RuntimeVersion; - // The version of the protocol class. Used to differentiate between ObjC1 - // and ObjC2 protocols. + /** + * The version of the protocol class. Used to differentiate between ObjC1 + * and ObjC2 protocols. Objective-C 1 protocols can not contain optional + * components and can not contain declared properties. We always emit + * Objective-C 2 property structures, but we have to pretend that they're + * Objective-C 1 property structures when targeting the GCC runtime or it + * will abort. + */ const int ProtocolVersion; private: + /** + * Generates an instance variable list structure. This is a structure + * containing a size and an array of structures containing instance variable + * metadata. This is used purely for introspection in the fragile ABI. In + * the non-fragile ABI, it's used for instance variable fixup. + */ llvm::Constant *GenerateIvarList( const llvm::SmallVectorImpl &IvarNames, const llvm::SmallVectorImpl &IvarTypes, const llvm::SmallVectorImpl &IvarOffsets); + /** + * Generates a method list structure. This is a structure containing a size + * and an array of structures containing method metadata. + * + * This structure is used by both classes and categories, and contains a next + * pointer allowing them to be chained together in a linked list. + */ llvm::Constant *GenerateMethodList(const llvm::StringRef &ClassName, const llvm::StringRef &CategoryName, const llvm::SmallVectorImpl &MethodSels, const llvm::SmallVectorImpl &MethodTypes, bool isClassMethodList); + /** + * Emits an empty protocol. This is used for @protocol() where no protocol + * is found. The runtime will (hopefully) fix up the pointer to refer to the + * real protocol. + */ llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName); + /** + * Generates a list of property metadata structures. This follows the same + * pattern as method and instance variable metadata lists. + */ llvm::Constant *GeneratePropertyList(const ObjCImplementationDecl *OID, llvm::SmallVectorImpl &InstanceMethodSels, llvm::SmallVectorImpl &InstanceMethodTypes); + /** + * Generates a list of referenced protocols. Classes, categories, and + * protocols all use this structure. + */ llvm::Constant *GenerateProtocolList( const llvm::SmallVectorImpl &Protocols); - // To ensure that all protocols are seen by the runtime, we add a category on - // a class defined in the runtime, declaring no methods, but adopting the - // protocols. + /** + * To ensure that all protocols are seen by the runtime, we add a category on + * a class defined in the runtime, declaring no methods, but adopting the + * protocols. This is a horribly ugly hack, but it allows us to collect all + * of the protocols without changing the ABI. + */ void GenerateProtocolHolderCategory(void); + /** + * Generates a class structure. + */ llvm::Constant *GenerateClassStructure( llvm::Constant *MetaClass, llvm::Constant *SuperClass, @@ -277,19 +501,44 @@ private: llvm::Constant *IvarOffsets, llvm::Constant *Properties, bool isMeta=false); + /** + * Generates a method list. This is used by protocols to define the required + * and optional methods. + */ llvm::Constant *GenerateProtocolMethodList( const llvm::SmallVectorImpl &MethodNames, const llvm::SmallVectorImpl &MethodTypes); + /** + * Returns a selector with the specified type encoding. An empty string is + * used to return an untyped selector (with the types field set to NULL). + */ llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, const std::string &TypeEncoding, bool lval); + /** + * Returns the variable used to store the offset of an instance variable. + */ llvm::GlobalVariable *ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, const ObjCIvarDecl *Ivar); + /** + * Emits a reference to a class. This allows the linker to object if there + * is no class of the matching name. + */ void EmitClassRef(const std::string &className); protected: + /** + * Looks up the method for sending a message to the specified object. This + * mechanism differs between the GCC and GNU runtimes, so this method must be + * overridden in subclasses. + */ virtual llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver, llvm::Value *cmd, llvm::MDNode *node) = 0; + /** + * Looks up the method for sending a message to a superclass. This mechanism + * differs between the GCC and GNU runtimes, so this method must be + * overridden in subclasses. + */ virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, llvm::Value *ObjCSuper, llvm::Value *cmd) = 0; -- 2.40.0